egui/emigui/src/context.rs

112 lines
2.9 KiB
Rust
Raw Normal View History

2020-04-17 21:30:01 +00:00
use std::sync::Arc;
use parking_lot::Mutex;
use crate::*;
/// Contains the input, style and output of all GUI commands.
pub struct Context {
/// The default style for new regions
pub(crate) style: Mutex<Style>,
pub(crate) fonts: Arc<Fonts>,
pub(crate) input: GuiInput,
pub(crate) memory: Mutex<Memory>,
pub(crate) graphics: Mutex<GraphicLayers>,
}
impl Clone for Context {
fn clone(&self) -> Self {
Context {
style: Mutex::new(self.style()),
fonts: self.fonts.clone(),
input: self.input,
2020-04-17 21:30:01 +00:00
memory: Mutex::new(self.memory.lock().clone()),
graphics: Mutex::new(self.graphics.lock().clone()),
}
}
}
impl Context {
pub fn new(pixels_per_point: f32) -> Context {
Context {
style: Default::default(),
fonts: Arc::new(Fonts::new(pixels_per_point)),
input: Default::default(),
memory: Default::default(),
graphics: Default::default(),
}
}
pub fn input(&self) -> &GuiInput {
&self.input
}
pub fn style(&self) -> Style {
2020-04-17 21:30:01 +00:00
*self.style.lock()
}
pub fn set_style(&self, style: Style) {
2020-04-17 21:30:01 +00:00
*self.style.lock() = style;
}
// TODO: move
pub fn new_frame(&mut self, gui_input: GuiInput) {
self.input = gui_input;
if !gui_input.mouse_down || gui_input.mouse_pos.is_none() {
2020-04-17 21:30:01 +00:00
self.memory.lock().active_id = None;
}
}
pub fn drain_paint_lists(&self) -> Vec<PaintCmd> {
2020-04-17 21:30:01 +00:00
let memory = self.memory.lock();
self.graphics.lock().drain(&memory.window_order).collect()
}
/// Is the user interacting with anything?
pub fn any_active(&self) -> bool {
2020-04-17 21:30:01 +00:00
self.memory.lock().active_id.is_some()
}
pub fn interact(&self, layer: Layer, rect: Rect, interaction_id: Option<Id>) -> InteractInfo {
2020-04-17 21:30:01 +00:00
let mut memory = self.memory.lock();
let hovered = if let Some(mouse_pos) = self.input.mouse_pos {
if rect.contains(mouse_pos) {
let is_something_else_active =
memory.active_id.is_some() && memory.active_id != interaction_id;
!is_something_else_active && layer == memory.layer_at(mouse_pos)
} else {
false
}
} else {
false
};
let active = if interaction_id.is_some() {
if hovered && self.input.mouse_clicked {
memory.active_id = interaction_id;
}
memory.active_id == interaction_id
} else {
false
};
let clicked = hovered && self.input.mouse_released;
InteractInfo {
rect,
hovered,
clicked,
active,
}
}
}
impl Context {
pub fn style_ui(&self, region: &mut Region) {
let mut style = self.style();
style.ui(region);
self.set_style(style);
}
}