Make Id a proper newtype

This commit is contained in:
Emil Ernerfeldt 2020-04-17 23:44:14 +02:00
parent 407df94945
commit 624e709a8f
7 changed files with 46 additions and 38 deletions

View file

@ -45,7 +45,7 @@ impl Emigui {
ctx: self.ctx.clone(), ctx: self.ctx.clone(),
layer: Layer::Background, layer: Layer::Background,
style: self.ctx.style(), style: self.ctx.style(),
id: Default::default(), id: Id::whole_screen(),
dir: layout::Direction::Vertical, dir: layout::Direction::Vertical,
align: layout::Align::Center, align: layout::Align::Center,
cursor: Default::default(), cursor: Default::default(),

29
emigui/src/id.rs Normal file
View 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())
}
}

View file

@ -1,4 +1,4 @@
use std::{hash::Hash, sync::Arc}; use std::sync::Arc;
use crate::{widgets::*, *}; 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 /// Show a pop-over window
pub fn show_popup<F>(ctx: &Arc<Context>, window_pos: Vec2, add_contents: F) pub fn show_popup<F>(ctx: &Arc<Context>, window_pos: Vec2, add_contents: F)
where where
@ -107,7 +95,7 @@ where
ctx: ctx.clone(), ctx: ctx.clone(),
layer, layer,
style, style,
id: Default::default(), id: Id::popup(),
dir: Direction::Vertical, dir: Direction::Vertical,
align: Align::Min, align: Align::Min,
cursor: window_pos + window_padding, cursor: window_pos + window_padding,

View file

@ -12,6 +12,7 @@ mod emigui;
pub mod example_app; pub mod example_app;
mod font; mod font;
mod fonts; mod fonts;
mod id;
mod layers; mod layers;
mod layout; mod layout;
pub mod math; pub mod math;
@ -29,8 +30,9 @@ pub use {
color::Color, color::Color,
context::Context, context::Context,
fonts::{FontDefinitions, Fonts, TextStyle}, fonts::{FontDefinitions, Fonts, TextStyle},
id::Id,
layers::*, layers::*,
layout::{Align, Id}, layout::Align,
math::*, math::*,
memory::Memory, memory::Memory,
mesher::{Mesh, Vertex}, mesher::{Mesh, Vertex},

View file

@ -359,21 +359,11 @@ impl Region {
} }
pub fn make_child_id<H: Hash>(&self, child_id: &H) -> Id { pub fn make_child_id<H: Hash>(&self, child_id: &H) -> Id {
use std::hash::Hasher; self.id.with(child_id)
let mut hasher = std::collections::hash_map::DefaultHasher::new();
hasher.write_u64(self.id);
child_id.hash(&mut hasher);
hasher.finish()
} }
pub fn combined_id(&self, child_id: Option<Id>) -> Option<Id> { pub fn combined_id(&self, child_id: Option<Id>) -> Option<Id> {
child_id.map(|child_id| { child_id.map(|child_id| self.id.with(&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()
})
} }
// Helper function // Helper function

View file

@ -1,7 +1,7 @@
#![allow(clippy::new_without_default_derive)] #![allow(clippy::new_without_default_derive)]
use crate::{ 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 text_color = self.text_color;
let value = (self.get_set_value)(None); let value = (self.get_set_value)(None);
let full_text = format!("{}: {:.*}", text, self.precision, value); 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; let mut naked = self;
naked.id = id; naked.id = id;
naked.text = None; naked.text = None;
@ -379,7 +379,10 @@ impl<'a> Widget for Slider<'a> {
let min = self.min; let min = self.min;
let max = self.max; let max = self.max;
debug_assert!(min <= 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( let interact = region.reserve_space(
Vec2 { Vec2 {
x: region.available_space.x, x: region.available_space.x,

View file

@ -1,10 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::{ use crate::{layout::Direction, widgets::Label, *};
layout::{make_id, Direction},
widgets::Label,
*,
};
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct WindowState { pub struct WindowState {
@ -28,7 +24,7 @@ impl Window {
where where
F: FnOnce(&mut Region), 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( let mut state = ctx.memory.lock().get_or_create_window(
id, id,
@ -48,7 +44,7 @@ impl Window {
ctx: ctx.clone(), ctx: ctx.clone(),
layer, layer,
style, style,
id: Default::default(), id,
dir: Direction::Vertical, dir: Direction::Vertical,
align: Align::Min, align: Align::Min,
cursor: state.rect.min() + window_padding, cursor: state.rect.min() + window_padding,