diff --git a/resources/icons/cog_f.svg b/resources/icons/cog_f.svg
new file mode 100644
index 0000000000..28267ddb4b
--- /dev/null
+++ b/resources/icons/cog_f.svg
@@ -0,0 +1,17 @@
+
+
+
diff --git a/resources/icons/undo_f.svg b/resources/icons/undo_f.svg
new file mode 100644
index 0000000000..c2db835498
--- /dev/null
+++ b/resources/icons/undo_f.svg
@@ -0,0 +1,12 @@
+
+
+
diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h
index ba3cd1c368..172db0ec95 100644
--- a/src/imgui/imconfig.h
+++ b/src/imgui/imconfig.h
@@ -153,8 +153,6 @@ namespace ImGui
const wchar_t PlugMarker = 0x1C;
const wchar_t DowelMarker = 0x1D;
const wchar_t SnapMarker = 0x1E;
- const wchar_t Lock = 0x1F;
- const wchar_t Unlock = 0x17;
const wchar_t HorizontalHide = 0xB1;
const wchar_t HorizontalShow = 0xB2;
// Do not forget use following letters only in wstring
@@ -191,6 +189,25 @@ namespace ImGui
const wchar_t InfoMarkerSmall = 0x2716;
const wchar_t CollapseBtn = 0x2715;
+ // icons for double slider (middle size icons)
+ const wchar_t Lock = 0x2801;
+ const wchar_t LockHovered = 0x2802;
+ const wchar_t Unlock = 0x2803;
+ const wchar_t UnlockHovered = 0x2804;
+ const wchar_t DSRevert = 0x2805;
+ const wchar_t DSRevertHovered = 0x2806;
+ const wchar_t DSSettings = 0x2807;
+ const wchar_t DSSettingsHovered = 0x2808;
+ // icons for double slider (small size icons)
+ const wchar_t ErrorTick = 0x2809;
+ const wchar_t ErrorTickHovered = 0x280A;
+ const wchar_t PausePrint = 0x280B;
+ const wchar_t PausePrintHovered = 0x280C;
+ const wchar_t EditGCode = 0x280D;
+ const wchar_t EditGCodeHovered = 0x280E;
+ const wchar_t RemoveTick = 0x280F;
+ const wchar_t RemoveTickHovered = 0x2810;
+
// void MyFunction(const char* name, const MyMatrix44& v);
}
diff --git a/src/slic3r/GUI/DoubleSlider.cpp b/src/slic3r/GUI/DoubleSlider.cpp
index 11673d7799..55e3eafe0e 100644
--- a/src/slic3r/GUI/DoubleSlider.cpp
+++ b/src/slic3r/GUI/DoubleSlider.cpp
@@ -52,6 +52,8 @@ constexpr double min_delta_area = scale_(scale_(25)); // equal to 25 mm2
constexpr double miscalculation = scale_(scale_(1)); // equal to 1 mm2
static const float LEFT_MARGIN = 13.0f + 100.0f; // avoid thumbnail toolbar
+static const float BTN_SZ = 24.f;
+
static const ImVec2 ONE_LAYER_OFFSET = ImVec2(41.0f, /*44*/33.0f);
static const ImVec2 HORIZONTAL_SLIDER_SIZE = ImVec2(764.0f, 90.0f);//764 = 680 + handle_dummy_width * 2 + text_right_dummy
static const ImVec2 VERTICAL_SLIDER_SIZE = ImVec2(105.0f, 748.0f);//748 = 680 + text_dummy_height * 2
@@ -91,6 +93,7 @@ Control::Control( wxWindow *parent,
m_min_value(minValue),
m_max_value(maxValue),
m_style(style == wxSL_HORIZONTAL || style == wxSL_VERTICAL ? style: wxSL_HORIZONTAL),
+ m_allow_editing(wxGetApp().is_editor()),
m_extra_style(style == wxSL_VERTICAL ? wxSL_AUTOTICKS | wxSL_VALUE_LABEL : 0)
{
#ifdef __WXOSX__
@@ -171,8 +174,10 @@ Control::Control( wxWindow *parent,
imgui_ctrl.set_get_label_cb([this](int pos) {return into_u8(get_label(pos)); });
- if (!is_horizontal())
+ if (!is_horizontal()) {
imgui_ctrl.set_get_label_on_move_cb([this](int pos) {return into_u8(get_label(pos, ltEstimatedTime)); });
+ imgui_ctrl.set_extra_draw_cb([this](const ImRect& draw_rc) {return draw_ticks(draw_rc); });
+ }
}
@@ -613,7 +618,8 @@ float Control::get_pos_from_value(int v_min, int v_max, int value, const ImRect&
return handle_pos;
}
-void Control::draw_ticks(const ImRect& slideable_region) {
+void Control::draw_ticks(const ImRect& slideable_region)
+{
//if(m_draw_mode != dmRegular)
// return;
//if (m_ticks.empty() || m_mode == MultiExtruder)
@@ -623,22 +629,22 @@ void Control::draw_ticks(const ImRect& slideable_region) {
ImGuiContext& context = *GImGui;
- ImVec2 tick_box = ImVec2(46.0f, 16.0f) * m_scale;
- ImVec2 tick_offset = ImVec2(19.0f, 11.0f) * m_scale;
- float tick_width = 1.0f * m_scale;
- ImVec2 icon_offset = ImVec2(13.0f, 7.0f) * m_scale;
- ImVec2 icon_size = ImVec2(14.0f, 14.0f) * m_scale;
+ const ImVec2 tick_border = ImVec2(23.0f, 2.0f) * m_scale;
+ // distance form center begin end
+ const ImVec2 tick_size = ImVec2(19.0f, 11.0f) * m_scale;
+ const float tick_width = 1.0f * m_scale;
+ const float icon_side = wxGetApp().imgui()->GetTextureCustomRect(ImGui::PausePrint)->Height;
+ const float icon_offset = 0.5f * icon_side;;
- const ImU32 tick_clr = ImGui::ColorConvertFloat4ToU32(ImGuiPureWrap::COL_ORANGE_DARK); //IM_COL32(144, 144, 144, 255);
- const ImU32 tick_hover_box_clr = ImGui::ColorConvertFloat4ToU32(ImGuiPureWrap::COL_WINDOW_BACKGROUND); //IM_COL32(219, 253, 231, 255);
- const ImU32 delete_btn_clr = IM_COL32(144, 144, 144, 255);
+ const ImU32 tick_clr = ImGui::ColorConvertFloat4ToU32(ImGuiPureWrap::COL_ORANGE_DARK);
+ const ImU32 tick_hovered_clr = ImGui::ColorConvertFloat4ToU32(ImGuiPureWrap::COL_WINDOW_BACKGROUND);
auto get_tick_pos = [this, slideable_region](int tick)
- {
- int v_min = GetMinValue();
- int v_max = GetMaxValue();
- return get_pos_from_value(v_min, v_max, tick, slideable_region);
- };
+ {
+ int v_min = GetMinValue();
+ int v_max = GetMaxValue();
+ return get_pos_from_value(v_min, v_max, tick, slideable_region);
+ };
std::set::const_iterator tick_it = m_ticks.ticks.begin();
while (tick_it != m_ticks.ticks.end())
@@ -646,17 +652,19 @@ void Control::draw_ticks(const ImRect& slideable_region) {
float tick_pos = get_tick_pos(tick_it->tick);
//draw tick hover box when hovered
- ImRect tick_hover_box = ImRect(slideable_region.GetCenter().x - tick_box.x / 2, tick_pos - tick_box.y / 2, slideable_region.GetCenter().x + tick_box.x / 2,
- tick_pos + tick_box.y / 2);
+ ImRect tick_hover_box = ImRect(slideable_region.GetCenter().x - tick_border.x, tick_pos - tick_border.y,
+ slideable_region.GetCenter().x + tick_border.x, tick_pos + tick_border.y - tick_width);
- if (ImGui::IsMouseHoveringRect(tick_hover_box.Min, tick_hover_box.Max))
- {
- ImGui::RenderFrame(tick_hover_box.Min, tick_hover_box.Max, tick_hover_box_clr, false);
- if (context.IO.MouseClicked[0]) {
- }
+ if (ImGui::IsMouseHoveringRect(tick_hover_box.Min, tick_hover_box.Max)) {
+ ImGui::RenderFrame(tick_hover_box.Min, tick_hover_box.Max, tick_hovered_clr, false);
+ break;
}
++tick_it;
}
+
+ auto active_tick_it = m_selection == ssHigher ? m_ticks.ticks.find(TickCode{ this->GetHigherValue() }) :
+ m_selection == ssLower ? m_ticks.ticks.find(TickCode{ this->GetLowerValue() }) :
+ m_ticks.ticks.end();
tick_it = m_ticks.ticks.begin();
while (tick_it != m_ticks.ticks.end())
@@ -664,42 +672,43 @@ void Control::draw_ticks(const ImRect& slideable_region) {
float tick_pos = get_tick_pos(tick_it->tick);
//draw ticks
- ImRect tick_left = ImRect(slideable_region.GetCenter().x - tick_offset.x, tick_pos - tick_width, slideable_region.GetCenter().x - tick_offset.y, tick_pos);
- ImRect tick_right = ImRect(slideable_region.GetCenter().x + tick_offset.y, tick_pos - tick_width, slideable_region.GetCenter().x + tick_offset.x, tick_pos);
+ ImRect tick_left = ImRect(slideable_region.GetCenter().x - tick_size.x, tick_pos - tick_width, slideable_region.GetCenter().x - tick_size.y, tick_pos);
+ ImRect tick_right = ImRect(slideable_region.GetCenter().x + tick_size.y, tick_pos - tick_width, slideable_region.GetCenter().x + tick_size.x, tick_pos);
ImGui::RenderFrame(tick_left.Min, tick_left.Max, tick_clr, false);
ImGui::RenderFrame(tick_right.Min, tick_right.Max, tick_clr, false);
- //draw pause icon
- if (tick_it->type == PausePrint) {
- //ImTextureID pause_icon_id = m_pause_icon_id;
- ImVec2 icon_pos = ImVec2(slideable_region.GetCenter().x + icon_offset.x, tick_pos - icon_offset.y);
- //button_with_pos(pause_icon_id, icon_size, icon_pos);
- if (ImGui::IsMouseHoveringRect(icon_pos, icon_pos + icon_size)) {
- if (context.IO.MouseClicked[0])
- int a = 0;
- }
- }
- ++tick_it;
- }
+ ImVec2 icon_pos = ImVec2(tick_right.Max.x + icon_offset, tick_pos - icon_offset);
+ std::string btn_label = "tick " + std::to_string(tick_it->tick);
- tick_it = m_selection == ssHigher ? m_ticks.ticks.find(TickCode{ this->GetHigherValue() }) :
- m_selection == ssLower ? m_ticks.ticks.find(TickCode{ this->GetLowerValue() }) :
- m_ticks.ticks.end();
- if (tick_it != m_ticks.ticks.end()) {
- // draw delete icon
- //ImTextureID delete_icon_id = m_delete_icon_id;
- ImVec2 icon_pos = ImVec2(slideable_region.GetCenter().x + icon_offset.x, get_tick_pos(tick_it->tick) - icon_offset.y);
- //! button_with_pos(m_delete_icon_id, icon_size, icon_pos);
- if (ImGui::IsMouseHoveringRect(icon_pos, icon_pos + icon_size)) {
- if (context.IO.MouseClicked[0]) {
- // delete tick
+ //draw tick icon-buttons
+ bool activate_this_tick = false;
+ if (tick_it == active_tick_it && m_allow_editing) {
+ // delete tick
+ if (render_button(ImGui::RemoveTick, ImGui::RemoveTickHovered, btn_label, icon_pos, m_selection == ssHigher ? fiHigherThumb : fiLowerThumb, tick_it->tick)) {
Type type = tick_it->type;
m_ticks.ticks.erase(tick_it);
post_ticks_changed_event(type);
+ break;
}
+ }
+ else if (m_draw_mode != dmRegular)// if we have non-regular draw mode, all ticks should be marked with error icon
+ activate_this_tick = render_button(ImGui::ErrorTick, ImGui::ErrorTickHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick);
+ else if (tick_it->type == ColorChange || tick_it->type == ToolChange) {
+ if (m_ticks.is_conflict_tick(*tick_it, m_mode, m_only_extruder, m_values[tick_it->tick]))
+ activate_this_tick = render_button(ImGui::ErrorTick, ImGui::ErrorTickHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick);
}
- }
+ else if (tick_it->type == PausePrint)
+ activate_this_tick = render_button(ImGui::PausePrint, ImGui::PausePrintHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick);
+ else
+ activate_this_tick = render_button(ImGui::EditGCode, ImGui::EditGCodeHovered, btn_label, icon_pos, fiActionIcon, tick_it->tick);
+ if (activate_this_tick) {
+ m_selection == ssHigher ? SetHigherValue(tick_it->tick) : SetLowerValue(tick_it->tick);
+ break;
+ }
+
+ ++tick_it;
+ }
}
inline int hex_to_int(const char c)
@@ -802,7 +811,7 @@ void Control::render_menu()
std::vector colors = wxGetApp().plater()->get_extruder_colors_from_plater_config();
int extruder_num = colors.size();
- if (m_show_menu) {
+ if (imgui_ctrl.is_rclick_on_thumb()) {
ImGui::OpenPopup("slider_menu_popup");
}
@@ -815,13 +824,14 @@ void Control::render_menu()
else
{
if (menu_item_with_icon(_u8L("Add Color Change").c_str(), "")) {
+ UseDefaultColors(false);
add_code_as_tick(ColorChange);
}
if (menu_item_with_icon(_u8L("Add Pause").c_str(), "")) {
add_code_as_tick(PausePrint);
}
if (menu_item_with_icon(_u8L("Add Custom G-code").c_str(), "")) {
-
+ add_code_as_tick(Custom);
}
if (!gcode(Template).empty()) {
if (menu_item_with_icon(_u8L("Add Custom Template").c_str(), "")) {
@@ -852,30 +862,39 @@ void Control::render_menu()
ImGui::PopStyleVar(3);
}
-bool Control::render_button(const wchar_t btn_icon, const std::string& label_id, FocusedItem focus)
+bool Control::render_button(const wchar_t btn_icon, const wchar_t btn_icon_hovered, const std::string& label_id, const ImVec2& pos, FocusedItem focus, int tick /*= -1*/)
{
- const ImGuiStyle& style = ImGui::GetStyle();
+ float scale = (float)wxGetApp().em_unit() / 10.0f;
- ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, { 1, style.ItemSpacing.y });
+ ImGui::PushStyleVar(ImGuiStyleVar_::ImGuiStyleVar_WindowBorderSize, 0);
+ ImGui::PushStyleVar(ImGuiStyleVar_::ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f));
+ ImGui::PushStyleVar(ImGuiStyleVar_::ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
- const ImVec4 col = { 0.25f, 0.25f, 0.25f, 0.0f };
- ImGui::PushStyleColor(ImGuiCol_Button, col);
- ImGui::PushStyleColor(ImGuiCol_ButtonHovered, col);
- ImGui::PushStyleColor(ImGuiCol_ButtonActive, col);
+ ImGui::PushStyleColor(ImGuiCol_::ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
+ ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyleColorVec4(ImGuiCol_Text));
- std::string btn_label;
- btn_label += btn_icon;
- const bool ret = ImGui::Button((btn_label + "##" + label_id).c_str(), ImVec2(16*m_scale, 0));
+ int windows_flag = ImGuiWindowFlags_NoTitleBar
+ | ImGuiWindowFlags_NoCollapse
+ | ImGuiWindowFlags_NoMove
+ | ImGuiWindowFlags_NoResize
+ | ImGuiWindowFlags_NoScrollbar
+ | ImGuiWindowFlags_NoScrollWithMouse;
- ImGui::PopStyleColor(3);
+ auto m_imgui = wxGetApp().imgui();
+ ImGuiPureWrap::set_next_window_pos(pos.x, pos.y, ImGuiCond_Always);
+ std::string win_name = label_id + "##btn_win";
+ ImGuiPureWrap::begin(win_name, windows_flag);
- if (ImGui::IsItemHovered()) {
- m_focus = focus;
- std::string tooltip = into_u8(get_tooltip());
- ImGuiPureWrap::tooltip(tooltip.c_str(), ImGui::GetFontSize() * 20.0f);
- }
+ ImGuiContext& g = *GImGui;
- ImGui::PopStyleVar();
+ std::string tooltip = m_allow_editing ? into_u8(get_tooltip(tick)) : "";
+ ImGui::SetCursorPos(ImVec2(0, 0));
+ const bool ret = m_imgui->image_button(g.HoveredWindow == g.CurrentWindow ? btn_icon_hovered : btn_icon, tooltip, false);
+
+ ImGuiPureWrap::end();
+
+ ImGui::PopStyleColor(2);
+ ImGui::PopStyleVar(3);
return ret;
}
@@ -902,7 +921,9 @@ bool Control::imgui_render(GUI::GLCanvas3D& canvas)
imgui_ctrl.ShowLabelOnMouseMove(false);
}
else {
- pos.x = canvas_width - VERTICAL_SLIDER_SIZE.x * scale;
+ const float tick_icon_side = wxGetApp().imgui()->GetTextureCustomRect(ImGui::PausePrint)->Height;
+
+ pos.x = canvas_width - VERTICAL_SLIDER_SIZE.x * scale - tick_icon_side;
pos.y = ONE_LAYER_OFFSET.y;
size = ImVec2(VERTICAL_SLIDER_SIZE.x * scale, canvas_height - 4 * pos.y);
imgui_ctrl.ShowLabelOnMouseMove(true);
@@ -912,9 +933,28 @@ bool Control::imgui_render(GUI::GLCanvas3D& canvas)
imgui_ctrl.SetSize(size);
imgui_ctrl.SetScale(scale);
+ const float btn_sz = BTN_SZ*scale;
+ ImVec2 btn_pos = ImVec2(pos.x + 2.7 * btn_sz, pos.y - 0.5 * btn_sz);
+
+ if (!is_horizontal() && !m_ticks.empty() && m_allow_editing &&
+ render_button(ImGui::DSRevert, ImGui::DSRevertHovered, "revert", btn_pos, fiRevertIcon))
+ discard_all_thicks();
+
if (imgui_ctrl.render(m_selection))
SetSelectionSpan(m_is_one_layer ? imgui_ctrl.GetHigherValue() : imgui_ctrl.GetLowerValue(), imgui_ctrl.GetHigherValue());
+ if (!is_horizontal()) {
+ btn_pos.y += 0.5 * btn_sz + size.y;
+ if (render_button(is_one_layer() ? ImGui::Lock : ImGui::Unlock, is_one_layer() ? ImGui::LockHovered : ImGui::UnlockHovered, "one_layer", btn_pos, fiOneLayerIcon))
+ switch_one_layer_mode();
+
+ btn_pos.y += btn_sz;
+ if (render_button(ImGui::DSSettings, ImGui::DSSettingsHovered, "settings", btn_pos, fiCogIcon))
+ show_cog_icon_context_menu();
+
+ if (m_allow_editing)
+ render_menu();
+ }
return result;
}
@@ -1739,9 +1779,11 @@ int Control::get_tick_near_point(const wxPoint& pt)
void Control::ChangeOneLayerLock()
{
m_is_one_layer = !m_is_one_layer;
- imgui_ctrl.CombineThumbs(m_is_one_layer);
+ imgui_ctrl.CombineThumbs(m_is_one_layer);
+ if (!m_selection || m_is_one_layer)
+ m_selection = ssHigher;
m_selection == ssLower ? correct_lower_value() : correct_higher_value();
- if (!m_selection) m_selection = ssHigher;
+ // if (!m_selection) m_selection = ssHigher;
Refresh();
Update();
@@ -2829,8 +2871,10 @@ void Control::switch_one_layer_mode()
SetLowerValue(m_min_value);
SetHigherValue(m_max_value);
}
+ if (!m_selection || m_is_one_layer)
+ m_selection = ssHigher;
m_selection == ssLower ? correct_lower_value() : correct_higher_value();
- if (m_selection == ssUndef) m_selection = ssHigher;
+// if (m_selection == ssUndef) m_selection = ssHigher;
}
// discard all custom changes on DoubleSlider
diff --git a/src/slic3r/GUI/DoubleSlider.hpp b/src/slic3r/GUI/DoubleSlider.hpp
index f5e57808f2..b021c774f9 100644
--- a/src/slic3r/GUI/DoubleSlider.hpp
+++ b/src/slic3r/GUI/DoubleSlider.hpp
@@ -381,6 +381,7 @@ private:
int m_higher_value;
bool m_render_as_disabled{ false };
+ bool m_allow_editing{ true };
ScalableBitmap m_bmp_thumb_higher;
ScalableBitmap m_bmp_thumb_lower;
@@ -490,7 +491,7 @@ private:
void draw_colored_band(const ImRect& groove, const ImRect& slideable_region);
void draw_ticks(const ImRect& slideable_region);
void render_menu();
- bool render_button(const wchar_t btn_icon, const std::string& label_id, FocusedItem focus);
+ bool render_button(const wchar_t btn_icon, const wchar_t btn_icon_hovered, const std::string& label_id, const ImVec2& pos, FocusedItem focus, int tick = -1);
diff --git a/src/slic3r/GUI/ImGuiDoubleSlider.cpp b/src/slic3r/GUI/ImGuiDoubleSlider.cpp
index 57bbd5d6c5..f06ab7eb98 100644
--- a/src/slic3r/GUI/ImGuiDoubleSlider.cpp
+++ b/src/slic3r/GUI/ImGuiDoubleSlider.cpp
@@ -95,7 +95,7 @@ ImRect ImGuiControl::DrawOptions::groove(const ImVec2& pos, const ImVec2& size,
ImVec2(pos.x + size.x - groove_sz().x - dummy_sz().x, pos.y + text_dummy_sz().y);
ImVec2 groove_size = is_horizontal ?
ImVec2(size.x - 2 * thumb_dummy_sz().x - text_dummy_sz().x, groove_sz().y) :
- ImVec2(groove_sz().x, size.y - 2 * text_dummy_sz().y);
+ ImVec2(groove_sz().x, size.y - 1.6 * text_dummy_sz().y);
return ImRect(groove_start, groove_start + groove_size);
}
@@ -180,6 +180,13 @@ void ImGuiControl::SetSliderValues(const std::vector& values)
m_values = values;
}
+void ImGuiControl::CombineThumbs(bool combine)
+{
+ m_combine_thumbs = combine;
+ if (combine)
+ m_selection = ssHigher;
+}
+
std::string ImGuiControl::get_label(int pos) const
{
if (m_cb_get_label)
@@ -219,9 +226,14 @@ void ImGuiControl::draw_scroll_line(const ImRect& scroll_line, const ImRect& sli
ImGui::RenderFrame(scroll_line.Min, scroll_line.Max, thumb_bg_clr, false, m_draw_opts.rounding());
}
-void ImGuiControl::draw_background(const ImRect& groove)
+void ImGuiControl::draw_background(const ImRect& slideable_region)
{
- ImVec2 groove_padding = (is_horizontal() ? ImVec2(2.0f, 2.0f) : ImVec2(3.0f, 4.0f)) * m_draw_opts.scale;
+ ImVec2 groove_sz = m_draw_opts.groove_sz() * 0.55f;
+ auto groove_center = slideable_region.GetCenter();
+ ImRect groove = is_horizontal() ?
+ ImRect(slideable_region.Min.x, groove_center.y - groove_sz.y, slideable_region.Max.x, groove_center.y + groove_sz.y) :
+ ImRect(groove_center.x - groove_sz.x, slideable_region.Min.y, groove_center.x + groove_sz.x, slideable_region.Max.y);
+ ImVec2 groove_padding = (is_horizontal() ? ImVec2(2.0f, 2.0f) : ImVec2(3.0f, 4.0f)) * m_draw_opts.scale;
ImRect bg_rect = groove;
bg_rect.Expand(groove_padding);
@@ -300,7 +312,7 @@ void ImGuiControl::apply_regions(int higher_value, int lower_value, const ImRect
ImRect(mid.x - thumb_radius, lower_thumb_pos - thumb_radius, mid.x + thumb_radius, lower_thumb_pos + thumb_radius);
}
-void ImGuiControl::check_thumbs(int* higher_value, int* lower_value)
+void ImGuiControl::check_and_correct_thumbs(int* higher_value, int* lower_value)
{
if (!m_draw_lower_thumb || m_combine_thumbs)
return;
@@ -353,13 +365,13 @@ bool ImGuiControl::draw_slider( int* higher_value, int* lower_value,
ImGuiContext& context = *GImGui;
const ImGuiID id = window->GetID(m_name.c_str());
- const ImRect draw_region(pos, pos + size);
- ImGui::ItemSize(draw_region);
+ const ImRect item_size(pos, pos + size);
+ ImGui::ItemSize(item_size);
- // calc slider groove size
+ // get slider groove size
ImRect groove = m_draw_opts.groove(pos, size, is_horizontal());
- // set active(draggable) region.
+ // get active(draggable) region.
ImRect draggable_region = m_draw_opts.draggable_region(groove, is_horizontal());
if (ImGui::ItemHoverable(draggable_region, id) && context.IO.MouseDown[0]) {
@@ -368,9 +380,13 @@ bool ImGuiControl::draw_slider( int* higher_value, int* lower_value,
ImGui::FocusWindow(window);
}
- // set slideable region and thumbs.
+ // set slideable regions and thumbs.
apply_regions(*higher_value, *lower_value, draggable_region);
+ // select and mark higher thumb by default
+ if (m_selection == ssUndef)
+ m_selection = ssHigher;
+
// Processing interacting
if (ImGui::ItemHoverable(m_regions.higher_thumb, id) && context.IO.MouseClicked[0])
@@ -382,44 +398,53 @@ bool ImGuiControl::draw_slider( int* higher_value, int* lower_value,
// update thumb position and value
bool value_changed = false;
- if (m_selection == ssHigher)
+ if (m_selection == ssHigher) {
value_changed = behavior(id, m_regions.higher_slideable_region, m_min_value, m_max_value,
higher_value, &m_regions.higher_thumb, is_horizontal() ? 0: ImGuiSliderFlags_Vertical);
- else if (m_draw_lower_thumb && !m_combine_thumbs)
+ }
+ else if (m_draw_lower_thumb && !m_combine_thumbs) {
value_changed = behavior(id, m_regions.lower_slideable_region, m_min_value, m_max_value,
lower_value, &m_regions.lower_thumb, is_horizontal() ? 0: ImGuiSliderFlags_Vertical);
+ }
+
+ // check thumbs values and correct them if needed
+ check_and_correct_thumbs(higher_value, lower_value);
+
+ const ImRect& slideable_region = m_selection == ssHigher ? m_regions.higher_slideable_region : m_regions.lower_slideable_region;
+ const ImRect& active_thumb = m_selection == ssHigher ? m_regions.higher_thumb : m_regions.lower_thumb;
bool show_move_label = false;
- ImRect mouse_pos_rc = m_regions.higher_thumb;
- if (!value_changed && ImGui::ItemHoverable(draw_region, id)) {
- behavior(id, draggable_region, m_min_value, m_max_value,
+ ImRect mouse_pos_rc = active_thumb;
+ if (!value_changed && ImGui::ItemHoverable(item_size, id) && !ImGui::IsMouseDragging(0)) {
+ behavior(id, slideable_region, m_min_value, m_max_value,
&m_mouse_pos_value, &mouse_pos_rc, is_horizontal() ? 0 : ImGuiSliderFlags_Vertical, true);
show_move_label = true;
}
- // check thumbs values and correct them if needed
- check_thumbs(higher_value, lower_value);
-
- // detect right click on thumb
- if (ImGui::ItemHoverable(m_selection == ssHigher ? m_regions.higher_thumb : m_regions.lower_thumb, id) && context.IO.MouseClicked[1])
+ // detect right click on selected thumb
+ if (ImGui::ItemHoverable(active_thumb, id) && context.IO.MouseClicked[1])
m_rclick_on_selected_thumb = true;
- if ((!ImGui::ItemHoverable(m_selection == ssHigher ? m_regions.higher_thumb : m_regions.lower_thumb, id) && context.IO.MouseClicked[1]) ||
+ if ((!ImGui::ItemHoverable(active_thumb, id) && context.IO.MouseClicked[1]) ||
context.IO.MouseClicked[0])
m_rclick_on_selected_thumb = false;
+ // render slider
+
ImVec2 higher_thumb_center = m_regions.higher_thumb.GetCenter();
ImVec2 lower_thumb_center = m_regions.lower_thumb.GetCenter();
- ImRect scroll_line = m_draw_opts.slider_line(draggable_region, higher_thumb_center, lower_thumb_center, is_horizontal());
+ ImRect scroll_line = m_draw_opts.slider_line(slideable_region, higher_thumb_center, lower_thumb_center, is_horizontal());
+
+ if (m_cb_extra_draw)
+ m_cb_extra_draw(slideable_region);
// draw background
- draw_background(groove);
+ draw_background(slideable_region);
// draw scroll line
- draw_scroll_line(m_combine_thumbs ? groove : scroll_line, groove);
+ draw_scroll_line(m_combine_thumbs ? groove : scroll_line, slideable_region);
// draw thumbs with label
- // select and mark higher thumb by default
- draw_thumb(higher_thumb_center, m_selection != ssLower && m_draw_lower_thumb);
+ draw_thumb(higher_thumb_center, m_selection == ssHigher && m_draw_lower_thumb);
draw_label(higher_label, m_regions.higher_thumb);
if (m_draw_lower_thumb && !m_combine_thumbs) {
diff --git a/src/slic3r/GUI/ImGuiDoubleSlider.hpp b/src/slic3r/GUI/ImGuiDoubleSlider.hpp
index 732ceff57d..406cb51a6e 100644
--- a/src/slic3r/GUI/ImGuiDoubleSlider.hpp
+++ b/src/slic3r/GUI/ImGuiDoubleSlider.hpp
@@ -69,21 +69,18 @@ public:
void SetMaxValue(const int max_value);
void SetSliderValues(const std::vector& values);
+ void CombineThumbs(bool combine);
void SetPos(ImVec2 pos) { m_pos = pos; }
void SetSize(ImVec2 size) { m_size = size; }
void SetScale(float scale) { m_draw_opts.scale = scale; }
void ShowLabelOnMouseMove(bool show = true) { m_show_move_label = show; }
- void CombineThumbs(bool combine = true) { m_combine_thumbs = combine; }
-
- void set_get_label_on_move_cb(std::function cb) { m_cb_get_label_on_move = cb; }
- void set_get_label_cb(std::function cb) { m_cb_get_label = cb; }
- void set_draw_scroll_line_cb(std::function cb) { m_cb_draw_scroll_line = cb; }
bool is_horizontal() const { return m_style == wxSL_HORIZONTAL; }
bool is_lower_at_min() const { return m_lower_value == m_min_value; }
bool is_higher_at_max() const { return m_higher_value == m_max_value; }
bool is_full_span() const { return this->is_lower_at_min() && this->is_higher_at_max(); }
+ bool is_rclick_on_thumb() const { return m_rclick_on_selected_thumb; }
bool render(SelectedSlider& selection);
void draw_scroll_line(const ImRect& scroll_line, const ImRect& slideable_region);
@@ -91,6 +88,11 @@ public:
std::string get_label(int pos) const;
std::string get_label_on_move(int pos) const { return m_cb_get_label_on_move ? m_cb_get_label_on_move(pos) : get_label(pos); }
+ void set_get_label_on_move_cb(std::function cb) { m_cb_get_label_on_move = cb; }
+ void set_get_label_cb(std::function cb) { m_cb_get_label = cb; }
+ void set_draw_scroll_line_cb(std::function cb) { m_cb_draw_scroll_line = cb; }
+ void set_extra_draw_cb(std::function cb) { m_cb_extra_draw = cb; }
+
struct DrawOptions {
float scale { 1.f }; // used for Retina on osx
@@ -133,7 +135,6 @@ private:
long m_style;
double m_label_koef{ 1. };
- bool m_lclick_on_selected_thumb{ false };
bool m_rclick_on_selected_thumb{ false };
bool m_draw_lower_thumb{ true };
@@ -143,13 +144,14 @@ private:
std::function m_cb_get_label { nullptr };
std::function m_cb_get_label_on_move { nullptr };
std::function m_cb_draw_scroll_line { nullptr };
+ std::function m_cb_extra_draw { nullptr };
void apply_regions(int higher_value, int lower_value, const ImRect& draggable_region);
float get_pos_from_value(int v_min, int v_max, int value, const ImRect& rect);
- void check_thumbs(int* higher_value, int* lower_value);
+ void check_and_correct_thumbs(int* higher_value, int* lower_value);
- void draw_background(const ImRect& groove);
+ void draw_background(const ImRect& slideable_region);
void draw_label(std::string label, const ImRect& thumb);
void draw_thumb(const ImVec2& center, bool mark = false);
bool draw_slider(int* higher_value, int* lower_value,
diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp
index 455e961c00..b776dd5bbe 100644
--- a/src/slic3r/GUI/ImGuiWrapper.cpp
+++ b/src/slic3r/GUI/ImGuiWrapper.cpp
@@ -75,6 +75,15 @@ static const std::map font_icons = {
{ImGui::SnapMarker , "snap" },
{ImGui::HorizontalHide , "horizontal_hide" },
{ImGui::HorizontalShow , "horizontal_show" },
+
+ {ImGui::ErrorTick , "error_tick" },
+ {ImGui::ErrorTickHovered , "error_tick_f" },
+ {ImGui::PausePrint , "pause_print" },
+ {ImGui::PausePrintHovered , "pause_print_f" },
+ {ImGui::EditGCode , "edit_gcode" },
+ {ImGui::EditGCodeHovered , "edit_gcode_f" },
+ {ImGui::RemoveTick , "colorchange_del" },
+ {ImGui::RemoveTickHovered , "colorchange_del_f" },
};
static const std::map font_icons_large = {
@@ -116,6 +125,17 @@ static const std::map font_icons_large = {
{ImGui::SlaViewProcessed , "sla_view_processed" },
};
+static const std::map font_icons_medium = {
+ {ImGui::Lock , "lock_closed" },
+ {ImGui::LockHovered , "lock_closed_f" },
+ {ImGui::Unlock , "lock_open" },
+ {ImGui::UnlockHovered , "lock_open_f" },
+ {ImGui::DSRevert , "undo" },
+ {ImGui::DSRevertHovered , "undo_f" },
+ {ImGui::DSSettings , "cog" },
+ {ImGui::DSSettingsHovered , "cog_f" },
+};
+
static const std::map font_icons_extra_large = {
{ImGui::ClippyMarker , "notification_clippy" },
};
@@ -470,7 +490,7 @@ bool ImGuiWrapper::slider_float(const wxString& label, float* v, float v_min, fl
return this->slider_float(label_utf8.c_str(), v, v_min, v_max, format, power, clamp, tooltip, show_edit_btn);
}
-bool ImGuiWrapper::image_button(const wchar_t icon, const std::string& tooltip)
+bool ImGuiWrapper::image_button(const wchar_t icon, const std::string& tooltip, bool highlight_on_hover/* = true*/)
{
const ImGuiIO& io = ImGui::GetIO();
const ImTextureID tex_id = io.Fonts->TexID;
@@ -481,9 +501,9 @@ bool ImGuiWrapper::image_button(const wchar_t icon, const std::string& tooltip)
const ImVec2 size = { float(rect->Width), float(rect->Height) };
const ImVec2 uv0 = ImVec2(float(rect->X) * inv_tex_w, float(rect->Y) * inv_tex_h);
const ImVec2 uv1 = ImVec2(float(rect->X + rect->Width) * inv_tex_w, float(rect->Y + rect->Height) * inv_tex_h);
- ImGui::PushStyleColor(ImGuiCol_Button, { 0.25f, 0.25f, 0.25f, 0.0f });
- ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.4f, 0.4f, 0.4f, 1.0f });
- ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.25f, 0.25f, 0.25f, 1.0f });
+ ImGui::PushStyleColor(ImGuiCol_Button, { 0.25f, 0.25f, 0.25f, 0.0f });
+ ImGui::PushStyleColor(ImGuiCol_ButtonHovered, { 0.4f, 0.4f, 0.4f, highlight_on_hover ? 1.0f : 0.0f });
+ ImGui::PushStyleColor(ImGuiCol_ButtonActive, { 0.25f, 0.25f, 0.25f, highlight_on_hover ? 1.0f : 0.0f });
const bool res = ImGuiPureWrap::image_button(tex_id, size, uv0, uv1);
ImGui::PopStyleColor(3);
@@ -1125,6 +1145,10 @@ void ImGuiWrapper::init_font(bool compress)
m_custom_glyph_rects_ids[icon.first] =
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz, icon_sz, 3.0 * font_scale + icon_sz);
}
+ for (auto& icon : font_icons_medium) {
+ m_custom_glyph_rects_ids[icon.first] =
+ io.Fonts->AddCustomRectFontGlyph(font, icon.first, 1.5 * icon_sz, 1.5 * icon_sz, 3.0 * font_scale + 1.5 * icon_sz);
+ }
for (auto& icon : font_icons_large) {
m_custom_glyph_rects_ids[icon.first] =
io.Fonts->AddCustomRectFontGlyph(font, icon.first, icon_sz * 2, icon_sz * 2, 3.0 * font_scale + icon_sz * 2);
@@ -1161,6 +1185,11 @@ void ImGuiWrapper::init_font(bool compress)
load_icon_from_svg(icon, icon_sz);
}
+ const int icon_sz_m = int(1.5 * icon_sz); // default size of medium icon is 24 px
+ for (auto icon : font_icons_medium) {
+ load_icon_from_svg(icon, icon_sz_m);
+ }
+
icon_sz *= 2; // default size of large icon is 32 px
for (auto icon : font_icons_large) {
load_icon_from_svg(icon, icon_sz);
diff --git a/src/slic3r/GUI/ImGuiWrapper.hpp b/src/slic3r/GUI/ImGuiWrapper.hpp
index 56797f7e3a..8cbec8b390 100644
--- a/src/slic3r/GUI/ImGuiWrapper.hpp
+++ b/src/slic3r/GUI/ImGuiWrapper.hpp
@@ -86,8 +86,7 @@ public:
bool slider_float(const std::string& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true);
bool slider_float(const wxString& label, float* v, float v_min, float v_max, const char* format = "%.3f", float power = 1.0f, bool clamp = true, const wxString& tooltip = {}, bool show_edit_btn = true);
- bool image_button(const wchar_t icon, const std::string& tooltip = {});
-
+ bool image_button(const wchar_t icon, const std::string& tooltip = {}, bool highlight_on_hover = true);
void search_list(const ImVec2& size, bool (*items_getter)(int, const char** label, const char** tooltip), char* search_str,
Search::OptionViewParameters& view_params, int& selected, bool& edited, int& mouse_wheel, bool is_localized);