diff --git a/resources/images/im_code.svg b/resources/images/im_code.svg new file mode 100644 index 0000000000..6af2404040 --- /dev/null +++ b/resources/images/im_code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/images/im_fold.svg b/resources/images/im_fold.svg index f4f3286dd4..9bd106e0d7 100644 --- a/resources/images/im_fold.svg +++ b/resources/images/im_fold.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/resources/images/im_hidden.svg b/resources/images/im_hidden.svg new file mode 100644 index 0000000000..4393cc3b11 --- /dev/null +++ b/resources/images/im_hidden.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/images/im_unfold.svg b/resources/images/im_unfold.svg index 45bcec6fbb..1d59d9cc41 100644 --- a/resources/images/im_unfold.svg +++ b/resources/images/im_unfold.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/resources/images/im_visible.svg b/resources/images/im_visible.svg new file mode 100644 index 0000000000..6c8c53b18a --- /dev/null +++ b/resources/images/im_visible.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/imgui/imconfig.h b/src/imgui/imconfig.h index b230fa718c..bd83a3c44e 100644 --- a/src/imgui/imconfig.h +++ b/src/imgui/imconfig.h @@ -173,6 +173,9 @@ namespace ImGui const wchar_t SphereButtonIcon = 0x0816; const wchar_t GapFillIcon = 0x0817; const wchar_t ConfirmIcon = 0x0818; + const wchar_t gCodeButtonIcon = 0x0819; // ORCA + const wchar_t VisibleIcon = 0x0820; // ORCA + const wchar_t HiddenIcon = 0x0821; // ORCA const wchar_t MinimalizeDarkButton = 0x081C; const wchar_t MinimalizeHoverDarkButton = 0x081D; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 31eb38b728..dad2dfb361 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -596,9 +596,9 @@ void GCodeViewer::SequentialView::GCodeWindow::render(float top, float bottom, f //BBS: GUI refactor: move to right //imgui.set_next_window_pos(0.0f, top, ImGuiCond_Always, 0.0f, 0.0f); - imgui.set_next_window_pos(right, top, ImGuiCond_Always, 1.0f, 0.0f); + imgui.set_next_window_pos(right, top + 6 * m_scale, ImGuiCond_Always, 1.0f, 0.0f); // ORCA add a small gap between legend and code viewer imgui.set_next_window_size(0.0f, wnd_height, ImGuiCond_Always); - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 8.0f * m_scale); // ORCA add window rounding to modernize / match style ImGui::SetNextWindowBgAlpha(0.8f); imgui.begin(std::string("G-code"), ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoMove); @@ -879,6 +879,7 @@ void GCodeViewer::set_scale(float scale) if (m_sequential_view.m_scale != scale) { m_sequential_view.m_scale = scale; m_sequential_view.marker.m_scale = scale; + m_sequential_view.gcode_window.m_scale = scale; // ORCA } } @@ -4053,7 +4054,7 @@ void GCodeViewer::render_all_plates_stats(const std::vectorAddRectFilled(ImVec2(pos_rect.x,pos_rect.y - ImGui::GetStyle().WindowPadding.y), - ImVec2(pos_rect.x + ImGui::GetWindowWidth() + ImGui::GetFrameHeight(),pos_rect.y + ImGui::GetFrameHeight() + window_padding * 2.5), - ImGui::GetColorU32(ImVec4(0,0,0,0.3))); + // ORCA dont use background on top bar to give modern look + //draw_list->AddRectFilled(ImVec2(pos_rect.x,pos_rect.y - ImGui::GetStyle().WindowPadding.y), + //ImVec2(pos_rect.x + ImGui::GetWindowWidth() + ImGui::GetFrameHeight(),pos_rect.y + ImGui::GetFrameHeight() + window_padding * 2.5), + //ImGui::GetColorU32(ImVec4(0,0,0,0.3))); auto append_item = [icon_size, &imgui, imperial_units, &window_padding, &draw_list, this]( EItemType type, @@ -4464,12 +4466,14 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv if (b_menu_item) callback(); if (checkbox) { - ImGui::SameLine(ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x / 2 - ImGui::GetFrameHeight() / 2 - 2 * window_padding); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0, 0.0)); - ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(0.00f, 0.59f, 0.53f, 1.00f)); - ImGui::Checkbox(("##" + columns_offsets[0].first).c_str(), &visible); - ImGui::PopStyleColor(1); - ImGui::PopStyleVar(1); + //ImGui::SameLine(ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x / 2 - ImGui::GetFrameHeight() / 2 - 2 * window_padding); + //ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0, 0.0)); + //ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(0.00f, 0.59f, 0.53f, 1.00f)); + //ImGui::Checkbox(("##" + columns_offsets[0].first).c_str(), &visible); + //ImGui::PopStyleVar(1); + // ORCA replace checkboxes with eye icon + ImGui::SameLine(ImGui::GetWindowWidth() - (16.f + 0.f) * m_scale - window_padding * 2 - (ImGui::GetScrollMaxY() > 0.0f ? ImGui::GetStyle().ScrollbarSize : 0)); + ImGui::Text(into_u8(visible ? ImGui::VisibleIcon : ImGui::HiddenIcon).c_str(), ImVec2(16 * m_scale, 16 * m_scale)); } } @@ -4515,8 +4519,13 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } }; - auto append_headers = [&imgui, window_padding](const std::vector>& title_offsets) { + auto append_headers = [&imgui, window_padding, this](const std::vector>& title_offsets) { for (size_t i = 0; i < title_offsets.size(); i++) { + if (title_offsets[i].first == _u8L("Display")) { // ORCA Hide Display header + ImGui::SameLine(title_offsets[i].second); + ImGui::Dummy({(16.f - 6.f) * m_scale, 1}); // 16(icon) - 6(half of spacing) + continue; + } ImGui::SameLine(title_offsets[i].second); imgui.bold_text(title_offsets[i].first); } @@ -4534,14 +4543,16 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv return ret; }; - auto calculate_offsets = [&imgui, max_width, window_padding](const std::vector>>& title_columns, float extra_size = 0.0f) { + auto calculate_offsets = [&imgui, max_width, window_padding, this](const std::vector>>& title_columns, float extra_size = 0.0f) { const ImGuiStyle& style = ImGui::GetStyle(); std::vector offsets; - offsets.push_back(max_width(title_columns[0].second, title_columns[0].first, extra_size) + 3.0f * style.ItemSpacing.x); + // ORCA increase spacing for more readable format. Using direct number requires much less code change in here. GetTextLineHeight for additional spacing for icon_size + offsets.push_back(max_width(title_columns[0].second, title_columns[0].first, extra_size) + 12.f * m_scale + ImGui::GetTextLineHeight()); for (size_t i = 1; i < title_columns.size() - 1; i++) - offsets.push_back(offsets.back() + max_width(title_columns[i].second, title_columns[i].first) + style.ItemSpacing.x); + offsets.push_back(offsets.back() + max_width(title_columns[i].second, title_columns[i].first) + 12.f * m_scale); // ORCA increase spacing for more readable format. Using direct number requires much less code change in here if (title_columns.back().first == _u8L("Display")) { - const auto preferred_offset = ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x - ImGui::GetFrameHeight() / 2 - 2 * window_padding - ImGui::GetStyle().ScrollbarSize; + //const auto preferred_offset = ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x - ImGui::GetFrameHeight() / 2 - 2 * window_padding - ImGui::GetStyle().ScrollbarSize; + const auto preferred_offset = ImGui::GetWindowWidth() - (16.f - 6.f) * m_scale - ImGui::GetFrameHeight() / 2 - 2 * window_padding - (ImGui::GetScrollMaxY() > 0.0f ? ImGui::GetStyle().ScrollbarSize : 0); if (preferred_offset > offsets.back()) { offsets.back() = preferred_offset; } @@ -4553,7 +4564,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv for (size_t i = 1; i < title_columns.size(); i++) { ret.push_back(std::max(offsets[i - 1], i * average_col_width)); } - return ret; }; @@ -4639,30 +4649,39 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv //BBS display Color Scheme ImGui::Dummy({ window_padding, window_padding }); ImGui::Dummy({ window_padding, window_padding }); - ImGui::SameLine(); + ImGui::SameLine(window_padding * 2); // ORCA Ignores item spacing to get perfect window margins since since this part uses dummies for window padding std::wstring btn_name; if (m_fold) btn_name = ImGui::UnfoldButtonIcon; else btn_name = ImGui::FoldButtonIcon; ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.0f, 0.59f, 0.53f, 1.00f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.0f, 0.59f, 0.53f, 0.78f)); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 0.0f)); - //ImGui::PushItemWidth( - float button_width = 34.0f; - if (ImGui::Button(into_u8(btn_name).c_str(), ImVec2(button_width, 0))) { + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f)); + float calc_padding = (ImGui::GetFrameHeight() - 16 * m_scale) / 2; // ORCA calculated padding for 16x16 icon + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(calc_padding, calc_padding)); // ORCA Center icon with frame padding + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f * m_scale); // ORCA Match button style with combo box + + float button_width = 16 * m_scale + calc_padding * 2; // ORCA match buttons height with combo box + if (ImGui::Button(into_u8(btn_name).c_str(), ImVec2(button_width, button_width))) { m_fold = !m_fold; } - ImGui::PopStyleColor(3); - ImGui::PopStyleVar(1); + ImGui::SameLine(); - imgui.bold_text(_u8L("Color Scheme")); + const wchar_t gCodeToggle = ImGui::gCodeButtonIcon; + if (ImGui::Button(into_u8(gCodeToggle).c_str(), ImVec2(button_width, button_width))) { + wxGetApp().toggle_show_gcode_window(); + wxGetApp().plater()->get_current_canvas3D()->post_event(SimpleEvent(wxEVT_PAINT)); + } + ImGui::PopStyleColor(3); + ImGui::PopStyleVar(2); + + //imgui.bold_text(_u8L("Color Scheme")); push_combo_style(); ImGui::SameLine(); const char* view_type_value = view_type_items_str[m_view_type_sel].c_str(); - ImGuiComboFlags flags = 0; + ImGuiComboFlags flags = ImGuiComboFlags_HeightLargest; // ORCA allow to fit all items to prevent scrolling on reaching last elements if (ImGui::BBLBeginCombo("", view_type_value, flags)) { ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.0f); for (int i = 0; i < view_type_items_str.size(); i++) { @@ -4685,11 +4704,15 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv ImGui::EndCombo(); } pop_combo_style(); - ImGui::SameLine(); + ImGui::SameLine(0, window_padding); // ORCA Without (0,window_padding) it adds unnecessary item spacing after combo box ImGui::Dummy({ window_padding, window_padding }); + ImGui::Dummy({ window_padding, window_padding }); // ORCA Matches top-bottom window paddings + float window_width = ImGui::GetWindowWidth(); // ORCA Store window width if (m_fold) { - legend_height = ImGui::GetStyle().WindowPadding.y + ImGui::GetFrameHeight() + window_padding * 2.5; + legend_height = ImGui::GetFrameHeight() + window_padding * 4; // ORCA using 4 instead 2 gives correct toolbar margins while its folded + ImGui::SameLine(window_width); // ORCA use stored window width while folded. This prevents annoying position change on fold/expand button + ImGui::Dummy({ 0, 0 }); imgui.end(); ImGui::PopStyleColor(6); ImGui::PopStyleVar(2); @@ -4813,16 +4836,16 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv labels.push_back(_u8L(ExtrusionEntity::role_to_string(role))); auto [time, percent] = role_time_and_percent(role); times.push_back((time > 0.0f) ? short_time(get_time_dhms(time)) : ""); - if (percent == 0) - ::sprintf(buffer, "0%%"); + if (percent == 0) // ORCA remove % symbol from rows + ::sprintf(buffer, "0"); else - percent > 0.001 ? ::sprintf(buffer, "%.1f%%", percent * 100) : ::sprintf(buffer, "<0.1%%"); + percent > 0.001 ? ::sprintf(buffer, "%.1f", percent * 100) : ::sprintf(buffer, "<0.1"); percents.push_back(buffer); auto [model_used_filament_m, model_used_filament_g] = used_filament_per_role(role); - ::sprintf(buffer, imperial_units ? "%.2f in" : "%.2f m", model_used_filament_m); + ::sprintf(buffer, imperial_units ? "%.2fin" : "%.2fm", model_used_filament_m); // ORCA dont use spacing between value and unit used_filaments_length.push_back(buffer); - ::sprintf(buffer, imperial_units ? "%.2f oz" : "%.2f g", model_used_filament_g); + ::sprintf(buffer, imperial_units ? "%.2foz" : "%.2fg", model_used_filament_g); // ORCA dont use spacing between value and unit used_filaments_weight.push_back(buffer); } } @@ -4831,15 +4854,16 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv { auto [time, percent] = move_time_and_percent(EMoveType::Travel); travel_time = (time > 0.0f) ? short_time(get_time_dhms(time)) : ""; - if (percent == 0) - ::sprintf(buffer, "0%%"); + if (percent == 0) // ORCA remove % symbol from rows + ::sprintf(buffer, "0"); else - percent > 0.001 ? ::sprintf(buffer, "%.1f%%", percent * 100) : ::sprintf(buffer, "<0.1%%"); + percent > 0.001 ? ::sprintf(buffer, "%.1f", percent * 100) : ::sprintf(buffer, "<0.1"); travel_percent = buffer; } - offsets = calculate_offsets({ {_u8L("Line Type"), labels}, {_u8L("Time"), times}, {_u8L("Percent"), percents}, {"", used_filaments_length}, {"", used_filaments_weight}, {_u8L("Display"), {""}}}, icon_size); - append_headers({{_u8L("Line Type"), offsets[0]}, {_u8L("Time"), offsets[1]}, {_u8L("Percent"), offsets[2]}, {_u8L("Used filament"), offsets[3]}, {_u8L("Display"), offsets[5]}}); + // ORCA use % symbol for percentage and use "Usage" for "Used filaments" + offsets = calculate_offsets({ {_u8L("Line Type"), labels}, {_u8L("Time"), times}, {_u8L("%"), percents}, {"", used_filaments_length}, {"", used_filaments_weight}, {_u8L("Display"), {""}}}, icon_size); + append_headers({{_u8L("Line Type"), offsets[0]}, {_u8L("Time"), offsets[1]}, {_u8L("%"), offsets[2]}, {_u8L("Usage"), offsets[3]}, {_u8L("Display"), offsets[5]}}); break; } case EViewType::Height: { imgui.title(_u8L("Layer Height (mm)")); break; } @@ -4870,7 +4894,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv } offsets = calculate_offsets({ { "Extruder NNN", {""}}}, icon_size); - append_headers({ {_u8L("Filament"), offsets[0]}, {_u8L("Used filament"), offsets[1]} }); + append_headers({ {_u8L("Filament"), offsets[0]}, {_u8L("Usage"), offsets[1]} }); break; } case EViewType::ColorPrint: @@ -5699,8 +5723,8 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv void GCodeViewer::push_combo_style() { - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f * m_scale); // ORCA scale rounding + ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * m_scale); // ORCA scale frame size ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8.0,8.0)); ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); diff --git a/src/slic3r/GUI/GCodeViewer.hpp b/src/slic3r/GUI/GCodeViewer.hpp index 18073c6a96..94a7b0bc43 100644 --- a/src/slic3r/GUI/GCodeViewer.hpp +++ b/src/slic3r/GUI/GCodeViewer.hpp @@ -660,6 +660,7 @@ public: std::vector m_lines; public: + float m_scale = 1.0f; GCodeWindow() = default; ~GCodeWindow() { stop_mapping_file(); } void load_gcode(const std::string& filename, const std::vector &lines_ends); diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index d70700b9cf..2229dd9a40 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -71,6 +71,9 @@ static const std::map font_icons = { {ImGui::GapFillIcon , "gap_fill" }, {ImGui::FoldButtonIcon , "im_fold" }, {ImGui::UnfoldButtonIcon , "im_unfold" }, + {ImGui::gCodeButtonIcon , "im_code" }, //ORCA + {ImGui::VisibleIcon , "im_visible" }, //ORCA + {ImGui::HiddenIcon , "im_hidden" }, //ORCA {ImGui::SphereButtonIcon , "toolbar_modifier_sphere" }, // dark mode icon {ImGui::MinimalizeDarkButton , "notification_minimalize_dark" },