Made the fields in Context private

This commit is contained in:
Emil Ernerfeldt 2020-05-04 21:35:16 +02:00
parent 45564f952b
commit d02194d33a
9 changed files with 68 additions and 54 deletions

View file

@ -80,7 +80,10 @@ Add extremely quick animations for some things, maybe 2-3 frames. For instance:
### Names and structure ### Names and structure
* [ ] Rename things to be more consistent with Dear ImGui * [ ] Rename things to be more consistent with Dear ImGui
* [ ] Combine Emigui and Context * [ ] Combine Emigui and Context?
* [ ] Solve which parts of Context are behind a mutex
* [ ] All of Context behind one mutex?
* [ } Break up Context into Input, State, Output ?
* [ ] Rename Region to something shorter? * [ ] Rename Region to something shorter?
* `region: &Region` `region.add(...)` :/ * `region: &Region` `region.add(...)` :/
* `gui: &Gui` `gui.add(...)` :) * `gui: &Gui` `gui.add(...)` :)

View file

@ -68,7 +68,7 @@ impl CollapsingHeader {
}); });
if interact.clicked { if interact.clicked {
state.open = !state.open; state.open = !state.open;
state.toggle_time = region.ctx.input.time; state.toggle_time = region.ctx.input().time;
} }
*state *state
}; };
@ -93,7 +93,7 @@ impl CollapsingHeader {
); );
let animation_time = region.style().animation_time; let animation_time = region.style().animation_time;
let time_since_toggle = (region.ctx.input.time - state.toggle_time) as f32; let time_since_toggle = (region.ctx.input().time - state.toggle_time) as f32;
let animate = time_since_toggle < animation_time; let animate = time_since_toggle < animation_time;
if animate { if animate {
region.indent(id, |region| { region.indent(id, |region| {

View file

@ -101,8 +101,8 @@ impl Floating {
let margin = 32.0; let margin = 32.0;
state.pos = state.pos.max(pos2(margin - state.size.x, 0.0)); state.pos = state.pos.max(pos2(margin - state.size.x, 0.0));
state.pos = state.pos.min(pos2( state.pos = state.pos.min(pos2(
ctx.input.screen_size.x - margin, ctx.input().screen_size.x - margin,
ctx.input.screen_size.y - margin, ctx.input().screen_size.y - margin,
)); ));
state.pos = state.pos.round(); state.pos = state.pos.round();
@ -115,8 +115,8 @@ impl Floating {
} }
fn mouse_pressed_on_floating(ctx: &Context, id: Id) -> bool { fn mouse_pressed_on_floating(ctx: &Context, id: Id) -> bool {
if let Some(mouse_pos) = ctx.input.mouse_pos { if let Some(mouse_pos) = ctx.input().mouse_pos {
ctx.input.mouse_pressed && ctx.memory().layer_at(mouse_pos) == Layer::Window(id) ctx.input().mouse_pressed && ctx.memory().layer_at(mouse_pos) == Layer::Window(id)
} else { } else {
false false
} }

View file

@ -101,12 +101,12 @@ impl ScrollArea {
let content_interact = outer_region.interact_rect(&inner_rect, scroll_area_id.with("area")); let content_interact = outer_region.interact_rect(&inner_rect, scroll_area_id.with("area"));
if content_interact.active { if content_interact.active {
// Dragging scroll area to scroll: // Dragging scroll area to scroll:
state.offset.y -= ctx.input.mouse_move.y; state.offset.y -= ctx.input().mouse_move.y;
} }
// TODO: check that nothing else is being inteacted with // TODO: check that nothing else is being inteacted with
if outer_region.contains_mouse(&outer_rect) && ctx.memory().active_id.is_none() { if outer_region.contains_mouse(&outer_rect) && ctx.memory().active_id.is_none() {
state.offset.y -= ctx.input.scroll_delta.y; state.offset.y -= ctx.input().scroll_delta.y;
} }
let show_scroll_this_frame = content_size.y > inner_size.y || self.always_show_scroll; let show_scroll_this_frame = content_size.y > inner_size.y || self.always_show_scroll;
@ -134,11 +134,11 @@ impl ScrollArea {
let interact_id = scroll_area_id.with("vertical"); let interact_id = scroll_area_id.with("vertical");
let handle_interact = outer_region.interact_rect(&handle_rect, interact_id); let handle_interact = outer_region.interact_rect(&handle_rect, interact_id);
if let Some(mouse_pos) = ctx.input.mouse_pos { if let Some(mouse_pos) = ctx.input().mouse_pos {
if handle_interact.active { if handle_interact.active {
if inner_rect.top() <= mouse_pos.y && mouse_pos.y <= inner_rect.bottom() { if inner_rect.top() <= mouse_pos.y && mouse_pos.y <= inner_rect.bottom() {
state.offset.y += state.offset.y +=
ctx.input.mouse_move.y * content_size.y / inner_rect.height(); ctx.input().mouse_move.y * content_size.y / inner_rect.height();
} }
} else { } else {
// Check for mouse down outside handle: // Check for mouse down outside handle:

View file

@ -5,21 +5,26 @@ use parking_lot::Mutex;
use crate::{layout::align_rect, *}; use crate::{layout::align_rect, *};
/// Contains the input, style and output of all GUI commands. /// Contains the input, style and output of all GUI commands.
/// Regions keep an Arc pointer to this.
/// This allows us to create several child regions at once,
/// all working against the same shared Context.
pub struct Context { pub struct Context {
/// The default style for new regions /// The default style for new regions
pub(crate) style: Mutex<Style>, style: Mutex<Style>,
pub(crate) fonts: Arc<Fonts>, fonts: Arc<Fonts>,
/// Raw input from last frame. Use `input()` instead.
last_raw_input: RawInput,
pub(crate) input: GuiInput,
mouse_tracker: MovementTracker<Pos2>,
memory: Mutex<Memory>, memory: Mutex<Memory>,
pub(crate) graphics: Mutex<GraphicLayers>,
output: Mutex<Output>,
/// Used to debug name clashes of e.g. windows /// Used to debug name clashes of e.g. windows
used_ids: Mutex<HashMap<Id, Pos2>>, used_ids: Mutex<HashMap<Id, Pos2>>,
// Input releated stuff:
/// Raw input from last frame. Use `input()` instead.
last_raw_input: RawInput,
input: GuiInput,
mouse_tracker: MovementTracker<Pos2>,
// The output of a frame:
graphics: Mutex<GraphicLayers>,
output: Mutex<Output>,
} }
// TODO: remove this impl. // TODO: remove this impl.
@ -58,6 +63,10 @@ impl Context {
self.memory.lock() self.memory.lock()
} }
pub fn graphics(&self) -> parking_lot::MutexGuard<GraphicLayers> {
self.graphics.lock()
}
pub fn output(&self) -> parking_lot::MutexGuard<Output> { pub fn output(&self) -> parking_lot::MutexGuard<Output> {
self.output.lock() self.output.lock()
} }
@ -76,6 +85,14 @@ impl Context {
&self.last_raw_input &self.last_raw_input
} }
pub fn fonts(&self) -> &Fonts {
&*self.fonts
}
pub fn set_fonts(&mut self, fonts: Fonts) {
self.fonts = Arc::new(fonts);
}
pub fn style(&self) -> Style { pub fn style(&self) -> Style {
*self.style.lock() *self.style.lock()
} }
@ -119,17 +136,17 @@ impl Context {
} }
pub fn end_frame(&self) -> Output { pub fn end_frame(&self) -> Output {
std::mem::take(&mut self.output.lock()) std::mem::take(&mut self.output())
} }
pub fn drain_paint_lists(&self) -> Vec<(Rect, PaintCmd)> { pub fn drain_paint_lists(&self) -> Vec<(Rect, PaintCmd)> {
let memory = self.memory.lock(); let memory = self.memory();
self.graphics.lock().drain(&memory.floating_order).collect() self.graphics().drain(&memory.floating_order).collect()
} }
/// Is the user interacting with anything? /// Is the user interacting with anything?
pub fn any_active(&self) -> bool { pub fn any_active(&self) -> bool {
self.memory.lock().active_id.is_some() self.memory().active_id.is_some()
} }
/// Generate a id from the given source. /// Generate a id from the given source.
@ -171,7 +188,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); let rect = rect.intersect(clip_rect);
if let Some(mouse_pos) = self.input.mouse_pos { if let Some(mouse_pos) = self.input.mouse_pos {
rect.contains(mouse_pos) && layer == self.memory.lock().layer_at(mouse_pos) rect.contains(mouse_pos) && layer == self.memory().layer_at(mouse_pos)
} else { } else {
false false
} }
@ -186,7 +203,7 @@ impl Context {
) -> InteractInfo { ) -> InteractInfo {
let hovered = self.contains_mouse(layer, clip_rect, &rect); let hovered = self.contains_mouse(layer, clip_rect, &rect);
let mut memory = self.memory.lock(); let mut memory = self.memory();
let active = interaction_id.is_some() && memory.active_id == interaction_id; let active = interaction_id.is_some() && memory.active_id == interaction_id;
if self.input.mouse_pressed { if self.input.mouse_pressed {
@ -315,8 +332,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 self.graphics()
.lock()
.layer(layer) .layer(layer)
.push((Rect::everything(), paint_cmd)) .push((Rect::everything(), paint_cmd))
} }

View file

@ -31,7 +31,7 @@ impl Emigui {
} }
pub fn texture(&self) -> &Texture { pub fn texture(&self) -> &Texture {
self.ctx.fonts.texture() self.ctx.fonts().texture()
} }
pub fn begin_frame(&mut self, new_input: RawInput) { pub fn begin_frame(&mut self, new_input: RawInput) {
@ -51,7 +51,7 @@ impl Emigui {
fn paint(&mut self) -> PaintBatches { fn paint(&mut self) -> PaintBatches {
self.mesher_options.aa_size = 1.0 / self.ctx().pixels_per_point(); self.mesher_options.aa_size = 1.0 / self.ctx().pixels_per_point();
let paint_commands = self.ctx.drain_paint_lists(); let paint_commands = self.ctx.drain_paint_lists();
let batches = mesh_paint_commands(&self.mesher_options, &self.ctx.fonts, paint_commands); let batches = mesh_paint_commands(&self.mesher_options, self.ctx.fonts(), paint_commands);
self.stats = Default::default(); self.stats = Default::default();
self.stats.num_batches = batches.len(); self.stats.num_batches = batches.len();
for (_, mesh) in &batches { for (_, mesh) in &batches {
@ -63,7 +63,7 @@ impl Emigui {
/// A region for the entire screen, behind any windows. /// A region for the entire screen, behind any windows.
pub fn background_region(&mut self) -> Region { pub fn background_region(&mut self) -> Region {
let rect = Rect::from_min_size(Default::default(), self.ctx.input.screen_size); let rect = Rect::from_min_size(Default::default(), self.ctx.input().screen_size);
Region::new(self.ctx.clone(), Layer::Background, Id::background(), rect) Region::new(self.ctx.clone(), Layer::Background, Id::background(), rect)
} }
} }
@ -83,15 +83,17 @@ impl Emigui {
}); });
region.collapsing("Fonts", |region| { region.collapsing("Fonts", |region| {
let old_font_definitions = self.ctx.fonts.definitions(); let old_font_definitions = self.ctx.fonts().definitions();
let mut new_font_definitions = old_font_definitions.clone(); let mut new_font_definitions = old_font_definitions.clone();
font_definitions_ui(&mut new_font_definitions, region); font_definitions_ui(&mut new_font_definitions, region);
self.ctx.fonts.texture().ui(region); self.ctx.fonts().texture().ui(region);
if *old_font_definitions != new_font_definitions { if *old_font_definitions != new_font_definitions {
let mut new_ctx = (*self.ctx).clone(); let mut new_ctx = (*self.ctx).clone();
let fonts = let fonts = Fonts::from_definitions(
Fonts::from_definitions(new_font_definitions, self.ctx.input.pixels_per_point); new_font_definitions,
new_ctx.fonts = Arc::new(fonts); self.ctx.input().pixels_per_point,
);
new_ctx.set_fonts(fonts);
self.ctx = Arc::new(new_ctx); self.ctx = Arc::new(new_ctx);
} }
}); });

View file

@ -96,12 +96,12 @@ pub fn align_rect(rect: &Rect, align: (Align, Align)) -> Rect {
/// Show a pop-over window /// Show a pop-over window
pub fn show_popup(ctx: &Arc<Context>, window_pos: Pos2, add_contents: impl FnOnce(&mut Region)) { pub fn show_popup(ctx: &Arc<Context>, window_pos: Pos2, add_contents: impl FnOnce(&mut Region)) {
let layer = Layer::Popup; let layer = Layer::Popup;
let where_to_put_background = ctx.graphics.lock().layer(layer).len(); let where_to_put_background = ctx.graphics().layer(layer).len();
let style = ctx.style(); let style = ctx.style();
let window_padding = style.window_padding; let window_padding = style.window_padding;
let size = vec2(ctx.input.screen_size.x.min(350.0), f32::INFINITY); // TODO: popup/tooltip width let size = vec2(ctx.input().screen_size.x.min(350.0), f32::INFINITY); // TODO: popup/tooltip width
let inner_rect = Rect::from_min_size(window_pos + window_padding, size); let inner_rect = Rect::from_min_size(window_pos + window_padding, size);
let mut contents_region = Region::new(ctx.clone(), layer, Id::popup(), inner_rect); let mut contents_region = Region::new(ctx.clone(), layer, Id::popup(), inner_rect);
@ -115,7 +115,7 @@ pub fn show_popup(ctx: &Arc<Context>, window_pos: Pos2, add_contents: impl FnOnc
let rect = Rect::from_min_size(window_pos, outer_size); let rect = Rect::from_min_size(window_pos, outer_size);
let mut graphics = ctx.graphics.lock(); let mut graphics = ctx.graphics();
graphics.layer(layer).insert( graphics.layer(layer).insert(
where_to_put_background, where_to_put_background,
( (

View file

@ -127,7 +127,7 @@ impl Region {
} }
pub fn fonts(&self) -> &Fonts { pub fn fonts(&self) -> &Fonts {
&*self.ctx.fonts self.ctx.fonts()
} }
/// Screen-space rectangle for clipping what we paint in this region. /// Screen-space rectangle for clipping what we paint in this region.
@ -342,8 +342,7 @@ impl Region {
/// NOTE: all coordinates are screen coordinates! /// NOTE: all coordinates are screen coordinates!
pub fn add_paint_cmd(&mut self, paint_cmd: PaintCmd) { pub fn add_paint_cmd(&mut self, paint_cmd: PaintCmd) {
self.ctx self.ctx
.graphics .graphics()
.lock()
.layer(self.layer) .layer(self.layer)
.push((self.clip_rect(), paint_cmd)) .push((self.clip_rect(), paint_cmd))
} }
@ -351,8 +350,7 @@ impl Region {
pub fn add_paint_cmds(&mut self, mut cmds: Vec<PaintCmd>) { pub fn add_paint_cmds(&mut self, mut cmds: Vec<PaintCmd>) {
let clip_rect = self.clip_rect(); let clip_rect = self.clip_rect();
self.ctx self.ctx
.graphics .graphics()
.lock()
.layer(self.layer) .layer(self.layer)
.extend(cmds.drain(..).map(|cmd| (clip_rect, cmd))); .extend(cmds.drain(..).map(|cmd| (clip_rect, cmd)));
} }
@ -360,14 +358,13 @@ impl Region {
/// Insert a paint cmd before existing ones /// Insert a paint cmd before existing ones
pub fn insert_paint_cmd(&mut self, pos: usize, paint_cmd: PaintCmd) { pub fn insert_paint_cmd(&mut self, pos: usize, paint_cmd: PaintCmd) {
self.ctx self.ctx
.graphics .graphics()
.lock()
.layer(self.layer) .layer(self.layer)
.insert(pos, (self.clip_rect(), paint_cmd)); .insert(pos, (self.clip_rect(), paint_cmd));
} }
pub fn paint_list_len(&self) -> usize { pub fn paint_list_len(&self) -> usize {
self.ctx.graphics.lock().layer(self.layer).len() self.ctx.graphics().layer(self.layer).len()
} }
/// Paint some debug text at current cursor /// Paint some debug text at current cursor

View file

@ -8,12 +8,8 @@ extern crate emigui_wasm;
use { use {
emigui::{ emigui::{
color::srgba, color::srgba, containers::*, example_app::ExampleWindow, label, widgets::Separator, Align,
containers::*, Emigui, RawInput, TextStyle, *,
example_app::ExampleWindow,
label,
widgets::{Label, Separator},
Align, Emigui, RawInput, TextStyle, *,
}, },
emigui_wasm::now_sec, emigui_wasm::now_sec,
}; };