Added description line for the "Post-processing scripts".

ogStaticText id extended for SetPathEnd() function. It allows to use description line like a hyperlink
This commit is contained in:
YuSanka 2021-12-02 15:14:39 +01:00
parent 8a151cd7c3
commit efbf64fdea
7 changed files with 146 additions and 77 deletions

View File

@ -1487,6 +1487,7 @@ void GUI_App::update_fonts(const MainFrame *main_frame)
m_normal_font = main_frame->normal_font();
m_small_font = m_normal_font;
m_bold_font = main_frame->normal_font().Bold();
m_link_font = m_bold_font.Underlined();
m_em_unit = main_frame->em_unit();
m_code_font.SetPointSize(m_normal_font.GetPointSize());
}

View File

@ -132,6 +132,7 @@ private:
wxFont m_bold_font;
wxFont m_normal_font;
wxFont m_code_font;
wxFont m_link_font;
int m_em_unit; // width of a "m"-symbol in pixels for current system font
// Note: for 100% Scale m_em_unit = 10 -> it's a good enough coefficient for a size setting of controls
@ -217,6 +218,7 @@ public:
const wxFont& bold_font() { return m_bold_font; }
const wxFont& normal_font() { return m_normal_font; }
const wxFont& code_font() { return m_code_font; }
const wxFont& link_font() { return m_link_font; }
int em_unit() const { return m_em_unit; }
bool tabs_as_menu() const;
wxSize get_min_size() const;

View File

@ -28,17 +28,6 @@ static wxSize get_bitmap_size(const wxBitmap& bmp)
#endif
}
static wxString get_url(const wxString& path_end, bool get_default = false)
{
if (path_end.IsEmpty())
return wxEmptyString;
wxString language = wxGetApp().app_config->get("translation_language");
wxString lang_marker = language.IsEmpty() ? "en" : language.BeforeFirst('_');
return wxString("https://help.prusa3d.com/") + lang_marker + "/article/" + path_end;
}
OG_CustomCtrl::OG_CustomCtrl( wxWindow* parent,
OptionsGroup* og,
const wxPoint& pos /* = wxDefaultPosition*/,
@ -264,7 +253,7 @@ void OG_CustomCtrl::OnMotion(wxMouseEvent& event)
line.is_focused = is_point_in_rect(pos, line.rect_label);
if (line.is_focused) {
if (!suppress_hyperlinks && !line.og_line.label_path.empty())
tooltip = get_url(line.og_line.label_path) +"\n\n";
tooltip = OptionsGroup::get_url(line.og_line.label_path) +"\n\n";
tooltip += line.og_line.label_tooltip;
break;
}
@ -577,7 +566,7 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos)
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);
is_url_string = !suppress_hyperlinks && !og_line.label_path.IsEmpty();
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);
}
@ -619,7 +608,7 @@ void OG_CustomCtrl::CtrlLine::render(wxDC& dc, wxCoord v_pos)
if (is_url_string)
is_url_string = false;
else if(opt == option_set.front())
is_url_string = !suppress_hyperlinks && !og_line.label_path.IsEmpty();
is_url_string = !suppress_hyperlinks && !og_line.label_path.empty();
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);
}
@ -766,36 +755,10 @@ wxCoord OG_CustomCtrl::CtrlLine::draw_act_bmps(wxDC& dc, wxPoint pos, const wxBi
bool OG_CustomCtrl::CtrlLine::launch_browser() const
{
if (!is_focused || og_line.label_path.IsEmpty())
if (!is_focused || og_line.label_path.empty())
return false;
bool launch = true;
if (get_app_config()->get("suppress_hyperlinks").empty()) {
RichMessageDialog dialog(nullptr, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxYES_NO);
dialog.ShowCheckBox(_L("Remember my choice"));
int answer = dialog.ShowModal();
if (dialog.IsCheckBoxChecked()) {
wxString preferences_item = _L("Suppress to open hyperlink in browser");
wxString msg =
_L("PrusaSlicer will remember your choice.") + "\n\n" +
_L("You will not be asked about it again on label hovering.") + "\n\n" +
format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto changes your choice."), preferences_item);
MessageDialog msg_dlg(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
if (msg_dlg.ShowModal() == wxID_CANCEL)
return false;
get_app_config()->set("suppress_hyperlinks", dialog.IsCheckBoxChecked() ? (answer == wxID_NO ? "1" : "0") : "");
}
launch = answer == wxID_YES;
}
if (launch)
launch = get_app_config()->get("suppress_hyperlinks") != "1";
return launch && wxLaunchDefaultBrowser(get_url(og_line.label_path));
return OptionsGroup::launch_browser(og_line.label_path);
}
} // GUI

View File

@ -3,6 +3,7 @@
#include "Plater.hpp"
#include "GUI_App.hpp"
#include "OG_CustomCtrl.hpp"
#include "MsgDialog.hpp"
#include <utility>
#include <wx/numformatter.h>
@ -10,6 +11,7 @@
#include <boost/algorithm/string/classification.hpp>
#include "libslic3r/Exception.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/AppConfig.hpp"
#include "I18N.hpp"
namespace Slic3r { namespace GUI {
@ -504,7 +506,7 @@ void OptionsGroup::clear(bool destroy_custom_ctrl)
m_fields.clear();
}
Line OptionsGroup::create_single_option_line(const Option& option, const wxString& path/* = wxEmptyString*/) const {
Line OptionsGroup::create_single_option_line(const Option& option, const std::string& path/* = std::string()*/) const {
// Line retval{ _(option.opt.label), _(option.opt.tooltip) };
wxString tooltip = _(option.opt.tooltip);
edit_tooltip(tooltip);
@ -962,6 +964,54 @@ void ConfigOptionsGroup::change_opt_value(const t_config_option_key& opt_key, co
m_modelconfig->touch();
}
wxString OptionsGroup::get_url(const std::string& path_end)
{
if (path_end.empty())
return wxEmptyString;
wxString language = get_app_config()->get("translation_language");
wxString lang_marker = language.IsEmpty() ? "en" : language.BeforeFirst('_');
return wxString("https://help.prusa3d.com/") + lang_marker + wxString("/article/" + path_end);
}
bool OptionsGroup::launch_browser(const std::string& path_end)
{
bool launch = true;
if (get_app_config()->get("suppress_hyperlinks").empty()) {
RichMessageDialog dialog(nullptr, _L("Open hyperlink in default browser?"), _L("PrusaSlicer: Open hyperlink"), wxYES_NO);
dialog.ShowCheckBox(_L("Remember my choice"));
int answer = dialog.ShowModal();
if (dialog.IsCheckBoxChecked()) {
wxString preferences_item = _L("Suppress to open hyperlink in browser");
wxString msg =
_L("PrusaSlicer will remember your choice.") + "\n\n" +
_L("You will not be asked about it again on label hovering.") + "\n\n" +
format_wxstr(_L("Visit \"Preferences\" and check \"%1%\"\nto changes your choice."), preferences_item);
MessageDialog msg_dlg(nullptr, msg, _L("PrusaSlicer: Don't ask me again"), wxOK | wxCANCEL | wxICON_INFORMATION);
if (msg_dlg.ShowModal() == wxID_CANCEL)
return false;
get_app_config()->set("suppress_hyperlinks", dialog.IsCheckBoxChecked() ? (answer == wxID_NO ? "1" : "0") : "");
}
launch = answer == wxID_YES;
}
if (launch)
launch = get_app_config()->get("suppress_hyperlinks") != "1";
return launch && wxLaunchDefaultBrowser(OptionsGroup::get_url(path_end));
}
//-------------------------------------------------------------------------------------------
// ogStaticText
//-------------------------------------------------------------------------------------------
ogStaticText::ogStaticText(wxWindow* parent, const wxString& text) :
wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize)
{
@ -979,5 +1029,37 @@ void ogStaticText::SetText(const wxString& value, bool wrap/* = true*/)
GetParent()->Layout();
}
void ogStaticText::SetPathEnd(const std::string& link)
{
if (get_app_config()->get("suppress_hyperlinks") != "1")
SetToolTip(OptionsGroup::get_url(link));
Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& event) {
if (HasCapture())
return;
this->CaptureMouse();
event.Skip();
} );
Bind(wxEVT_LEFT_UP, [link, this](wxMouseEvent& event) {
if (!HasCapture())
return;
ReleaseMouse();
OptionsGroup::launch_browser(link);
event.Skip();
} );
Bind(wxEVT_ENTER_WINDOW, [this](wxMouseEvent& event) { FocusText(true) ; event.Skip(); });
Bind(wxEVT_LEAVE_WINDOW, [this](wxMouseEvent& event) { FocusText(false); event.Skip(); });
}
void ogStaticText::FocusText(bool focus)
{
if (get_app_config()->get("suppress_hyperlinks") == "1")
return;
SetFont(focus ? Slic3r::GUI::wxGetApp().link_font() :
Slic3r::GUI::wxGetApp().normal_font());
Refresh();
}
} // GUI
} // Slic3r

View File

@ -53,7 +53,7 @@ class Line {
public:
wxString label;
wxString label_tooltip;
wxString label_path;
std::string label_path;
size_t full_width {0};
wxColour* full_Label_color {nullptr};
@ -133,8 +133,8 @@ public:
// delete all controls from the option group
void clear(bool destroy_custom_ctrl = false);
Line create_single_option_line(const Option& option, const wxString& path = wxEmptyString) const;
void append_single_option_line(const Option& option, const wxString& path = wxEmptyString) { append_line(create_single_option_line(option, path)); }
Line create_single_option_line(const Option& option, const std::string& path = std::string()) const;
void append_single_option_line(const Option& option, const std::string& path = std::string()) { append_line(create_single_option_line(option, path)); }
void append_separator();
// return a non-owning pointer reference
@ -219,6 +219,10 @@ protected:
virtual void on_change_OG(const t_config_option_key& opt_id, const boost::any& value);
virtual void back_to_initial_value(const std::string& opt_key) {}
virtual void back_to_sys_value(const std::string& opt_key) {}
public:
static wxString get_url(const std::string& path_end);
static bool launch_browser(const std::string& path_end);
};
class ConfigOptionsGroup: public OptionsGroup {
@ -239,17 +243,17 @@ public:
void set_config_category_and_type(const wxString &category, int type) { m_config_category = category; m_config_type = type; }
void set_config(DynamicPrintConfig* config) { m_config = config; m_modelconfig = nullptr; }
Option get_option(const std::string& opt_key, int opt_index = -1);
Line create_single_option_line(const std::string& title, const wxString& path = wxEmptyString, int idx = -1) /*const*/{
Line create_single_option_line(const std::string& title, const std::string& path = std::string(), int idx = -1) /*const*/{
Option option = get_option(title, idx);
return OptionsGroup::create_single_option_line(option, path);
}
Line create_single_option_line(const Option& option, const wxString& path = wxEmptyString) const {
Line create_single_option_line(const Option& option, const std::string& path = std::string()) const {
return OptionsGroup::create_single_option_line(option, path);
}
void append_single_option_line(const Option& option, const wxString& path = wxEmptyString) {
void append_single_option_line(const Option& option, const std::string& path = std::string()) {
OptionsGroup::append_single_option_line(option, path);
}
void append_single_option_line(const std::string title, const wxString& path = wxEmptyString, int idx = -1)
void append_single_option_line(const std::string title, const std::string& path = std::string(), int idx = -1)
{
Option option = get_option(title, idx);
append_single_option_line(option, path);
@ -298,6 +302,9 @@ public:
~ogStaticText() {}
void SetText(const wxString& value, bool wrap = true);
// Set special path end. It will be used to generation of the hyperlink on info page
void SetPathEnd(const std::string& link);
void FocusText(bool focus);
};
}}

View File

@ -1432,7 +1432,7 @@ void TabPrint::build()
load_initial_data();
auto page = add_options_page(L("Layers and perimeters"), "layers");
wxString category_path = "layers-and-perimeters_1748#";
std::string category_path = "layers-and-perimeters_1748#";
auto optgroup = page->new_optgroup(L("Layer height"));
optgroup->append_single_option_line("layer_height", category_path + "layer-height");
optgroup->append_single_option_line("first_layer_height", category_path + "first-layer-height");
@ -1673,6 +1673,12 @@ void TabPrint::build()
optgroup->append_single_option_line(option);
optgroup = page->new_optgroup(L("Post-processing scripts"), 0);
line = { "", "" };
line.full_width = 1;
line.widget = [this](wxWindow* parent) {
return description_line_widget(parent, &m_post_process_explanation);
};
optgroup->append_line(line);
option = optgroup->get_option("post_process");
option.opt.full_width = true;
option.opt.height = 5;//50;
@ -1688,7 +1694,7 @@ void TabPrint::build()
page = add_options_page(L("Dependencies"), "wrench.png");
optgroup = page->new_optgroup(L("Profile dependencies"));
create_line_with_widget(optgroup.get(), "compatible_printers", wxEmptyString, [this](wxWindow* parent) {
create_line_with_widget(optgroup.get(), "compatible_printers", "", [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_printers);
});
@ -1721,6 +1727,12 @@ void TabPrint::update_description_lines()
m_top_bottom_shell_thickness_explanation->SetText(
from_u8(PresetHints::top_bottom_shell_thickness_explanation(*m_preset_bundle)));
}
if (m_active_page && m_active_page->title() == "Output options" && m_post_process_explanation) {
m_post_process_explanation->SetText(
_u8L("Post processing scripts shall modify G-code file in place."));
m_post_process_explanation->SetPathEnd("post-processing-scripts_283913");
}
}
void TabPrint::toggle_options()
@ -1774,6 +1786,7 @@ void TabPrint::clear_pages()
m_recommended_thin_wall_thickness_description_line = nullptr;
m_top_bottom_shell_thickness_explanation = nullptr;
m_post_process_explanation = nullptr;
}
bool Tab::validate_custom_gcode(const wxString& title, const std::string& gcode)
@ -1938,7 +1951,7 @@ void TabFilament::build()
optgroup->append_line(line);
page = add_options_page(L("Cooling"), "cooling");
wxString category_path = "cooling_127569#";
std::string category_path = "cooling_127569#";
optgroup = page->new_optgroup(L("Enable"));
optgroup->append_single_option_line("fan_always_on");
optgroup->append_single_option_line("cooling");
@ -1999,7 +2012,7 @@ void TabFilament::build()
optgroup->append_single_option_line("filament_cooling_initial_speed");
optgroup->append_single_option_line("filament_cooling_final_speed");
create_line_with_widget(optgroup.get(), "filament_ramming_parameters", wxEmptyString, [this](wxWindow* parent) {
create_line_with_widget(optgroup.get(), "filament_ramming_parameters", "", [this](wxWindow* parent) {
auto ramming_dialog_btn = new wxButton(parent, wxID_ANY, _(L("Ramming settings"))+dots, wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
wxGetApp().UpdateDarkUI(ramming_dialog_btn);
ramming_dialog_btn->SetFont(Slic3r::GUI::wxGetApp().normal_font());
@ -2055,7 +2068,7 @@ void TabFilament::build()
page = add_options_page(L("Dependencies"), "wrench.png");
optgroup = page->new_optgroup(L("Profile dependencies"));
create_line_with_widget(optgroup.get(), "compatible_printers", wxEmptyString, [this](wxWindow* parent) {
create_line_with_widget(optgroup.get(), "compatible_printers", "", [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_printers);
});
@ -2063,7 +2076,7 @@ void TabFilament::build()
option.opt.full_width = true;
optgroup->append_single_option_line(option);
create_line_with_widget(optgroup.get(), "compatible_prints", wxEmptyString, [this](wxWindow* parent) {
create_line_with_widget(optgroup.get(), "compatible_prints", "", [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_prints);
});
@ -2695,7 +2708,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
m_pages.insert(m_pages.begin() + n_before_extruders + extruder_idx, page);
auto optgroup = page->new_optgroup(L("Size"));
optgroup->append_single_option_line("nozzle_diameter", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("nozzle_diameter", "", extruder_idx);
optgroup->m_on_change = [this, extruder_idx](const t_config_option_key& opt_key, boost::any value)
{
@ -2734,32 +2747,32 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
};
optgroup = page->new_optgroup(L("Layer height limits"));
optgroup->append_single_option_line("min_layer_height", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("max_layer_height", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("min_layer_height", "", extruder_idx);
optgroup->append_single_option_line("max_layer_height", "", extruder_idx);
optgroup = page->new_optgroup(L("Position (for multi-extruder printers)"));
optgroup->append_single_option_line("extruder_offset", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("extruder_offset", "", extruder_idx);
optgroup = page->new_optgroup(L("Retraction"));
optgroup->append_single_option_line("retract_length", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_lift", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_length", "", extruder_idx);
optgroup->append_single_option_line("retract_lift", "", extruder_idx);
Line line = { L("Only lift Z"), "" };
line.append_option(optgroup->get_option("retract_lift_above", extruder_idx));
line.append_option(optgroup->get_option("retract_lift_below", extruder_idx));
optgroup->append_line(line);
optgroup->append_single_option_line("retract_speed", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("deretract_speed", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_restart_extra", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_before_travel", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_layer_change", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("wipe", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_before_wipe", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_speed", "", extruder_idx);
optgroup->append_single_option_line("deretract_speed", "", extruder_idx);
optgroup->append_single_option_line("retract_restart_extra", "", extruder_idx);
optgroup->append_single_option_line("retract_before_travel", "", extruder_idx);
optgroup->append_single_option_line("retract_layer_change", "", extruder_idx);
optgroup->append_single_option_line("wipe", "", extruder_idx);
optgroup->append_single_option_line("retract_before_wipe", "", extruder_idx);
optgroup = page->new_optgroup(L("Retraction when tool is disabled (advanced settings for multi-extruder setups)"));
optgroup->append_single_option_line("retract_length_toolchange", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_restart_extra_toolchange", wxEmptyString, extruder_idx);
optgroup->append_single_option_line("retract_length_toolchange", "", extruder_idx);
optgroup->append_single_option_line("retract_restart_extra_toolchange", "", extruder_idx);
optgroup = page->new_optgroup(L("Preview"));
@ -2787,7 +2800,7 @@ void TabPrinter::build_unregular_pages(bool from_initial_build/* = false*/)
return sizer;
};
line = optgroup->create_single_option_line("extruder_colour", wxEmptyString, extruder_idx);
line = optgroup->create_single_option_line("extruder_colour", "", extruder_idx);
line.append_widget(reset_to_filament_color);
optgroup->append_line(line);
}
@ -3736,7 +3749,7 @@ void Tab::update_ui_from_settings()
}
}
void Tab::create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const wxString& path, widget_t widget)
void Tab::create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const std::string& path, widget_t widget)
{
Line line = optgroup->create_single_option_line(opt_key);
line.widget = widget;
@ -4224,7 +4237,7 @@ void TabSLAMaterial::build()
page = add_options_page(L("Dependencies"), "wrench.png");
optgroup = page->new_optgroup(L("Profile dependencies"));
create_line_with_widget(optgroup.get(), "compatible_printers", wxEmptyString, [this](wxWindow* parent) {
create_line_with_widget(optgroup.get(), "compatible_printers", "", [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_printers);
});
@ -4232,7 +4245,7 @@ void TabSLAMaterial::build()
option.opt.full_width = true;
optgroup->append_single_option_line(option);
create_line_with_widget(optgroup.get(), "compatible_prints", wxEmptyString, [this](wxWindow* parent) {
create_line_with_widget(optgroup.get(), "compatible_prints", "", [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_prints);
});
@ -4371,7 +4384,7 @@ void TabSLAPrint::build()
page = add_options_page(L("Dependencies"), "wrench");
optgroup = page->new_optgroup(L("Profile dependencies"));
create_line_with_widget(optgroup.get(), "compatible_printers", wxEmptyString, [this](wxWindow* parent) {
create_line_with_widget(optgroup.get(), "compatible_printers", "", [this](wxWindow* parent) {
return compatible_widget_create(parent, m_compatible_printers);
});

View File

@ -351,7 +351,7 @@ public:
bool validate_custom_gcodes_was_shown{ false };
protected:
void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const wxString& path, widget_t widget);
void create_line_with_widget(ConfigOptionsGroup* optgroup, const std::string& opt_key, const std::string& path, widget_t widget);
wxSizer* compatible_widget_create(wxWindow* parent, PresetDependencies &deps);
void compatible_widget_reload(PresetDependencies &deps);
void load_key_value(const std::string& opt_key, const boost::any& value, bool saved_value = false);
@ -387,6 +387,7 @@ public:
private:
ogStaticText* m_recommended_thin_wall_thickness_description_line = nullptr;
ogStaticText* m_top_bottom_shell_thickness_explanation = nullptr;
ogStaticText* m_post_process_explanation = nullptr;
};
class TabFilament : public Tab