Implemented upgrade_text_entry_dialog() fuction to avoid a getting an empty string from wxTextEntryDialog (disable OK button, if TextCtrl is empty)
All mode conflicting or meaningless ticks are marked by "exclamation" icon and described in tooltip.
This commit is contained in:
parent
be8f464bf8
commit
d8b1d074a1
2 changed files with 100 additions and 27 deletions
|
@ -555,7 +555,7 @@ void Control::draw_ticks(wxDC& dc)
|
||||||
// Draw icon for "Pause print" or "Custom Gcode"
|
// Draw icon for "Pause print" or "Custom Gcode"
|
||||||
if (tick.gcode != ColorChangeCode && tick.gcode != ToolChangeCode)
|
if (tick.gcode != ColorChangeCode && tick.gcode != ToolChangeCode)
|
||||||
icon = create_scaled_bitmap(this, tick.gcode == PausePrintCode ? "pause_print" : "edit_gcode");
|
icon = create_scaled_bitmap(this, tick.gcode == PausePrintCode ? "pause_print" : "edit_gcode");
|
||||||
else if (m_ticks.is_conflict_tick(tick, m_mode))
|
else if (m_ticks.is_conflict_tick(tick, m_mode, m_only_extruder, m_values[tick.tick]))
|
||||||
icon = create_scaled_bitmap(this, "error_tick");
|
icon = create_scaled_bitmap(this, "error_tick");
|
||||||
|
|
||||||
if (!icon.IsNull())
|
if (!icon.IsNull())
|
||||||
|
@ -931,10 +931,18 @@ wxString Control::get_tooltip(IconFocus icon_focus)
|
||||||
|
|
||||||
// If tick is marked as a conflict (exclamation icon),
|
// If tick is marked as a conflict (exclamation icon),
|
||||||
// we should to explain why
|
// we should to explain why
|
||||||
if (m_ticks.is_conflict_tick(*tick_code_it, m_mode))
|
ConflictType conflict = m_ticks.is_conflict_tick(*tick_code_it, m_mode, m_only_extruder, m_values[tick]);
|
||||||
tooltip += "\n" + _(L("Note")) + "! " +
|
if (conflict != ctNone)
|
||||||
_(L("G-code of this tick has a conflict with slider(print) mode.")) + "\n" +
|
tooltip += "\n\n" + _(L("Note")) + "! ";
|
||||||
_(L("Any its editing will cause a changes of DoubleSlider data."));
|
if (conflict == ctModeConflict)
|
||||||
|
tooltip += _(L("G-code of this tick has a conflict with slider(print) mode.\n"
|
||||||
|
"Any its editing will cause a changes of DoubleSlider data."));
|
||||||
|
else if (conflict == ctMeaningless)
|
||||||
|
tooltip += _(L("There is a color change for extruder that wouldn't be used till the end of printing.\n"
|
||||||
|
"This code wouldn't be processed during GCode generation."));
|
||||||
|
else if (conflict == ctRedundant)
|
||||||
|
tooltip += _(L("There is a color change for extruder that has not been used before.\n"
|
||||||
|
"Check your choice to avoid redundant color changes."));
|
||||||
|
|
||||||
// Show list of actions with existing tick
|
// Show list of actions with existing tick
|
||||||
tooltip += "\n\n" + _(L("For Delete tick use left mouse button click OR pres \"-\" key")) + "\n" + (
|
tooltip += "\n\n" + _(L("For Delete tick use left mouse button click OR pres \"-\" key")) + "\n" + (
|
||||||
|
@ -1033,7 +1041,8 @@ void Control::append_add_color_change_menu_item(wxMenu* menu, bool switch_curren
|
||||||
const int extruders_cnt = GUI::wxGetApp().extruders_edited_cnt();
|
const int extruders_cnt = GUI::wxGetApp().extruders_edited_cnt();
|
||||||
if (extruders_cnt > 1)
|
if (extruders_cnt > 1)
|
||||||
{
|
{
|
||||||
std::set<int> used_extruders_for_tick = get_used_extruders_for_tick(m_selection == ssLower ? m_lower_value : m_higher_value);
|
int tick = m_selection == ssLower ? m_lower_value : m_higher_value;
|
||||||
|
std::set<int> used_extruders_for_tick = m_ticks.get_used_extruders_for_tick(tick, m_only_extruder, m_values[tick]);
|
||||||
|
|
||||||
wxMenu* add_color_change_menu = new wxMenu();
|
wxMenu* add_color_change_menu = new wxMenu();
|
||||||
|
|
||||||
|
@ -1046,7 +1055,7 @@ void Control::append_add_color_change_menu_item(wxMenu* menu, bool switch_curren
|
||||||
|
|
||||||
append_menu_item(add_color_change_menu, wxID_ANY, item_name, "",
|
append_menu_item(add_color_change_menu, wxID_ANY, item_name, "",
|
||||||
[this, i](wxCommandEvent&) { add_code_as_tick(ColorChangeCode, i); }, "", menu,
|
[this, i](wxCommandEvent&) { add_code_as_tick(ColorChangeCode, i); }, "", menu,
|
||||||
[is_used_extruder]() { return is_used_extruder; }, GUI::wxGetApp().plater());
|
[]() { return true; }, GUI::wxGetApp().plater());
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString menu_name = switch_current_code ?
|
const wxString menu_name = switch_current_code ?
|
||||||
|
@ -1267,10 +1276,10 @@ std::array<int, 2> Control::get_active_extruders_for_tick(int tick) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get used extruders for tick.
|
// Get used extruders for tick.
|
||||||
// Means all extruders(toools) will be used during printing from current tick to the end
|
// Means all extruders(tools) which will be used during printing from current tick to the end
|
||||||
std::set<int> Control::get_used_extruders_for_tick(int tick) const
|
std::set<int> TickCodeInfo::get_used_extruders_for_tick(int tick, int only_extruder, double print_z) const
|
||||||
{
|
{
|
||||||
if (m_mode == t_mode::MultiExtruder)
|
if (mode == t_mode::MultiExtruder)
|
||||||
{
|
{
|
||||||
// #ys_FIXME: get tool ordering from _correct_ place
|
// #ys_FIXME: get tool ordering from _correct_ place
|
||||||
const ToolOrdering& tool_ordering = GUI::wxGetApp().plater()->fff_print().get_tool_ordering();
|
const ToolOrdering& tool_ordering = GUI::wxGetApp().plater()->fff_print().get_tool_ordering();
|
||||||
|
@ -1280,7 +1289,7 @@ std::set<int> Control::get_used_extruders_for_tick(int tick) const
|
||||||
|
|
||||||
std::set<int> used_extruders;
|
std::set<int> used_extruders;
|
||||||
|
|
||||||
auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(m_values[tick]));
|
auto it_layer_tools = std::lower_bound(tool_ordering.begin(), tool_ordering.end(), LayerTools(print_z));
|
||||||
for (; it_layer_tools != tool_ordering.end(); ++it_layer_tools)
|
for (; it_layer_tools != tool_ordering.end(); ++it_layer_tools)
|
||||||
{
|
{
|
||||||
const std::vector<unsigned>& extruders = it_layer_tools->extruders;
|
const std::vector<unsigned>& extruders = it_layer_tools->extruders;
|
||||||
|
@ -1291,12 +1300,11 @@ std::set<int> Control::get_used_extruders_for_tick(int tick) const
|
||||||
return used_extruders;
|
return used_extruders;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int default_initial_extruder = m_mode == t_mode::MultiAsSingle ? std::max(m_only_extruder, 1) : 1;
|
const int default_initial_extruder = mode == t_mode::MultiAsSingle ? std::max(only_extruder, 1) : 1;
|
||||||
if (m_ticks.empty())
|
if (ticks.empty())
|
||||||
return {default_initial_extruder};
|
return {default_initial_extruder};
|
||||||
|
|
||||||
std::set<int> used_extruders;
|
std::set<int> used_extruders;
|
||||||
const std::set<TickCode>& ticks = m_ticks.ticks;
|
|
||||||
|
|
||||||
auto it_start = ticks.lower_bound(TickCode{tick});
|
auto it_start = ticks.lower_bound(TickCode{tick});
|
||||||
auto it = it_start;
|
auto it = it_start;
|
||||||
|
@ -1411,6 +1419,28 @@ static std::string get_new_color(const std::string& color)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// To avoid get an empty string from wxTextEntryDialog
|
||||||
|
// Let disable OK button, if TextCtrl is empty
|
||||||
|
static void upgrade_text_entry_dialog(wxTextEntryDialog* dlg)
|
||||||
|
{
|
||||||
|
// detect TextCtrl and OK button
|
||||||
|
wxTextCtrl* textctrl {nullptr};
|
||||||
|
wxWindowList& dlg_items = dlg->GetChildren();
|
||||||
|
for (auto item : dlg_items) {
|
||||||
|
textctrl = dynamic_cast<wxTextCtrl*>(item);
|
||||||
|
if (textctrl)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!textctrl)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxButton* btn_OK = static_cast<wxButton*>(dlg->FindWindowById(wxID_OK));
|
||||||
|
btn_OK->Bind(wxEVT_UPDATE_UI, [textctrl](wxUpdateUIEvent& evt) {
|
||||||
|
evt.Enable(!textctrl->IsEmpty());
|
||||||
|
}, btn_OK->GetId());
|
||||||
|
}
|
||||||
|
|
||||||
static std::string get_custom_code(const std::string& code_in, double height)
|
static std::string get_custom_code(const std::string& code_in, double height)
|
||||||
{
|
{
|
||||||
wxString msg_text = from_u8(_utf8(L("Enter custom G-code used on current layer"))) + ":";
|
wxString msg_text = from_u8(_utf8(L("Enter custom G-code used on current layer"))) + ":";
|
||||||
|
@ -1419,7 +1449,9 @@ static std::string get_custom_code(const std::string& code_in, double height)
|
||||||
// get custom gcode
|
// get custom gcode
|
||||||
wxTextEntryDialog dlg(nullptr, msg_text, msg_header, code_in,
|
wxTextEntryDialog dlg(nullptr, msg_text, msg_header, code_in,
|
||||||
wxTextEntryDialogStyle | wxTE_MULTILINE);
|
wxTextEntryDialogStyle | wxTE_MULTILINE);
|
||||||
if (dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty())
|
upgrade_text_entry_dialog(&dlg);
|
||||||
|
|
||||||
|
if (dlg.ShowModal() != wxID_OK)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
return dlg.GetValue().ToStdString();
|
return dlg.GetValue().ToStdString();
|
||||||
|
@ -1433,6 +1465,8 @@ static std::string get_pause_print_msg(const std::string& msg_in, double height)
|
||||||
// get custom gcode
|
// get custom gcode
|
||||||
wxTextEntryDialog dlg(nullptr, msg_text, msg_header, from_u8(msg_in),
|
wxTextEntryDialog dlg(nullptr, msg_text, msg_header, from_u8(msg_in),
|
||||||
wxTextEntryDialogStyle);
|
wxTextEntryDialogStyle);
|
||||||
|
upgrade_text_entry_dialog(&dlg);
|
||||||
|
|
||||||
if (dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty())
|
if (dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty())
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
|
@ -1791,13 +1825,44 @@ bool TickCodeInfo::has_tick_with_code(const std::string& gcode)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TickCodeInfo::is_conflict_tick(const TickCode& tick, t_mode out_mode)
|
ConflictType TickCodeInfo::is_conflict_tick(const TickCode& tick, t_mode out_mode, int only_extruder, double print_z)
|
||||||
{
|
{
|
||||||
return (tick.gcode == ColorChangeCode && (
|
if ((tick.gcode == ColorChangeCode && (
|
||||||
(mode == t_mode::SingleExtruder && out_mode == t_mode::MultiExtruder ) ||
|
(mode == t_mode::SingleExtruder && out_mode == t_mode::MultiExtruder ) ||
|
||||||
(mode == t_mode::MultiExtruder && out_mode == t_mode::SingleExtruder) )) ||
|
(mode == t_mode::MultiExtruder && out_mode == t_mode::SingleExtruder) )) ||
|
||||||
(tick.gcode == ToolChangeCode &&
|
(tick.gcode == ToolChangeCode &&
|
||||||
(mode == t_mode::MultiAsSingle && out_mode != t_mode::MultiAsSingle));
|
(mode == t_mode::MultiAsSingle && out_mode != t_mode::MultiAsSingle)) )
|
||||||
|
return ctModeConflict;
|
||||||
|
|
||||||
|
// check ColorChange tick
|
||||||
|
if (tick.gcode == ColorChangeCode)
|
||||||
|
{
|
||||||
|
// We should mark a tick as a "Meaningless",
|
||||||
|
// if it has a ColorChange for unused extruder from current print to end of the print
|
||||||
|
std::set<int> used_extruders_for_tick = get_used_extruders_for_tick(tick.tick, only_extruder, print_z);
|
||||||
|
|
||||||
|
if (used_extruders_for_tick.find(tick.extruder) == used_extruders_for_tick.end())
|
||||||
|
return ctMeaningless;
|
||||||
|
|
||||||
|
// We should mark a tick as a "Redundant",
|
||||||
|
// if it has a ColorChange for extruder that has not been used before
|
||||||
|
if (mode == t_mode::MultiAsSingle && tick.extruder != std::max<int>(only_extruder, 1) )
|
||||||
|
{
|
||||||
|
auto it = ticks.lower_bound( tick );
|
||||||
|
if (it == ticks.begin() && it->gcode == ToolChangeCode && tick.extruder == it->extruder)
|
||||||
|
return ctNone;
|
||||||
|
|
||||||
|
while (it != ticks.begin()) {
|
||||||
|
--it;
|
||||||
|
if (it->gcode == ToolChangeCode && tick.extruder == it->extruder)
|
||||||
|
return ctNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctRedundant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // DoubleSlider
|
} // DoubleSlider
|
||||||
|
|
|
@ -39,6 +39,14 @@ enum IconFocus {
|
||||||
ifCog
|
ifCog
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ConflictType
|
||||||
|
{
|
||||||
|
ctNone,
|
||||||
|
ctModeConflict,
|
||||||
|
ctMeaningless,
|
||||||
|
ctRedundant
|
||||||
|
};
|
||||||
|
|
||||||
using t_mode = CustomGCode::Mode;
|
using t_mode = CustomGCode::Mode;
|
||||||
|
|
||||||
struct TickCode
|
struct TickCode
|
||||||
|
@ -74,8 +82,12 @@ public:
|
||||||
bool switch_code_for_tick(std::set<TickCode>::iterator it, const std::string& code_to, const int extruder);
|
bool switch_code_for_tick(std::set<TickCode>::iterator it, const std::string& code_to, const int extruder);
|
||||||
void erase_all_ticks_with_code(const std::string& gcode);
|
void erase_all_ticks_with_code(const std::string& gcode);
|
||||||
|
|
||||||
bool has_tick_with_code(const std::string& gcode);
|
bool has_tick_with_code(const std::string& gcode);
|
||||||
bool is_conflict_tick(const TickCode& tick, t_mode out_mode);
|
ConflictType is_conflict_tick(const TickCode& tick, t_mode out_mode, int only_extruder, double print_z);
|
||||||
|
|
||||||
|
// Get used extruders for tick.
|
||||||
|
// Means all extruders(tools) which will be used during printing from current tick to the end
|
||||||
|
std::set<int> get_used_extruders_for_tick(int tick, int only_extruder, double print_z) const;
|
||||||
|
|
||||||
void suppress_plus (bool suppress) { m_suppress_plus = suppress; }
|
void suppress_plus (bool suppress) { m_suppress_plus = suppress; }
|
||||||
void suppress_minus(bool suppress) { m_suppress_minus = suppress; }
|
void suppress_minus(bool suppress) { m_suppress_minus = suppress; }
|
||||||
|
@ -253,10 +265,6 @@ private:
|
||||||
// Use those values to disable selection of active extruders
|
// Use those values to disable selection of active extruders
|
||||||
std::array<int, 2> get_active_extruders_for_tick(int tick) const;
|
std::array<int, 2> get_active_extruders_for_tick(int tick) const;
|
||||||
|
|
||||||
// Get used extruders for tick.
|
|
||||||
// Means all extruders(toools) will be used during printing from current tick to the end
|
|
||||||
std::set<int> get_used_extruders_for_tick(int tick) const;
|
|
||||||
|
|
||||||
void post_ticks_changed_event(const std::string& gcode = "");
|
void post_ticks_changed_event(const std::string& gcode = "");
|
||||||
bool check_ticks_changed_event(const std::string& gcode);
|
bool check_ticks_changed_event(const std::string& gcode);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue