2020-04-21 12:47:17 +00:00
|
|
|
use std::collections::HashMap;
|
2020-04-17 13:29:48 +00:00
|
|
|
|
2020-04-25 20:49:57 +00:00
|
|
|
use crate::{
|
|
|
|
containers::{collapsing_header, floating, resize, scroll_area},
|
|
|
|
Id, Layer, Pos2, Rect,
|
|
|
|
};
|
2020-04-21 12:47:17 +00:00
|
|
|
|
2020-05-02 09:37:12 +00:00
|
|
|
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
|
|
|
#[serde(default)]
|
2020-04-17 13:29:48 +00:00
|
|
|
pub struct Memory {
|
|
|
|
/// The widget being interacted with (e.g. dragged, in case of a slider).
|
2020-05-02 09:37:12 +00:00
|
|
|
#[serde(skip)]
|
2020-04-17 13:29:48 +00:00
|
|
|
pub(crate) active_id: Option<Id>,
|
|
|
|
|
2020-04-29 19:25:49 +00:00
|
|
|
/// The widget with keyboard focus (i.e. a text input field).
|
2020-05-02 09:37:12 +00:00
|
|
|
#[serde(skip)]
|
2020-04-29 19:25:49 +00:00
|
|
|
pub(crate) kb_focus_id: Option<Id>,
|
|
|
|
|
2020-04-21 18:48:31 +00:00
|
|
|
// states of various types of widgets
|
2020-04-22 16:15:27 +00:00
|
|
|
pub(crate) collapsing_headers: HashMap<Id, collapsing_header::State>,
|
2020-04-22 16:25:02 +00:00
|
|
|
pub(crate) scroll_areas: HashMap<Id, scroll_area::State>,
|
2020-04-25 12:37:39 +00:00
|
|
|
pub(crate) resize: HashMap<Id, resize::State>,
|
2020-04-25 20:49:57 +00:00
|
|
|
floating: HashMap<Id, floating::State>,
|
2020-04-17 13:29:48 +00:00
|
|
|
|
|
|
|
/// Top is last
|
2020-04-25 20:49:57 +00:00
|
|
|
pub floating_order: Vec<Id>,
|
2020-04-17 13:29:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Memory {
|
2020-05-02 09:37:12 +00:00
|
|
|
pub(crate) fn get_floating(&mut self, id: Id) -> Option<floating::State> {
|
2020-04-25 20:49:57 +00:00
|
|
|
self.floating.get(&id).cloned()
|
2020-04-19 21:34:34 +00:00
|
|
|
}
|
|
|
|
|
2020-05-02 09:37:12 +00:00
|
|
|
pub(crate) fn set_floating_state(&mut self, id: Id, state: floating::State) {
|
2020-04-25 20:49:57 +00:00
|
|
|
let did_insert = self.floating.insert(id, state).is_none();
|
2020-04-19 21:34:34 +00:00
|
|
|
if did_insert {
|
2020-04-25 20:49:57 +00:00
|
|
|
self.floating_order.push(id);
|
2020-04-19 21:34:34 +00:00
|
|
|
}
|
2020-04-17 13:29:48 +00:00
|
|
|
}
|
|
|
|
|
2020-04-21 18:46:30 +00:00
|
|
|
/// TODO: call once at the start of the frame for the current mouse pos
|
2020-04-18 23:05:49 +00:00
|
|
|
pub fn layer_at(&self, pos: Pos2) -> Layer {
|
2020-04-25 20:49:57 +00:00
|
|
|
for floating_id in self.floating_order.iter().rev() {
|
|
|
|
if let Some(state) = self.floating.get(floating_id) {
|
|
|
|
let rect = Rect::from_min_size(state.pos, state.size);
|
|
|
|
if rect.contains(pos) {
|
|
|
|
return Layer::Window(*floating_id);
|
2020-04-17 13:29:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Layer::Background
|
|
|
|
}
|
|
|
|
|
2020-04-25 20:49:57 +00:00
|
|
|
pub fn move_floating_to_top(&mut self, id: Id) {
|
|
|
|
if self.floating_order.last() == Some(&id) {
|
2020-04-17 21:22:28 +00:00
|
|
|
return; // common case early-out
|
|
|
|
}
|
2020-04-25 20:49:57 +00:00
|
|
|
if let Some(index) = self.floating_order.iter().position(|x| *x == id) {
|
|
|
|
self.floating_order.remove(index);
|
2020-04-17 21:22:28 +00:00
|
|
|
}
|
2020-04-25 20:49:57 +00:00
|
|
|
self.floating_order.push(id);
|
2020-04-17 13:29:48 +00:00
|
|
|
}
|
|
|
|
}
|