From 74d6aea4d488ab4737f58953cc32c1a11f51835b Mon Sep 17 00:00:00 2001 From: YuSanka Date: Tue, 13 Oct 2020 12:17:39 +0200 Subject: Custom control: first implementation --- src/slic3r/CMakeLists.txt | 2 + src/slic3r/GUI/Field.cpp | 15 +- src/slic3r/GUI/Field.hpp | 24 ++- src/slic3r/GUI/OG_CustomCtrl.cpp | 384 +++++++++++++++++++++++++++++++++++++++ src/slic3r/GUI/OG_CustomCtrl.hpp | 89 +++++++++ src/slic3r/GUI/OptionsGroup.cpp | 199 +++++++++++++------- src/slic3r/GUI/OptionsGroup.hpp | 10 +- src/slic3r/GUI/wxExtensions.hpp | 2 + 8 files changed, 643 insertions(+), 82 deletions(-) create mode 100644 src/slic3r/GUI/OG_CustomCtrl.cpp create mode 100644 src/slic3r/GUI/OG_CustomCtrl.hpp (limited to 'src') diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 105d02613..c44b76970 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -111,6 +111,8 @@ set(SLIC3R_GUI_SOURCES GUI/Field.hpp GUI/OptionsGroup.cpp GUI/OptionsGroup.hpp + GUI/OG_CustomCtrl.cpp + GUI/OG_CustomCtrl.hpp GUI/BedShapeDialog.cpp GUI/BedShapeDialog.hpp GUI/2DBed.cpp diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 0bb3f0068..55c785317 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -63,18 +63,23 @@ Field::~Field() m_back_to_initial_value = nullptr; if (m_back_to_sys_value) m_back_to_sys_value = nullptr; + if (getWindow()) { + wxWindow* win = getWindow(); + win->Destroy(); + win = nullptr; + } } void Field::PostInitialize() { auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW); - m_Undo_btn = new RevertButton(m_parent, "bullet_white.png"); - m_Undo_to_sys_btn = new RevertButton(m_parent, "bullet_white.png"); +// m_Undo_btn = new RevertButton(m_parent, "bullet_white.png"); +// m_Undo_to_sys_btn = new RevertButton(m_parent, "bullet_white.png"); - m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); - m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); +// m_Undo_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_initial_value(); })); +// m_Undo_to_sys_btn->Bind(wxEVT_BUTTON, ([this](wxCommandEvent) { on_back_to_sys_value(); })); - m_blinking_bmp = new BlinkingBitmap(m_parent); +// m_blinking_bmp = new BlinkingBitmap(m_parent); switch (m_opt.type) { diff --git a/src/slic3r/GUI/Field.hpp b/src/slic3r/GUI/Field.hpp index aa047d030..c716259db 100644 --- a/src/slic3r/GUI/Field.hpp +++ b/src/slic3r/GUI/Field.hpp @@ -168,7 +168,7 @@ public: bool set_undo_bitmap(const ScalableBitmap *bmp) { if (m_undo_bitmap != bmp) { m_undo_bitmap = bmp; - m_Undo_btn->SetBitmap_(*bmp); +// m_Undo_btn->SetBitmap_(*bmp); return true; } return false; @@ -177,33 +177,33 @@ public: bool set_undo_to_sys_bitmap(const ScalableBitmap *bmp) { if (m_undo_to_sys_bitmap != bmp) { m_undo_to_sys_bitmap = bmp; - m_Undo_to_sys_btn->SetBitmap_(*bmp); +// m_Undo_to_sys_btn->SetBitmap_(*bmp); return true; } return false; } bool set_label_colour(const wxColour *clr) { - if (m_Label == nullptr) return false; +// if (m_Label == nullptr) return false; if (m_label_color != clr) { m_label_color = clr; - m_Label->SetForegroundColour(*clr); - m_Label->Refresh(true); +// m_Label->SetForegroundColour(*clr); +// m_Label->Refresh(true); } return false; } bool set_label_colour_force(const wxColour *clr) { if (m_Label == nullptr) return false; - m_Label->SetForegroundColour(*clr); - m_Label->Refresh(true); +// m_Label->SetForegroundColour(*clr); +// m_Label->Refresh(true); return false; } bool set_undo_tooltip(const wxString *tip) { if (m_undo_tooltip != tip) { m_undo_tooltip = tip; - m_Undo_btn->SetToolTip(*tip); +// m_Undo_btn->SetToolTip(*tip); return true; } return false; @@ -212,7 +212,7 @@ public: bool set_undo_to_sys_tooltip(const wxString *tip) { if (m_undo_to_sys_tooltip != tip) { m_undo_to_sys_tooltip = tip; - m_Undo_to_sys_btn->SetToolTip(*tip); +// m_Undo_to_sys_btn->SetToolTip(*tip); return true; } return false; @@ -235,6 +235,12 @@ public: BlinkingBitmap* blinking_bitmap() const { return m_blinking_bmp;} + const ScalableBitmap* undo_bitmap() { return m_undo_bitmap; } + const wxString* undo_tooltip() { return m_undo_tooltip; } + const ScalableBitmap* undo_to_sys_bitmap() { return m_undo_to_sys_bitmap; } + const wxString* undo_to_sys_tooltip() { return m_undo_to_sys_tooltip; } + const wxColour* label_color() { return m_label_color; } + protected: RevertButton* m_Undo_btn = nullptr; // Bitmap and Tooltip text for m_Undo_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one. diff --git a/src/slic3r/GUI/OG_CustomCtrl.cpp b/src/slic3r/GUI/OG_CustomCtrl.cpp new file mode 100644 index 000000000..0641f0103 --- /dev/null +++ b/src/slic3r/GUI/OG_CustomCtrl.cpp @@ -0,0 +1,384 @@ +#include "OG_CustomCtrl.hpp" +#include "OptionsGroup.hpp" +#include "ConfigExceptions.hpp" +#include "Plater.hpp" +#include "GUI_App.hpp" + +#include +#include +#include +#include +#include "libslic3r/Exception.hpp" +#include "libslic3r/Utils.hpp" +#include "I18N.hpp" + +namespace Slic3r { namespace GUI { + +OG_CustomCtrl::OG_CustomCtrl( wxWindow* parent, + OptionsGroup* og, + const wxPoint& pos /* = wxDefaultPosition*/, + const wxSize& size/* = wxDefaultSize*/, + const wxValidator& val /* = wxDefaultValidator*/, + const wxString& name/* = wxEmptyString*/) : + wxControl(parent, wxID_ANY, pos, size, wxWANTS_CHARS | wxBORDER_NONE), + m_og(og) +{ + if (!wxOSX) + SetDoubleBuffered(true);// SetDoubleBuffered exists on Win and Linux/GTK, but is missing on OSX + + // init bitmaps + m_bmp_mode_simple = ScalableBitmap(this, "mode_simple" , wxOSX ? 10 : 12); + m_bmp_mode_advanced = ScalableBitmap(this, "mode_advanced", wxOSX ? 10 : 12); + m_bmp_mode_expert = ScalableBitmap(this, "mode_expert" , wxOSX ? 10 : 12); + m_bmp_blinking = ScalableBitmap(this, "search_blink"); + + m_border = lround(0.2 * wxGetApp().em_unit()); + m_v_gap = lround(1.0 * wxGetApp().em_unit()); + m_h_gap = lround(0.2 * wxGetApp().em_unit()); + + init_ctrl_lines();// from og.lines() + + this->Bind(wxEVT_PAINT, &OG_CustomCtrl::OnPaint, this); + this->Bind(wxEVT_MOTION, &OG_CustomCtrl::OnMotion, this); + this->Bind(wxEVT_LEFT_DOWN, &OG_CustomCtrl::OnLeftDown, this); + this->Bind(wxEVT_LEFT_UP, &OG_CustomCtrl::OnLeftUp, this); + + const wxFont& font = wxGetApp().normal_font(); + m_font = wxOSX ? font.Smaller() : font; +} + +void OG_CustomCtrl::init_ctrl_lines() +{ + wxCoord v_pos = 0; + + for (const Line& line : m_og->get_lines()) + { + if (line.full_width && ( + // description line + line.widget != nullptr || + // description line with widget (button) + !line.get_extra_widgets().empty()) + ) + continue; + + auto option_set = line.get_options(); + + wxCoord height = 0; + + // if we have a single option with no label, no sidetext just add it directly to sizer + if (option_set.size() == 1 && m_og->label_width == 0 && option_set.front().opt.full_width && + option_set.front().opt.label.empty() && + option_set.front().opt.sidetext.size() == 0 && option_set.front().side_widget == nullptr && + line.get_extra_widgets().size() == 0) + { + height = m_bmp_blinking.bmp().GetHeight() + m_v_gap; + ctrl_lines.emplace_back(CtrlLine{ height, this, line, true }); + } + else if (m_og->label_width != 0 && !line.label.IsEmpty()) + { + wxSize label_sz = GetTextExtent(line.label); + height = label_sz.y * (label_sz.GetWidth() > (m_og->label_width*wxGetApp().em_unit()) ? 2 : 1) + m_v_gap; + ctrl_lines.emplace_back(CtrlLine{ height, this, line }); + } + else + int i = 0; + v_pos += height; + } + + this->SetMinSize(wxSize(wxDefaultCoord, v_pos)); +} + +wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/) +{ + wxCoord v_pos = 0; + wxCoord h_pos = 0; + for (auto ctrl_line : ctrl_lines) { + if (&ctrl_line.m_og_line == &line) + { + h_pos = m_bmp_mode_simple.bmp().GetWidth() + m_h_gap; + if (line.near_label_widget) { + if (field_in) + h_pos += m_bmp_blinking.bmp().GetWidth() + m_h_gap; // ysFIXME + else + break; + } + + wxString label = line.label; + if (m_og->label_width != 0 && !label.IsEmpty()) + h_pos += m_og->label_width * wxGetApp().em_unit(); + + if (line.widget) + break; + + // If we have a single option with no sidetext + const std::vector