From 8add404adcef1aa2c9744edec5c3738d4586621f Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 12 Jan 2026 21:00:24 +0100 Subject: [PATCH] WIP --- .../laybasic/gsiDeclLayEditorOptionsPage.cc | 31 +++++++++++++++ .../laybasic/gsiDeclLayEditorOptionsPage.h | 3 ++ src/laybasic/laybasic/layEditorOptionsPage.cc | 39 +++++++++++++++++-- src/laybasic/laybasic/layEditorOptionsPage.h | 7 +++- src/laybasic/laybasic/layEditorServiceBase.cc | 12 ++++-- src/laybasic/laybasic/layMove.cc | 27 ++----------- 6 files changed, 87 insertions(+), 32 deletions(-) diff --git a/src/laybasic/laybasic/gsiDeclLayEditorOptionsPage.cc b/src/laybasic/laybasic/gsiDeclLayEditorOptionsPage.cc index 7a63b0df5..1d2d335fd 100644 --- a/src/laybasic/laybasic/gsiDeclLayEditorOptionsPage.cc +++ b/src/laybasic/laybasic/gsiDeclLayEditorOptionsPage.cc @@ -73,6 +73,10 @@ Class decl_EditorOptionsPageBase (QT_EXTERNAL_BASE (QWid ) + method ("setup", &lay::EditorOptionsPage::setup, gsi::arg ("dispatcher"), "@brief Transfers data from the configuration to the page\n" + ) + + method ("cancel", &lay::EditorOptionsPage::cancel, + "@brief Gets called when the Escape key is pressed on a non-modal page\n" + "This method has been introduced in version 0.30.6." ), "@brief The plugin framework's editor options page base class\n" "\n" @@ -111,6 +115,11 @@ static void setup_fb (EditorOptionsPageImpl *ep, lay::Dispatcher *root) ep->lay::EditorOptionsPage::setup (root); } +static void cancel_fb (EditorOptionsPageImpl *ep) +{ + ep->lay::EditorOptionsPage::cancel (); +} + void EditorOptionsPageImpl::apply_impl (lay::Dispatcher *root) { @@ -143,6 +152,22 @@ EditorOptionsPageImpl::setup (lay::Dispatcher *root) } } +void +EditorOptionsPageImpl::cancel_impl () +{ + lay::EditorOptionsPage::cancel (); +} + +void +EditorOptionsPageImpl::cancel () +{ + if (f_cancel.can_issue ()) { + f_cancel.issue (&EditorOptionsPageImpl::cancel_impl); + } else { + EditorOptionsPageImpl::cancel_impl (); + } +} + EditorOptionsPageImpl *new_editor_options_page (const std::string &title, int index) { return new EditorOptionsPageImpl (title, index); @@ -173,6 +198,12 @@ Class decl_EditorOptionsPage (decl_EditorOptionsPageBase, "In this method, you should transfer all configuration data to the widgets.\n" "Use \\Dispatcher#get_config on the dispatcher object ('dispatcher' argument) to get a configuration parameter " "and set the editing widget's state accordingly.\n" + ) + + // prevents infinite recursion + method_ext ("cancel", &cancel_fb, "@hide") + + callback ("cancel", &EditorOptionsPageImpl::cancel, &EditorOptionsPageImpl::f_cancel, + "@brief Reimplement this method to receive Escape key events for the page\n" + "This method has been added in version 0.30.6.\n" ), "@brief The plugin framework's editor options page\n" "\n" diff --git a/src/laybasic/laybasic/gsiDeclLayEditorOptionsPage.h b/src/laybasic/laybasic/gsiDeclLayEditorOptionsPage.h index 0e1598898..c679b0d0e 100644 --- a/src/laybasic/laybasic/gsiDeclLayEditorOptionsPage.h +++ b/src/laybasic/laybasic/gsiDeclLayEditorOptionsPage.h @@ -53,9 +53,11 @@ public: void call_edited (); virtual void apply (lay::Dispatcher *root); virtual void setup (lay::Dispatcher *root); + virtual void cancel (); gsi::Callback f_apply; gsi::Callback f_setup; + gsi::Callback f_cancel; private: tl::weak_ptr mp_view; @@ -65,6 +67,7 @@ private: void apply_impl (lay::Dispatcher *root); void setup_impl (lay::Dispatcher *root); + void cancel_impl (); }; } diff --git a/src/laybasic/laybasic/layEditorOptionsPage.cc b/src/laybasic/laybasic/layEditorOptionsPage.cc index 291d815db..44bd772f1 100644 --- a/src/laybasic/laybasic/layEditorOptionsPage.cc +++ b/src/laybasic/laybasic/layEditorOptionsPage.cc @@ -188,10 +188,17 @@ void EditorOptionsPageWidget::keyPressEvent (QKeyEvent *event) { BEGIN_PROTECTED - if (! is_modal_page () && event->modifiers () == Qt::NoModifier && event->key () == Qt::Key_Return) { - // The Return key on a non-modal page commits the values and gives back the focus - // to the view - apply (dispatcher ()); + if (! is_modal_page () && + event->modifiers () == Qt::NoModifier && + (event->key () == Qt::Key_Return || event->key () == Qt::Key_Enter || event->key () == Qt::Key_Escape)) { + if (event->key () == Qt::Key_Escape) { + // The Escape key creates a call to cancel() + cancel (); + } else { + // The Return key on a non-modal page commits the values and gives back the focus + // to the view + apply (dispatcher ()); + } view ()->set_focus (); event->accept (); } else { @@ -200,6 +207,24 @@ BEGIN_PROTECTED END_PROTECTED } +bool +EditorOptionsPageWidget::event (QEvent *event) +{ + if (event->type () == QEvent::ShortcutOverride) { + QKeyEvent *ke = dynamic_cast (event); + if (ke->key () == Qt::Key_Escape || + ke->key () == Qt::Key_Tab || + ke->key () == Qt::Key_Enter || + ke->key () == Qt::Key_Return || + ke->key () == Qt::Key_Backtab) { + // accept the shortcut override event for some keys, so we can handle + // it in keyPressEvent + ke->accept (); + } + } + return QWidget::event (event); +} + void EditorOptionsPageWidget::set_focus () { @@ -215,6 +240,12 @@ EditorOptionsPageWidget::set_visible (bool visible) setVisible (visible); } +bool +EditorOptionsPageWidget::is_visible () const +{ + return isVisible (); +} + #endif } diff --git a/src/laybasic/laybasic/layEditorOptionsPage.h b/src/laybasic/laybasic/layEditorOptionsPage.h index b4a541e40..20cfb81c1 100644 --- a/src/laybasic/laybasic/layEditorOptionsPage.h +++ b/src/laybasic/laybasic/layEditorOptionsPage.h @@ -83,13 +83,16 @@ public: virtual int order () const = 0; virtual const char *name () const { return 0; } virtual void apply (lay::Dispatcher * /*root*/) { } + virtual void cancel () { } virtual void setup (lay::Dispatcher * /*root*/) { } virtual void commit_recent (lay::Dispatcher * /*root*/) { } virtual void config_recent_for_layer (lay::Dispatcher * /*root*/, const db::LayerProperties & /*lp*/, int /*cv_index*/) { } virtual void set_focus () { } - virtual void set_visible (bool /*visible*/) { } virtual EditorOptionsPageWidget *widget () { return 0; } + virtual bool is_visible () const { return false; } + virtual void set_visible (bool /*visible*/) { } + bool is_focus_page () const { return m_focus_page; } void set_focus_page (bool f) { m_focus_page = f; } @@ -159,6 +162,7 @@ public: virtual ~EditorOptionsPageWidget (); virtual void set_focus (); + virtual bool is_visible () const; virtual void set_visible (bool visible); virtual EditorOptionsPageWidget *widget () { return this; } @@ -168,6 +172,7 @@ protected slots: protected: virtual bool focusNextPrevChild (bool next); virtual void keyPressEvent (QKeyEvent *event); + virtual bool event (QEvent *event); }; #endif // defined(HAVE_QT) diff --git a/src/laybasic/laybasic/layEditorServiceBase.cc b/src/laybasic/laybasic/layEditorServiceBase.cc index 0783817ba..e56116965 100644 --- a/src/laybasic/laybasic/layEditorServiceBase.cc +++ b/src/laybasic/laybasic/layEditorServiceBase.cc @@ -369,9 +369,9 @@ EditorServiceBase::focus_page () } bool -EditorServiceBase::key_event (unsigned int key, unsigned int buttons) +EditorServiceBase::key_event (unsigned int key, unsigned int /*buttons*/) { - if (is_active () && key == Qt::Key_Tab && buttons == 0) { + if (is_active () && (key == Qt::Key_Tab || key == Qt::Key_Backtab)) { focus_page_open (); return true; } else { @@ -380,9 +380,13 @@ EditorServiceBase::key_event (unsigned int key, unsigned int buttons) } bool -EditorServiceBase::shortcut_override_event (unsigned int key, unsigned int buttons) +EditorServiceBase::shortcut_override_event (unsigned int key, unsigned int /*buttons*/) { - return is_active () && key == Qt::Key_Tab && buttons == 0 && focus_page (); + auto fp = focus_page (); + return is_active () + && (key == Qt::Key_Tab || key == Qt::Key_Backtab) + && fp + && (fp->is_modal_page () || fp->is_visible ()); } int diff --git a/src/laybasic/laybasic/layMove.cc b/src/laybasic/laybasic/layMove.cc index 0664a4bc9..80e63b68d 100644 --- a/src/laybasic/laybasic/layMove.cc +++ b/src/laybasic/laybasic/layMove.cc @@ -431,33 +431,14 @@ public: hide (); } - virtual void keyPressEvent (QKeyEvent *event) + virtual void apply (lay::Dispatcher * /*dispatcher*/) { - if (event->key () == Qt::Key_Escape) { - tl::info << "@@@ Escape!"; - view ()->set_focus (); - } else if (event->key () == Qt::Key_Enter || event->key () == Qt::Key_Return) { - tl::info << "@@@ Accept!"; - view ()->set_focus (); - } - QWidget::keyPressEvent (event); + tl::info << "@@@ Accept!"; } - virtual bool event (QEvent *event) + virtual void cancel () { - if (event->type () == QEvent::ShortcutOverride) { - QKeyEvent *ke = dynamic_cast (event); - if (ke->key () == Qt::Key_Escape || - ke->key () == Qt::Key_Tab || - ke->key () == Qt::Key_Enter || - ke->key () == Qt::Key_Return || - ke->key () == Qt::Key_Backtab) { - // accept the shortcut override event for some keys, so we can handle - // it in keyPressEvent - ke->accept (); - } - } - return QWidget::event (event); + tl::info << "@@@ Escape!"; } private: