From 226ac347c51e21440d1740d85b5e9912d1ce08e5 Mon Sep 17 00:00:00 2001 From: "B. Stack" Date: Mon, 6 Dec 2021 07:57:52 -0500 Subject: add upstream 11.15 --- wx+/popup_dlg.cpp | 25 ++++++++++++++++++++ wx+/popup_dlg.h | 3 +++ wx+/std_button_layout.h | 61 +++++++++++++++++++++++++++---------------------- 3 files changed, 62 insertions(+), 27 deletions(-) (limited to 'wx+') diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp index 88ed590b..3d4077c3 100644 --- a/wx+/popup_dlg.cpp +++ b/wx+/popup_dlg.cpp @@ -6,14 +6,17 @@ #include "popup_dlg.h" #include +#include #include #include +#include #include "no_flicker.h" #include "font_size.h" #include "image_resources.h" #include "popup_dlg_generated.h" #include "std_button_layout.h" #include "taskbar.h" + #include "window_tools.h" using namespace zen; @@ -194,6 +197,27 @@ public: Bind(wxEVT_CHAR_HOOK, [this](wxKeyEvent& event) { onLocalKeyEvent(event); }); //dialog-specific local key events + //play sound reminder when waiting for user confirmation + if (!cfg.soundFileAlertPending.empty()) + { + timer_.Bind(wxEVT_TIMER, [this, parent, alertSoundPath = cfg.soundFileAlertPending](wxTimerEvent& event) + { + //wxWidgets shows modal error dialog by default => "no, wxWidgets, NO!" + wxLog* oldLogTarget = wxLog::SetActiveTarget(new wxLogStderr); //transfer and receive ownership! + ZEN_ON_SCOPE_EXIT(delete wxLog::SetActiveTarget(oldLogTarget)); + + wxSound::Play(utfTo(alertSoundPath), wxSOUND_ASYNC); + + RequestUserAttention(wxUSER_ATTENTION_INFO); + /* wxUSER_ATTENTION_INFO: flashes window 3 times, unconditionally + wxUSER_ATTENTION_ERROR: flashes without limit, but *only* if not in foreground (FLASHW_TIMERNOFG) :( */ + if (parent) + if (auto tlw = dynamic_cast(&getRootWindow(*parent))) + tlw->RequestUserAttention(wxUSER_ATTENTION_INFO); //top-level window needed for the taskbar flash! + }); + timer_.Start(60'000 /*unit: [ms]*/); + } + //------------------------------------------------------------------------------ StdButtons stdBtns; stdBtns.setAffirmative(m_buttonAccept); @@ -312,6 +336,7 @@ private: bool* checkBoxValue_; const ConfirmationButton3 buttonToDisableWhenChecked_; std::unique_ptr taskbar_; + wxTimer timer_; }; //######################################################################################## diff --git a/wx+/popup_dlg.h b/wx+/popup_dlg.h index bb7ba51b..11e96e3b 100644 --- a/wx+/popup_dlg.h +++ b/wx+/popup_dlg.h @@ -8,6 +8,7 @@ #define POPUP_DLG_H_820780154723456 #include +#include #include #include #include @@ -68,6 +69,7 @@ struct PopupDialogCfg PopupDialogCfg& setMainInstructions (const wxString& label) { textMain = label; return *this; } //set at least one of these! PopupDialogCfg& setDetailInstructions(const wxString& label) { textDetail = label; return *this; } // PopupDialogCfg& disableButton(ConfirmationButton3 button) { disabledButtons.insert(button); return *this; } + PopupDialogCfg& remindWhenPending(const Zstring& soundFilePath) { soundFileAlertPending = soundFilePath; return *this; } PopupDialogCfg& setCheckBox(bool& value, const wxString& label, ConfirmationButton3 disableWhenChecked = ConfirmationButton3::cancel) { checkBoxValue = &value; @@ -84,6 +86,7 @@ private: wxString textMain; wxString textDetail; std::set disabledButtons; + Zstring soundFileAlertPending; bool* checkBoxValue = nullptr; //in/out wxString checkBoxLabel; ConfirmationButton3 buttonToDisableWhenChecked = ConfirmationButton3::cancel; diff --git a/wx+/std_button_layout.h b/wx+/std_button_layout.h index 25745132..e84b0c78 100644 --- a/wx+/std_button_layout.h +++ b/wx+/std_button_layout.h @@ -47,6 +47,11 @@ void setStandardButtonLayout(wxBoxSizer& sizer, const StdButtons& buttons) { assert(sizer.GetOrientation() == wxHORIZONTAL); + //GNOME Human Interface Guidelines: https://developer.gnome.org/hig-book/3.2/hig-book.html#alert-spacing + const int spaceH = fastFromDIP( 6); //OK + const int spaceRimH = fastFromDIP(12); //OK + const int spaceRimV = fastFromDIP(12); //OK + StdButtons buttonsTmp = buttons; auto detach = [&](wxButton*& btn) @@ -54,15 +59,11 @@ void setStandardButtonLayout(wxBoxSizer& sizer, const StdButtons& buttons) if (btn) { assert(btn->GetContainingSizer() == &sizer); - if (btn->IsShown()) - { - bool rv = sizer.Detach(btn); - assert(rv); - if (!rv) - btn = nullptr; - } - else - btn = nullptr; + if (btn->IsShown() && sizer.Detach(btn)) + return; + + assert(false); //why is it hidden!? + btn = nullptr; } }; @@ -71,10 +72,30 @@ void setStandardButtonLayout(wxBoxSizer& sizer, const StdButtons& buttons) detach(buttonsTmp.btnNo); detach(buttonsTmp.btnCancel); - //GNOME Human Interface Guidelines: https://developer.gnome.org/hig-book/3.2/hig-book.html#alert-spacing - const int spaceH = fastFromDIP( 6); //OK - const int spaceRimH = fastFromDIP(12); //OK - const int spaceRimV = fastFromDIP(12); //OK + + //"All your fixed-size spacers are belong to us!" => have a clean slate: consider repeated setStandardButtonLayout() calls + for (size_t pos = sizer.GetItemCount(); pos-- > 0;) + if (wxSizerItem& item = *sizer.GetItem(pos); + item.IsSpacer() && item.GetProportion() == 0 && item.GetSize().y == 0) + { + [[maybe_unused]] bool rv = sizer.Detach(pos); + assert(rv); + } + + //set border on left considering existing items + if (!sizer.IsEmpty()) //for yet another retarded reason wxWidgets will have wxSizer::GetItem(0) cause an assert rather than just return nullptr as documented + if (wxSizerItem& item = *sizer.GetItem(static_cast(0)); + item.IsShown()) + { + assert(item.GetBorder() <= spaceRimV); //pragmatic check: other controls in the sizer should not have a larger border + + if (const int flag = item.GetFlag(); + flag & wxLEFT) + item.SetFlag(flag & ~wxLEFT); + + sizer.Prepend(spaceRimH, 0); + } + bool settingFirstButton = true; auto attach = [&](wxButton* btn) @@ -93,20 +114,6 @@ void setStandardButtonLayout(wxBoxSizer& sizer, const StdButtons& buttons) } }; - //set border on left considering existing items - if (sizer.GetChildren().GetCount() > 0) //for yet another retarded reason wxWidgets will have wxSizer::GetItem(0) cause an assert rather than just return nullptr as documented - if (wxSizerItem* item = sizer.GetItem(static_cast(0))) - { - assert(item->GetBorder() <= spaceRimV); //pragmatic check: other controls in the sizer should not have a larger border - int flag = item->GetFlag(); - if (flag & wxLEFT) - { - flag &= ~wxLEFT; - item->SetFlag(flag); - } - sizer.Insert(static_cast(0), spaceRimH, 0); - } - sizer.Add(spaceRimH, 0); attach(buttonsTmp.btnNo); attach(buttonsTmp.btnCancel); -- cgit