mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-28 12:46:48 -06:00
Release focus when the sheet tab rename ends (#145)
This commit is contained in:
@@ -8,6 +8,12 @@ use crate::SheetApp;
|
||||
use crate::icons::{self, Icon};
|
||||
use crate::theme::{self, Tokens};
|
||||
|
||||
/// The rename field asks for focus only while it has not got it yet. Asking again on the frame it lost focus (Enter or a click elsewhere)
|
||||
/// would keep the field focused after it is closed, so the keyboard stayed stuck in the sheet name.
|
||||
fn rename_needs_focus(has_focus: bool, lost_focus: bool) -> bool {
|
||||
!has_focus && !lost_focus
|
||||
}
|
||||
|
||||
pub fn sheet_tabs(app: &mut SheetApp, ui: &mut Ui) {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
egui::Panel::bottom("sheet_tabs").exact_size(32.0).frame(egui::Frame::NONE.fill(t.tab_bar)).show(ui, |ui| {
|
||||
@@ -61,7 +67,9 @@ pub fn sheet_tabs(app: &mut SheetApp, ui: &mut Ui) {
|
||||
let mut child = ui.new_child(egui::UiBuilder::new().max_rect(r.shrink2(vec2(6.0, 5.0))));
|
||||
let ed = child.add(egui::TextEdit::singleline(&mut text).font(theme::ui_font(13.0)).desired_width(r.width() - 12.0));
|
||||
app.grid.rename_text = text.clone();
|
||||
ed.request_focus();
|
||||
if rename_needs_focus(ed.has_focus(), ed.lost_focus()) {
|
||||
ed.request_focus();
|
||||
}
|
||||
if ed.lost_focus() {
|
||||
if !ui.input(|i| i.key_pressed(egui::Key::Escape)) && text != name {
|
||||
app.run_or_alert("sheet.rename", json!({"sheet": i, "name": text}));
|
||||
@@ -285,3 +293,15 @@ pub fn status_bar(app: &mut SheetApp, ui: &mut Ui) {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::rename_needs_focus;
|
||||
|
||||
#[test]
|
||||
fn rename_field_takes_focus_once_and_lets_go_on_commit() {
|
||||
assert!(rename_needs_focus(false, false), "first frame: grab focus");
|
||||
assert!(!rename_needs_focus(true, false), "already focused: do not ask again");
|
||||
assert!(!rename_needs_focus(false, true), "Enter or click-away: must not take focus back");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
//! Renaming a sheet tab: the name field must let go of the keyboard when the user is done (#145).
|
||||
|
||||
use egui::{Event, Key, Modifiers, PointerButton};
|
||||
use gridcraft_engine::Session;
|
||||
use gridcraft_engine::core::CellRef;
|
||||
use gridcraft_ui_egui::{SheetApp, grid::Geo};
|
||||
|
||||
fn harness() -> egui_kittest::Harness<'static, SheetApp> {
|
||||
let mut s = Session::new();
|
||||
s.new_workbook();
|
||||
let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_ui_state(
|
||||
|ui, app: &mut SheetApp| {
|
||||
let ctx = ui.ctx().clone();
|
||||
app.logic(&ctx);
|
||||
app.ui(ui);
|
||||
},
|
||||
SheetApp::new(s, Default::default()),
|
||||
);
|
||||
h.run_steps(4);
|
||||
h
|
||||
}
|
||||
|
||||
fn start_rename(h: &mut egui_kittest::Harness<'static, SheetApp>, new_name: &str) {
|
||||
h.state_mut().grid.renaming_tab = Some(0);
|
||||
h.state_mut().grid.rename_text = new_name.to_string();
|
||||
h.run_steps(3);
|
||||
}
|
||||
|
||||
fn sheet_name(h: &egui_kittest::Harness<'static, SheetApp>) -> String {
|
||||
h.state().session.active().unwrap().wb.sheets[0].name.clone()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn enter_saves_the_sheet_name_and_closes_the_field() {
|
||||
let mut h = harness();
|
||||
start_rename(&mut h, "Budget");
|
||||
h.input_mut().events.push(Event::Key { key: Key::Enter, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE });
|
||||
h.input_mut().events.push(Event::Key { key: Key::Enter, physical_key: None, pressed: false, repeat: false, modifiers: Modifiers::NONE });
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().grid.renaming_tab, None, "Enter must close the rename field");
|
||||
assert_eq!(sheet_name(&h), "Budget");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clicking_a_cell_saves_the_sheet_name_and_closes_the_field() {
|
||||
let mut h = harness();
|
||||
start_rename(&mut h, "Ledger");
|
||||
let app = h.state();
|
||||
let sheet = app.session.active().unwrap().wb.active().unwrap();
|
||||
let geo = Geo::new(sheet, app.grid.rect.unwrap(), app.view().scroll);
|
||||
let pos = geo.cell_rect(sheet, CellRef::parse("B2").unwrap()).center();
|
||||
h.input_mut().events.extend([
|
||||
Event::PointerMoved(pos),
|
||||
Event::PointerButton { pos, button: PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE },
|
||||
Event::PointerButton { pos, button: PointerButton::Primary, pressed: false, modifiers: Modifiers::NONE },
|
||||
]);
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().grid.renaming_tab, None, "clicking elsewhere must close the rename field");
|
||||
assert_eq!(sheet_name(&h), "Ledger");
|
||||
}
|
||||
Reference in New Issue
Block a user