Refactor: Clump area logic together inside of Memory
This commit is contained in:
parent
9dab3628a1
commit
216036e49c
3 changed files with 59 additions and 44 deletions
|
@ -99,18 +99,12 @@ impl Area {
|
||||||
let id = ctx.register_unique_id(id, "Area", default_pos);
|
let id = ctx.register_unique_id(id, "Area", default_pos);
|
||||||
let layer = Layer { order, id };
|
let layer = Layer { order, id };
|
||||||
|
|
||||||
let (mut state, _is_new) = match ctx.memory().get_area(id) {
|
let mut state = ctx.memory().areas.get(id).unwrap_or_else(|| State {
|
||||||
Some(state) => (state, false),
|
pos: default_pos,
|
||||||
None => {
|
size: Vec2::zero(),
|
||||||
let state = State {
|
interactable,
|
||||||
pos: default_pos,
|
vel: Vec2::zero(),
|
||||||
size: Vec2::zero(),
|
});
|
||||||
interactable,
|
|
||||||
vel: Vec2::zero(),
|
|
||||||
};
|
|
||||||
(state, true)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
state.pos = fixed_pos.unwrap_or(state.pos);
|
state.pos = fixed_pos.unwrap_or(state.pos);
|
||||||
state.pos = state.pos.round();
|
state.pos = state.pos.round();
|
||||||
|
|
||||||
|
@ -162,9 +156,9 @@ impl Area {
|
||||||
// );
|
// );
|
||||||
|
|
||||||
if move_interact.active || mouse_pressed_on_area(ctx, layer) {
|
if move_interact.active || mouse_pressed_on_area(ctx, layer) {
|
||||||
ctx.memory().move_area_to_top(layer);
|
ctx.memory().areas.move_to_top(layer);
|
||||||
}
|
}
|
||||||
ctx.memory().set_area_state(layer, state);
|
ctx.memory().areas.set_state(layer, state);
|
||||||
|
|
||||||
move_interact
|
move_interact
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,7 +183,7 @@ impl Context {
|
||||||
|
|
||||||
fn drain_paint_lists(&self) -> Vec<(Rect, PaintCmd)> {
|
fn drain_paint_lists(&self) -> Vec<(Rect, PaintCmd)> {
|
||||||
let memory = self.memory();
|
let memory = self.memory();
|
||||||
self.graphics().drain(memory.area_order()).collect()
|
self.graphics().drain(memory.areas.order()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint(&self) -> PaintBatches {
|
fn paint(&self) -> PaintBatches {
|
||||||
|
@ -218,7 +218,7 @@ impl Context {
|
||||||
id,
|
id,
|
||||||
};
|
};
|
||||||
// Ensure we register the background area so it is painted:
|
// Ensure we register the background area so it is painted:
|
||||||
self.memory().set_area_state(
|
self.memory().areas.set_state(
|
||||||
layer,
|
layer,
|
||||||
containers::area::State {
|
containers::area::State {
|
||||||
pos: rect.min,
|
pos: rect.min,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
containers::{area, collapsing_header, resize, scroll_area},
|
containers::{area, collapsing_header, menu, resize, scroll_area},
|
||||||
Id, Layer, Pos2, Rect,
|
Id, Layer, Pos2, Rect,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,39 +18,61 @@ pub struct Memory {
|
||||||
|
|
||||||
// states of various types of widgets
|
// states of various types of widgets
|
||||||
pub(crate) collapsing_headers: HashMap<Id, collapsing_header::State>,
|
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) scroll_areas: HashMap<Id, scroll_area::State>,
|
||||||
pub(crate) resize: HashMap<Id, resize::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
|
/// Top is last
|
||||||
area_order: Vec<Layer>,
|
order: Vec<Layer>,
|
||||||
area_visible_last_frame: HashSet<Layer>,
|
visible_last_frame: HashSet<Layer>,
|
||||||
area_visible_current_frame: HashSet<Layer>,
|
visible_current_frame: HashSet<Layer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Memory {
|
impl Memory {
|
||||||
pub(crate) fn get_area(&mut self, id: Id) -> Option<area::State> {
|
pub(crate) fn begin_frame(&mut self) {
|
||||||
self.area.get(&id).cloned()
|
self.areas.begin_frame()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn area_order(&self) -> &[Layer] {
|
/// TODO: call once at the start of the frame for the current mouse pos
|
||||||
&self.area_order
|
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) {
|
pub(crate) fn get(&mut self, id: Id) -> Option<area::State> {
|
||||||
self.area_visible_current_frame.insert(layer);
|
self.areas.get(&id).cloned()
|
||||||
let did_insert = self.area.insert(layer.id, state).is_none();
|
}
|
||||||
|
|
||||||
|
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 {
|
if did_insert {
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TODO: call once at the start of the frame for the current mouse pos
|
/// TODO: call once at the start of the frame for the current mouse pos
|
||||||
pub fn layer_at(&self, pos: Pos2) -> Option<Layer> {
|
pub fn layer_at(&self, pos: Pos2) -> Option<Layer> {
|
||||||
for layer in self.area_order.iter().rev() {
|
for layer in self.order.iter().rev() {
|
||||||
if self.is_area_visible(layer) {
|
if self.is_visible(layer) {
|
||||||
if let Some(state) = self.area.get(&layer.id) {
|
if let Some(state) = self.areas.get(&layer.id) {
|
||||||
if state.interactable {
|
if state.interactable {
|
||||||
let rect = Rect::from_min_size(state.pos, state.size);
|
let rect = Rect::from_min_size(state.pos, state.size);
|
||||||
if rect.contains(pos) {
|
if rect.contains(pos) {
|
||||||
|
@ -63,26 +85,25 @@ impl Memory {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_area_visible(&self, layer: &Layer) -> bool {
|
pub fn is_visible(&self, layer: &Layer) -> bool {
|
||||||
self.area_visible_last_frame.contains(layer)
|
self.visible_last_frame.contains(layer) || self.visible_current_frame.contains(layer)
|
||||||
|| self.area_visible_current_frame.contains(layer)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_area_to_top(&mut self, layer: Layer) {
|
pub fn move_to_top(&mut self, layer: Layer) {
|
||||||
self.area_visible_current_frame.insert(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
|
return; // common case early-out
|
||||||
}
|
}
|
||||||
if let Some(index) = self.area_order.iter().position(|x| *x == layer) {
|
if let Some(index) = self.order.iter().position(|x| *x == layer) {
|
||||||
self.area_order.remove(index);
|
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) {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue