diff --git a/emigui/src/containers/area.rs b/emigui/src/containers/area.rs index 64e4b5a6..ce1e8f24 100644 --- a/emigui/src/containers/area.rs +++ b/emigui/src/containers/area.rs @@ -24,12 +24,11 @@ pub(crate) struct State { pub vel: Vec2, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] pub struct Area { - id: Id, + layer: Layer, movable: bool, interactable: bool, - order: Order, default_pos: Option, fixed_pos: Option, } @@ -37,20 +36,19 @@ pub struct Area { impl Area { pub fn new(id_source: impl Hash) -> Self { Self { - id: Id::new(id_source), + layer: Layer { + id: Id::new(id_source), + order: Order::Middle, + }, movable: true, interactable: true, - order: Order::Middle, default_pos: None, fixed_pos: None, } } - pub fn layer(&self) -> Layer { - Layer { - order: self.order, - id: self.id, - } + pub fn layer(&self) -> &Layer { + &self.layer } /// moveable by draggin the area? @@ -74,7 +72,7 @@ impl Area { /// `order(Order::Foreground)` for an Area that should always be on top pub fn order(mut self, order: Order) -> Self { - self.order = order; + self.layer.order = order; self } @@ -101,19 +99,17 @@ pub(crate) struct Prepared { impl Area { pub(crate) fn begin(self, ctx: &Arc) -> Prepared { let Area { - id, + mut layer, movable, - order, interactable, default_pos, fixed_pos, } = self; let default_pos = default_pos.unwrap_or_else(|| pos2(100.0, 100.0)); // TODO - let id = ctx.register_unique_id(id, "Area", default_pos); - let layer = Layer { order, id }; + layer.id = ctx.register_unique_id(layer.id, "Area", default_pos); - let mut state = ctx.memory().areas.get(id).unwrap_or_else(|| State { + let mut state = ctx.memory().areas.get(&layer.id).unwrap_or_else(|| State { pos: default_pos, size: Vec2::zero(), interactable, @@ -124,8 +120,7 @@ impl Area { let content_ui = Ui::new( ctx.clone(), - layer, - id, + layer.clone(), Rect::from_min_size(state.pos, Vec2::infinity()), ); @@ -163,8 +158,13 @@ impl Prepared { } else { None }; - let move_interact = - ctx.interact(layer, clip_rect, rect, interact_id, Sense::click_and_drag()); + let move_interact = ctx.interact( + &layer, + clip_rect, + rect, + interact_id.as_ref(), + Sense::click_and_drag(), + ); let input = ctx.input(); if move_interact.active { @@ -199,10 +199,10 @@ impl Prepared { // ); if move_interact.active - || mouse_pressed_on_area(ctx, layer) + || mouse_pressed_on_area(ctx, &layer) || !ctx.memory().areas.visible_last_frame(&layer) { - ctx.memory().areas.move_to_top(layer); + ctx.memory().areas.move_to_top(&layer); } ctx.memory().areas.set_state(layer, state); @@ -210,7 +210,7 @@ impl Prepared { } } -fn mouse_pressed_on_area(ctx: &Context, layer: Layer) -> bool { +fn mouse_pressed_on_area(ctx: &Context, layer: &Layer) -> bool { if let Some(mouse_pos) = ctx.input().mouse.pos { ctx.input().mouse.pressed && ctx.memory().layer_at(mouse_pos) == Some(layer) } else { diff --git a/emigui/src/containers/collapsing_header.rs b/emigui/src/containers/collapsing_header.rs index 71388cec..5d08b808 100644 --- a/emigui/src/containers/collapsing_header.rs +++ b/emigui/src/containers/collapsing_header.rs @@ -28,10 +28,10 @@ impl Default for State { } impl State { - pub fn from_memory_with_default_open(ui: &Ui, id: Id, default_open: bool) -> Self { + pub fn from_memory_with_default_open(ui: &Ui, id: &Id, default_open: bool) -> Self { ui.memory() .collapsing_headers - .entry(id) + .entry(id.clone()) .or_insert(State { open: default_open, ..Default::default() @@ -40,13 +40,20 @@ impl State { } // Helper - pub fn is_open(ctx: &Context, id: Id) -> Option { + pub fn is_open(ctx: &Context, id: &Id) -> Option { ctx.memory() .collapsing_headers - .get(&id) + .get(id) .map(|state| state.open) } + // // Helper + // pub fn toggle_by_id(ui: &Ui, id: &Id) { + // if let Some(state) = ui.memory().collapsing_headers.get_mut(id) { + // state.toggle(ui); + // } + // } + pub fn toggle(&mut self, ui: &Ui) { self.open = !self.open; self.toggle_time = ui.input().time; @@ -196,10 +203,10 @@ impl CollapsingHeader { ); let rect = ui.allocate_space(size); - let interact = ui.interact(rect, id, Sense::click()); + let interact = ui.interact(rect, &id, Sense::click()); let text_pos = pos2(text_pos.x, interact.rect.center().y - galley.size.y / 2.0); - let mut state = State::from_memory_with_default_open(ui, id, default_open); + let mut state = State::from_memory_with_default_open(ui, &id, default_open); if interact.clicked { state.toggle(ui); } @@ -241,7 +248,7 @@ impl CollapsingHeader { pub fn show(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> Option { let Prepared { id, mut state } = self.begin(ui); - let r_interact = state.add_contents(ui, |ui| ui.indent(id, add_contents).0); + let r_interact = state.add_contents(ui, |ui| ui.indent(&id, add_contents).0); let ret = r_interact.map(|ri| ri.0); ui.memory().collapsing_headers.insert(id, state); ret diff --git a/emigui/src/containers/menu.rs b/emigui/src/containers/menu.rs index 466ed481..632c5ecb 100644 --- a/emigui/src/containers/menu.rs +++ b/emigui/src/containers/menu.rs @@ -2,7 +2,7 @@ use crate::{widgets::*, *}; use super::*; -#[derive(Clone, Copy, Debug, serde_derive::Deserialize, serde_derive::Serialize)] +#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)] pub struct BarState { #[serde(skip)] open_menu: Option, @@ -53,7 +53,7 @@ fn menu_impl<'c>( add_contents: Box, ) { let title = title.into(); - let bar_id = ui.id(); + let bar_id = ui.id().clone(); let menu_id = Id::new(&title); let mut bar_state = ui @@ -65,15 +65,15 @@ fn menu_impl<'c>( let mut button = Button::new(title); - if bar_state.open_menu == Some(menu_id) { + if bar_state.open_menu.as_ref() == Some(&menu_id) { button = button.fill(Some(ui.style().interact.active.fill)); } let button_interact = ui.add(button); - interact_with_menu_button(&mut bar_state, ui.input(), menu_id, &button_interact); + interact_with_menu_button(&mut bar_state, ui.input(), &menu_id, &button_interact); - if bar_state.open_menu == Some(menu_id) { + if bar_state.open_menu.as_ref() == Some(&menu_id) { let area = Area::new(menu_id) .order(Order::Foreground) .fixed_pos(button_interact.rect.left_bottom()); @@ -110,14 +110,14 @@ fn menu_impl<'c>( fn interact_with_menu_button( bar_state: &mut BarState, input: &InputState, - menu_id: Id, + menu_id: &Id, button_interact: &GuiResponse, ) { if button_interact.hovered && input.mouse.pressed { if bar_state.open_menu.is_some() { bar_state.open_menu = None; } else { - bar_state.open_menu = Some(menu_id); + bar_state.open_menu = Some(menu_id.clone()); bar_state.open_time = input.time; } } @@ -126,7 +126,7 @@ fn interact_with_menu_button( let time_since_open = input.time - bar_state.open_time; if time_since_open < 0.4 { // A quick click - bar_state.open_menu = Some(menu_id); + bar_state.open_menu = Some(menu_id.clone()); bar_state.open_time = input.time; } else { // A long hold, then release @@ -135,7 +135,7 @@ fn interact_with_menu_button( } if button_interact.hovered && bar_state.open_menu.is_some() { - bar_state.open_menu = Some(menu_id); + bar_state.open_menu = Some(menu_id.clone()); } let pressed_escape = input.events.iter().any(|event| { diff --git a/emigui/src/containers/resize.rs b/emigui/src/containers/resize.rs index 9ee6cd75..d793006f 100644 --- a/emigui/src/containers/resize.rs +++ b/emigui/src/containers/resize.rs @@ -11,7 +11,7 @@ pub(crate) struct State { } // TODO: auto-shink/grow should be part of another container! -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] pub struct Resize { id: Option, @@ -178,7 +178,10 @@ struct Prepared { impl Resize { fn begin(&mut self, ui: &mut Ui) -> Prepared { - let id = self.id.unwrap_or_else(|| ui.make_child_id("resize")); + let id = self + .id + .clone() + .unwrap_or_else(|| ui.make_child_id("resize")); self.min_size = self.min_size.min(ui.available().size()); self.max_size = self.max_size.min(ui.available().size()); self.max_size = self.max_size.max(self.min_size); @@ -209,7 +212,7 @@ impl Resize { position + state.size + self.handle_offset - corner_size, corner_size, ); - let corner_interact = ui.interact(corner_rect, id.with("corner"), Sense::drag()); + let corner_interact = ui.interact(corner_rect, &id.with("corner"), Sense::drag()); if corner_interact.active { if let Some(mouse_pos) = ui.input().mouse.pos { diff --git a/emigui/src/containers/scroll_area.rs b/emigui/src/containers/scroll_area.rs index 0d82f370..aa490cca 100644 --- a/emigui/src/containers/scroll_area.rs +++ b/emigui/src/containers/scroll_area.rs @@ -147,7 +147,7 @@ impl Prepared { if content_is_too_small { // Drag contents to scroll (for touch screens mostly): - let content_interact = ui.interact(inner_rect, id.with("area"), Sense::drag()); + let content_interact = ui.interact(inner_rect, &id.with("area"), Sense::drag()); if content_interact.active { state.offset.y -= ui.input().mouse.delta.y; } @@ -181,7 +181,7 @@ impl Prepared { // intentionally use same id for inside and outside of handle let interact_id = id.with("vertical"); - let mut interact = ui.interact(handle_rect, interact_id, Sense::click_and_drag()); + let mut interact = ui.interact(handle_rect, &interact_id, Sense::click_and_drag()); if let Some(mouse_pos) = ui.input().mouse.pos { if interact.active { @@ -192,7 +192,7 @@ impl Prepared { } else { // Check for mouse down outside handle: let scroll_bg_interact = - ui.interact(outer_scroll_rect, interact_id, Sense::click_and_drag()); + ui.interact(outer_scroll_rect, &interact_id, Sense::click_and_drag()); if scroll_bg_interact.active { // Center scroll at mouse pos: diff --git a/emigui/src/containers/window.rs b/emigui/src/containers/window.rs index 20f63d24..4a11704a 100644 --- a/emigui/src/containers/window.rs +++ b/emigui/src/containers/window.rs @@ -149,21 +149,19 @@ impl<'open> Window<'open> { } let window_id = Id::new(title_label.text()); - let area_layer = area.layer(); let resize_id = window_id.with("resize"); let collapsing_id = window_id.with("collapsing"); let possible = PossibleInteractions { movable: area.is_movable(), resizable: resize.is_resizable() - && collapsing_header::State::is_open(ctx, collapsing_id).unwrap_or_default(), + && collapsing_header::State::is_open(ctx, &collapsing_id).unwrap_or_default(), }; let area = area.movable(false); // We move it manually + let area_layer = area.layer().clone(); let resize = resize.resizable(false); // We move it manually - - let resize = resize.id(resize_id); - + let resize = resize.id(resize_id.clone()); let frame = frame.unwrap_or_else(|| Frame::window(&ctx.style())); let mut area = area.begin(ctx); @@ -174,7 +172,7 @@ impl<'open> Window<'open> { let default_expanded = true; let mut collapsing = collapsing_header::State::from_memory_with_default_open( &mut frame.content_ui, - collapsing_id, + &collapsing_id, default_expanded, ); let show_close_button = open.is_some(); @@ -182,7 +180,7 @@ impl<'open> Window<'open> { &mut frame.content_ui, title_label, show_close_button, - collapsing_id, + &collapsing_id, &mut collapsing, ); @@ -208,16 +206,16 @@ impl<'open> Window<'open> { interact( ctx, possible, - area_layer, + &area_layer, &mut area.state, - window_id, - resize_id, + &window_id, + &resize_id, outer_rect, ) } else { None }; - let hover_interaction = resize_hover(ctx, possible, area_layer, outer_rect); + let hover_interaction = resize_hover(ctx, possible, &area_layer, outer_rect); title_bar.ui( &mut area.content_ui, @@ -264,7 +262,7 @@ struct PossibleInteractions { resizable: bool, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] pub(crate) struct WindowInteraction { pub(crate) area_layer: Layer, pub(crate) start_rect: Rect, @@ -299,10 +297,10 @@ impl WindowInteraction { fn interact( ctx: &Context, possible: PossibleInteractions, - area_layer: Layer, + area_layer: &Layer, area_state: &mut area::State, - window_id: Id, - resize_id: Id, + window_id: &Id, + resize_id: &Id, rect: Rect, ) -> Option { let pre_resize = ctx.round_rect_to_pixels(rect); @@ -310,7 +308,7 @@ fn interact( ctx, possible, area_layer, - window_id.with("frame_resize"), + &window_id.with("frame_resize"), rect, )?; let new_rect = resize_window(ctx, &window_interaction)?; @@ -324,9 +322,9 @@ fn interact( // resize_state.size += new_rect.size() - pre_resize.size(); // resize_state.size = new_rect.size() - some margin; resize_state.requested_size = Some(resize_state.size + new_rect.size() - pre_resize.size()); - ctx.memory().resize.insert(resize_id, resize_state); + ctx.memory().resize.insert(resize_id.clone(), resize_state); - ctx.memory().areas.move_to_top(area_layer); + ctx.memory().areas.move_to_top(&area_layer); Some(window_interaction) } @@ -358,14 +356,14 @@ fn resize_window(ctx: &Context, window_interaction: &WindowInteraction) -> Optio fn window_interaction( ctx: &Context, possible: PossibleInteractions, - area_layer: Layer, - id: Id, + area_layer: &Layer, + id: &Id, rect: Rect, ) -> Option { { - let drag_id = ctx.memory().interaction.drag_id; + let drag_id = ctx.memory().interaction.drag_id.clone(); - if drag_id.is_some() && drag_id != Some(id) { + if drag_id.is_some() && drag_id.as_ref() != Some(id) { return None; } } @@ -376,17 +374,17 @@ fn window_interaction( if let Some(hover_window_interaction) = resize_hover(ctx, possible, area_layer, rect) { hover_window_interaction.set_cursor(ctx); if ctx.input().mouse.pressed { - ctx.memory().interaction.drag_id = Some(id); + ctx.memory().interaction.drag_id = Some(id.clone()); window_interaction = Some(hover_window_interaction); - ctx.memory().window_interaction = window_interaction; + ctx.memory().window_interaction = window_interaction.clone(); } } } if let Some(window_interaction) = window_interaction { - let is_active = ctx.memory().interaction.drag_id == Some(id); + let is_active = ctx.memory().interaction.drag_id.as_ref() == Some(id); - if is_active && window_interaction.area_layer == area_layer { + if is_active && &window_interaction.area_layer == area_layer { return Some(window_interaction); } } @@ -397,7 +395,7 @@ fn window_interaction( fn resize_hover( ctx: &Context, possible: PossibleInteractions, - area_layer: Layer, + area_layer: &Layer, rect: Rect, ) -> Option { if let Some(mouse_pos) = ctx.input().mouse.pos { @@ -451,7 +449,7 @@ fn resize_hover( if any_resize || possible.movable { Some(WindowInteraction { - area_layer, + area_layer: area_layer.clone(), start_rect: rect, left, right, @@ -528,7 +526,7 @@ fn show_title_bar( ui: &mut Ui, title_label: Label, show_close_button: bool, - collapsing_id: Id, + collapsing_id: &Id, collapsing: &mut collapsing_header::State, ) -> TitleBar { let title_bar_and_rect = ui.inner_layout(Layout::horizontal(Align::Center), |ui| { @@ -618,7 +616,7 @@ impl TitleBar { let title_bar_id = ui.make_child_id("title_bar"); if ui - .interact(self.rect, title_bar_id, Sense::click()) + .interact(self.rect, &title_bar_id, Sense::click()) .double_clicked { collapsing.toggle(ui); @@ -641,7 +639,7 @@ impl TitleBar { fn close_button(ui: &mut Ui, rect: Rect) -> InteractInfo { let close_id = ui.make_child_id("window_close_button"); - let interact = ui.interact(rect, close_id, Sense::click()); + let interact = ui.interact(rect, &close_id, Sense::click()); ui.expand_to_include_child(interact.rect); let stroke_color = ui.style().interact(&interact).stroke_color; diff --git a/emigui/src/context.rs b/emigui/src/context.rs index 0b77d67e..599c4178 100644 --- a/emigui/src/context.rs +++ b/emigui/src/context.rs @@ -204,7 +204,7 @@ impl Context { }; // Ensure we register the background area so it is painted: self.memory().areas.set_state( - layer, + layer.clone(), containers::area::State { pos: rect.min, size: rect.size(), @@ -212,7 +212,7 @@ impl Context { vel: Default::default(), }, ); - Ui::new(self.clone(), layer, id, rect) + Ui::new(self.clone(), layer, rect) } // --------------------------------------------------------------------- @@ -228,7 +228,7 @@ impl Context { /// If the given Id is not unique, an error will be printed at the given position. pub fn register_unique_id(&self, id: Id, source_name: impl std::fmt::Debug, pos: Pos2) -> Id { - if let Some(clash_pos) = self.used_ids.lock().insert(id, pos) { + if let Some(clash_pos) = self.used_ids.lock().insert(id.clone(), pos) { if clash_pos.distance(pos) < 4.0 { self.show_error( pos, @@ -253,7 +253,7 @@ impl Context { } } - pub fn contains_mouse(&self, layer: Layer, clip_rect: Rect, rect: Rect) -> bool { + pub fn contains_mouse(&self, layer: &Layer, clip_rect: Rect, rect: Rect) -> bool { let rect = rect.intersect(clip_rect); if let Some(mouse_pos) = self.input.mouse.pos { rect.contains(mouse_pos) && self.memory().layer_at(mouse_pos) == Some(layer) @@ -264,10 +264,10 @@ impl Context { pub fn interact( &self, - layer: Layer, + layer: &Layer, clip_rect: Rect, rect: Rect, - interaction_id: Option, + interaction_id: Option<&Id>, sense: Sense, ) -> InteractInfo { let interact_rect = rect.expand2(0.5 * self.style().item_spacing); // make it easier to click. TODO: nice way to do this @@ -290,8 +290,8 @@ impl Context { memory.interaction.click_interest |= hovered && sense.click; memory.interaction.drag_interest |= hovered && sense.drag; - let active = memory.interaction.click_id == Some(interaction_id) - || memory.interaction.drag_id == Some(interaction_id); + let active = memory.interaction.click_id.as_ref() == Some(interaction_id) + || memory.interaction.drag_id.as_ref() == Some(interaction_id); if self.input.mouse.pressed { if hovered { @@ -305,13 +305,13 @@ impl Context { if sense.click && !memory.interaction.click_id.is_some() { // start of a click - memory.interaction.click_id = Some(interaction_id); + memory.interaction.click_id = Some(interaction_id.clone()); info.active = true; } if sense.drag && !memory.interaction.drag_id.is_some() { // start of a drag - memory.interaction.drag_id = Some(interaction_id); + memory.interaction.drag_id = Some(interaction_id.clone()); info.active = true; } @@ -365,7 +365,7 @@ impl Context { let galley = font.layout_multiline(text, f32::INFINITY); let rect = align_rect(Rect::from_min_size(pos, galley.size), align); self.add_paint_cmd( - layer, + &layer, PaintCmd::Rect { corner_radius: 0.0, fill: Some(color::gray(0, 240)), @@ -373,7 +373,7 @@ impl Context { rect: rect.expand(2.0), }, ); - self.add_galley(layer, rect.min, galley, text_style, Some(color::RED)); + self.add_galley(&layer, rect.min, galley, text_style, Some(color::RED)); } pub fn debug_text(&self, pos: Pos2, text: impl Into) { @@ -381,7 +381,7 @@ impl Context { let layer = Layer::debug(); let align = (Align::Min, Align::Min); self.floating_text( - layer, + &layer, pos, text, TextStyle::Monospace, @@ -394,7 +394,7 @@ impl Context { let text = text.into(); let layer = Layer::debug(); self.add_paint_cmd( - layer, + &layer, PaintCmd::Rect { corner_radius: 0.0, fill: None, @@ -404,14 +404,14 @@ impl Context { ); let align = (Align::Min, Align::Min); let text_style = TextStyle::Monospace; - self.floating_text(layer, rect.min, text, text_style, align, Some(color::RED)); + self.floating_text(&layer, rect.min, text, text_style, align, Some(color::RED)); } /// Show some text anywhere on screen. /// To center the text at the given position, use `align: (Center, Center)`. pub fn floating_text( &self, - layer: Layer, + layer: &Layer, pos: Pos2, text: String, text_style: TextStyle, @@ -428,7 +428,7 @@ impl Context { /// Already layed out text. pub fn add_galley( &self, - layer: Layer, + layer: &Layer, pos: Pos2, galley: font::Galley, text_style: TextStyle, @@ -446,7 +446,7 @@ impl Context { ); } - pub fn add_paint_cmd(&self, layer: Layer, paint_cmd: PaintCmd) { + pub fn add_paint_cmd(&self, layer: &Layer, paint_cmd: PaintCmd) { self.graphics() .layer(layer) .push((Rect::everything(), paint_cmd)) diff --git a/emigui/src/id.rs b/emigui/src/id.rs index 7a46b80c..be2672ef 100644 --- a/emigui/src/id.rs +++ b/emigui/src/id.rs @@ -52,7 +52,7 @@ impl Id { Id(hasher.finish()) } - pub fn with(self, child: impl Hash) -> Id { + pub fn with(&self, child: impl Hash) -> Id { use std::hash::Hasher; let mut hasher = ahash::AHasher::default(); hasher.write_u64(self.0); diff --git a/emigui/src/layers.rs b/emigui/src/layers.rs index 1324f1b7..02da7f2f 100644 --- a/emigui/src/layers.rs +++ b/emigui/src/layers.rs @@ -18,7 +18,7 @@ pub enum Order { /// An ideintifer for a paint layer. /// Also acts as an identifier for `Area`:s. -#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Deserialize, Serialize)] +#[derive(Clone, Debug, Hash, Eq, PartialEq, Deserialize, Serialize)] pub struct Layer { pub order: Order, pub id: Id, @@ -41,8 +41,8 @@ type PaintList = Vec<(Rect, PaintCmd)>; pub struct GraphicLayers(AHashMap); impl GraphicLayers { - pub fn layer(&mut self, layer: Layer) -> &mut PaintList { - self.0.entry(layer).or_default() + pub fn layer(&mut self, layer: &Layer) -> &mut PaintList { + self.0.entry(layer.clone()).or_default() } pub fn drain( diff --git a/emigui/src/memory.rs b/emigui/src/memory.rs index 4872a22b..c479dc05 100644 --- a/emigui/src/memory.rs +++ b/emigui/src/memory.rs @@ -89,7 +89,7 @@ impl Memory { if window_interaction.is_pure_move() { // Throw windows because it is fun: let area_layer = window_interaction.area_layer; - let area_state = self.areas.get(area_layer.id).clone(); + let area_state = self.areas.get(&area_layer.id).clone(); if let Some(mut area_state) = area_state { area_state.vel = prev_input.mouse.velocity; self.areas.set_state(area_layer, area_state); @@ -104,7 +104,7 @@ impl Memory { } /// TODO: call once at the start of the frame for the current mouse pos - pub fn layer_at(&self, pos: Pos2) -> Option { + pub fn layer_at(&self, pos: Pos2) -> Option<&Layer> { self.areas.layer_at(pos) } } @@ -114,7 +114,7 @@ impl Areas { self.areas.len() } - pub(crate) fn get(&mut self, id: Id) -> Option { + pub(crate) fn get(&mut self, id: &Id) -> Option { self.areas.get(&id).cloned() } @@ -123,22 +123,22 @@ impl Areas { } pub(crate) fn set_state(&mut self, layer: Layer, state: area::State) { - self.visible_current_frame.insert(layer); - let did_insert = self.areas.insert(layer.id, state).is_none(); + self.visible_current_frame.insert(layer.clone()); + let did_insert = self.areas.insert(layer.id.clone(), state).is_none(); if did_insert { self.order.push(layer); } } /// TODO: call once at the start of the frame for the current mouse pos - pub fn layer_at(&self, pos: Pos2) -> Option { + pub fn layer_at(&self, pos: Pos2) -> Option<&Layer> { for layer in self.order.iter().rev() { if self.is_visible(layer) { if let Some(state) = self.areas.get(&layer.id) { if state.interactable { let rect = Rect::from_min_size(state.pos, state.size); if rect.contains(pos) { - return Some(*layer); + return Some(&layer); } } } @@ -155,12 +155,12 @@ impl Areas { self.visible_last_frame.contains(layer) || self.visible_current_frame.contains(layer) } - pub fn move_to_top(&mut self, layer: Layer) { - self.visible_current_frame.insert(layer); - self.wants_to_be_on_top.insert(layer); + pub fn move_to_top(&mut self, layer: &Layer) { + self.visible_current_frame.insert(layer.clone()); + self.wants_to_be_on_top.insert(layer.clone()); - if self.order.iter().find(|x| **x == layer).is_none() { - self.order.push(layer); + if self.order.iter().find(|x| *x == layer).is_none() { + self.order.push(layer.clone()); } } diff --git a/emigui/src/ui.rs b/emigui/src/ui.rs index b16a2b63..c9b13369 100644 --- a/emigui/src/ui.rs +++ b/emigui/src/ui.rs @@ -55,11 +55,11 @@ impl Ui { // ------------------------------------------------------------------------ // Creation: - pub fn new(ctx: Arc, layer: Layer, id: Id, rect: Rect) -> Self { + pub fn new(ctx: Arc, layer: Layer, rect: Rect) -> Self { let style = ctx.style(); Ui { ctx, - id, + id: layer.id.clone(), layer, clip_rect: rect.expand(style.clip_rect_margin), desired_rect: rect, @@ -77,8 +77,8 @@ impl Ui { let clip_rect = self.clip_rect(); // Keep it unless the child explciitly desires differently Ui { ctx: self.ctx.clone(), - id: self.id, - layer: self.layer, + id: self.id.clone(), + layer: self.layer.clone(), clip_rect, desired_rect: child_rect, child_bounds: Rect::from_min_size(child_rect.min, Vec2::zero()), // TODO: Rect::nothing() ? @@ -102,8 +102,8 @@ impl Ui { self.ctx.round_pos_to_pixels(pos) } - pub fn id(&self) -> Id { - self.id + pub fn id(&self) -> &Id { + &self.id } /// Options for this ui, and any child uis we may spawn. @@ -263,11 +263,11 @@ impl Ui { // ------------------------------------------------------------------------ pub fn contains_mouse(&self, rect: Rect) -> bool { - self.ctx.contains_mouse(self.layer, self.clip_rect, rect) + self.ctx.contains_mouse(&self.layer, self.clip_rect, rect) } - pub fn has_kb_focus(&self, id: Id) -> bool { - self.memory().kb_focus_id == Some(id) + pub fn has_kb_focus(&self, id: &Id) -> bool { + self.memory().kb_focus_id.as_ref() == Some(id) } pub fn request_kb_focus(&self, id: Id) { @@ -303,14 +303,14 @@ impl Ui { // ------------------------------------------------------------------------ // Interaction - pub fn interact(&self, rect: Rect, id: Id, sense: Sense) -> InteractInfo { + pub fn interact(&self, rect: Rect, id: &Id, sense: Sense) -> InteractInfo { self.ctx - .interact(self.layer, self.clip_rect, rect, Some(id), sense) + .interact(&self.layer, self.clip_rect, rect, Some(id), sense) } pub fn interact_hover(&self, rect: Rect) -> InteractInfo { self.ctx - .interact(self.layer, self.clip_rect, rect, None, Sense::nothing()) + .interact(&self.layer, self.clip_rect, rect, None, Sense::nothing()) } pub fn hovered(&self, rect: Rect) -> bool { @@ -405,7 +405,7 @@ impl Ui { pub fn add_paint_cmd(&mut self, paint_cmd: PaintCmd) { self.ctx .graphics() - .layer(self.layer) + .layer(&self.layer) .push((self.clip_rect(), paint_cmd)) } @@ -413,7 +413,7 @@ impl Ui { let clip_rect = self.clip_rect(); self.ctx .graphics() - .layer(self.layer) + .layer(&self.layer) .extend(cmds.drain(..).map(|cmd| (clip_rect, cmd))); } @@ -421,12 +421,12 @@ impl Ui { pub fn insert_paint_cmd(&mut self, pos: usize, paint_cmd: PaintCmd) { self.ctx .graphics() - .layer(self.layer) + .layer(&self.layer) .insert(pos, (self.clip_rect(), paint_cmd)); } pub fn paint_list_len(&self) -> usize { - self.ctx.graphics().layer(self.layer).len() + self.ctx.graphics().layer(&self.layer).len() } /// Paint some debug text at current cursor diff --git a/emigui/src/widgets.rs b/emigui/src/widgets.rs index 267617fc..6f3af080 100644 --- a/emigui/src/widgets.rs +++ b/emigui/src/widgets.rs @@ -159,7 +159,7 @@ impl Widget for Hyperlink { let font = &ui.fonts()[text_style]; let galley = font.layout_multiline(text, ui.available().width()); let rect = ui.allocate_space(galley.size); - let interact = ui.interact(rect, id, Sense::click()); + let interact = ui.interact(rect, &id, Sense::click()); if interact.hovered { ui.ctx().output().cursor_icon = CursorIcon::PointingHand; } @@ -241,7 +241,7 @@ impl Widget for Button { let mut size = galley.size + 2.0 * padding; size.y = size.y.max(ui.style().clickable_diameter); let rect = ui.allocate_space(size); - let interact = ui.interact(rect, id, Sense::click()); + let interact = ui.interact(rect, &id, Sense::click()); let text_cursor = interact.rect.left_center() + vec2(padding.x, -0.5 * galley.size.y); let bg_fill = fill.or(ui.style().interact(&interact).bg_fill); ui.add_paint_cmd(PaintCmd::Rect { @@ -298,7 +298,7 @@ impl<'a> Widget for Checkbox<'a> { + galley.size + ui.style().button_padding; let rect = ui.allocate_space(size); - let interact = ui.interact(rect, id, Sense::click()); + let interact = ui.interact(rect, &id, Sense::click()); let text_cursor = interact.rect.min + ui.style().button_padding + vec2(ui.style().start_icon_width, 0.0); if interact.clicked { @@ -377,7 +377,7 @@ impl Widget for RadioButton { + galley.size + ui.style().button_padding; let rect = ui.allocate_space(size); - let interact = ui.interact(rect, id, Sense::click()); + let interact = ui.interact(rect, &id, Sense::click()); let text_cursor = interact.rect.min + ui.style().button_padding + vec2(ui.style().start_icon_width, 0.0); diff --git a/emigui/src/widgets/slider.rs b/emigui/src/widgets/slider.rs index 3efd5d79..e46ff9ed 100644 --- a/emigui/src/widgets/slider.rs +++ b/emigui/src/widgets/slider.rs @@ -138,14 +138,14 @@ impl<'a> Widget for Slider<'a> { let height = font.line_spacing().max(ui.style().clickable_diameter); let handle_radius = height / 2.5; - let id = self.id.unwrap_or_else(|| ui.make_position_id()); + let id = self.id.clone().unwrap_or_else(|| ui.make_position_id()); let size = Vec2 { x: ui.available().width(), y: height, }; let rect = ui.allocate_space(size); - let interact = ui.interact(rect, id, Sense::click_and_drag()); + let interact = ui.interact(rect, &id, Sense::click_and_drag()); let left = interact.rect.left() + handle_radius; let right = interact.rect.right() - handle_radius; diff --git a/emigui/src/widgets/text_edit.rs b/emigui/src/widgets/text_edit.rs index 7956ca0e..b093f4cd 100644 --- a/emigui/src/widgets/text_edit.rs +++ b/emigui/src/widgets/text_edit.rs @@ -72,10 +72,10 @@ impl<'t> Widget for TextEdit<'t> { }; let desired_size = galley.size.max(vec2(available_width, line_spacing)); let rect = ui.allocate_space(desired_size); - let interact = ui.interact(rect, id, Sense::click_and_drag()); // TODO: implement drag-select + let interact = ui.interact(rect, &id, Sense::click_and_drag()); // TODO: implement drag-select if interact.clicked { - ui.request_kb_focus(id); + ui.request_kb_focus(id.clone()); if let Some(mouse_pos) = ui.input().mouse.pos { state.cursor = Some(galley.char_at(mouse_pos - interact.rect.min).char_idx); } @@ -83,7 +83,7 @@ impl<'t> Widget for TextEdit<'t> { if interact.hovered { ui.output().cursor_icon = CursorIcon::Text; } - let has_kb_focus = ui.has_kb_focus(id); + let has_kb_focus = ui.has_kb_focus(&id); if has_kb_focus { let mut cursor = state.cursor.unwrap_or_else(|| text.chars().count());