move button to titlebar and add global brightness slider

This commit is contained in:
LordMZTE 2021-10-24 00:31:23 +02:00
parent 8d5eedc1e9
commit 74f7775691
3 changed files with 88 additions and 51 deletions

View file

@ -10,11 +10,15 @@ use super::Msg;
pub struct HeaderBarModel { pub struct HeaderBarModel {
settings: Component<Settings>, settings: Component<Settings>,
rootwintx: Sender<Msg>,
} }
#[derive(Clone, Msg)] #[derive(Clone, Msg)]
pub enum HeaderBarMsg { pub enum HeaderBarMsg {
OpenSettings, OpenSettings,
RefreshLights,
SelectAll,
DeselectAll,
} }
#[widget] #[widget]
@ -23,6 +27,7 @@ impl Widget for HeaderBar {
HeaderBarModel { HeaderBarModel {
settings: relm::init::<Settings>((data.0.clone(), data.2, data.3)) settings: relm::init::<Settings>((data.0.clone(), data.2, data.3))
.expect("failed to create settings window"), .expect("failed to create settings window"),
rootwintx: data.1,
} }
} }
fn update(&mut self, msg: HeaderBarMsg) { fn update(&mut self, msg: HeaderBarMsg) {
@ -30,6 +35,18 @@ impl Widget for HeaderBar {
HeaderBarMsg::OpenSettings => { HeaderBarMsg::OpenSettings => {
self.model.settings.widget().show(); self.model.settings.widget().show();
}, },
HeaderBarMsg::RefreshLights => {
let _ = self.model.rootwintx.send(Msg::RefreshLights);
},
HeaderBarMsg::SelectAll => {
let _ = self.model.rootwintx.send(Msg::SelectAll);
},
HeaderBarMsg::DeselectAll => {
let _ = self.model.rootwintx.send(Msg::DeselectAll);
},
} }
} }
@ -42,7 +59,25 @@ impl Widget for HeaderBar {
image: Some(&gtk::Image::from_icon_name(Some("preferences-system"), gtk::IconSize::LargeToolbar)), image: Some(&gtk::Image::from_icon_name(Some("preferences-system"), gtk::IconSize::LargeToolbar)),
clicked => HeaderBarMsg::OpenSettings, clicked => HeaderBarMsg::OpenSettings,
} },
gtk::Button {
image: Some(&gtk::Image::from_icon_name(Some("view-refresh"), gtk::IconSize::LargeToolbar)),
clicked => HeaderBarMsg::RefreshLights,
},
gtk::Button {
label: "Select All",
clicked => HeaderBarMsg::SelectAll,
},
gtk::Button {
label: "Deselect All",
clicked => HeaderBarMsg::DeselectAll,
},
} }
} }
} }

View file

@ -15,7 +15,7 @@ pub struct LightEntryModel {
name: String, name: String,
runtime: UnboundedSender<RuntimeMsg>, runtime: UnboundedSender<RuntimeMsg>,
on: bool, on: bool,
brightness: u8, brightness: f64,
color: Rc<Cell<Rgb<f64>>>, color: Rc<Cell<Rgb<f64>>>,
} }
@ -39,7 +39,7 @@ impl Widget for LightEntry {
name: params.1.name, name: params.1.name,
runtime: params.2, runtime: params.2,
on: params.1.state.on, on: params.1.state.on,
brightness: params.1.state.bri, brightness: params.1.state.bri as f64,
color: Rc::new(Cell::new( color: Rc::new(Cell::new(
Hsv::new( Hsv::new(
Turns(params.1.state.hue as f64 / 65535f64), Turns(params.1.state.hue as f64 / 65535f64),
@ -56,18 +56,21 @@ impl Widget for LightEntry {
LightEntryMsg::Update(upd) => { LightEntryMsg::Update(upd) => {
debug!("updating light {}", &self.model.id); debug!("updating light {}", &self.model.id);
if let (Some(h), Some(s), Some(v)) = (upd.hue, upd.sat, upd.bri) { if let (Some(h), Some(s), Some(v)) = (upd.hue, upd.sat, upd.bri) {
self.model.color.set( let hsv = Hsv::new(
Hsv::new( Turns(h as f64 / 65535f64),
Turns(h as f64 / 65535f64), s as f64 / 255f64,
s as f64 / 255f64, v as f64 / 255f64,
v as f64 / 255f64,
)
.into(),
); );
self.model.color.set(hsv.into());
self.widgets.color_indicator.queue_draw(); self.widgets.color_indicator.queue_draw();
} }
if let Some(bri) = upd.bri {
self.model.brightness = bri as f64;
}
if let Some(on) = upd.on { if let Some(on) = upd.on {
self.model.on = on; self.model.on = on;
} }
@ -115,7 +118,7 @@ impl Widget for LightEntry {
self.widgets.brightness_slider.set_increments(1., 0.); self.widgets.brightness_slider.set_increments(1., 0.);
self.widgets self.widgets
.brightness_slider .brightness_slider
.set_value(self.model.brightness as f64); .set_value(self.model.brightness);
let col = Rc::clone(&self.model.color); let col = Rc::clone(&self.model.color);
self.widgets.color_indicator.connect_draw(move |_, c| { self.widgets.color_indicator.connect_draw(move |_, c| {
@ -147,11 +150,12 @@ impl Widget for LightEntry {
#[name = "brightness_slider"] #[name = "brightness_slider"]
gtk::Scale { gtk::Scale {
value: self.model.brightness as f64, value: self.model.brightness,
value_changed => LightEntryMsg::PropertyChanged(EntryLightProperty::Brightness),
width_request: 200, width_request: 200,
draw_value: false, draw_value: false,
margin: 4, margin: 4,
value_changed => LightEntryMsg::PropertyChanged(EntryLightProperty::Brightness),
}, },
gtk::Label { gtk::Label {

View file

@ -39,6 +39,7 @@ pub enum Msg {
pub enum LightProperty { pub enum LightProperty {
On, On,
Color, Color,
Brightness,
} }
#[widget] #[widget]
@ -70,7 +71,11 @@ impl Widget for Win {
Msg::PropertyChanged(prop) => { Msg::PropertyChanged(prop) => {
let rgba = self.widgets.color_chooser.rgba(); let rgba = self.widgets.color_chooser.rgba();
let rgb = Rgb::new(rgba.red, rgba.green, rgba.blue); let rgb = Rgb::new(rgba.red, rgba.green, rgba.blue);
let hsv = Hsv::<_, Turns<_>>::from(rgb); let mut hsv = Hsv::<_, Turns<_>>::from(rgb);
if prop == LightProperty::Brightness {
hsv.set_value(self.widgets.brightness_slider.value() / 255f64);
}
let upd = StateUpdate { let upd = StateUpdate {
hue: if prop == LightProperty::Color { hue: if prop == LightProperty::Color {
@ -83,7 +88,7 @@ impl Widget for Win {
} else { } else {
None None
}, },
bri: if prop == LightProperty::Color { bri: if prop == LightProperty::Color || prop == LightProperty::Brightness {
Some((hsv.value() * 255f64) as u8) Some((hsv.value() * 255f64) as u8)
} else { } else {
None None
@ -144,6 +149,11 @@ impl Widget for Win {
} }
} }
fn init_view(&mut self) {
self.widgets.brightness_slider.set_range(0., 255.);
self.widgets.brightness_slider.set_increments(1., 0.);
}
view! { view! {
gtk::Window { gtk::Window {
titlebar: Some(self.model.headerbar.widget()), titlebar: Some(self.model.headerbar.widget()),
@ -151,43 +161,13 @@ impl Widget for Win {
gtk::Box { gtk::Box {
orientation: Orientation::Horizontal, orientation: Orientation::Horizontal,
gtk::Box { gtk::Frame {
orientation: Orientation::Vertical, label: Some("Lights"),
hexpand: true,
gtk::Box { #[name = "lights_list"]
orientation: Orientation::Horizontal, gtk::ListBox {
selection_mode: SelectionMode::Multiple,
gtk::Spinner {
active: self.model.spinning,
},
gtk::Button {
image: Some(&gtk::Image::from_icon_name(Some("view-refresh"), gtk::IconSize::LargeToolbar)),
clicked => Msg::RefreshLights,
},
gtk::Button {
label: "Select All",
clicked => Msg::SelectAll,
},
gtk::Button {
label: "Deselect All",
clicked => Msg::DeselectAll,
},
},
gtk::Frame {
label: Some("Lights"),
hexpand: true,
#[name = "lights_list"]
gtk::ListBox {
selection_mode: SelectionMode::Multiple,
}
} }
}, },
@ -215,6 +195,24 @@ impl Widget for Win {
#[name = "on_switch"] #[name = "on_switch"]
gtk::Switch { gtk::Switch {
state_set(_, _) => (Msg::PropertyChanged(LightProperty::On), Inhibit(false)), state_set(_, _) => (Msg::PropertyChanged(LightProperty::On), Inhibit(false)),
margin: 4,
},
},
gtk::Box {
orientation: Orientation::Horizontal,
gtk::Label {
text: "Brightness",
},
#[name = "brightness_slider"]
gtk::Scale {
value: 0.,
hexpand: true,
draw_value: false,
margin: 4,
value_changed => Msg::PropertyChanged(LightProperty::Brightness),
}, },
} }
} }