@@ -9,7 +9,7 @@ build = "src/build.rs" | |||
cstr = "0.1.0" | |||
cpp = "0.5" | |||
tokio = "0.1.15" | |||
huey = { git = "https://git.vpzom.click/vpzom/huey", rev = "0b62be" } | |||
huey = { git = "https://git.vpzom.click/vpzom/huey", rev = "6b67e0b" } | |||
# huey = { path = "../hueclient" } | |||
futures = "0.1.25" | |||
try_future = "0.1.3" | |||
@@ -410,6 +410,34 @@ ApplicationWindow { | |||
Item { Layout.preferredWidth: 2 } | |||
} | |||
} | |||
ItemDelegate { | |||
Layout.fillWidth: true | |||
visible: !light.state.color.valid && light.state.ct_valid | |||
RowLayout { | |||
height: parent.height | |||
width: parent.width | |||
Item { | |||
Layout.preferredWidth: 8 | |||
} | |||
Label { | |||
text: tr.gettext("Color Temperature") | |||
verticalAlignment: Text.AlignVCenter | |||
} | |||
Item { Layout.fillWidth: true } | |||
Slider { | |||
from: light.ct_min | |||
to: light.ct_max | |||
value: light.state.ct | |||
stepSize: 1 | |||
onMoved: { | |||
console.log(value); | |||
connector.start_set_light_ct(lightID, value); | |||
} | |||
} | |||
Item { Layout.preferredWidth: 2 } | |||
} | |||
} | |||
} | |||
BridgeConnectionConnector { | |||
@@ -7,12 +7,21 @@ pub struct RadiateLight { | |||
name_changed: qt_signal!(), | |||
state: qt_property!(RadiateLightState; NOTIFY state_changed), | |||
state_changed: qt_signal!(), | |||
ct_min: qt_property!(u16; NOTIFY ct_min_changed), | |||
ct_min_changed: qt_signal!(), | |||
ct_max: qt_property!(u16; NOTIFY ct_max_changed), | |||
ct_max_changed: qt_signal!(), | |||
} | |||
#[derive(QGadget, Default, Clone)] | |||
pub struct RadiateLightState { | |||
on: qt_property!(bool), | |||
bri: qt_property!(u8), | |||
ct_valid: qt_property!(bool), | |||
ct: qt_property!(u16), | |||
color: qt_property!(RadiateLightColorState), | |||
} | |||
@@ -27,6 +36,15 @@ impl From<&huey::connection::Light> for RadiateLight { | |||
fn from(light: &huey::connection::Light) -> Self { | |||
let mut result: Self = Default::default(); | |||
result.name = light.name.clone(); | |||
if let Some(ref cap) = light.capabilities.control.ct { | |||
result.ct_min = cap.min; | |||
result.ct_max = cap.max; | |||
} else { | |||
result.ct_min = 233; | |||
result.ct_max = 233; | |||
} | |||
result.state.on = light.state.on; | |||
result.state.bri = light.state.bri; | |||
if let Some(ref color) = light.state.color { | |||
@@ -34,6 +52,13 @@ impl From<&huey::connection::Light> for RadiateLight { | |||
result.state.color.hue = color.hue; | |||
result.state.color.sat = color.sat; | |||
} | |||
if let Some(ct) = light.state.ct { | |||
result.state.ct_valid = true; | |||
result.state.ct = ct; | |||
} else { | |||
result.state.ct_valid = false; | |||
result.state.ct = 233; // probably doesn't matter anyway | |||
} | |||
result | |||
} | |||
@@ -43,6 +43,7 @@ pub struct BridgeConnectionConnector { | |||
start_set_light_brightness: qt_method!(fn(&self, id: String, new_value: u8)), | |||
start_set_light_hue: qt_method!(fn(&self, id: String, new_value: u16)), | |||
start_set_light_saturation: qt_method!(fn(&self, id: String, new_value: u8)), | |||
start_set_light_ct: qt_method!(fn(&self, id: String, new_value: u16)), | |||
lights_changed: qt_signal!(), | |||
light_changed: qt_signal!(id: String), | |||
@@ -55,6 +56,7 @@ pub struct BridgeConnectionConnector { | |||
brightness_queue: Arc<Mutex<HashMap<String, u8>>>, | |||
hue_queue: Arc<Mutex<HashMap<String, u16>>>, | |||
saturation_queue: Arc<Mutex<HashMap<String, u8>>>, | |||
ct_queue: Arc<Mutex<HashMap<String, u16>>>, | |||
} | |||
fn new_qobject(parent: &QObject, object: impl QObject) -> QJSValue { | |||
@@ -166,6 +168,24 @@ fn set_saturation_loop(saturation_queue: Arc<Mutex<HashMap<String, u8>>>, id: St | |||
}, saturation_queue, id, new_value, callback) | |||
} | |||
fn set_ct_loop(ct_queue: Arc<Mutex<HashMap<String, u16>>>, id: String, new_value: u16, callback: Box<Fn() + Send>) -> Box<Future<Item=(), Error=()> + Send> { | |||
set_prop_loop(|id, new_value| { | |||
if let Some(ref state) = *STATE.read().unwrap() { | |||
Box::new(state.connection.set_light_color_temperature(id, new_value)) | |||
} else { | |||
panic!("STATE missing"); | |||
} | |||
}, |id, new_value| { | |||
if let Some(ref mut state) = *STATE.write().unwrap() { | |||
if let Some(ref mut lights) = state.lights { | |||
if let Some(ref mut light) = lights.get_mut(id) { | |||
light.state.ct = Some(new_value); | |||
} | |||
} | |||
} | |||
}, ct_queue, id, new_value, callback) | |||
} | |||
impl BridgeConnectionConnector { | |||
fn init(&mut self, address: String, username: String) { | |||
{ | |||
@@ -342,6 +362,22 @@ impl BridgeConnectionConnector { | |||
} | |||
} | |||
fn start_set_light_ct(&self, id: String, new_value: u16) { | |||
let mut queue = self.ct_queue.lock().unwrap(); | |||
let old_value = queue.insert(id.clone(), new_value); | |||
if old_value == None { | |||
let callback = { | |||
let ptr = QPointer::from(&*self); | |||
let id = id.clone(); | |||
queued_callback(move |_| { | |||
ptr.as_ref().map(|x| x.light_changed(id.clone())); | |||
}) | |||
}; | |||
tokio::spawn(set_ct_loop(self.ct_queue.clone(), id, new_value, Box::new(move || callback(())))); | |||
} | |||
} | |||
fn get_groups(&self) -> QVariant { | |||
if let Some(ref state) = *STATE.read().unwrap() { | |||
if let Some(ref groups) = state.groups { | |||