Skip to content

Commit

Permalink
Revert buttons are added for options which have no related field but …
Browse files Browse the repository at this point in the history
…some widgets (like buttons)

+ Code refactoring: variables contained an information about revert buttons and functions to update them are extracted to the separate class UndoValueUIManager.
And Field and Line classes are inherited from UndoValueUIManager now.
  • Loading branch information
YuSanka committed Jan 14, 2022
1 parent 88521bb commit 32ff20d
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 106 deletions.
143 changes: 80 additions & 63 deletions src/slic3r/GUI/Field.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,86 @@ using t_back_to_init = std::function<void(const std::string&)>;
wxString double_to_string(double const value, const int max_precision = 4);
wxString get_thumbnails_string(const std::vector<Vec2d>& values);

class Field {
class UndoValueUIManager
{
struct UndoValueUI {
// 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.
const ScalableBitmap* undo_bitmap{ nullptr };
const wxString* undo_tooltip{ nullptr };
// Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
const ScalableBitmap* undo_to_sys_bitmap{ nullptr };
const wxString* undo_to_sys_tooltip{ nullptr };
// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
const wxColour* label_color{ nullptr };
// State of the blinker icon
bool blink{ false };

bool set_undo_bitmap(const ScalableBitmap* bmp) {
if (undo_bitmap != bmp) {
undo_bitmap = bmp;
return true;
}
return false;
}

bool set_undo_to_sys_bitmap(const ScalableBitmap* bmp) {
if (undo_to_sys_bitmap != bmp) {
undo_to_sys_bitmap = bmp;
return true;
}
return false;
}

bool set_label_colour(const wxColour* clr) {
if (label_color != clr) {
label_color = clr;
}
return false;
}

bool set_undo_tooltip(const wxString* tip) {
if (undo_tooltip != tip) {
undo_tooltip = tip;
return true;
}
return false;
}

bool set_undo_to_sys_tooltip(const wxString* tip) {
if (undo_to_sys_tooltip != tip) {
undo_to_sys_tooltip = tip;
return true;
}
return false;
}
};

UndoValueUI m_undo_ui;

public:
UndoValueUIManager() {}
~UndoValueUIManager() {}

bool set_undo_bitmap(const ScalableBitmap* bmp) { return m_undo_ui.set_undo_bitmap(bmp); }
bool set_undo_to_sys_bitmap(const ScalableBitmap* bmp) { return m_undo_ui.set_undo_to_sys_bitmap(bmp); }
bool set_label_colour(const wxColour* clr) { return m_undo_ui.set_label_colour(clr); }
bool set_undo_tooltip(const wxString* tip) { return m_undo_ui.set_undo_tooltip(tip); }
bool set_undo_to_sys_tooltip(const wxString* tip) { return m_undo_ui.set_undo_to_sys_tooltip(tip); }

// ui items used for revert line value
bool has_undo_ui() const { return m_undo_ui.undo_bitmap != nullptr; }
const wxBitmap& undo_bitmap() const { return m_undo_ui.undo_bitmap->bmp(); }
const wxString* undo_tooltip() const { return m_undo_ui.undo_tooltip; }
const wxBitmap& undo_to_sys_bitmap() const { return m_undo_ui.undo_to_sys_bitmap->bmp(); }
const wxString* undo_to_sys_tooltip() const { return m_undo_ui.undo_to_sys_tooltip; }
const wxColour* label_color() const { return m_undo_ui.label_color; }
const bool blink() const { return m_undo_ui.blink; }
bool* get_blink_ptr() { return &m_undo_ui.blink; }
};


class Field : public UndoValueUIManager
{
protected:
// factory function to defer and enforce creation of derived type.
virtual void PostInitialize();
Expand Down Expand Up @@ -137,49 +216,6 @@ class Field {
return std::move(p); //!p;
}

bool set_undo_bitmap(const ScalableBitmap *bmp) {
if (m_undo_bitmap != bmp) {
m_undo_bitmap = bmp;
return true;
}
return false;
}

bool set_undo_to_sys_bitmap(const ScalableBitmap *bmp) {
if (m_undo_to_sys_bitmap != bmp) {
m_undo_to_sys_bitmap = bmp;
return true;
}
return false;
}

bool set_label_colour(const wxColour *clr) {
if (m_label_color != clr) {
m_label_color = clr;
}
return false;
}

bool set_undo_tooltip(const wxString *tip) {
if (m_undo_tooltip != tip) {
m_undo_tooltip = tip;
return true;
}
return false;
}

bool set_undo_to_sys_tooltip(const wxString *tip) {
if (m_undo_to_sys_tooltip != tip) {
m_undo_to_sys_tooltip = tip;
return true;
}
return false;
}

bool* get_blink_ptr() {
return &m_blink;
}

virtual void msw_rescale();
virtual void sys_color_changed();

Expand All @@ -191,26 +227,7 @@ class Field {
static int def_width_wider() ;
static int def_width_thinner() ;

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; }
const bool blink() { return m_blink; }

protected:
// 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.
const ScalableBitmap* m_undo_bitmap = nullptr;
const wxString* m_undo_tooltip = nullptr;
// Bitmap and Tooltip text for m_Undo_to_sys_btn. The wxButton will be updated only if the new wxBitmap pointer differs from the currently rendered one.
const ScalableBitmap* m_undo_to_sys_bitmap = nullptr;
const wxString* m_undo_to_sys_tooltip = nullptr;

bool m_blink{ false };

// Color for Label. The wxColour will be updated only if the new wxColour pointer differs from the currently rendered one.
const wxColour* m_label_color = nullptr;

// current value
boost::any m_value;
// last maeningful value
Expand Down
71 changes: 46 additions & 25 deletions src/slic3r/GUI/OG_CustomCtrl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ wxPoint OG_CustomCtrl::get_pos(const Line& line, Field* field_in/* = nullptr*/)
int blinking_button_width = m_bmp_blinking_sz.GetWidth() + m_h_gap;

if (line.widget) {
h_pos += blinking_button_width;
h_pos += (line.has_undo_ui() ? 3 : 1) * blinking_button_width;

for (auto child : line.widget_sizer->GetChildren())
if (child->IsWindow())
Expand Down Expand Up @@ -257,22 +257,28 @@ void OG_CustomCtrl::OnMotion(wxMouseEvent& event)
break;
}

for (size_t opt_idx = 0; opt_idx < line.rects_undo_icon.size(); opt_idx++)
size_t undo_icons_cnt = line.rects_undo_icon.size();
assert(line.rects_undo_icon.size() == line.rects_undo_to_sys_icon.size());

const std::vector<Option>& option_set = line.og_line.get_options();

for (size_t opt_idx = 0; opt_idx < undo_icons_cnt; opt_idx++) {
const std::string& opt_key = option_set[opt_idx].opt_id;
if (is_point_in_rect(pos, line.rects_undo_icon[opt_idx])) {
const std::vector<Option>& option_set = line.og_line.get_options();
Field* field = opt_group->get_field(option_set[opt_idx].opt_id);
if (field)
if (line.og_line.has_undo_ui())
tooltip = *line.og_line.undo_tooltip();
else if (Field* field = opt_group->get_field(opt_key))
tooltip = *field->undo_tooltip();
break;
}
for (size_t opt_idx = 0; opt_idx < line.rects_undo_to_sys_icon.size(); opt_idx++)
if (is_point_in_rect(pos, line.rects_undo_to_sys_icon[opt_idx])) {
const std::vector<Option>& option_set = line.og_line.get_options();
Field* field = opt_group->get_field(option_set[opt_idx].opt_id);
if (field)
if (line.og_line.has_undo_ui())
tooltip = *line.og_line.undo_to_sys_tooltip();
else if (Field* field = opt_group->get_field(opt_key))
tooltip = *field->undo_to_sys_tooltip();
break;
}
}
if (!tooltip.IsEmpty())
break;
}
Expand All @@ -292,24 +298,36 @@ void OG_CustomCtrl::OnLeftDown(wxMouseEvent& event)
for (const CtrlLine& line : ctrl_lines) {
if (line.launch_browser())
return;
for (size_t opt_idx = 0; opt_idx < line.rects_undo_icon.size(); opt_idx++)

size_t undo_icons_cnt = line.rects_undo_icon.size();
assert(line.rects_undo_icon.size() == line.rects_undo_to_sys_icon.size());

const std::vector<Option>& option_set = line.og_line.get_options();
for (size_t opt_idx = 0; opt_idx < undo_icons_cnt; opt_idx++) {
const std::string& opt_key = option_set[opt_idx].opt_id;

if (is_point_in_rect(pos, line.rects_undo_icon[opt_idx])) {
const std::vector<Option>& option_set = line.og_line.get_options();
Field* field = opt_group->get_field(option_set[opt_idx].opt_id);
if (field)
if (line.og_line.has_undo_ui()) {
if (ConfigOptionsGroup* conf_OG = dynamic_cast<ConfigOptionsGroup*>(line.ctrl->opt_group))
conf_OG->back_to_initial_value(opt_key);
}
else if (Field* field = opt_group->get_field(opt_key))
field->on_back_to_initial_value();
event.Skip();
return;
}
for (size_t opt_idx = 0; opt_idx < line.rects_undo_to_sys_icon.size(); opt_idx++)

if (is_point_in_rect(pos, line.rects_undo_to_sys_icon[opt_idx])) {
const std::vector<Option>& option_set = line.og_line.get_options();
Field* field = opt_group->get_field(option_set[opt_idx].opt_id);
if (field)
if (line.og_line.has_undo_ui()) {
if (ConfigOptionsGroup* conf_OG = dynamic_cast<ConfigOptionsGroup*>(line.ctrl->opt_group))
conf_OG->back_to_sys_value(opt_key);
}
else if (Field* field = opt_group->get_field(opt_key))
field->on_back_to_sys_value();
event.Skip();
return;
}
}
}

}
Expand Down Expand Up @@ -550,7 +568,7 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos)
bool suppress_hyperlinks = get_app_config()->get("suppress_hyperlinks") == "1";
if (draw_just_act_buttons) {
if (field)
draw_act_bmps(dc, wxPoint(0, v_pos), field->undo_to_sys_bitmap()->bmp(), field->undo_bitmap()->bmp(), field->blink());
draw_act_bmps(dc, wxPoint(0, v_pos), field->undo_to_sys_bitmap(), field->undo_bitmap(), field->blink());
return;
}

Expand All @@ -564,14 +582,17 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos)
wxString label = og_line.label;
bool is_url_string = false;
if (ctrl->opt_group->label_width != 0 && !label.IsEmpty()) {
const wxColour* text_clr = (option_set.size() == 1 && field ? field->label_color() : og_line.full_Label_color);
const wxColour* text_clr = (option_set.size() == 1 && field ? field->label_color() : og_line.label_color());
is_url_string = !suppress_hyperlinks && !og_line.label_path.empty();
h_pos = draw_text(dc, wxPoint(h_pos, v_pos), label + ":", text_clr, ctrl->opt_group->label_width * ctrl->m_em_unit, is_url_string);
}

// If there's a widget, build it and set result to the correct position.
if (og_line.widget != nullptr) {
draw_blinking_bmp(dc, wxPoint(h_pos, v_pos), og_line.blink);
if (og_line.has_undo_ui())
draw_act_bmps(dc, wxPoint(h_pos, v_pos), og_line.undo_to_sys_bitmap(), og_line.undo_bitmap(), og_line.blink());
else
draw_blinking_bmp(dc, wxPoint(h_pos, v_pos), og_line.blink());
return;
}

Expand All @@ -582,9 +603,9 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos)
if (option_set.size() == 1 && option_set.front().opt.sidetext.size() == 0 &&
option_set.front().side_widget == nullptr && og_line.get_extra_widgets().size() == 0)
{
if (field && field->undo_to_sys_bitmap())
h_pos = draw_act_bmps(dc, wxPoint(h_pos, v_pos), field->undo_to_sys_bitmap()->bmp(), field->undo_bitmap()->bmp(), field->blink()) + ctrl->m_h_gap;
else if (field && !field->undo_to_sys_bitmap() && field->blink())
if (field && field->has_undo_ui())
h_pos = draw_act_bmps(dc, wxPoint(h_pos, v_pos), field->undo_to_sys_bitmap(), field->undo_bitmap(), field->blink()) + ctrl->m_h_gap;
else if (field && !field->has_undo_ui() && field->blink())
draw_blinking_bmp(dc, wxPoint(h_pos, v_pos), field->blink());
// update width for full_width fields
if (option_set.front().opt.full_width && field->getWindow())
Expand All @@ -611,8 +632,8 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos)
h_pos = draw_text(dc, wxPoint(h_pos, v_pos), label, field ? field->label_color() : nullptr, ctrl->opt_group->sublabel_width * ctrl->m_em_unit, is_url_string);
}

if (field && field->undo_to_sys_bitmap()) {
h_pos = draw_act_bmps(dc, wxPoint(h_pos, v_pos), field->undo_to_sys_bitmap()->bmp(), field->undo_bitmap()->bmp(), field->blink(), bmp_rect_id++);
if (field && field->has_undo_ui()) {
h_pos = draw_act_bmps(dc, wxPoint(h_pos, v_pos), field->undo_to_sys_bitmap(), field->undo_bitmap(), field->blink(), bmp_rect_id++);
if (field->getSizer())
{
auto children = field->getSizer()->GetChildren();
Expand Down
1 change: 1 addition & 0 deletions src/slic3r/GUI/OptionsGroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,7 @@ void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config,
opt_key == "compatible_printers" || opt_key == "compatible_prints" ) {
value = get_config_value(config, opt_key);
this->change_opt_value(opt_key, value);
OptionsGroup::on_change_OG(opt_key, value);
return;
}
else
Expand Down
15 changes: 11 additions & 4 deletions src/slic3r/GUI/OptionsGroup.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,15 @@ struct Option {
using t_option = std::unique_ptr<Option>; //!

/// Represents option lines
class Line {
class Line : public UndoValueUIManager
{
bool m_is_separator{ false };
public:
wxString label;
wxString label_tooltip;
std::string label_path;

size_t full_width {0};
wxColour* full_Label_color {nullptr};
bool blink {false};
widget_t widget {nullptr};
std::function<wxWindow*(wxWindow*)> near_label_widget{ nullptr };
wxWindow* near_label_widget_win {nullptr};
Expand All @@ -81,10 +80,10 @@ class Line {
}

bool is_separator() const { return m_is_separator; }
bool has_only_option(const std::string& opt_key) const { return m_options.size() == 1 && m_options[0].opt_id == opt_key; }

const std::vector<widget_t>& get_extra_widgets() const {return m_extra_widgets;}
const std::vector<Option>& get_options() const { return m_options; }
bool* get_blink_ptr() { return &blink; }

private:
std::vector<Option> m_options;//! {std::vector<Option>()};
Expand Down Expand Up @@ -148,6 +147,14 @@ class OptionsGroup {
if (m_fields.find(id) == m_fields.end()) return nullptr;
return m_fields.at(id).get();
}

inline Line* get_line(const t_config_option_key& id) {
for (Line& line : m_lines)
if (line.has_only_option(id))
return &line;
return nullptr;
}

bool set_value(const t_config_option_key& id, const boost::any& value, bool change_event = false) {
if (m_fields.find(id) == m_fields.end()) return false;
m_fields.at(id)->set_value(value, change_event);
Expand Down
Loading

0 comments on commit 32ff20d

Please sign in to comment.