Skip to content

Commit

Permalink
Move the focus state from Panel up to widgetry in general, so two dif…
Browse files Browse the repository at this point in the history
…ferent panels don't clash
  • Loading branch information
dabreegster committed Oct 15, 2021
1 parent 698e26a commit 7d57deb
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 15 deletions.
10 changes: 10 additions & 0 deletions widgetry/src/event_ctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ pub struct EventCtx<'a> {
pub(crate) style: &'a mut Style,
pub(crate) updates_requested: Vec<UpdateType>,
pub(crate) canvas_movement_called: bool,

/// This widget (in some panel) exclusively owns focus. Don't modify.
pub(crate) focus_owned_by: Option<String>,
/// While handling an event, this widget (in some panel) this widget declared that it owns
/// focus. This will become `focus_owned_by` during the next event.
pub(crate) next_focus_owned_by: Option<String>,
}

impl<'a> EventCtx<'a> {
Expand Down Expand Up @@ -84,6 +90,8 @@ impl<'a> EventCtx<'a> {
style: self.style,
updates_requested: vec![],
canvas_movement_called: false,
focus_owned_by: None,
next_focus_owned_by: None,
};
let result = cb(&mut tmp);
self.updates_requested.extend(tmp.updates_requested);
Expand Down Expand Up @@ -268,6 +276,8 @@ impl<'a> LoadingScreen<'a> {
style: &mut self.style,
updates_requested: vec![],
canvas_movement_called: false,
focus_owned_by: None,
next_focus_owned_by: None,
};

let mut txt = Text::from(Line(&self.title).small_heading());
Expand Down
17 changes: 16 additions & 1 deletion widgetry/src/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ pub(crate) struct State<A: SharedAppState> {
pub(crate) app: App<A>,
pub(crate) canvas: Canvas,
style: Style,

focus_owned_by: Option<String>,
}

impl<A: SharedAppState> State<A> {
Expand Down Expand Up @@ -108,9 +110,15 @@ impl<A: SharedAppState> State<A> {
style: &mut self.style,
updates_requested: vec![],
canvas_movement_called: false,

focus_owned_by: self.focus_owned_by.take(),
// If the widget owning focus doesn't renew it, then it'll expire by the end of
// this event.
next_focus_owned_by: None,
};
let started = Instant::now();
self.app.event(&mut ctx);
self.focus_owned_by = ctx.next_focus_owned_by.take();
if DEBUG_PERFORMANCE {
println!("- event() took {}s", elapsed_seconds(started));
}
Expand Down Expand Up @@ -356,6 +364,8 @@ pub fn run<
style: &mut style,
updates_requested: vec![],
canvas_movement_called: false,
focus_owned_by: None,
next_focus_owned_by: None,
});
timer.stop("setup app");
let app = App {
Expand All @@ -364,7 +374,12 @@ pub fn run<
};
timer.done();

let mut state = State { app, canvas, style };
let mut state = State {
app,
canvas,
style,
focus_owned_by: None,
};

let dump_raw_events = settings.dump_raw_events;

Expand Down
2 changes: 1 addition & 1 deletion widgetry/src/widgets/containers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl WidgetImpl for Container {

fn event(&mut self, ctx: &mut EventCtx, output: &mut WidgetOutput) {
for w in &mut self.members {
if let Some(id) = output.prev_focus_owned_by.as_ref() {
if let Some(id) = ctx.focus_owned_by.as_ref() {
// Container is the only place that needs to actually enforce focus. If a Panel
// consists of only one top-level widget, then there's nothing else to conflict
// with focus. And in the common case, we have a tree of Containers, with
Expand Down
3 changes: 0 additions & 3 deletions widgetry/src/widgets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,13 @@ pub struct WidgetOutput {
/// This widget produced an Outcome, and event handling should immediately stop. Most widgets
/// shouldn't set this.
pub outcome: Outcome,
/// This widget exclusively owned focus as of the last event. Don't modify.
pub prev_focus_owned_by: Option<String>,
}

impl WidgetOutput {
pub fn new() -> WidgetOutput {
WidgetOutput {
redo_layout: false,
outcome: Outcome::Nothing,
prev_focus_owned_by: None,
}
}
}
Expand Down
12 changes: 2 additions & 10 deletions widgetry/src/widgets/panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ pub struct Panel {
contents_dims: ScreenDims,
container_dims: ScreenDims,
clip_rect: Option<ScreenRectangle>,

// TODO Currently this only works for widgets in the same Panel, but this should handle all
// Panels on-screen.
focus_owned_by: Option<String>,
}

impl Panel {
Expand Down Expand Up @@ -310,9 +306,6 @@ impl Panel {

let before = self.scroll_offset();
let mut output = WidgetOutput::new();
// If the widget owning focus doesn't renew it, then it'll expire by the end of this event.
output.prev_focus_owned_by = self.focus_owned_by.take();

self.top_level.widget.event(ctx, &mut output);

if output.redo_layout {
Expand All @@ -323,7 +316,8 @@ impl Panel {

// Remember this for the next event
if let Outcome::Focused(ref id) = output.outcome {
self.focus_owned_by = Some(id.clone());
assert!(ctx.next_focus_owned_by.is_none());
ctx.next_focus_owned_by = Some(id.clone());
}

output.outcome
Expand Down Expand Up @@ -616,8 +610,6 @@ impl PanelBuilder {
container_dims: ScreenDims::new(0.0, 0.0),
clip_rect: None,
cached_flexbox: None,

focus_owned_by: None,
};
match panel.dims {
Dims::ExactPercent(w, h) => {
Expand Down

0 comments on commit 7d57deb

Please sign in to comment.