1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-31 05:40:03 -04:00

Refactor: Clump area logic together inside of Memory

This commit is contained in:
Emil Ernerfeldt
2020-05-10 19:02:17 +02:00
parent 9dab3628a1
commit 216036e49c
3 changed files with 59 additions and 44 deletions

View File

@@ -1,7 +1,7 @@
use std::collections::{HashMap, HashSet};
use crate::{
containers::{area, collapsing_header, resize, scroll_area},
containers::{area, collapsing_header, menu, resize, scroll_area},
Id, Layer, Pos2, Rect,
};
@@ -18,39 +18,61 @@ pub struct Memory {
// states of various types of widgets
pub(crate) collapsing_headers: HashMap<Id, collapsing_header::State>,
pub(crate) menu_bar: HashMap<Id, menu::BarState>,
pub(crate) scroll_areas: HashMap<Id, scroll_area::State>,
pub(crate) resize: HashMap<Id, resize::State>,
area: HashMap<Id, area::State>,
pub(crate) areas: Areas,
}
#[derive(Clone, Debug, Default, serde_derive::Deserialize, serde_derive::Serialize)]
#[serde(default)]
pub struct Areas {
areas: HashMap<Id, area::State>,
/// Top is last
area_order: Vec<Layer>,
area_visible_last_frame: HashSet<Layer>,
area_visible_current_frame: HashSet<Layer>,
order: Vec<Layer>,
visible_last_frame: HashSet<Layer>,
visible_current_frame: HashSet<Layer>,
}
impl Memory {
pub(crate) fn get_area(&mut self, id: Id) -> Option<area::State> {
self.area.get(&id).cloned()
pub(crate) fn begin_frame(&mut self) {
self.areas.begin_frame()
}
pub(crate) fn area_order(&self) -> &[Layer] {
&self.area_order
/// TODO: call once at the start of the frame for the current mouse pos
pub fn layer_at(&self, pos: Pos2) -> Option<Layer> {
self.areas.layer_at(pos)
}
}
impl Areas {
pub(crate) fn count(&self) -> usize {
self.areas.len()
}
pub(crate) fn set_area_state(&mut self, layer: Layer, state: area::State) {
self.area_visible_current_frame.insert(layer);
let did_insert = self.area.insert(layer.id, state).is_none();
pub(crate) fn get(&mut self, id: Id) -> Option<area::State> {
self.areas.get(&id).cloned()
}
pub(crate) fn order(&self) -> &[Layer] {
&self.order
}
pub(crate) fn set_state(&mut self, layer: Layer, state: area::State) {
self.visible_current_frame.insert(layer);
let did_insert = self.areas.insert(layer.id, state).is_none();
if did_insert {
self.area_order.push(layer);
self.area_order.sort_by_key(|layer| layer.order);
self.order.push(layer);
self.order.sort_by_key(|layer| layer.order);
}
}
/// TODO: call once at the start of the frame for the current mouse pos
pub fn layer_at(&self, pos: Pos2) -> Option<Layer> {
for layer in self.area_order.iter().rev() {
if self.is_area_visible(layer) {
if let Some(state) = self.area.get(&layer.id) {
for layer in self.order.iter().rev() {
if self.is_visible(layer) {
if let Some(state) = self.areas.get(&layer.id) {
if state.interactable {
let rect = Rect::from_min_size(state.pos, state.size);
if rect.contains(pos) {
@@ -63,26 +85,25 @@ impl Memory {
None
}
pub fn is_area_visible(&self, layer: &Layer) -> bool {
self.area_visible_last_frame.contains(layer)
|| self.area_visible_current_frame.contains(layer)
pub fn is_visible(&self, layer: &Layer) -> bool {
self.visible_last_frame.contains(layer) || self.visible_current_frame.contains(layer)
}
pub fn move_area_to_top(&mut self, layer: Layer) {
self.area_visible_current_frame.insert(layer);
pub fn move_to_top(&mut self, layer: Layer) {
self.visible_current_frame.insert(layer);
if self.area_order.last() == Some(&layer) {
if self.order.last() == Some(&layer) {
return; // common case early-out
}
if let Some(index) = self.area_order.iter().position(|x| *x == layer) {
self.area_order.remove(index);
if let Some(index) = self.order.iter().position(|x| *x == layer) {
self.order.remove(index);
}
self.area_order.push(layer);
self.order.push(layer);
self.area_order.sort_by_key(|layer| layer.order);
self.order.sort_by_key(|layer| layer.order);
}
pub(crate) fn begin_frame(&mut self) {
self.area_visible_last_frame = std::mem::take(&mut self.area_visible_current_frame);
self.visible_last_frame = std::mem::take(&mut self.visible_current_frame);
}
}