layout: Gather state-related stuff together

This commit is contained in:
Dorota Czaplejewicz
2022-09-30 17:12:00 +00:00
parent afe6a6cf74
commit c017a773ea
2 changed files with 71 additions and 54 deletions

View File

@ -91,7 +91,7 @@ mod c {
&state.action, &state.action,
&active_modifiers, &active_modifiers,
layout.get_view_latched(), layout.get_view_latched(),
&layout.current_view, &layout.state.current_view,
); );
if state.pressed == keyboard::PressType::Pressed if state.pressed == keyboard::PressType::Pressed
|| locked != LockedStyle::Free || locked != LockedStyle::Free

View File

@ -238,7 +238,7 @@ pub mod c {
// The list must be copied, // The list must be copied,
// because it will be mutated in the loop // because it will be mutated in the loop
for key in layout.pressed_keys.clone() { for key in layout.state.pressed_keys.clone() {
let key: &Rc<RefCell<KeyState>> = key.borrow(); let key: &Rc<RefCell<KeyState>> = key.borrow();
seat::handle_release_key( seat::handle_release_key(
layout, layout,
@ -265,7 +265,7 @@ pub mod c {
let mut submission = submission.borrow_mut(); let mut submission = submission.borrow_mut();
// The list must be copied, // The list must be copied,
// because it will be mutated in the loop // because it will be mutated in the loop
for key in layout.pressed_keys.clone() { for key in layout.state.pressed_keys.clone() {
let key: &Rc<RefCell<KeyState>> = key.borrow(); let key: &Rc<RefCell<KeyState>> = key.borrow();
seat::handle_release_key( seat::handle_release_key(
layout, layout,
@ -344,7 +344,7 @@ pub mod c {
Point { x: x_widget, y: y_widget } Point { x: x_widget, y: y_widget }
); );
let pressed = layout.pressed_keys.clone(); let pressed = layout.state.pressed_keys.clone();
let button_info = { let button_info = {
let place = layout.find_button_by_position(point); let place = layout.find_button_by_position(point);
place.map(|place| {( place.map(|place| {(
@ -658,15 +658,11 @@ pub enum LatchedState {
// Arrangement (views) + details (keymap) + State (keys) // Arrangement (views) + details (keymap) + State (keys)
/// State of the UI, contains the backend as well /// State of the UI, contains the backend as well
pub struct Layout { pub struct Layout {
pub state: LayoutState,
pub margins: Margins, pub margins: Margins,
pub kind: ArrangementKind, pub kind: ArrangementKind,
pub purpose: ContentPurpose, pub purpose: ContentPurpose,
pub current_view: String,
// If current view is latched,
// clicking any button that emits an action (erase, submit, set modifier)
// will cause lock buttons to unlatch.
view_latched: LatchedState,
// Views own the actual buttons which have state // Views own the actual buttons which have state
// Maybe they should own UI only, // Maybe they should own UI only,
@ -677,7 +673,16 @@ pub struct Layout {
// Non-UI stuff // Non-UI stuff
/// xkb keymaps applicable to the contained keys. Unchangeable /// xkb keymaps applicable to the contained keys. Unchangeable
pub keymaps: Vec<CString>, pub keymaps: Vec<CString>,
// Changeable state }
/// Changeable state that can't be derived from the definition of the layout
pub struct LayoutState {
pub current_view: String,
// If current view is latched,
// clicking any button that emits an action (erase, submit, set modifier)
// will cause lock buttons to unlatch.
view_latched: LatchedState,
// a Vec would be enough, but who cares, this will be small & fast enough // a Vec would be enough, but who cares, this will be small & fast enough
// TODO: turn those into per-input point *_buttons to track dragging. // TODO: turn those into per-input point *_buttons to track dragging.
// The renderer doesn't need the list of pressed keys any more, // The renderer doesn't need the list of pressed keys any more,
@ -713,28 +718,30 @@ impl Layout {
pub fn new(data: LayoutData, kind: ArrangementKind, purpose: ContentPurpose) -> Layout { pub fn new(data: LayoutData, kind: ArrangementKind, purpose: ContentPurpose) -> Layout {
Layout { Layout {
kind, kind,
current_view: "base".to_owned(),
view_latched: LatchedState::Not,
views: data.views, views: data.views,
keymaps: data.keymaps, keymaps: data.keymaps,
pressed_keys: HashSet::new(),
margins: data.margins, margins: data.margins,
purpose, purpose,
state: LayoutState {
current_view: "base".to_owned(),
view_latched: LatchedState::Not,
pressed_keys: HashSet::new(),
},
} }
} }
pub fn get_current_view_position(&self) -> &(c::Point, View) { pub fn get_current_view_position(&self) -> &(c::Point, View) {
&self.views &self.views
.get(&self.current_view).expect("Selected nonexistent view") .get(&self.state.current_view).expect("Selected nonexistent view")
} }
pub fn get_current_view(&self) -> &View { pub fn get_current_view(&self) -> &View {
&self.views.get(&self.current_view).expect("Selected nonexistent view").1 &self.views.get(&self.state.current_view).expect("Selected nonexistent view").1
} }
fn set_view(&mut self, view: String) -> Result<(), NoSuchView> { fn set_view(&mut self, view: String) -> Result<(), NoSuchView> {
if self.views.contains_key(&view) { if self.views.contains_key(&view) {
self.current_view = view; self.state.current_view = view;
Ok(()) Ok(())
} else { } else {
Err(NoSuchView) Err(NoSuchView)
@ -744,7 +751,7 @@ impl Layout {
// Layout is passed around mutably, // Layout is passed around mutably,
// so better keep the field away from direct access. // so better keep the field away from direct access.
pub fn get_view_latched(&self) -> &LatchedState { pub fn get_view_latched(&self) -> &LatchedState {
&self.view_latched &self.state.view_latched
} }
/// Calculates size without margins /// Calculates size without margins
@ -816,8 +823,8 @@ impl Layout {
) { ) {
let (transition, new_latched) = Layout::process_action_for_view( let (transition, new_latched) = Layout::process_action_for_view(
action, action,
&self.current_view, &self.state.current_view,
&self.view_latched, &self.state.view_latched,
); );
match transition { match transition {
@ -826,15 +833,15 @@ impl Layout {
ViewTransition::NoChange => {}, ViewTransition::NoChange => {},
}; };
self.view_latched = new_latched; self.state.view_latched = new_latched;
} }
/// Unlatch all latched keys, /// Unlatch all latched keys,
/// so that the new view is the one before first press. /// so that the new view is the one before first press.
fn unstick_locks(&mut self) { fn unstick_locks(&mut self) {
if let LatchedState::FromView(name) = self.view_latched.clone() { if let LatchedState::FromView(name) = self.state.view_latched.clone() {
match self.set_view(name.clone()) { match self.set_view(name.clone()) {
Ok(_) => { self.view_latched = LatchedState::Not; } Ok(_) => { self.state.view_latched = LatchedState::Not; }
Err(e) => log_print!( Err(e) => log_print!(
logging::Level::Bug, logging::Level::Bug,
"Bad view {}, can't unlatch ({:?})", "Bad view {}, can't unlatch ({:?})",
@ -1004,7 +1011,7 @@ mod seat {
time: Timestamp, time: Timestamp,
rckey: &Rc<RefCell<KeyState>>, rckey: &Rc<RefCell<KeyState>>,
) { ) {
if !layout.pressed_keys.insert(::util::Pointer(rckey.clone())) { if !layout.state.pressed_keys.insert(::util::Pointer(rckey.clone())) {
log_print!( log_print!(
logging::Level::Bug, logging::Level::Bug,
"Key {:?} was already pressed", rckey, "Key {:?} was already pressed", rckey,
@ -1118,7 +1125,7 @@ mod seat {
let pointer = ::util::Pointer(rckey.clone()); let pointer = ::util::Pointer(rckey.clone());
// Apply state changes // Apply state changes
layout.pressed_keys.remove(&pointer); layout.state.pressed_keys.remove(&pointer);
// Commit activated button state changes // Commit activated button state changes
RefCell::replace(rckey, key); RefCell::replace(rckey, key);
} }
@ -1220,11 +1227,13 @@ mod test {
)]); )]);
let mut layout = Layout { let mut layout = Layout {
state: LayoutState {
current_view: "base".into(), current_view: "base".into(),
view_latched: LatchedState::Not, view_latched: LatchedState::Not,
pressed_keys: HashSet::new(),
},
keymaps: Vec::new(), keymaps: Vec::new(),
kind: ArrangementKind::Base, kind: ArrangementKind::Base,
pressed_keys: HashSet::new(),
margins: Margins { margins: Margins {
top: 0.0, top: 0.0,
left: 0.0, left: 0.0,
@ -1243,18 +1252,18 @@ mod test {
// Basic cycle // Basic cycle
layout.apply_view_transition(&switch); layout.apply_view_transition(&switch);
assert_eq!(&layout.current_view, "locked"); assert_eq!(&layout.state.current_view, "locked");
layout.apply_view_transition(&switch); layout.apply_view_transition(&switch);
assert_eq!(&layout.current_view, "locked"); assert_eq!(&layout.state.current_view, "locked");
layout.apply_view_transition(&submit); layout.apply_view_transition(&submit);
assert_eq!(&layout.current_view, "locked"); assert_eq!(&layout.state.current_view, "locked");
layout.apply_view_transition(&switch); layout.apply_view_transition(&switch);
assert_eq!(&layout.current_view, "base"); assert_eq!(&layout.state.current_view, "base");
layout.apply_view_transition(&switch); layout.apply_view_transition(&switch);
// Unlatch // Unlatch
assert_eq!(&layout.current_view, "locked"); assert_eq!(&layout.state.current_view, "locked");
layout.apply_view_transition(&submit); layout.apply_view_transition(&submit);
assert_eq!(&layout.current_view, "base"); assert_eq!(&layout.state.current_view, "base");
} }
#[test] #[test]
@ -1296,11 +1305,13 @@ mod test {
)]); )]);
let mut layout = Layout { let mut layout = Layout {
state: LayoutState {
current_view: "base".into(), current_view: "base".into(),
view_latched: LatchedState::Not, view_latched: LatchedState::Not,
pressed_keys: HashSet::new(),
},
keymaps: Vec::new(), keymaps: Vec::new(),
kind: ArrangementKind::Base, kind: ArrangementKind::Base,
pressed_keys: HashSet::new(),
margins: Margins { margins: Margins {
top: 0.0, top: 0.0,
left: 0.0, left: 0.0,
@ -1319,9 +1330,9 @@ mod test {
}; };
layout.apply_view_transition(&switch); layout.apply_view_transition(&switch);
assert_eq!(&layout.current_view, "locked"); assert_eq!(&layout.state.current_view, "locked");
layout.apply_view_transition(&unswitch); layout.apply_view_transition(&unswitch);
assert_eq!(&layout.current_view, "unlocked"); assert_eq!(&layout.state.current_view, "unlocked");
} }
#[test] #[test]
@ -1363,11 +1374,13 @@ mod test {
)]); )]);
let mut layout = Layout { let mut layout = Layout {
state: LayoutState {
current_view: "base".into(), current_view: "base".into(),
view_latched: LatchedState::Not, view_latched: LatchedState::Not,
pressed_keys: HashSet::new(),
},
keymaps: Vec::new(), keymaps: Vec::new(),
kind: ArrangementKind::Base, kind: ArrangementKind::Base,
pressed_keys: HashSet::new(),
margins: Margins { margins: Margins {
top: 0.0, top: 0.0,
left: 0.0, left: 0.0,
@ -1387,14 +1400,14 @@ mod test {
// Latch twice, then Ąto-unlatch across 2 levels // Latch twice, then Ąto-unlatch across 2 levels
layout.apply_view_transition(&switch); layout.apply_view_transition(&switch);
println!("{:?}", layout.view_latched); println!("{:?}", layout.state.view_latched);
assert_eq!(&layout.current_view, "locked"); assert_eq!(&layout.state.current_view, "locked");
layout.apply_view_transition(&switch_again); layout.apply_view_transition(&switch_again);
println!("{:?}", layout.view_latched); println!("{:?}", layout.state.view_latched);
assert_eq!(&layout.current_view, "ĄĘ"); assert_eq!(&layout.state.current_view, "ĄĘ");
layout.apply_view_transition(&submit); layout.apply_view_transition(&submit);
println!("{:?}", layout.view_latched); println!("{:?}", layout.state.view_latched);
assert_eq!(&layout.current_view, "base"); assert_eq!(&layout.state.current_view, "base");
} }
#[test] #[test]
@ -1468,11 +1481,13 @@ mod test {
), ),
]); ]);
let layout = Layout { let layout = Layout {
state: LayoutState {
current_view: String::new(), current_view: String::new(),
view_latched: LatchedState::Not, view_latched: LatchedState::Not,
pressed_keys: HashSet::new(),
},
keymaps: Vec::new(), keymaps: Vec::new(),
kind: ArrangementKind::Base, kind: ArrangementKind::Base,
pressed_keys: HashSet::new(),
// Lots of bottom margin // Lots of bottom margin
margins: Margins { margins: Margins {
top: 0.0, top: 0.0,
@ -1521,11 +1536,13 @@ mod test {
), ),
]); ]);
let layout = Layout { let layout = Layout {
state: LayoutState {
current_view: String::new(), current_view: String::new(),
view_latched: LatchedState::Not, view_latched: LatchedState::Not,
pressed_keys: HashSet::new(),
},
keymaps: Vec::new(), keymaps: Vec::new(),
kind: ArrangementKind::Base, kind: ArrangementKind::Base,
pressed_keys: HashSet::new(),
margins: Margins { margins: Margins {
top: 0.0, top: 0.0,
left: 0.0, left: 0.0,