1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 01:27:43 +00:00

Spreadsheet: Have cursor movement keys commit and stop cell editing

Customize the cell editing delegate to stop editing when one of the
various cursor movement keys is hit. This allows you to type into a
cell and then move to an adjacent cell by simply pressing an arrow.

This may not be the best factoring for this feature, but it's pretty
dang cool and we'll see how it evolves over time. :^)
This commit is contained in:
Andreas Kling 2020-08-28 21:24:59 +02:00
parent 057d04d98f
commit c3b2495320
2 changed files with 69 additions and 3 deletions

View file

@ -78,8 +78,13 @@ SpreadsheetView::SpreadsheetView(Sheet& sheet)
m_table_view->set_alternating_row_colors(false);
m_table_view->set_highlight_selected_rows(false);
m_table_view->set_editable(true);
m_table_view->aid_create_editing_delegate = [&](auto&) {
return make<EditingDelegate>(*m_sheet);
m_table_view->aid_create_editing_delegate = [this](auto&) {
auto delegate = make<EditingDelegate>(*m_sheet);
delegate->on_cursor_key_pressed = [this](auto& event) {
m_table_view->stop_editing();
m_table_view->event(event);
};
return delegate;
};
m_table_view->on_selection_change = [&] {

View file

@ -34,6 +34,49 @@
namespace Spreadsheet {
class CellEditor final : public GUI::TextEditor {
C_OBJECT(CellEditor);
public:
virtual ~CellEditor() { }
Function<void(GUI::KeyEvent&)> on_cursor_key_pressed;
private:
CellEditor()
: TextEditor(TextEditor::Type::SingleLine)
{
}
static bool is_navigation(const GUI::KeyEvent& event)
{
if (event.modifiers() == KeyModifier::Mod_Shift && event.key() == KeyCode::Key_Tab)
return true;
if (event.modifiers())
return false;
switch (event.key()) {
case KeyCode::Key_Tab:
case KeyCode::Key_Left:
case KeyCode::Key_Right:
case KeyCode::Key_Up:
case KeyCode::Key_Down:
return true;
default:
return false;
}
}
virtual void keydown_event(GUI::KeyEvent& event) override
{
if (is_navigation(event))
on_cursor_key_pressed(event);
else
TextEditor::keydown_event(event);
}
};
class SpreadsheetView final : public GUI::Widget {
C_OBJECT(SpreadsheetView);
@ -52,7 +95,7 @@ private:
SpreadsheetView(Sheet&);
class EditingDelegate : public GUI::StringModelEditingDelegate {
class EditingDelegate final : public GUI::StringModelEditingDelegate {
public:
EditingDelegate(const Sheet& sheet)
: m_sheet(sheet)
@ -60,6 +103,24 @@ private:
}
virtual void set_value(const GUI::Variant& value) override;
virtual RefPtr<Widget> create_widget() override
{
auto textbox = CellEditor::construct();
textbox->on_return_pressed = [this] {
commit();
};
textbox->on_escape_pressed = [this] {
rollback();
};
textbox->on_cursor_key_pressed = [this](auto& event) {
commit();
on_cursor_key_pressed(event);
};
return textbox;
}
Function<void(GUI::KeyEvent&)> on_cursor_key_pressed;
private:
bool m_has_set_initial_value { false };
const Sheet& m_sheet;