1 #include "gui/windows/Widgets.h"
2 #include "gui/MainLoop.h"
3 #include "gui/Utils.h"
4 #include "thread/CheckFunction.h"
5 #include <wx/msgdlg.h>
6 #include <wx/propgrid/propgrid.h>
7 #include <wx/propgrid/props.h>
8 #include <wx/sizer.h>
9 #include <wx/stattext.h>
10
11 NAMESPACE_SPH_BEGIN
12
FloatTextCtrl(wxWindow * parent,const double value,const Interval range)13 FloatTextCtrl::FloatTextCtrl(wxWindow* parent, const double value, const Interval range)
14 : value(value)
15 , range(range) {
16
17 lastValidValue = value;
18
19 wxValidator* validator = wxFloatProperty::GetClassValidator();
20 this->Create(parent,
21 wxID_ANY,
22 std::to_string(value),
23 wxDefaultPosition,
24 wxSize(100, 25),
25 wxTE_PROCESS_ENTER | wxTE_RIGHT,
26 *validator);
27
28 this->Bind(wxEVT_TEXT_ENTER, [this](wxCommandEvent& evt) {
29 this->validate();
30 evt.Skip();
31 });
32 this->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& evt) {
33 this->validate();
34 evt.Skip();
35 });
36
37 this->validate();
38 }
39
setValue(double newValue)40 void FloatTextCtrl::setValue(double newValue) {
41 value = range.clamp(newValue);
42 lastValidValue = value;
43
44 wxFloatProperty prop;
45 wxVariant variant(value);
46 this->ChangeValue(prop.ValueToString(variant));
47 }
48
validate()49 void FloatTextCtrl::validate() {
50 wxFloatProperty prop;
51 wxVariant variant = this->GetValue();
52 wxPGValidationInfo info;
53 if (!prop.ValidateValue(variant, info)) {
54 value = lastValidValue;
55 } else {
56 value = float(variant.GetDouble());
57 }
58
59 value = range.clamp(value);
60
61 if (onValueChanged && value != lastValidValue) {
62 const bool validated = onValueChanged(value);
63 if (!validated) {
64 value = lastValidValue;
65 }
66 }
67
68 lastValidValue = value;
69 variant = double(value);
70 this->ChangeValue(prop.ValueToString(variant));
71 }
72
73 class WaitDialog : public wxDialog {
74 public:
WaitDialog(wxWindow * parent,const String & message)75 WaitDialog(wxWindow* parent, const String& message)
76 : wxDialog(parent, wxID_ANY, "Info", wxDefaultPosition, wxDefaultSize, wxCAPTION | wxSYSTEM_MENU) {
77 const wxSize size = wxSize(320, 90);
78 this->SetSize(size);
79 wxStaticText* text = new wxStaticText(this, wxID_ANY, message.toUnicode());
80 wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
81 sizer->AddStretchSpacer();
82 sizer->Add(text, 1, wxALIGN_CENTER_HORIZONTAL);
83 sizer->AddStretchSpacer();
84 this->SetSizer(sizer);
85 this->Layout();
86 this->CentreOnScreen();
87 }
88 };
89
ClosablePage(wxWindow * parent,const String & label)90 ClosablePage::ClosablePage(wxWindow* parent, const String& label)
91 : wxPanel(parent, wxID_ANY)
92 , label(label) {}
93
close()94 bool ClosablePage::close() {
95 CHECK_FUNCTION(CheckFunction::MAIN_THREAD | CheckFunction::NO_THROW);
96 if (this->isRunning()) {
97 const int retval = messageBox(
98 capitalize(label) + " is currently in progress. Do you want to stop it and close the window?",
99 "Stop?",
100 wxYES_NO | wxCENTRE);
101 if (retval == wxYES) {
102 this->stop();
103 dialog = new WaitDialog(this, "Waiting for " + label + " to finish ...");
104 dialog->ShowModal();
105 this->quit();
106 return true;
107 } else {
108 return false;
109 }
110 } else {
111 return true;
112 }
113 }
114
onStopped()115 void ClosablePage::onStopped() {
116 if (dialog) {
117 executeOnMainThread([weakDialog = wxWeakRef<WaitDialog>(dialog)] {
118 if (weakDialog) {
119 weakDialog->EndModal(0);
120 }
121 });
122 }
123 }
124
125
126 NAMESPACE_SPH_END
127