-
Notifications
You must be signed in to change notification settings - Fork 568
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add hot glow option to multiwin example. #845
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,23 +14,25 @@ | |
|
||
//! Opening and closing windows and using window and context menus. | ||
|
||
use druid::widget::{Align, Button, Flex, Label, Padding}; | ||
use druid::widget::prelude::*; | ||
use druid::widget::{Align, BackgroundBrush, Button, Flex, Label, Padding}; | ||
use druid::{ | ||
commands as sys_cmds, AppDelegate, AppLauncher, Command, ContextMenu, Data, DelegateCtx, Env, | ||
Event, EventCtx, LocalizedString, MenuDesc, MenuItem, Selector, Target, Widget, WindowDesc, | ||
WindowId, | ||
commands as sys_cmds, AppDelegate, AppLauncher, Color, Command, ContextMenu, Data, DelegateCtx, | ||
LocalizedString, MenuDesc, MenuItem, Selector, Target, WidgetPod, WindowDesc, WindowId, | ||
}; | ||
|
||
use log::info; | ||
|
||
const MENU_COUNT_ACTION: Selector = Selector::new("menu-count-action"); | ||
const MENU_INCREMENT_ACTION: Selector = Selector::new("menu-increment-action"); | ||
const MENU_DECREMENT_ACTION: Selector = Selector::new("menu-decrement-action"); | ||
const MENU_SWITCH_GLOW_ACTION: Selector = Selector::new("menu-switch-glow"); | ||
|
||
#[derive(Debug, Clone, Default, Data)] | ||
struct State { | ||
menu_count: usize, | ||
selected: usize, | ||
glow_hot: bool, | ||
} | ||
|
||
pub fn main() { | ||
|
@@ -79,7 +81,58 @@ fn ui_builder() -> impl Widget<State> { | |
row.add_child(Padding::new(5.0, inc_button)); | ||
row.add_child(Padding::new(5.0, dec_button)); | ||
col.add_flex_child(Align::centered(row), 1.0); | ||
col | ||
Glow::new(col) | ||
} | ||
|
||
struct Glow<W> { | ||
inner: WidgetPod<State, W>, | ||
} | ||
|
||
impl<W: Widget<State>> Glow<W> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just a note: I think you could have achieved this using a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps in some way, but it wasn't super obvious. Like the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh huh for some reason I thought it did repaint on hot. My mistake! I wonder if it makes sense to just make 'paint on hot' be an option for painter? but that's a small thing. |
||
pub fn new(inner: W) -> Glow<W> { | ||
Glow { | ||
inner: WidgetPod::new(inner), | ||
} | ||
} | ||
} | ||
|
||
impl<W: Widget<State>> Widget<State> for Glow<W> { | ||
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut State, env: &Env) { | ||
self.inner.event(ctx, event, data, env); | ||
} | ||
|
||
fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &State, env: &Env) { | ||
if let LifeCycle::HotChanged(_) = event { | ||
ctx.request_paint(); | ||
} | ||
self.inner.lifecycle(ctx, event, data, env); | ||
} | ||
|
||
fn update(&mut self, ctx: &mut UpdateCtx, old_data: &State, data: &State, env: &Env) { | ||
if old_data.glow_hot != data.glow_hot { | ||
ctx.request_paint(); | ||
} | ||
self.inner.update(ctx, data, env); | ||
} | ||
|
||
fn layout( | ||
&mut self, | ||
ctx: &mut LayoutCtx, | ||
bc: &BoxConstraints, | ||
data: &State, | ||
env: &Env, | ||
) -> Size { | ||
let size = self.inner.layout(ctx, bc, data, env); | ||
self.inner.set_layout_rect(ctx, data, env, size.to_rect()); | ||
size | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. a general note; I think it's good to call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, my inspiration came from |
||
} | ||
|
||
fn paint(&mut self, ctx: &mut PaintCtx, data: &State, env: &Env) { | ||
if data.glow_hot && ctx.is_hot() { | ||
BackgroundBrush::Color(Color::rgb8(200, 55, 55)).paint(ctx, data, env); | ||
} | ||
self.inner.paint(ctx, data, env); | ||
} | ||
} | ||
|
||
struct Delegate; | ||
|
@@ -144,6 +197,10 @@ impl AppDelegate<State> for Delegate { | |
ctx.submit_command(cmd, *id); | ||
false | ||
} | ||
(_, &MENU_SWITCH_GLOW_ACTION) => { | ||
data.glow_hot = !data.glow_hot; | ||
false | ||
} | ||
_ => true, | ||
} | ||
} | ||
|
@@ -207,4 +264,8 @@ fn make_context_menu<T: Data>() -> MenuDesc<T> { | |
LocalizedString::new("Decrement"), | ||
MENU_DECREMENT_ACTION, | ||
)) | ||
.append(MenuItem::new( | ||
LocalizedString::new("Glow when hot"), | ||
MENU_SWITCH_GLOW_ACTION, | ||
)) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if a widget is entirely transparent for the purposes of event handling and layout (it is just passing things through) then WidgetPod is unnecessary. It doesn't hurt in any meaningful way, but it is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really needs to be written down 😅