#ifndef slic3r_Notebook_hpp_ #define slic3r_Notebook_hpp_ #ifdef _WIN32 #include class ModeSizer; class ScalableButton; // custom message the ButtonsListCtrl sends to its parent (Notebook) to notify a selection change: wxDECLARE_EVENT(wxCUSTOMEVT_NOTEBOOK_SEL_CHANGED, wxCommandEvent); class ButtonsListCtrl : public wxControl { public: ButtonsListCtrl(wxWindow* parent, bool add_mode_buttons = false); ~ButtonsListCtrl() {} void OnPaint(wxPaintEvent&); void SetSelection(int sel); void UpdateMode(); void Rescale(); bool InsertPage(size_t n, const wxString& text, bool bSelect = false, const std::string& bmp_name = ""); void RemovePage(size_t n); bool SetPageImage(size_t n, const std::string& bmp_name) const; void SetPageText(size_t n, const wxString& strText); wxString GetPageText(size_t n) const; private: wxWindow* m_parent; wxFlexGridSizer* m_buttons_sizer; wxBoxSizer* m_sizer; std::vector m_pageButtons; int m_selection {-1}; int m_btn_margin; int m_line_margin; ModeSizer* m_mode_sizer {nullptr}; }; class Notebook: public wxBookCtrlBase { public: Notebook(wxWindow * parent, wxWindowID winid = wxID_ANY, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = 0, bool add_mode_buttons = false) { Init(); Create(parent, winid, pos, size, style, add_mode_buttons); } bool Create(wxWindow * parent, wxWindowID winid = wxID_ANY, const wxPoint & pos = wxDefaultPosition, const wxSize & size = wxDefaultSize, long style = 0, bool add_mode_buttons = false) { if (!wxBookCtrlBase::Create(parent, winid, pos, size, style | wxBK_TOP)) return false; m_bookctrl = new ButtonsListCtrl(this, add_mode_buttons); wxSizer* mainSizer = new wxBoxSizer(IsVertical() ? wxVERTICAL : wxHORIZONTAL); if (style & wxBK_RIGHT || style & wxBK_BOTTOM) mainSizer->Add(0, 0, 1, wxEXPAND, 0); m_controlSizer = new wxBoxSizer(IsVertical() ? wxHORIZONTAL : wxVERTICAL); m_controlSizer->Add(m_bookctrl, wxSizerFlags(1).Expand()); wxSizerFlags flags; if (IsVertical()) flags.Expand(); else flags.CentreVertical(); mainSizer->Add(m_controlSizer, flags.Border(wxALL, m_controlMargin)); SetSizer(mainSizer); this->Bind(wxCUSTOMEVT_NOTEBOOK_SEL_CHANGED, [this](wxCommandEvent& evt) { if (int page_idx = evt.GetId(); page_idx >= 0) SetSelection(page_idx); }); return true; } // Methods specific to this class. // A method allowing to add a new page without any label (which is unused // by this control) and show it immediately. bool ShowNewPage(wxWindow * page) { return AddPage(page, wxString(), ""/*true *//* select it */); } // Set effect to use for showing/hiding pages. void SetEffects(wxShowEffect showEffect, wxShowEffect hideEffect) { m_showEffect = showEffect; m_hideEffect = hideEffect; } // Or the same effect for both of them. void SetEffect(wxShowEffect effect) { SetEffects(effect, effect); } // And the same for time outs. void SetEffectsTimeouts(unsigned showTimeout, unsigned hideTimeout) { m_showTimeout = showTimeout; m_hideTimeout = hideTimeout; } void SetEffectTimeout(unsigned timeout) { SetEffectsTimeouts(timeout, timeout); } // Implement base class pure virtual methods. // adds a new page to the control bool AddPage(wxWindow* page, const wxString& text, const std::string& bmp_name, bool bSelect = false) { DoInvalidateBestSize(); return InsertPage(GetPageCount(), page, text, bmp_name, bSelect); } // Page management virtual bool InsertPage(size_t n, wxWindow * page, const wxString & text, bool bSelect = false, int imageId = NO_IMAGE) override { if (!wxBookCtrlBase::InsertPage(n, page, text, bSelect, imageId)) return false; GetBtnsListCtrl()->InsertPage(n, text, bSelect); if (!DoSetSelectionAfterInsertion(n, bSelect)) page->Hide(); return true; } bool InsertPage(size_t n, wxWindow * page, const wxString & text, const std::string& bmp_name = "", bool bSelect = false) { if (!wxBookCtrlBase::InsertPage(n, page, text, bSelect)) return false; GetBtnsListCtrl()->InsertPage(n, text, bSelect, bmp_name); if (!DoSetSelectionAfterInsertion(n, bSelect)) page->Hide(); return true; } virtual int SetSelection(size_t n) override { GetBtnsListCtrl()->SetSelection(n); return DoSetSelection(n, SetSelection_SendEvent); } virtual int ChangeSelection(size_t n) override { GetBtnsListCtrl()->SetSelection(n); return DoSetSelection(n); } // Neither labels nor images are supported but we still store the labels // just in case the user code attaches some importance to them. virtual bool SetPageText(size_t n, const wxString & strText) override { wxCHECK_MSG(n < GetPageCount(), false, wxS("Invalid page")); GetBtnsListCtrl()->SetPageText(n, strText); return true; } virtual wxString GetPageText(size_t n) const override { wxCHECK_MSG(n < GetPageCount(), wxString(), wxS("Invalid page")); return GetBtnsListCtrl()->GetPageText(n); } virtual bool SetPageImage(size_t WXUNUSED(n), int WXUNUSED(imageId)) override { return false; } virtual int GetPageImage(size_t WXUNUSED(n)) const override { return NO_IMAGE; } bool SetPageImage(size_t n, const std::string& bmp_name) { return GetBtnsListCtrl()->SetPageImage(n, bmp_name); } // Override some wxWindow methods too. virtual void SetFocus() override { wxWindow* const page = GetCurrentPage(); if (page) page->SetFocus(); } ButtonsListCtrl* GetBtnsListCtrl() const { return static_cast(m_bookctrl); } void UpdateMode() { GetBtnsListCtrl()->UpdateMode(); } void Rescale() { GetBtnsListCtrl()->Rescale(); } protected: virtual void UpdateSelectedPage(size_t WXUNUSED(newsel)) override { // Nothing to do here, but must be overridden to avoid the assert in // the base class version. } virtual wxBookCtrlEvent * CreatePageChangingEvent() const override { return new wxBookCtrlEvent(wxEVT_BOOKCTRL_PAGE_CHANGING, GetId()); } virtual void MakeChangedEvent(wxBookCtrlEvent & event) override { event.SetEventType(wxEVT_BOOKCTRL_PAGE_CHANGED); } virtual wxWindow * DoRemovePage(size_t page) override { wxWindow* const win = wxBookCtrlBase::DoRemovePage(page); if (win) { GetBtnsListCtrl()->RemovePage(page); DoSetSelectionAfterRemoval(page); } return win; } virtual void DoSize() override { wxWindow* const page = GetCurrentPage(); if (page) page->SetSize(GetPageRect()); } virtual void DoShowPage(wxWindow * page, bool show) override { if (show) page->ShowWithEffect(m_showEffect, m_showTimeout); else page->HideWithEffect(m_hideEffect, m_hideTimeout); } private: void Init() { // We don't need any border as we don't have anything to separate the // page contents from. SetInternalBorder(0); // No effects by default. m_showEffect = m_hideEffect = wxSHOW_EFFECT_NONE; m_showTimeout = m_hideTimeout = 0; } wxShowEffect m_showEffect, m_hideEffect; unsigned m_showTimeout, m_hideTimeout; ButtonsListCtrl* m_ctrl{ nullptr }; }; #endif // _WIN32 #endif // slic3r_Notebook_hpp_