summaryrefslogtreecommitdiff
path: root/wx+/popup_dlg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'wx+/popup_dlg.cpp')
-rwxr-xr-x[-rw-r--r--]wx+/popup_dlg.cpp614
1 files changed, 302 insertions, 312 deletions
diff --git a/wx+/popup_dlg.cpp b/wx+/popup_dlg.cpp
index f96884d9..dca93658 100644..100755
--- a/wx+/popup_dlg.cpp
+++ b/wx+/popup_dlg.cpp
@@ -1,312 +1,302 @@
-// *****************************************************************************
-// * This file is part of the FreeFileSync project. It is distributed under *
-// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
-// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
-// *****************************************************************************
-
-#include "popup_dlg.h"
-#include <wx/app.h>
-#include <wx/display.h>
-#include <wx+/std_button_layout.h>
-#include <wx+/font_size.h>
-#include <wx+/image_resources.h>
-#include "popup_dlg_generated.h"
-
-#ifdef ZEN_WIN
- #include <wx+/mouse_move_dlg.h>
-#endif
-
-using namespace zen;
-
-namespace
-{
-void setAsStandard(wxButton& btn)
-{
- btn.SetDefault();
- btn.SetFocus();
-}
-
-
-void setBestInitialSize(wxTextCtrl& ctrl, const wxString& text, wxSize maxSize)
-{
- const int scrollbarWidth = 30;
- if (maxSize.x <= scrollbarWidth) //implicitly checks for non-zero, too!
- return;
- maxSize.x -= scrollbarWidth;
-
- int bestWidth = 0;
- int rowCount = 0;
- int rowHeight = 0;
-
- auto evalLineExtent = [&](const wxSize& sz) -> bool //return true when done
- {
- if (sz.x > bestWidth)
- bestWidth = std::min(maxSize.x, sz.x);
-
- rowCount += (sz.x + maxSize.x - 1) / maxSize.x; //integer round up: consider line-wraps!
- rowHeight = std::max(rowHeight, sz.y); //all rows *should* have same height
-
- return rowCount * rowHeight >= maxSize.y;
- };
-
- for (auto it = text.begin();;)
- {
- auto itEnd = std::find(it, text.end(), L'\n');
- wxString line(it, itEnd);
- if (line.empty())
- line = L" "; //GetTextExtent() returns (0, 0) for empty strings!
-
- wxSize sz = ctrl.GetTextExtent(line); //exactly gives row height, but does *not* consider newlines
- if (evalLineExtent(sz))
- break;
-
- if (itEnd == text.end())
- break;
- it = itEnd + 1;
- }
-
-#if defined ZEN_WIN || defined ZEN_LINUX
- const int rowGap = 0;
-#elif defined ZEN_MAC
- const int rowGap = 1;
-#endif
- const wxSize bestSize(bestWidth + scrollbarWidth, std::min(rowCount * (rowHeight + rowGap), maxSize.y));
- ctrl.SetMinSize(bestSize); //alas, SetMinClientSize() is just not working!
-}
-}
-
-
-class zen::StandardPopupDialog : public PopupDialogGenerated
-{
-public:
- StandardPopupDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg) :
- PopupDialogGenerated(parent),
- checkBoxValue_(cfg.checkBoxValue)
- {
-#ifdef ZEN_WIN
- new zen::MouseMoveWindow(*this); //allow moving main dialog by clicking (nearly) anywhere...; ownership passed to "this"
-#endif
- wxBitmap iconTmp;
- wxString titleTmp;
- switch (type)
- {
- case DialogInfoType::INFO:
- //"Information" is meaningless as caption text!
- //confirmation doesn't use info icon
- //iconTmp = getResourceImage(L"msg_info");
- break;
- case DialogInfoType::WARNING:
- iconTmp = getResourceImage(L"msg_warning");
- titleTmp = _("Warning");
- break;
- case DialogInfoType::ERROR2:
- iconTmp = getResourceImage(L"msg_error");
- titleTmp = _("Error");
- break;
- }
- if (cfg.icon.IsOk())
- iconTmp = cfg.icon;
-
- if (!cfg.title.empty())
- titleTmp = cfg.title;
- //-----------------------------------------------
- m_bitmapMsgType->SetBitmap(iconTmp);
-
- if (titleTmp.empty())
- SetTitle(wxTheApp->GetAppDisplayName());
- else
- {
- if (parent && parent->IsShownOnScreen())
- SetTitle(titleTmp);
- else
- SetTitle(wxTheApp->GetAppDisplayName() + L" - " + titleTmp);
- }
-
- int maxWidth = 500;
- int maxHeight = 400; //try to determine better value based on actual display resolution:
-
- if (parent)
- {
- const int disPos = wxDisplay::GetFromWindow(parent); //window must be visible
- if (disPos != wxNOT_FOUND)
- maxHeight = wxDisplay(disPos).GetClientArea().GetHeight() * 2 / 3;
- }
-
- assert(!cfg.textMain.empty() || !cfg.textDetail.empty());
- if (!cfg.textMain.empty())
- {
- setMainInstructionFont(*m_staticTextMain);
- m_staticTextMain->SetLabel(cfg.textMain);
- m_staticTextMain->Wrap(maxWidth); //call *after* SetLabel()
- }
- else
- m_staticTextMain->Hide();
-
- if (!cfg.textDetail.empty())
- {
- const wxString& text = L"\n" + trimCpy(cfg.textDetail) + L"\n"; //add empty top/bottom lines *instead* of using border space!
- setBestInitialSize(*m_textCtrlTextDetail, text, wxSize(maxWidth, maxHeight));
- m_textCtrlTextDetail->ChangeValue(text);
- }
- else
- m_textCtrlTextDetail->Hide();
-
- if (checkBoxValue_)
- {
- assert(contains(cfg.checkBoxLabel, L"&"));
- m_checkBoxCustom->SetLabel(cfg.checkBoxLabel);
- m_checkBoxCustom->SetValue(*checkBoxValue_);
- }
- else
- m_checkBoxCustom->Hide();
-
- Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(StandardPopupDialog::OnKeyPressed), nullptr, this); //dialog-specific local key events
- }
-
-private:
- void OnClose (wxCloseEvent& event) override { EndModal(static_cast<int>(ConfirmationButton3::CANCEL)); }
- void OnCancel(wxCommandEvent& event) override { EndModal(static_cast<int>(ConfirmationButton3::CANCEL)); }
-
- void OnKeyPressed(wxKeyEvent& event)
- {
- switch (event.GetKeyCode())
- {
- case WXK_RETURN:
- case WXK_NUMPAD_ENTER:
- {
- wxCommandEvent dummy(wxEVT_COMMAND_BUTTON_CLICKED);
- OnButtonAffirmative(dummy);
- return;
- }
-
- case WXK_ESCAPE: //handle case where cancel button is hidden!
- EndModal(static_cast<int>(ConfirmationButton3::CANCEL));
- return;
- }
- event.Skip();
- }
-
- void OnButtonAffirmative(wxCommandEvent& event) override
- {
- if (checkBoxValue_)
- *checkBoxValue_ = m_checkBoxCustom->GetValue();
- EndModal(static_cast<int>(ConfirmationButton3::DO_IT));
- }
-
- void OnButtonNegative(wxCommandEvent& event) override
- {
- if (checkBoxValue_)
- *checkBoxValue_ = m_checkBoxCustom->GetValue();
- EndModal(static_cast<int>(ConfirmationButton3::DONT_DO_IT));
- }
-
- bool* checkBoxValue_;
-};
-
-
-namespace
-{
-class NotificationDialog : public StandardPopupDialog
-{
-public:
- NotificationDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg) :
- StandardPopupDialog(parent, type, cfg)
- {
- m_buttonAffirmative->SetLabel(_("Close")); //UX Guide: use "Close" for errors, warnings and windows in which users can't make changes (no ampersand!)
- m_buttonNegative->Hide();
- m_buttonCancel->Hide();
-
- //set std order after button visibility was set
- setStandardButtonLayout(*bSizerStdButtons, StdButtons().setAffirmative(m_buttonAffirmative));
- setAsStandard(*m_buttonAffirmative);
- GetSizer()->SetSizeHints(this); //~=Fit() + SetMinSize()
- Center(); //needs to be re-applied after a dialog size change!
- }
-};
-
-
-class ConfirmationDialog : public StandardPopupDialog
-{
-public:
- ConfirmationDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg, const wxString& labelDoIt) :
- StandardPopupDialog(parent, type, cfg)
- {
- assert(contains(labelDoIt, L"&"));
- m_buttonAffirmative->SetLabel(labelDoIt);
- m_buttonNegative->Hide();
-
- //set std order after button visibility was set
- setStandardButtonLayout(*bSizerStdButtons, StdButtons().setAffirmative(m_buttonAffirmative).setCancel(m_buttonCancel));
- setAsStandard(*m_buttonAffirmative);
- GetSizer()->SetSizeHints(this); //~=Fit() + SetMinSize()
- Center(); //needs to be re-applied after a dialog size change!
- }
-};
-}
-
-class zen::ConfirmationDialog3 : public StandardPopupDialog
-{
-public:
- ConfirmationDialog3(wxWindow* parent, DialogInfoType type, const PopupDialogCfg3& cfg, const wxString& labelDoIt, const wxString& labelDontDoIt) :
- StandardPopupDialog(parent, type, cfg.pdCfg_),
- buttonToDisableWhenChecked_(cfg.buttonToDisableWhenChecked_)
- {
- assert(contains(labelDoIt, L"&"));
- assert(contains(labelDontDoIt, L"&"));
- m_buttonAffirmative->SetLabel(labelDoIt);
- m_buttonNegative ->SetLabel(labelDontDoIt);
-
- //m_buttonAffirmative->SetId(wxID_IGNORE); -> setting id after button creation breaks "mouse snap to" functionality
- //m_buttonNegative ->SetId(wxID_RETRY); -> also wxWidgets docs seem to hide some info: "Normally, the identifier should be provided on creation and should not be modified subsequently."
-
- updateGui();
-
- //set std order after button visibility was set
- setStandardButtonLayout(*bSizerStdButtons, StdButtons().setAffirmative(m_buttonAffirmative).setNegative(m_buttonNegative).setCancel(m_buttonCancel));
- setAsStandard(*m_buttonAffirmative);
- GetSizer()->SetSizeHints(this); //~=Fit() + SetMinSize()
- Center(); //needs to be re-applied after a dialog size change!
- }
-
-private:
- void OnCheckBoxClick(wxCommandEvent& event) override { updateGui(); event.Skip(); }
-
- void updateGui()
- {
- switch (buttonToDisableWhenChecked_)
- {
- case ConfirmationButton3::DO_IT:
- m_buttonAffirmative->Enable(!m_checkBoxCustom->GetValue());
- break;
- case ConfirmationButton3::DONT_DO_IT:
- m_buttonNegative->Enable(!m_checkBoxCustom->GetValue());
- break;
- case ConfirmationButton3::CANCEL:
- break;
- }
- }
-
- const ConfirmationButton3 buttonToDisableWhenChecked_;
-};
-
-//########################################################################################
-
-void zen::showNotificationDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg)
-{
- NotificationDialog dlg(parent, type, cfg);
- dlg.ShowModal();
-}
-
-
-ConfirmationButton zen::showConfirmationDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg, const wxString& labelDoIt)
-{
- ConfirmationDialog dlg(parent, type, cfg, labelDoIt);
- return static_cast<ConfirmationButton>(dlg.ShowModal());
-}
-
-
-ConfirmationButton3 zen::showConfirmationDialog3(wxWindow* parent, DialogInfoType type, const PopupDialogCfg3& cfg, const wxString& labelDoIt, const wxString& labelDontDoIt)
-{
- ConfirmationDialog3 dlg(parent, type, cfg, labelDoIt, labelDontDoIt);
- return static_cast<ConfirmationButton3>(dlg.ShowModal());
-}
+// *****************************************************************************
+// * This file is part of the FreeFileSync project. It is distributed under *
+// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 *
+// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved *
+// *****************************************************************************
+
+#include "popup_dlg.h"
+#include <wx/app.h>
+#include <wx/display.h>
+#include <wx+/std_button_layout.h>
+#include <wx+/font_size.h>
+#include <wx+/image_resources.h>
+#include "popup_dlg_generated.h"
+
+
+using namespace zen;
+
+namespace
+{
+void setAsStandard(wxButton& btn)
+{
+ btn.SetDefault();
+ btn.SetFocus();
+}
+
+
+void setBestInitialSize(wxTextCtrl& ctrl, const wxString& text, wxSize maxSize)
+{
+ const int scrollbarWidth = 30;
+ if (maxSize.x <= scrollbarWidth) //implicitly checks for non-zero, too!
+ return;
+ maxSize.x -= scrollbarWidth;
+
+ int bestWidth = 0;
+ int rowCount = 0;
+ int rowHeight = 0;
+
+ auto evalLineExtent = [&](const wxSize& sz) -> bool //return true when done
+ {
+ if (sz.x > bestWidth)
+ bestWidth = std::min(maxSize.x, sz.x);
+
+ rowCount += (sz.x + maxSize.x - 1) / maxSize.x; //integer round up: consider line-wraps!
+ rowHeight = std::max(rowHeight, sz.y); //all rows *should* have same height
+
+ return rowCount * rowHeight >= maxSize.y;
+ };
+
+ for (auto it = text.begin();;)
+ {
+ auto itEnd = std::find(it, text.end(), L'\n');
+ wxString line(it, itEnd);
+ if (line.empty())
+ line = L" "; //GetTextExtent() returns (0, 0) for empty strings!
+
+ wxSize sz = ctrl.GetTextExtent(line); //exactly gives row height, but does *not* consider newlines
+ if (evalLineExtent(sz))
+ break;
+
+ if (itEnd == text.end())
+ break;
+ it = itEnd + 1;
+ }
+
+ const int rowGap = 0;
+ const wxSize bestSize(bestWidth + scrollbarWidth, std::min(rowCount * (rowHeight + rowGap), maxSize.y));
+ ctrl.SetMinSize(bestSize); //alas, SetMinClientSize() is just not working!
+}
+}
+
+
+class zen::StandardPopupDialog : public PopupDialogGenerated
+{
+public:
+ StandardPopupDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg) :
+ PopupDialogGenerated(parent),
+ checkBoxValue_(cfg.checkBoxValue)
+ {
+ wxBitmap iconTmp;
+ wxString titleTmp;
+ switch (type)
+ {
+ case DialogInfoType::INFO:
+ //"Information" is meaningless as caption text!
+ //confirmation doesn't use info icon
+ //iconTmp = getResourceImage(L"msg_info");
+ break;
+ case DialogInfoType::WARNING:
+ iconTmp = getResourceImage(L"msg_warning");
+ titleTmp = _("Warning");
+ break;
+ case DialogInfoType::ERROR2:
+ iconTmp = getResourceImage(L"msg_error");
+ titleTmp = _("Error");
+ break;
+ }
+ if (cfg.icon.IsOk())
+ iconTmp = cfg.icon;
+
+ if (!cfg.title.empty())
+ titleTmp = cfg.title;
+ //-----------------------------------------------
+ m_bitmapMsgType->SetBitmap(iconTmp);
+
+ if (titleTmp.empty())
+ SetTitle(wxTheApp->GetAppDisplayName());
+ else
+ {
+ if (parent && parent->IsShownOnScreen())
+ SetTitle(titleTmp);
+ else
+ SetTitle(wxTheApp->GetAppDisplayName() + L" - " + titleTmp);
+ }
+
+ int maxWidth = 500;
+ int maxHeight = 400; //try to determine better value based on actual display resolution:
+
+ if (parent)
+ {
+ const int disPos = wxDisplay::GetFromWindow(parent); //window must be visible
+ if (disPos != wxNOT_FOUND)
+ maxHeight = wxDisplay(disPos).GetClientArea().GetHeight() * 2 / 3;
+ }
+
+ assert(!cfg.textMain.empty() || !cfg.textDetail.empty());
+ if (!cfg.textMain.empty())
+ {
+ setMainInstructionFont(*m_staticTextMain);
+ m_staticTextMain->SetLabel(cfg.textMain);
+ m_staticTextMain->Wrap(maxWidth); //call *after* SetLabel()
+ }
+ else
+ m_staticTextMain->Hide();
+
+ if (!cfg.textDetail.empty())
+ {
+ const wxString& text = L"\n" + trimCpy(cfg.textDetail) + L"\n"; //add empty top/bottom lines *instead* of using border space!
+ setBestInitialSize(*m_textCtrlTextDetail, text, wxSize(maxWidth, maxHeight));
+ m_textCtrlTextDetail->ChangeValue(text);
+ }
+ else
+ m_textCtrlTextDetail->Hide();
+
+ if (checkBoxValue_)
+ {
+ assert(contains(cfg.checkBoxLabel, L"&"));
+ m_checkBoxCustom->SetLabel(cfg.checkBoxLabel);
+ m_checkBoxCustom->SetValue(*checkBoxValue_);
+ }
+ else
+ m_checkBoxCustom->Hide();
+
+ Connect(wxEVT_CHAR_HOOK, wxKeyEventHandler(StandardPopupDialog::OnKeyPressed), nullptr, this); //dialog-specific local key events
+ }
+
+private:
+ void OnClose (wxCloseEvent& event) override { EndModal(static_cast<int>(ConfirmationButton3::CANCEL)); }
+ void OnCancel(wxCommandEvent& event) override { EndModal(static_cast<int>(ConfirmationButton3::CANCEL)); }
+
+ void OnKeyPressed(wxKeyEvent& event)
+ {
+ switch (event.GetKeyCode())
+ {
+ case WXK_RETURN:
+ case WXK_NUMPAD_ENTER:
+ {
+ wxCommandEvent dummy(wxEVT_COMMAND_BUTTON_CLICKED);
+ OnButtonAffirmative(dummy);
+ return;
+ }
+
+ case WXK_ESCAPE: //handle case where cancel button is hidden!
+ EndModal(static_cast<int>(ConfirmationButton3::CANCEL));
+ return;
+ }
+ event.Skip();
+ }
+
+ void OnButtonAffirmative(wxCommandEvent& event) override
+ {
+ if (checkBoxValue_)
+ *checkBoxValue_ = m_checkBoxCustom->GetValue();
+ EndModal(static_cast<int>(ConfirmationButton3::DO_IT));
+ }
+
+ void OnButtonNegative(wxCommandEvent& event) override
+ {
+ if (checkBoxValue_)
+ *checkBoxValue_ = m_checkBoxCustom->GetValue();
+ EndModal(static_cast<int>(ConfirmationButton3::DONT_DO_IT));
+ }
+
+ bool* checkBoxValue_;
+};
+
+
+namespace
+{
+class NotificationDialog : public StandardPopupDialog
+{
+public:
+ NotificationDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg) :
+ StandardPopupDialog(parent, type, cfg)
+ {
+ m_buttonAffirmative->SetLabel(_("Close")); //UX Guide: use "Close" for errors, warnings and windows in which users can't make changes (no ampersand!)
+ m_buttonNegative->Hide();
+ m_buttonCancel->Hide();
+
+ //set std order after button visibility was set
+ setStandardButtonLayout(*bSizerStdButtons, StdButtons().setAffirmative(m_buttonAffirmative));
+ setAsStandard(*m_buttonAffirmative);
+ GetSizer()->SetSizeHints(this); //~=Fit() + SetMinSize()
+ Center(); //needs to be re-applied after a dialog size change!
+ }
+};
+
+
+class ConfirmationDialog : public StandardPopupDialog
+{
+public:
+ ConfirmationDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg, const wxString& labelDoIt) :
+ StandardPopupDialog(parent, type, cfg)
+ {
+ assert(contains(labelDoIt, L"&"));
+ m_buttonAffirmative->SetLabel(labelDoIt);
+ m_buttonNegative->Hide();
+
+ //set std order after button visibility was set
+ setStandardButtonLayout(*bSizerStdButtons, StdButtons().setAffirmative(m_buttonAffirmative).setCancel(m_buttonCancel));
+ setAsStandard(*m_buttonAffirmative);
+ GetSizer()->SetSizeHints(this); //~=Fit() + SetMinSize()
+ Center(); //needs to be re-applied after a dialog size change!
+ }
+};
+}
+
+class zen::ConfirmationDialog3 : public StandardPopupDialog
+{
+public:
+ ConfirmationDialog3(wxWindow* parent, DialogInfoType type, const PopupDialogCfg3& cfg, const wxString& labelDoIt, const wxString& labelDontDoIt) :
+ StandardPopupDialog(parent, type, cfg.pdCfg_),
+ buttonToDisableWhenChecked_(cfg.buttonToDisableWhenChecked_)
+ {
+ assert(contains(labelDoIt, L"&"));
+ assert(contains(labelDontDoIt, L"&"));
+ m_buttonAffirmative->SetLabel(labelDoIt);
+ m_buttonNegative ->SetLabel(labelDontDoIt);
+
+ //m_buttonAffirmative->SetId(wxID_IGNORE); -> setting id after button creation breaks "mouse snap to" functionality
+ //m_buttonNegative ->SetId(wxID_RETRY); -> also wxWidgets docs seem to hide some info: "Normally, the identifier should be provided on creation and should not be modified subsequently."
+
+ updateGui();
+
+ //set std order after button visibility was set
+ setStandardButtonLayout(*bSizerStdButtons, StdButtons().setAffirmative(m_buttonAffirmative).setNegative(m_buttonNegative).setCancel(m_buttonCancel));
+ setAsStandard(*m_buttonAffirmative);
+ GetSizer()->SetSizeHints(this); //~=Fit() + SetMinSize()
+ Center(); //needs to be re-applied after a dialog size change!
+ }
+
+private:
+ void OnCheckBoxClick(wxCommandEvent& event) override { updateGui(); event.Skip(); }
+
+ void updateGui()
+ {
+ switch (buttonToDisableWhenChecked_)
+ {
+ case ConfirmationButton3::DO_IT:
+ m_buttonAffirmative->Enable(!m_checkBoxCustom->GetValue());
+ break;
+ case ConfirmationButton3::DONT_DO_IT:
+ m_buttonNegative->Enable(!m_checkBoxCustom->GetValue());
+ break;
+ case ConfirmationButton3::CANCEL:
+ break;
+ }
+ }
+
+ const ConfirmationButton3 buttonToDisableWhenChecked_;
+};
+
+//########################################################################################
+
+void zen::showNotificationDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg)
+{
+ NotificationDialog dlg(parent, type, cfg);
+ dlg.ShowModal();
+}
+
+
+ConfirmationButton zen::showConfirmationDialog(wxWindow* parent, DialogInfoType type, const PopupDialogCfg& cfg, const wxString& labelDoIt)
+{
+ ConfirmationDialog dlg(parent, type, cfg, labelDoIt);
+ return static_cast<ConfirmationButton>(dlg.ShowModal());
+}
+
+
+ConfirmationButton3 zen::showConfirmationDialog3(wxWindow* parent, DialogInfoType type, const PopupDialogCfg3& cfg, const wxString& labelDoIt, const wxString& labelDontDoIt)
+{
+ ConfirmationDialog3 dlg(parent, type, cfg, labelDoIt, labelDontDoIt);
+ return static_cast<ConfirmationButton3>(dlg.ShowModal());
+}
bgstack15