Make Id a proper newtype
This commit is contained in:
parent
407df94945
commit
624e709a8f
7 changed files with 46 additions and 38 deletions
|
@ -45,7 +45,7 @@ impl Emigui {
|
|||
ctx: self.ctx.clone(),
|
||||
layer: Layer::Background,
|
||||
style: self.ctx.style(),
|
||||
id: Default::default(),
|
||||
id: Id::whole_screen(),
|
||||
dir: layout::Direction::Vertical,
|
||||
align: layout::Align::Center,
|
||||
cursor: Default::default(),
|
||||
|
|
29
emigui/src/id.rs
Normal file
29
emigui/src/id.rs
Normal file
|
@ -0,0 +1,29 @@
|
|||
use std::{collections::hash_map::DefaultHasher, hash::Hash};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
|
||||
pub struct Id(u64);
|
||||
|
||||
impl Id {
|
||||
pub fn whole_screen() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
pub fn popup() -> Self {
|
||||
Self(1)
|
||||
}
|
||||
|
||||
pub fn new<H: Hash>(source: &H) -> Id {
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = DefaultHasher::new();
|
||||
source.hash(&mut hasher);
|
||||
Id(hasher.finish())
|
||||
}
|
||||
|
||||
pub fn with<H: Hash>(self, child: &H) -> Id {
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = DefaultHasher::new();
|
||||
hasher.write_u64(self.0);
|
||||
child.hash(&mut hasher);
|
||||
Id(hasher.finish())
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
use std::{hash::Hash, sync::Arc};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{widgets::*, *};
|
||||
|
||||
|
@ -80,18 +80,6 @@ impl Default for Align {
|
|||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// TODO: newtype
|
||||
pub type Id = u64;
|
||||
|
||||
pub fn make_id<H: Hash>(source: &H) -> Id {
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
||||
source.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// Show a pop-over window
|
||||
pub fn show_popup<F>(ctx: &Arc<Context>, window_pos: Vec2, add_contents: F)
|
||||
where
|
||||
|
@ -107,7 +95,7 @@ where
|
|||
ctx: ctx.clone(),
|
||||
layer,
|
||||
style,
|
||||
id: Default::default(),
|
||||
id: Id::popup(),
|
||||
dir: Direction::Vertical,
|
||||
align: Align::Min,
|
||||
cursor: window_pos + window_padding,
|
||||
|
|
|
@ -12,6 +12,7 @@ mod emigui;
|
|||
pub mod example_app;
|
||||
mod font;
|
||||
mod fonts;
|
||||
mod id;
|
||||
mod layers;
|
||||
mod layout;
|
||||
pub mod math;
|
||||
|
@ -29,8 +30,9 @@ pub use {
|
|||
color::Color,
|
||||
context::Context,
|
||||
fonts::{FontDefinitions, Fonts, TextStyle},
|
||||
id::Id,
|
||||
layers::*,
|
||||
layout::{Align, Id},
|
||||
layout::Align,
|
||||
math::*,
|
||||
memory::Memory,
|
||||
mesher::{Mesh, Vertex},
|
||||
|
|
|
@ -359,21 +359,11 @@ impl Region {
|
|||
}
|
||||
|
||||
pub fn make_child_id<H: Hash>(&self, child_id: &H) -> Id {
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
||||
hasher.write_u64(self.id);
|
||||
child_id.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
self.id.with(child_id)
|
||||
}
|
||||
|
||||
pub fn combined_id(&self, child_id: Option<Id>) -> Option<Id> {
|
||||
child_id.map(|child_id| {
|
||||
use std::hash::Hasher;
|
||||
let mut hasher = std::collections::hash_map::DefaultHasher::new();
|
||||
hasher.write_u64(self.id);
|
||||
child_id.hash(&mut hasher);
|
||||
hasher.finish()
|
||||
})
|
||||
child_id.map(|child_id| self.id.with(&child_id))
|
||||
}
|
||||
|
||||
// Helper function
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(clippy::new_without_default_derive)]
|
||||
|
||||
use crate::{
|
||||
layout::{make_id, Direction, GuiResponse},
|
||||
layout::{Direction, GuiResponse},
|
||||
*,
|
||||
};
|
||||
|
||||
|
@ -351,7 +351,7 @@ impl<'a> Widget for Slider<'a> {
|
|||
let text_color = self.text_color;
|
||||
let value = (self.get_set_value)(None);
|
||||
let full_text = format!("{}: {:.*}", text, self.precision, value);
|
||||
let id = Some(self.id.unwrap_or_else(|| make_id(text)));
|
||||
let id = Some(self.id.unwrap_or_else(|| Id::new(text)));
|
||||
let mut naked = self;
|
||||
naked.id = id;
|
||||
naked.text = None;
|
||||
|
@ -379,7 +379,10 @@ impl<'a> Widget for Slider<'a> {
|
|||
let min = self.min;
|
||||
let max = self.max;
|
||||
debug_assert!(min <= max);
|
||||
let id = region.combined_id(Some(self.id.unwrap_or(42))); // TODO: slider ID
|
||||
let id = region.combined_id(Some(
|
||||
self.id
|
||||
.expect("Sliders must have a text label or an explicit id"),
|
||||
));
|
||||
let interact = region.reserve_space(
|
||||
Vec2 {
|
||||
x: region.available_space.x,
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
layout::{make_id, Direction},
|
||||
widgets::Label,
|
||||
*,
|
||||
};
|
||||
use crate::{layout::Direction, widgets::Label, *};
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct WindowState {
|
||||
|
@ -28,7 +24,7 @@ impl Window {
|
|||
where
|
||||
F: FnOnce(&mut Region),
|
||||
{
|
||||
let id = make_id(&self.title);
|
||||
let id = Id::new(&self.title);
|
||||
|
||||
let mut state = ctx.memory.lock().get_or_create_window(
|
||||
id,
|
||||
|
@ -48,7 +44,7 @@ impl Window {
|
|||
ctx: ctx.clone(),
|
||||
layer,
|
||||
style,
|
||||
id: Default::default(),
|
||||
id,
|
||||
dir: Direction::Vertical,
|
||||
align: Align::Min,
|
||||
cursor: state.rect.min() + window_padding,
|
||||
|
|
Loading…
Reference in a new issue