This commit is contained in:
Matthias Koefferlein 2026-01-12 21:00:24 +01:00
parent 67790c0ce7
commit 8add404adc
6 changed files with 87 additions and 32 deletions

View File

@ -73,6 +73,10 @@ Class<lay::EditorOptionsPage> 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> (&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<EditorOptionsPageImpl> 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"

View File

@ -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<lay::LayoutViewBase> mp_view;
@ -65,6 +67,7 @@ private:
void apply_impl (lay::Dispatcher *root);
void setup_impl (lay::Dispatcher *root);
void cancel_impl ();
};
}

View File

@ -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<QKeyEvent *> (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
}

View File

@ -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)

View File

@ -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

View File

@ -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<QKeyEvent *> (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: