1 #ifndef slic3r_GUI_wxExtensions_hpp_
2 #define slic3r_GUI_wxExtensions_hpp_
3 
4 #include <wx/checklst.h>
5 #include <wx/combo.h>
6 #include <wx/dataview.h>
7 #include <wx/button.h>
8 #include <wx/sizer.h>
9 #include <wx/menu.h>
10 #include <wx/bmpcbox.h>
11 #include <wx/statbmp.h>
12 
13 #include <vector>
14 #include <functional>
15 
16 
17 #ifdef __WXMSW__
18 void                msw_rescale_menu(wxMenu* menu);
19 #else /* __WXMSW__ */
msw_rescale_menu(wxMenu *)20 inline void         msw_rescale_menu(wxMenu* /* menu */) {}
21 #endif /* __WXMSW__ */
22 
23 wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
24     std::function<void(wxCommandEvent& event)> cb, const wxBitmap& icon, wxEvtHandler* event_handler = nullptr,
__anond55f5dfe0102() 25     std::function<bool()> const cb_condition = []() { return true;}, wxWindow* parent = nullptr, int insert_pos = wxNOT_FOUND);
26 wxMenuItem* append_menu_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
27     std::function<void(wxCommandEvent& event)> cb, const std::string& icon = "", wxEvtHandler* event_handler = nullptr,
__anond55f5dfe0202() 28     std::function<bool()> const cb_condition = []() { return true; }, wxWindow* parent = nullptr, int insert_pos = wxNOT_FOUND);
29 
30 wxMenuItem* append_submenu(wxMenu* menu, wxMenu* sub_menu, int id, const wxString& string, const wxString& description,
31     const std::string& icon = "",
__anond55f5dfe0302() 32     std::function<bool()> const cb_condition = []() { return true; }, wxWindow* parent = nullptr);
33 
34 wxMenuItem* append_menu_radio_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
35     std::function<void(wxCommandEvent& event)> cb, wxEvtHandler* event_handler);
36 
37 wxMenuItem* append_menu_check_item(wxMenu* menu, int id, const wxString& string, const wxString& description,
38     std::function<void(wxCommandEvent & event)> cb, wxEvtHandler* event_handler,
__anond55f5dfe0402() 39     std::function<bool()> const enable_condition = []() { return true; },
__anond55f5dfe0502() 40     std::function<bool()> const check_condition = []() { return true; }, wxWindow* parent = nullptr);
41 
42 void enable_menu_item(wxUpdateUIEvent& evt, std::function<bool()> const cb_condition, wxMenuItem* item, wxWindow* win);
43 
44 class wxDialog;
45 
46 void    edit_tooltip(wxString& tooltip);
47 void    msw_buttons_rescale(wxDialog* dlg, const int em_unit, const std::vector<int>& btn_ids);
48 int     em_unit(wxWindow* win);
49 int     mode_icon_px_size();
50 
51 wxBitmap create_scaled_bitmap(const std::string& bmp_name, wxWindow *win = nullptr,
52     const int px_cnt = 16, const bool grayscale = false);
53 
54 std::vector<wxBitmap*> get_extruder_color_icons(bool thin_icon = false);
55 void apply_extruder_selector(wxBitmapComboBox** ctrl,
56                              wxWindow* parent,
57                              const std::string& first_item = "",
58                              wxPoint pos = wxDefaultPosition,
59                              wxSize size = wxDefaultSize,
60                              bool use_thin_icon = false);
61 
62 class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup
63 {
64     static const unsigned int DefaultWidth;
65     static const unsigned int DefaultHeight;
66 
67     wxString m_text;
68 
69     // Events sent on mouseclick are quite complex. Function OnListBoxSelection is supposed to pass the event to the checkbox, which works fine on
70     // Win. On OSX and Linux the events are generated differently - clicking on the checkbox square generates the event twice (and the square
71     // therefore seems not to respond).
72     // This enum is meant to save current state of affairs, i.e., if the event forwarding is ok to do or not. It is only used on Linux
73     // and OSX by some #ifdefs. It also stores information whether OnListBoxSelection is supposed to change the checkbox status,
74     // or if it changed status on its own already (which happens when the square is clicked). More comments in OnCheckListBox(...)
75     // There indeed is a better solution, maybe making a custom event used for the event passing to distinguish the original and passed message
76     // and blocking one of them on OSX and Linux. Feel free to refactor, but carefully test on all platforms.
77     enum class OnCheckListBoxFunction{
78         FreeToProceed,
79         RefuseToProceed,
80         WasRefusedLastTime
81     } m_check_box_events_status = OnCheckListBoxFunction::FreeToProceed;
82 
83 
84 public:
85     virtual bool Create(wxWindow* parent);
86     virtual wxWindow* GetControl();
87     virtual void SetStringValue(const wxString& value);
88     virtual wxString GetStringValue() const;
89     virtual wxSize GetAdjustedSize(int minWidth, int prefHeight, int maxHeight);
90 
91     virtual void OnKeyEvent(wxKeyEvent& evt);
92 
93     void OnCheckListBox(wxCommandEvent& evt);
94     void OnListBoxSelection(wxCommandEvent& evt);
95 };
96 
97 
98 // ***  wxDataViewTreeCtrlComboBox  ***
99 
100 class wxDataViewTreeCtrlComboPopup: public wxDataViewTreeCtrl, public wxComboPopup
101 {
102     static const unsigned int DefaultWidth;
103     static const unsigned int DefaultHeight;
104     static const unsigned int DefaultItemHeight;
105 
106     wxString	m_text;
107     int			m_cnt_open_items{0};
108 
109 public:
110     virtual bool		Create(wxWindow* parent);
GetControl()111     virtual wxWindow*	GetControl() { return this; }
SetStringValue(const wxString & value)112     virtual void		SetStringValue(const wxString& value) { m_text = value; }
GetStringValue() const113     virtual wxString	GetStringValue() const { return m_text; }
114 //	virtual wxSize		GetAdjustedSize(int minWidth, int prefHeight, int maxHeight);
115 
116     virtual void		OnKeyEvent(wxKeyEvent& evt);
117     void				OnDataViewTreeCtrlSelection(wxCommandEvent& evt);
SetItemsCnt(int cnt)118     void				SetItemsCnt(int cnt) { m_cnt_open_items = cnt; }
119 };
120 
121 
122 // ----------------------------------------------------------------------------
123 // ScalableBitmap
124 // ----------------------------------------------------------------------------
125 
126 class ScalableBitmap
127 {
128 public:
ScalableBitmap()129     ScalableBitmap() {};
130     ScalableBitmap( wxWindow *parent,
131                     const std::string& icon_name = "",
132                     const int px_cnt = 16,
133                     const bool grayscale = false);
134 
~ScalableBitmap()135     ~ScalableBitmap() {}
136 
137     wxSize  GetBmpSize() const;
138     int     GetBmpWidth() const;
139     int     GetBmpHeight() const;
140 
141     void                msw_rescale();
142 
bmp() const143     const wxBitmap&     bmp() const { return m_bmp; }
bmp()144     wxBitmap&           bmp()       { return m_bmp; }
name() const145     const std::string&  name() const{ return m_icon_name; }
146 
px_cnt() const147     int                 px_cnt()const           {return m_px_cnt;}
148 
149 private:
150     wxWindow*       m_parent{ nullptr };
151     wxBitmap        m_bmp = wxBitmap();
152     std::string     m_icon_name = "";
153     int             m_px_cnt {16};
154     bool            m_grayscale {false};
155 };
156 
157 
158 // ----------------------------------------------------------------------------
159 // LockButton
160 // ----------------------------------------------------------------------------
161 
162 class LockButton : public wxButton
163 {
164 public:
165     LockButton(
166         wxWindow *parent,
167         wxWindowID id,
168         const wxPoint& pos = wxDefaultPosition,
169         const wxSize& size = wxDefaultSize);
~LockButton()170     ~LockButton() {}
171 
172     void    OnButton(wxCommandEvent& event);
173 
IsLocked() const174     bool    IsLocked() const                { return m_is_pushed; }
175     void    SetLock(bool lock);
176 
177     // create its own Enable/Disable functions to not really disabled button because of tooltip enabling
enable()178     void    enable()                        { m_disabled = false; }
disable()179     void    disable()                       { m_disabled = true;  }
180 
181     void    msw_rescale();
182 
183 protected:
184     void    update_button_bitmaps();
185 
186 private:
187     bool        m_is_pushed = false;
188     bool        m_disabled = false;
189 
190     ScalableBitmap    m_bmp_lock_closed;
191     ScalableBitmap    m_bmp_lock_closed_f;
192     ScalableBitmap    m_bmp_lock_open;
193     ScalableBitmap    m_bmp_lock_open_f;
194 };
195 
196 
197 // ----------------------------------------------------------------------------
198 // ScalableButton
199 // ----------------------------------------------------------------------------
200 
201 class ScalableButton : public wxButton
202 {
203 public:
ScalableButton()204     ScalableButton(){}
205     ScalableButton(
206         wxWindow *          parent,
207         wxWindowID          id,
208         const std::string&  icon_name = "",
209         const wxString&     label = wxEmptyString,
210         const wxSize&       size = wxDefaultSize,
211         const wxPoint&      pos = wxDefaultPosition,
212         long                style = wxBU_EXACTFIT | wxNO_BORDER,
213         bool                use_default_disabled_bitmap = false,
214         int                 bmp_px_cnt = 16);
215 
216     ScalableButton(
217         wxWindow *          parent,
218         wxWindowID          id,
219         const ScalableBitmap&  bitmap,
220         const wxString&     label = wxEmptyString,
221         long                style = wxBU_EXACTFIT | wxNO_BORDER);
222 
~ScalableButton()223     ~ScalableButton() {}
224 
225     void SetBitmap_(const ScalableBitmap& bmp);
226     void SetBitmapDisabled_(const ScalableBitmap &bmp);
227     int  GetBitmapHeight();
228     void UseDefaultBitmapDisabled();
229 
230     void    msw_rescale();
231 
232 private:
233     wxWindow*       m_parent { nullptr };
234     std::string     m_current_icon_name;
235     std::string     m_disabled_icon_name;
236     int             m_width {-1}; // should be multiplied to em_unit
237     int             m_height{-1}; // should be multiplied to em_unit
238 
239     bool            m_use_default_disabled_bitmap {false};
240 
241     // bitmap dimensions
242     int             m_px_cnt{ 16 };
243 };
244 
245 
246 // ----------------------------------------------------------------------------
247 // ModeButton
248 // ----------------------------------------------------------------------------
249 
250 class ModeButton : public ScalableButton
251 {
252 public:
253     ModeButton(
254         wxWindow*           parent,
255         wxWindowID          id,
256         const std::string&  icon_name = "",
257         const wxString&     mode = wxEmptyString,
258         const wxSize&       size = wxDefaultSize,
259         const wxPoint&      pos = wxDefaultPosition);
260 
261     ModeButton(
262         wxWindow*           parent,
263         const wxString&     mode = wxEmptyString,
264         const std::string&  icon_name = "",
265         int                 px_cnt = 16);
266 
~ModeButton()267     ~ModeButton() {}
268 
269     void Init(const wxString& mode);
270 
271     void    OnButton(wxCommandEvent& event);
OnEnterBtn(wxMouseEvent & event)272     void    OnEnterBtn(wxMouseEvent& event) { focus_button(true); event.Skip(); }
OnLeaveBtn(wxMouseEvent & event)273     void    OnLeaveBtn(wxMouseEvent& event) { focus_button(m_is_selected); event.Skip(); }
274 
275     void    SetState(const bool state);
276 
277 protected:
278     void    focus_button(const bool focus);
279 
280 private:
281     bool        m_is_selected = false;
282 
283     wxString    m_tt_selected;
284     wxString    m_tt_focused;
285 };
286 
287 
288 
289 // ----------------------------------------------------------------------------
290 // ModeSizer
291 // ----------------------------------------------------------------------------
292 
293 class ModeSizer : public wxFlexGridSizer
294 {
295 public:
296     ModeSizer( wxWindow *parent, int hgap = 0);
~ModeSizer()297     ~ModeSizer() {}
298 
299     void SetMode(const /*ConfigOptionMode*/int mode);
300 
301     void set_items_flag(int flag);
302     void set_items_border(int border);
303 
304     void msw_rescale();
305 
306 private:
307     std::vector<ModeButton*> m_mode_btns;
308 };
309 
310 
311 
312 // ----------------------------------------------------------------------------
313 // MenuWithSeparators
314 // ----------------------------------------------------------------------------
315 
316 class MenuWithSeparators : public wxMenu
317 {
318 public:
MenuWithSeparators(const wxString & title,long style=0)319     MenuWithSeparators(const wxString& title, long style = 0)
320         : wxMenu(title, style) {}
321 
MenuWithSeparators(long style=0)322     MenuWithSeparators(long style = 0)
323         : wxMenu(style) {}
324 
~MenuWithSeparators()325     ~MenuWithSeparators() {}
326 
327     void DestroySeparators();
328     void SetFirstSeparator();
329     void SetSecondSeparator();
330 
331 private:
332     wxMenuItem* m_separator_frst { nullptr };    // use like separator before settings item
333     wxMenuItem* m_separator_scnd { nullptr };   // use like separator between settings items
334 };
335 
336 
337 // ----------------------------------------------------------------------------
338 // BlinkingBitmap
339 // ----------------------------------------------------------------------------
340 
341 class BlinkingBitmap : public wxStaticBitmap
342 {
343 public:
BlinkingBitmap()344     BlinkingBitmap() {};
345     BlinkingBitmap(wxWindow* parent, const std::string& icon_name = "search_blink");
346 
~BlinkingBitmap()347     ~BlinkingBitmap() {}
348 
349     void    msw_rescale();
350     void    invalidate();
351     void    activate();
352     void    blink();
353 
get_bmp() const354     const wxBitmap& get_bmp() const { return bmp.bmp(); }
355 
356 private:
357     ScalableBitmap  bmp;
358     bool            show {false};
359 };
360 
361 
362 
363 #endif // slic3r_GUI_wxExtensions_hpp_
364