mirror of
				https://github.com/SoftFever/OrcaSlicer.git
				synced 2025-10-31 20:51:12 -06:00 
			
		
		
		
	ENH:refine GcodeViewer
1.recalculate layout of filament page 2.add fan speed and temperature page 3.fix that value of time and percent too small to display correctly Change-Id: I5d0cfaea03aa6e9286fe2d7243de7dd413fe7982
This commit is contained in:
		
							parent
							
								
									5761f8c050
								
							
						
					
					
						commit
						e27a1cdd9b
					
				
					 4 changed files with 315 additions and 394 deletions
				
			
		|  | @ -659,7 +659,7 @@ namespace ImGui | |||
|     IMGUI_API void          EndMainMenuBar();                                                   // only call EndMainMenuBar() if BeginMainMenuBar() returns true!
 | ||||
|     IMGUI_API bool          BeginMenu(const char* label, bool enabled = true);                  // create a sub-menu entry. only call EndMenu() if this returns true!
 | ||||
|     IMGUI_API void          EndMenu();                                                          // only call EndMenu() if BeginMenu() returns true!
 | ||||
|     IMGUI_API bool          BBLMenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true);  // return true when activated.
 | ||||
|     IMGUI_API bool          BBLMenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true, float size_arg_y = 0.0f);  // return true when activated.
 | ||||
|     IMGUI_API bool          MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true);  // return true when activated.
 | ||||
|     IMGUI_API bool          MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true);              // return true when activated + toggle (*p_selected) if p_selected != NULL
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -7917,7 +7917,7 @@ void ImGui::EndMenu() | |||
|     EndPopup(); | ||||
| } | ||||
| 
 | ||||
| bool ImGui::BBLMenuItem(const char* label, const char* shortcut, bool selected, bool enabled) | ||||
| bool ImGui::BBLMenuItem(const char* label, const char* shortcut, bool selected, bool enabled, float size_arg_y) | ||||
| { | ||||
|     ImGuiWindow* window = GetCurrentWindow(); | ||||
|     if (window->SkipItems) | ||||
|  | @ -7939,7 +7939,7 @@ bool ImGui::BBLMenuItem(const char* label, const char* shortcut, bool selected, | |||
|         float w = label_size.x; | ||||
|         window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * 0.5f); | ||||
|         PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x * 2.0f, style.ItemSpacing.y)); | ||||
|         pressed = BBLSelectable(label, selected, flags, ImVec2(w, 0.0f)); | ||||
|         pressed = BBLSelectable(label, selected, flags, ImVec2(w, size_arg_y)); | ||||
|         PopStyleVar(); | ||||
|         window->DC.CursorPos.x += IM_FLOOR(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar().
 | ||||
|     } | ||||
|  | @ -7951,7 +7951,7 @@ bool ImGui::BBLMenuItem(const char* label, const char* shortcut, bool selected, | |||
|         float shortcut_w = shortcut ? CalcTextSize(shortcut, NULL).x : 0.0f; | ||||
|         float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame
 | ||||
|         float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); | ||||
|         pressed = BBLSelectable(label, false, flags | ImGuiSelectableFlags_SpanAvailWidth | ImGuiComboFlags_NoArrowButton, ImVec2(min_w, 0.0f)); | ||||
|         pressed = BBLSelectable(label, false, flags | ImGuiSelectableFlags_SpanAvailWidth | ImGuiComboFlags_NoArrowButton, ImVec2(min_w, size_arg_y)); | ||||
|         if (shortcut_w > 0.0f) | ||||
|         { | ||||
|             PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); | ||||
|  |  | |||
|  | @ -346,7 +346,7 @@ inline std::string short_time(const std::string &time) | |||
|     int days = 0; | ||||
|     int hours = 0; | ||||
|     int minutes = 0; | ||||
|     int seconds = 0; | ||||
|     float seconds = 0; | ||||
|     if (time.find('d') != std::string::npos) | ||||
|         ::sscanf(time.c_str(), "%dd %dh %dm %ds", &days, &hours, &minutes, &seconds); | ||||
|     else if (time.find('h') != std::string::npos) | ||||
|  | @ -354,7 +354,7 @@ inline std::string short_time(const std::string &time) | |||
|     else if (time.find('m') != std::string::npos) | ||||
|         ::sscanf(time.c_str(), "%dm %ds", &minutes, &seconds); | ||||
|     else if (time.find('s') != std::string::npos) | ||||
|         ::sscanf(time.c_str(), "%ds", &seconds); | ||||
|         ::sscanf(time.c_str(), "%fs", &seconds); | ||||
|     // Round to full minutes.
 | ||||
|     if (days + hours + minutes > 0 && seconds >= 30) { | ||||
|         if (++minutes == 60) { | ||||
|  | @ -372,9 +372,13 @@ inline std::string short_time(const std::string &time) | |||
|     else if (hours > 0) | ||||
|         ::sprintf(buffer, "%dh%dm", hours, minutes); | ||||
|     else if (minutes > 0) | ||||
|         ::sprintf(buffer, "%dm%ds", minutes, seconds); | ||||
|     else | ||||
|         ::sprintf(buffer, "%ds", seconds); | ||||
|         ::sprintf(buffer, "%dm%ds", minutes, (int)seconds); | ||||
|     else if (seconds > 1) | ||||
|         ::sprintf(buffer, "%ds", (int)seconds); | ||||
|     else if (seconds > 0) | ||||
|         ::sprintf(buffer, "<1s"); | ||||
|     else if (seconds == 0) | ||||
|         ::sprintf(buffer, "0s"); | ||||
|     return buffer; | ||||
| } | ||||
| 
 | ||||
|  | @ -395,8 +399,10 @@ inline std::string get_time_dhms(float time_in_secs) | |||
|         ::sprintf(buffer, "%dh %dm %ds", hours, minutes, (int)time_in_secs); | ||||
|     else if (minutes > 0) | ||||
|         ::sprintf(buffer, "%dm %ds", minutes, (int)time_in_secs); | ||||
|     else | ||||
|     else if (time_in_secs > 1) | ||||
|         ::sprintf(buffer, "%ds", (int)time_in_secs); | ||||
|     else | ||||
|         ::sprintf(buffer, "%fs", time_in_secs); | ||||
| 
 | ||||
|     return buffer; | ||||
| } | ||||
|  |  | |||
|  | @ -363,107 +363,91 @@ void GCodeViewer::SequentialView::Marker::render(int canvas_width, int canvas_he | |||
|     std::string width = ImGui::ColorMarkerStart + _u8L("Width: ") + ImGui::ColorMarkerEnd; | ||||
|     std::string speed = ImGui::ColorMarkerStart + _u8L("Speed: ") + ImGui::ColorMarkerEnd; | ||||
|     std::string flow = ImGui::ColorMarkerStart + _u8L("Flow: ") + ImGui::ColorMarkerEnd; | ||||
|     std::string fanspeed = ImGui::ColorMarkerStart + _u8L("Fan Speed: ") + ImGui::ColorMarkerEnd; | ||||
|     std::string temperature = ImGui::ColorMarkerStart + _u8L("Temperature: ") + ImGui::ColorMarkerEnd; | ||||
|     const float item_size = imgui.calc_text_size("X: 000.000  ").x; | ||||
|     const float item_spacing = imgui.get_item_spacing().x; | ||||
|     const float window_padding = ImGui::GetStyle().WindowPadding.x; | ||||
| 
 | ||||
|     char buf[1024]; | ||||
|     switch (view_type){ | ||||
|     if (view_type == EViewType::Height || | ||||
|         view_type == EViewType::Width || | ||||
|         view_type == EViewType::Feedrate || | ||||
|         view_type == EViewType::VolumetricRate || | ||||
|         view_type == EViewType::FanSpeed || | ||||
|         view_type == EViewType::Temperature) | ||||
|     { | ||||
|         sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); | ||||
|         ImGui::PushItemWidth(item_size); | ||||
|         imgui.text(buf); | ||||
| 
 | ||||
|         ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|         sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); | ||||
|         ImGui::PushItemWidth(item_size); | ||||
|         imgui.text(buf); | ||||
| 
 | ||||
|         sprintf(buf, "%s%.3f", z.c_str(), position.z()); | ||||
|         ImGui::PushItemWidth(item_size); | ||||
|         imgui.text(buf); | ||||
| 
 | ||||
|         switch (view_type) { | ||||
|         case EViewType::Height: { | ||||
|             sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             sprintf(buf, "%s%.3f", z.c_str(), position.z()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.2f", height.c_str(), it->height); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
|              | ||||
|             break; | ||||
|         } | ||||
|         case EViewType::Width: { | ||||
|             sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             sprintf(buf, "%s%.3f", z.c_str(), position.z()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.2f", width.c_str(), it->width); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             break; | ||||
|         } | ||||
|         case EViewType::Feedrate: { | ||||
|             sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); | ||||
|             sprintf(buf, "%s%.0f", speed.c_str(), it->feedrate); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             sprintf(buf, "%s%.3f", z.c_str(), position.z()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.2f", speed.c_str(), it->feedrate); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             break; | ||||
|         } | ||||
|         case EViewType::VolumetricRate: { | ||||
|             sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             sprintf(buf, "%s%.3f", z.c_str(), position.z()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.2f", flow.c_str(), it->volumetric_rate()); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
|              | ||||
|             break; | ||||
|         } | ||||
|         case EViewType::FanSpeed: { | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.0f", fanspeed.c_str(), it->fan_speed); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
|             break; | ||||
|         } | ||||
|         case EViewType::Temperature: { | ||||
|             ImGui::SameLine(window_padding + item_size + item_spacing); | ||||
|             sprintf(buf, "%s%.0f", temperature.c_str(), it->temperature); | ||||
|             ImGui::PushItemWidth(item_size); | ||||
|             imgui.text(buf); | ||||
|             break; | ||||
|         } | ||||
|         default: | ||||
|             sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); | ||||
|             imgui.text(buf); | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     else { | ||||
|         sprintf(buf, "%s%.3f", x.c_str(), position.x() - plate->get_origin().x()); | ||||
|         imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(); | ||||
|             sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); | ||||
|             imgui.text(buf); | ||||
|         ImGui::SameLine(); | ||||
|         sprintf(buf, "%s%.3f", y.c_str(), position.y() - plate->get_origin().y()); | ||||
|         imgui.text(buf); | ||||
| 
 | ||||
|             ImGui::SameLine(); | ||||
|             sprintf(buf, "%s%.3f", z.c_str(), position.z()); | ||||
|             imgui.text(buf); | ||||
|         ImGui::SameLine(); | ||||
|         sprintf(buf, "%s%.3f", z.c_str(), position.z()); | ||||
|         imgui.text(buf); | ||||
|     } | ||||
| 
 | ||||
|     // force extra frame to automatically update window size
 | ||||
|  | @ -901,9 +885,9 @@ void GCodeViewer::update_by_mode(ConfigOptionMode mode) | |||
|     view_type_items.push_back(EViewType::Height); | ||||
|     view_type_items.push_back(EViewType::Width); | ||||
|     view_type_items.push_back(EViewType::VolumetricRate); | ||||
|     view_type_items.push_back(EViewType::FanSpeed); | ||||
|     view_type_items.push_back(EViewType::Temperature); | ||||
|     if (mode == ConfigOptionMode::comDevelop) { | ||||
|         view_type_items.push_back(EViewType::FanSpeed); | ||||
|         view_type_items.push_back(EViewType::Temperature); | ||||
|         view_type_items.push_back(EViewType::Tool); | ||||
|     } | ||||
| 
 | ||||
|  | @ -4072,7 +4056,6 @@ void GCodeViewer::render_shells() | |||
| //    glsafe(::glDepthMask(GL_TRUE));
 | ||||
| } | ||||
| 
 | ||||
| //BBS: GUI refactor: add canvas size
 | ||||
| void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canvas_height, int right_margin) | ||||
| { | ||||
|     if (!m_legend_enabled) | ||||
|  | @ -4111,7 +4094,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|     //BBS
 | ||||
|     /*bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType ||
 | ||||
|         (m_view_type == EViewType::ColorPrint && !time_mode.custom_gcode_times.empty()));*/ | ||||
|     bool show_estimated_time = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || m_view_type == EViewType::ColorPrint); | ||||
|     bool show_estimated = time_mode.time > 0.0f && (m_view_type == EViewType::FeatureType || m_view_type == EViewType::ColorPrint); | ||||
| 
 | ||||
|     const float icon_size = ImGui::GetTextLineHeight() * 0.7; | ||||
|     //BBS GUI refactor
 | ||||
|  | @ -4127,18 +4110,15 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         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, percent_bar_size, &imgui, imperial_units,&window_padding,&draw_list,this](EItemType type, const Color &color, const std::string &label, | ||||
|         bool visible = true, const std::string& time = "", float percent = 0.0f, float max_percent = 0.0f, const std::array<float, 4>& offsets = { 0.0f, 0.0f, 0.0f, 0.0f }, | ||||
|         double used_filament_m = 0.0, double used_filament_g = 0.0, | ||||
|         std::function<void()> callback = nullptr) { | ||||
|         /* BBS GUI refactor */ | ||||
|         /*if (!visible)
 | ||||
|             ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); | ||||
|         */ | ||||
| 
 | ||||
|     auto append_item = [icon_size, &imgui, imperial_units, &window_padding, &draw_list, this]( | ||||
|         EItemType type, | ||||
|         const Color& color, | ||||
|         const std::vector<std::pair<std::string, float>>& columns_offsets, | ||||
|         bool visible = true, | ||||
|         std::function<void()> callback = nullptr) | ||||
|     { | ||||
|         // render icon
 | ||||
|         ImVec2 pos = ImVec2(ImGui::GetCursorScreenPos().x + window_padding * 3, ImGui::GetCursorScreenPos().y); | ||||
|         float dummy_size = icon_size * m_scale; | ||||
| 
 | ||||
|         switch (type) { | ||||
|         default: | ||||
|         case EItemType::Rect: { | ||||
|  | @ -4160,125 +4140,62 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|             draw_list->AddLine({ pos.x + 1, pos.y + icon_size + 2 }, { pos.x + icon_size - 1, pos.y + 4 }, ImGui::GetColorU32({ color[0], color[1], color[2], 1.0f }), 3.0f); | ||||
|             break; | ||||
|         case EItemType::None: | ||||
|             dummy_size = 0; | ||||
|             break; | ||||
|         } | ||||
|         } | ||||
| 
 | ||||
|         // draw text
 | ||||
|         ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(20.0, 6.0 * m_scale)); | ||||
|         ImGui::Dummy({ dummy_size, 0.0 }); | ||||
|         ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(20.0 * m_scale, 6.0 * m_scale)); | ||||
| 
 | ||||
|         // BBS render selectable
 | ||||
|         ImGui::Dummy({ 0.0, 0.0 }); | ||||
|         ImGui::SameLine(); | ||||
|         if (callback != nullptr) { | ||||
|         if (callback) { | ||||
|             ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 1.0f * m_scale); | ||||
|             ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0 * m_scale,0.0)); | ||||
|             ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20.0 * m_scale, 0.0)); | ||||
|             ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(1.00f, 0.68f, 0.26f, 0.0f)); | ||||
|             ImGui::PushStyleColor(ImGuiCol_BorderActive, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); | ||||
|             bool b_menu_item = ImGui::BBLMenuItem(label.c_str()); | ||||
|             float max_height = 0.f; | ||||
|             for (auto column_offset : columns_offsets) { | ||||
|                 if (ImGui::CalcTextSize(column_offset.first.c_str()).y > max_height) | ||||
|                     max_height = ImGui::CalcTextSize(column_offset.first.c_str()).y; | ||||
|             } | ||||
|             bool b_menu_item = ImGui::BBLMenuItem(("###" + columns_offsets[0].first).c_str(), nullptr, false, true, max_height); | ||||
|             ImGui::PopStyleVar(2); | ||||
|             ImGui::PopStyleColor(2); | ||||
|             if (b_menu_item) | ||||
|                 callback(); | ||||
|             else { | ||||
|                 // show tooltip
 | ||||
|                 if (ImGui::IsItemHovered()) { | ||||
|                     /* BBS GUI refactor */ | ||||
|                     /*
 | ||||
|                     if (!visible) | ||||
|                         ImGui::PopStyleVar(); | ||||
|                     */ | ||||
|                     //ImGui::PushStyleColor(ImGuiCol_PopupBg, ImGuiWrapper::COL_WINDOW_BACKGROUND);
 | ||||
|         } | ||||
| 
 | ||||
|                     //ImGui::BeginTooltip();
 | ||||
|                     //imgui.text(visible ? _u8L("Click to hide") : _u8L("Click to show"));
 | ||||
|                     //ImGui::EndTooltip();
 | ||||
|                     //ImGui::PopStyleColor();
 | ||||
|                     /* BBS GUI refactor */ | ||||
|                     /*
 | ||||
|                     if (!visible) | ||||
|                         ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.3333f); | ||||
|                     */ | ||||
|         // BBS render column item
 | ||||
|         { | ||||
|             float dummy_size = type == EItemType::None ? window_padding * 3 : ImGui::GetStyle().ItemSpacing.x + icon_size * m_scale; | ||||
|             ImGui::SameLine(dummy_size); | ||||
|             imgui.text(columns_offsets[0].first); | ||||
| 
 | ||||
|                     // to avoid the tooltip to change size when moving the mouse
 | ||||
| #if ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT | ||||
|                     imgui.set_requires_extra_frame(); | ||||
| #else | ||||
|                     wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); | ||||
|                     wxGetApp().plater()->get_current_canvas3D()->request_extra_frame(); | ||||
| #endif // ENABLE_ENHANCED_IMGUI_SLIDER_FLOAT
 | ||||
|                 } | ||||
|             for (auto i = 1; i < columns_offsets.size(); i++) { | ||||
|                 ImGui::SameLine(columns_offsets[i].second); | ||||
|                 imgui.text(columns_offsets[i].first); | ||||
|             } | ||||
| 
 | ||||
|             //BBS GUI:refactor
 | ||||
|             if (!time.empty()) { | ||||
|                 ImGui::SameLine(offsets[0]); | ||||
|                 imgui.text(time); | ||||
|                 ImGui::SameLine(offsets[1]); | ||||
|                 pos = ImGui::GetCursorScreenPos(); | ||||
|                 const float width = std::max(1.0f, percent_bar_size * percent / max_percent); | ||||
|                 /* BBS GUI refactor do not draw percentage
 | ||||
|                 draw_list->AddRectFilled({ pos.x, pos.y + 2.0f }, { pos.x + width, pos.y + icon_size - 2.0f }, | ||||
|                     ImGui::GetColorU32(ImGuiWrapper::COL_ORANGE_LIGHT)); | ||||
|                 ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.20f, 0.64f, 1.00f, 1.00f)); | ||||
|                 ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.20f, 0.64f, 1.00f, 0.00f)); | ||||
|                 ImGui::BBLProgressBar(1.0 * percent, ImVec2(25.0f, 0.0f)); | ||||
|                 ImGui::PopStyleColor(2); | ||||
|                 ImGui::SameLine();*/ | ||||
|                 char buf[64]; | ||||
|                 ::sprintf(buf, "%.1f%%", 100.0f * percent); | ||||
|                 ImGui::TextUnformatted((percent > 0.0f) ? buf : ""); | ||||
| 
 | ||||
|                 ImGui::SameLine(offsets[3]); | ||||
|             if (callback && m_view_type != EViewType::ColorPrint) { | ||||
|                 ImGui::SameLine(ImGui::GetWindowWidth() - imgui.calc_text_size(_u8L("Display")).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.68f, 0.26f, 1.00f)); | ||||
|                 ImGui::Checkbox("", &visible); | ||||
|                 ImGui::PopStyleColor(1); | ||||
|                 ImGui::PopStyleVar(1); | ||||
|                 ImGui::PopStyleColor(1); | ||||
|             } else { | ||||
|                 if (used_filament_m > 0.0) { | ||||
|                     char buf[64]; | ||||
|                     ImGui::SameLine(offsets[0]); | ||||
|                     ::sprintf(buf, imperial_units ? "%.2f in" : "%.2f m", used_filament_m); | ||||
|                     imgui.text(buf); | ||||
|                     ImGui::SameLine(offsets[1]); | ||||
|                     ::sprintf(buf, "%.2fg", used_filament_g); | ||||
|                     imgui.text(buf); | ||||
|                 } | ||||
|                 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0, 0.0)); | ||||
|                 ImGui::SameLine(offsets[3]); | ||||
|                 ImGui::PushStyleColor(ImGuiCol_CheckMark, ImVec4(0.00f, 0.68f, 0.26f, 1.00f)); | ||||
|                 ImGui::Checkbox("", &visible); | ||||
|                 ImGui::PopStyleColor(1); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|                 ImGui::PopStyleVar(1); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             imgui.text(label); | ||||
|             // BBS refactor do not show used_filament info
 | ||||
|             if (used_filament_m > 0.0) { | ||||
|                 char buf[64]; | ||||
|                 ImGui::SameLine(offsets[0]); | ||||
|                 ::sprintf(buf, imperial_units ? "%.2f in" : "%.2f m", used_filament_m); | ||||
|                 imgui.text(buf); | ||||
|                 ImGui::SameLine(offsets[1]); | ||||
|                 ::sprintf(buf, "%.2f g", used_filament_g); | ||||
|                 imgui.text(buf); | ||||
|             } | ||||
|         } | ||||
|         ImGui::PopStyleVar(1); | ||||
| 
 | ||||
|         /* BBS GUI refactor */ | ||||
|         /*if (!visible)
 | ||||
|             ImGui::PopStyleVar(); | ||||
|         */ | ||||
|     }; | ||||
| 
 | ||||
|     auto append_range = [append_item](const Extrusions::Range& range, unsigned int decimals) { | ||||
|         auto append_range_item = [append_item](int i, float value, unsigned int decimals) { | ||||
|             char buf[1024]; | ||||
|             ::sprintf(buf, "%.*f", decimals, value); | ||||
|             append_item(EItemType::Rect, Range_Colors[i], buf); | ||||
|             append_item(EItemType::Rect, Range_Colors[i], { { buf , 0} }); | ||||
|         }; | ||||
| 
 | ||||
|         if (range.count == 1) | ||||
|  | @ -4296,13 +4213,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     auto append_headers = [&imgui](const std::array<std::string, 5>& texts, const std::array<float, 4>& offsets) { | ||||
|         size_t i = 0; | ||||
|         for (; i < offsets.size(); i++) { | ||||
|             imgui.bold_text(texts[i]); | ||||
|             ImGui::SameLine(offsets[i]); | ||||
|     auto append_headers = [&imgui](const std::vector<std::pair<std::string, float>>& title_offsets) { | ||||
|         for (size_t i = 0; i < title_offsets.size(); i++) { | ||||
|             ImGui::SameLine(title_offsets[i].second); | ||||
|             imgui.bold_text(title_offsets[i].first); | ||||
|         } | ||||
|         imgui.bold_text(texts[i]); | ||||
|         ImGui::Separator(); | ||||
|     }; | ||||
| 
 | ||||
|  | @ -4314,13 +4229,16 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         return ret; | ||||
|     }; | ||||
| 
 | ||||
|     auto calculate_offsets = [max_width](const std::vector<std::string>& labels, const std::vector<std::string>& times, | ||||
|         const std::array<std::string, 4>& titles, float extra_size = 0.0f) { | ||||
|     auto calculate_offsets = [max_width](const std::vector<std::pair<std::string, std::vector<::string>>>& title_columns, float extra_size = 0.0f) { | ||||
|             const ImGuiStyle& style = ImGui::GetStyle(); | ||||
|             std::array<float, 4> ret = { 0.0f, 0.0f, 0.0f, 0.0f }; | ||||
|             ret[0] = max_width(labels, titles[0], extra_size) + 3.0f * style.ItemSpacing.x; | ||||
|             for (size_t i = 1; i < titles.size(); i++) | ||||
|                 ret[i] = ret[i-1] + max_width(times, titles[i]) + style.ItemSpacing.x; | ||||
|             std::vector<float> ret; | ||||
|             ret.push_back(0); | ||||
|             ret.push_back(max_width(title_columns[0].second, title_columns[0].first, extra_size) + 3.0f * style.ItemSpacing.x); | ||||
|             for (size_t i = 1; i < title_columns.size() - 1; i++) | ||||
|                 ret.push_back(ret.back() + max_width(title_columns[i].second, title_columns[i].first) + style.ItemSpacing.x); | ||||
|             if (title_columns.back().first == _u8L("Display")) | ||||
|                 ret.back() = ImGui::GetWindowWidth() - ImGui::CalcTextSize(_u8L("Display").c_str()).x - 2 * style.ItemSpacing.x; | ||||
| 
 | ||||
|             return ret; | ||||
|     }; | ||||
| 
 | ||||
|  | @ -4445,45 +4363,19 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|     } | ||||
| 
 | ||||
|     // data used to properly align items in columns when showing time
 | ||||
|     std::array<float, 4> offsets = { 0.0f, 0.0f, 0.0f, 0.0f }; | ||||
|     std::vector<float> offsets; | ||||
|     std::vector<std::string> labels; | ||||
|     std::vector<std::string> times; | ||||
|     std::vector<float> percents; | ||||
|     std::vector<double> used_filaments_m; | ||||
|     std::vector<double> used_filaments_g; | ||||
|     double total_flushed_filament_m = 0.0; | ||||
|     double total_flushed_filament_g = 0.0; | ||||
| 
 | ||||
|     float max_percent = 0.0f; | ||||
| 
 | ||||
|     if (m_view_type == EViewType::FeatureType) { | ||||
|         // calculate offsets to align time/percentage data
 | ||||
|         for (size_t i = 0; i < m_roles.size(); ++i) { | ||||
|             ExtrusionRole role = m_roles[i]; | ||||
|             if (role < erCount) { | ||||
|                 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)) : ""); | ||||
|                 percents.push_back(percent); | ||||
|                 max_percent = std::max(max_percent, percent); | ||||
|                 auto [used_filament_m, used_filament_g] = used_filament_per_role(role); | ||||
|                 used_filaments_m.push_back(used_filament_m); | ||||
|                 used_filaments_g.push_back(used_filament_g); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         std::string longest_percentage_string; | ||||
|         for (double item : percents) { | ||||
|             char buffer[64]; | ||||
|             ::sprintf(buffer, "%.2f %%", item); | ||||
|             if (::strlen(buffer) > longest_percentage_string.length()) | ||||
|                 longest_percentage_string = buffer; | ||||
|         } | ||||
|         if (_u8L("Percent").length() > longest_percentage_string.length()) | ||||
|             longest_percentage_string = _u8L("Percent"); | ||||
| 
 | ||||
|         offsets = calculate_offsets(labels, times, {_u8L("Line Type"), _u8L("Time"), longest_percentage_string, _u8L("Display")}, icon_size); | ||||
|     } | ||||
|     std::vector<std::string> percents; | ||||
|     std::vector<double> model_used_filaments_m; | ||||
|     std::vector<double> model_used_filaments_g; | ||||
|     double total_model_used_filament_m = 0, total_model_used_filament_g = 0; | ||||
|     std::vector<double> flushed_filaments_m; | ||||
|     std::vector<double> flushed_filaments_g; | ||||
|     double total_flushed_filament_m = 0, total_flushed_filament_g = 0; | ||||
|     const PrintStatistics& ps = wxGetApp().plater()->get_partplate_list().get_current_fff_print().print_statistics(); | ||||
|     double koef = imperial_units ? GizmoObjectManipulation::in_to_mm : 1000.0; | ||||
|     double unit_conver = imperial_units ? GizmoObjectManipulation::oz_to_g : 1; | ||||
| 
 | ||||
|     // get used filament (meters and grams) from used volume in respect to the active extruder
 | ||||
|     auto get_used_filament_from_volume = [this, imperial_units](double volume, int extruder_id) { | ||||
|  | @ -4493,29 +4385,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         return ret; | ||||
|     }; | ||||
| 
 | ||||
|     if (m_view_type == EViewType::Tool) { | ||||
|         // calculate used filaments data
 | ||||
|         for (size_t extruder_id : m_extruder_ids) { | ||||
|             if (m_print_statistics.volumes_per_extruder.find(extruder_id) == m_print_statistics.volumes_per_extruder.end()) | ||||
|                 continue; | ||||
|             double volume = m_print_statistics.volumes_per_extruder.at(extruder_id); | ||||
| 
 | ||||
|             auto [used_filament_m, used_filament_g] = get_used_filament_from_volume(volume, extruder_id); | ||||
|             used_filaments_m.push_back(used_filament_m); | ||||
|             used_filaments_g.push_back(used_filament_g); | ||||
|         } | ||||
| 
 | ||||
|         std::string longest_used_filament_string; | ||||
|         for (double item : used_filaments_m) { | ||||
|             char buffer[64]; | ||||
|             ::sprintf(buffer, imperial_units ? "%.2f in" : "%.2f m", item); | ||||
|             if (::strlen(buffer) > longest_used_filament_string.length()) | ||||
|                 longest_used_filament_string = buffer; | ||||
|         } | ||||
| 
 | ||||
|         offsets = calculate_offsets(labels, times, { "Extruder NNN", longest_used_filament_string }, icon_size); | ||||
|     } | ||||
| 
 | ||||
|     // extrusion paths section -> title
 | ||||
|     ImGui::Dummy({ window_padding, window_padding }); | ||||
|     ImGui::SameLine(); | ||||
|  | @ -4523,7 +4392,27 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|     { | ||||
|     case EViewType::FeatureType: | ||||
|     { | ||||
|         append_headers({_u8L("Line Type"), _u8L("Time"), _u8L("Percent"), "", _u8L("Display")}, offsets); | ||||
|         // calculate offsets to align time/percentage data
 | ||||
|         char buffer[64]; | ||||
|         for (size_t i = 0; i < m_roles.size(); ++i) { | ||||
|             ExtrusionRole role = m_roles[i]; | ||||
|             if (role < erCount) { | ||||
|                 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%%"); | ||||
|                 else | ||||
|                     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);
 | ||||
|                 //model_used_filaments_m.push_back(model_used_filament_m);
 | ||||
|                 //model_used_filaments_g.push_back(model_used_filament_g);
 | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         offsets = calculate_offsets({ {_u8L("Line Type"), labels}, {_u8L("Time"), times}, {_u8L("Percent"), percents}, {_u8L("Display"), {""}}}, icon_size); | ||||
|         append_headers({{_u8L("Line Type"), offsets[0]}, {_u8L("Time"), offsets[1]}, {_u8L("Percent"), offsets[2]}, {_u8L("Display"), offsets[3]}}); | ||||
|         break; | ||||
|     } | ||||
|     case EViewType::Height:         { imgui.title(_u8L("Layer Height (mm)")); break; } | ||||
|  | @ -4531,7 +4420,6 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|     case EViewType::Feedrate: | ||||
|     { | ||||
|         imgui.title(_u8L("Speed (mm/s)")); | ||||
|         offsets = calculate_offsets(labels, times, {_u8L("Speed (mm/s)")}, icon_size); | ||||
|         break; | ||||
|     } | ||||
| 
 | ||||
|  | @ -4540,55 +4428,61 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|     case EViewType::VolumetricRate: { imgui.title(_u8L("Volumetric flow rate (mm³/s)")); break; } | ||||
|     case EViewType::Tool: | ||||
|     { | ||||
|         append_headers({ _u8L("Filament"), _u8L("Used filament") }, offsets); | ||||
|         // calculate used filaments data
 | ||||
|         for (size_t extruder_id : m_extruder_ids) { | ||||
|             if (m_print_statistics.volumes_per_extruder.find(extruder_id) == m_print_statistics.volumes_per_extruder.end()) | ||||
|                 continue; | ||||
|             double volume = m_print_statistics.volumes_per_extruder.at(extruder_id); | ||||
| 
 | ||||
|             auto [model_used_filament_m, model_used_filament_g] = get_used_filament_from_volume(volume, extruder_id); | ||||
|             model_used_filaments_m.push_back(model_used_filament_m); | ||||
|             model_used_filaments_g.push_back(model_used_filament_g); | ||||
|         } | ||||
| 
 | ||||
|         offsets = calculate_offsets({ { "Extruder NNN", {""}}}, icon_size); | ||||
|         append_headers({ {_u8L("Filament"), offsets[0]}, {_u8L("Used filament"), offsets[1]} }); | ||||
|         break; | ||||
|     } | ||||
|     case EViewType::ColorPrint: | ||||
|     { | ||||
|         for (size_t extruder_id : m_extruder_ids) { | ||||
|             if (m_print_statistics.volumes_per_extruder.find(extruder_id) == m_print_statistics.volumes_per_extruder.end()) continue; | ||||
|             double volume                           = m_print_statistics.volumes_per_extruder.at(extruder_id); | ||||
|             auto [used_filament_m, used_filament_g] = get_used_filament_from_volume(volume, extruder_id); | ||||
|             used_filaments_m.push_back(used_filament_m); | ||||
|             used_filaments_g.push_back(used_filament_g); | ||||
|             double volume = m_print_statistics.volumes_per_extruder.at(extruder_id); | ||||
|             auto [model_used_filament_m, model_used_filament_g] = get_used_filament_from_volume(volume, extruder_id); | ||||
|             model_used_filaments_m.push_back(model_used_filament_m); | ||||
|             model_used_filaments_g.push_back(model_used_filament_g); | ||||
|             total_model_used_filament_m += model_used_filament_m; | ||||
|             total_model_used_filament_g += model_used_filament_g; | ||||
|         } | ||||
| 
 | ||||
|         for (size_t extruder_id : m_extruder_ids) { | ||||
|             if (m_print_statistics.flush_per_filament.find(extruder_id) == m_print_statistics.flush_per_filament.end()) continue; | ||||
|             double volume = m_print_statistics.flush_per_filament.at(extruder_id); | ||||
|             auto [flushed_filament_m, flushed_filament_g] = get_used_filament_from_volume(volume, extruder_id); | ||||
|             flushed_filaments_m.push_back(flushed_filament_m); | ||||
|             flushed_filaments_g.push_back(flushed_filament_g); | ||||
|             total_flushed_filament_m += flushed_filament_m; | ||||
|             total_flushed_filament_g += flushed_filament_g; | ||||
|         } | ||||
| 
 | ||||
|         std::string longest_used_filament_string; | ||||
|         std::vector<std::string> total_filaments; | ||||
|         char buffer[64]; | ||||
|         for (double item : used_filaments_m) { | ||||
|             ::sprintf(buffer, imperial_units ? "%.2f in" : "%.2f m", item); | ||||
|             if (::strlen(buffer) > longest_used_filament_string.length()) longest_used_filament_string = buffer; | ||||
|         } | ||||
|         ::sprintf(buffer, imperial_units ? "%.2f in" : "%.2f m", total_flushed_filament_m); | ||||
|         if (::strlen(buffer) > longest_used_filament_string.length()) longest_used_filament_string = buffer; | ||||
|         ::sprintf(buffer, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", ps.total_used_filament / /*1000*/koef, ps.total_weight / unit_conver); | ||||
|         total_filaments.push_back(buffer); | ||||
| 
 | ||||
|         std::string longest_used_filament_g_string; | ||||
|         for (double item : used_filaments_g) { | ||||
|             ::sprintf(buffer, imperial_units ? "%.2f g" : "%.2f g", item); | ||||
|             if (::strlen(buffer) > longest_used_filament_g_string.length()) longest_used_filament_g_string = buffer; | ||||
|         } | ||||
|         ::sprintf(buffer, imperial_units ? "%.2f g" : "%.2f g", total_flushed_filament_g); | ||||
|         if (::strlen(buffer) > longest_used_filament_g_string.length()) longest_used_filament_g_string = buffer; | ||||
| 
 | ||||
|         // BBL XX is placeholder
 | ||||
|         offsets = calculate_offsets(labels, times, {_u8L("Filament N XX"), longest_used_filament_string, longest_used_filament_g_string, _u8L("Display")}, icon_size); | ||||
|         append_headers({ _u8L("Color Print"), _u8L("Comsumption"), "", "", _u8L("Display") }, offsets); | ||||
|         offsets = calculate_offsets({ {_u8L("Filament"), {""}}, {_u8L("Model"), total_filaments}, {_u8L("Flushed"), total_filaments}, {_u8L("Tower"), total_filaments}, {_u8L("Total"), total_filaments} }, icon_size); | ||||
|         if (m_extruder_ids.size() == 1) | ||||
|             append_headers({ {_u8L("Filamet"), offsets[0]}, {_u8L("Model"), offsets[2]}}); | ||||
|         else | ||||
|             append_headers({ {_u8L("Filamet"), offsets[0]}, {_u8L("Model"), offsets[1]}, {_u8L("Flushed"), offsets[2]}, {_u8L(""), offsets[3]}, {_u8L("Total"), offsets[4]}});// to add Tower
 | ||||
|         break; | ||||
|     } | ||||
|     default: { break; } | ||||
|     } | ||||
| 
 | ||||
|     auto append_option_item = [this,append_item](EMoveType type, std::array<float, 4> offsets) { | ||||
|     auto append_option_item = [this, append_item](EMoveType type, std::vector<float> offsets) { | ||||
|         auto append_option_item_with_type = [this, offsets, append_item](EMoveType type, const Color& color, const std::string& label, bool visible) { | ||||
|             append_item(EItemType::Rect, color, label, visible, "", 0.0f, 0.0f, offsets, 0.0, 0.0, [this, type, visible]() { | ||||
|             append_item(EItemType::Rect, color, {{ label , offsets[0] }}, visible, [this, type, visible]() { | ||||
|                 m_buffers[buffer_id(type)].visible = !m_buffers[buffer_id(type)].visible; | ||||
|                 // update buffers' render paths
 | ||||
|                 refresh_render_paths(false, false); | ||||
|  | @ -4623,8 +4517,12 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|             if (role >= erCount) | ||||
|                 continue; | ||||
|             const bool visible = is_visible(role); | ||||
|             append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast<unsigned int>(role)], labels[i], | ||||
|                 visible, times[i], percents[i], max_percent, offsets, used_filaments_m[i], used_filaments_g[i], [this, role, visible]() { | ||||
|             std::vector<std::pair<std::string, float>> columns_offsets; | ||||
|             columns_offsets.push_back({ labels[i], offsets[0] }); | ||||
|             columns_offsets.push_back({ times[i], offsets[1] }); | ||||
|             columns_offsets.push_back({ percents[i], offsets[2] }); | ||||
|             append_item(EItemType::Rect, Extrusion_Role_Colors[static_cast<unsigned int>(role)], columns_offsets, | ||||
|                 visible, [this, role, visible]() { | ||||
|                     m_extrusions.role_visibility_flags = visible ? m_extrusions.role_visibility_flags & ~(1 << role) : m_extrusions.role_visibility_flags | (1 << role); | ||||
|                     // update buffers' render paths
 | ||||
|                     refresh_render_paths(false, false); | ||||
|  | @ -4634,7 +4532,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         } | ||||
| 
 | ||||
|         for(auto item : options_items) { | ||||
|             append_option_item(item,offsets); | ||||
|             append_option_item(item, offsets); | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|  | @ -4645,10 +4543,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         ImGui::Spacing(); | ||||
|         ImGui::Dummy({ window_padding, window_padding }); | ||||
|         ImGui::SameLine(); | ||||
|         append_headers({_u8L("Options"), "", "", "", _u8L("Display")}, offsets); | ||||
|         offsets = calculate_offsets({ { _u8L("Options"), { _u8L("travel")}}, { _u8L("Display"), {""}} }, icon_size); | ||||
|         append_headers({ {_u8L("Options"), offsets[0] }, { _u8L("Display"), offsets[1]} }); | ||||
|         const bool travel_visible = m_buffers[buffer_id(EMoveType::Travel)].visible; | ||||
|         ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 3.0f)); | ||||
|         append_item(EItemType::None, Travel_Colors[0], _u8L("travel"), travel_visible, "", 0.0f, 0.0f, offsets, 0.0, 0.0, [this, travel_visible]() { | ||||
|         append_item(EItemType::None, Travel_Colors[0], { {_u8L("travel"), offsets[0] }}, travel_visible, [this, travel_visible]() { | ||||
|             m_buffers[buffer_id(EMoveType::Travel)].visible = !m_buffers[buffer_id(EMoveType::Travel)].visible; | ||||
|             // update buffers' render paths
 | ||||
|             refresh_render_paths(false, false); | ||||
|  | @ -4664,10 +4563,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|     case EViewType::Tool: | ||||
|     { | ||||
|         // shows only extruders actually used
 | ||||
|         char buf[64]; | ||||
|         size_t i = 0; | ||||
|         for (unsigned char extruder_id : m_extruder_ids) { | ||||
|             append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_id], _u8L("Extruder") + " " + std::to_string(extruder_id + 1), | ||||
|                         true, "", 0.0f, 0.0f, offsets, used_filaments_m[i], used_filaments_g[i]); | ||||
|             ::sprintf(buf, imperial_units ? "%.2f in    %.2f g" : "%.2f m    %.2f g", model_used_filaments_m[i], model_used_filaments_g[i]); | ||||
|             append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_id], { { _u8L("Extruder") + " " + std::to_string(extruder_id + 1), offsets[0]}, {buf, offsets[1]} }); | ||||
|             i++; | ||||
|         } | ||||
|         break; | ||||
|  | @ -4685,119 +4585,130 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         // add scrollable region, if needed
 | ||||
|         if (need_scrollable) | ||||
|             ImGui::BeginChild("color_prints", { -1.0f, child_height }, false); | ||||
|         if (m_extruders_count == 1) { // single extruder use case
 | ||||
|         if (m_extruder_ids.size() == 1) { // single extruder use case
 | ||||
|             const std::vector<std::pair<Color, std::pair<double, double>>> cp_values = color_print_ranges(0, custom_gcode_per_print_z); | ||||
|             const int items_cnt = static_cast<int>(cp_values.size()); | ||||
|             auto extruder_idx = m_extruder_ids[0]; | ||||
|             if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode
 | ||||
|                 append_item(EItemType::Rect, m_tools.m_tool_colors.front(), _u8L("Filament 1")); | ||||
|                     std::vector<std::pair<std::string, float>> columns_offsets; | ||||
|                     columns_offsets.push_back({ std::to_string(extruder_idx + 1), offsets[0] }); | ||||
| 
 | ||||
|                     char buf[64]; | ||||
|                     ::sprintf(buf, imperial_units ? "%.2f in    %.2f g" : "%.2f m    %.2f g", model_used_filaments_m[0] , model_used_filaments_g[0]); | ||||
|                     columns_offsets.push_back({ buf, offsets[2] }); | ||||
| 
 | ||||
|                     append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_idx], columns_offsets); | ||||
|             } | ||||
|             else { | ||||
|                 for (int i = items_cnt; i >= 0; --i) { | ||||
|                     // create label for color change item
 | ||||
|                     if (i == 0) { | ||||
|                         append_item(EItemType::Rect, m_tools.m_tool_colors[0], upto_label(cp_values.front().second.first)); | ||||
|                         append_item(EItemType::Rect, m_tools.m_tool_colors[0], {{ upto_label(cp_values.front().second.first), offsets[1]} }); | ||||
|                         break; | ||||
|                     } | ||||
|                     else if (i == items_cnt) { | ||||
|                         append_item(EItemType::Rect, cp_values[i - 1].first, above_label(cp_values[i - 1].second.second)); | ||||
|                         append_item(EItemType::Rect, cp_values[i - 1].first, { {above_label(cp_values[i - 1].second.second), offsets[1]} }); | ||||
|                         continue; | ||||
|                     } | ||||
|                     append_item(EItemType::Rect, cp_values[i - 1].first, fromto_label(cp_values[i - 1].second.second, cp_values[i].second.first)); | ||||
|                     append_item(EItemType::Rect, cp_values[i - 1].first, { {fromto_label(cp_values[i - 1].second.second, cp_values[i].second.first), offsets[1]} }); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         else { // multi extruder use case
 | ||||
|             // shows only extruders actually used
 | ||||
|             int extruder_idx = 0; | ||||
|             for (unsigned char i : m_extruder_ids) { | ||||
|                 const std::vector<std::pair<Color, std::pair<double, double>>> cp_values = color_print_ranges(i, custom_gcode_per_print_z); | ||||
|             size_t i = 0; | ||||
|             for (auto extruder_idx : m_extruder_ids) { | ||||
|                 const std::vector<std::pair<Color, std::pair<double, double>>> cp_values = color_print_ranges(extruder_idx, custom_gcode_per_print_z); | ||||
|                 const int items_cnt = static_cast<int>(cp_values.size()); | ||||
|                 if (items_cnt == 0) { // There are no color changes, but there are some pause print or custom Gcode
 | ||||
|                     const bool filament_visible = m_tools.m_tool_visibles[i]; | ||||
|                     if (extruder_idx < used_filaments_m.size() && extruder_idx < used_filaments_g.size()) { | ||||
|                         append_item(EItemType::Rect, m_tools.m_tool_colors[i], _u8L("Filament") + " " + std::to_string(i + 1), filament_visible, "", 0.0f, 0.0f, offsets, | ||||
|                                     used_filaments_m[extruder_idx], used_filaments_g[extruder_idx], [this, i]() { | ||||
|                                         m_tools.m_tool_visibles[i] = !m_tools.m_tool_visibles[i]; | ||||
|                                         // update buffers' render paths
 | ||||
|                                         refresh_render_paths(false, false); | ||||
|                                         update_moves_slider(); | ||||
|                                         wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); | ||||
|                                     }); | ||||
|                     const bool filament_visible = m_tools.m_tool_visibles[extruder_idx]; | ||||
|                     if (i < model_used_filaments_m.size() && i < model_used_filaments_g.size()) { | ||||
|                         std::vector<std::pair<std::string, float>> columns_offsets; | ||||
|                         columns_offsets.push_back({ std::to_string(extruder_idx + 1), offsets[0] }); | ||||
| 
 | ||||
|                         char buf[64]; | ||||
|                         ::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", model_used_filaments_m[i], model_used_filaments_g[i]); | ||||
|                         columns_offsets.push_back({ buf, offsets[1]}); | ||||
| 
 | ||||
|                         ::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", flushed_filaments_m[i], flushed_filaments_g[i]); | ||||
|                         columns_offsets.push_back({ buf, offsets[2] }); | ||||
| 
 | ||||
|                         ::sprintf(buf, imperial_units ? "%.2f in\n%.2f g" : "%.2f m\n%.2f g", model_used_filaments_m[i] + flushed_filaments_m[i], model_used_filaments_g[i] + flushed_filaments_g[i]); | ||||
|                         columns_offsets.push_back({ buf, offsets[4] }); | ||||
| 
 | ||||
|                         append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_idx], columns_offsets, filament_visible, [this, extruder_idx]() { | ||||
|                                 m_tools.m_tool_visibles[extruder_idx] = !m_tools.m_tool_visibles[extruder_idx]; | ||||
|                                 // update buffers' render paths
 | ||||
|                                 refresh_render_paths(false, false); | ||||
|                                 update_moves_slider(); | ||||
|                                 wxGetApp().plater()->get_current_canvas3D()->set_as_dirty(); | ||||
|                             }); | ||||
|                     } | ||||
|                 } | ||||
|                 else { | ||||
|                     for (int j = items_cnt; j >= 0; --j) { | ||||
|                         // create label for color change item
 | ||||
|                         std::string label = _u8L("Filament") + " " + std::to_string(i + 1); | ||||
|                         std::string label = _u8L("Filament") + " " + std::to_string(extruder_idx + 1); | ||||
|                         if (j == 0) { | ||||
|                             label += " " + upto_label(cp_values.front().second.first); | ||||
|                             append_item(EItemType::Rect, m_tools.m_tool_colors[i], label); | ||||
|                             append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_idx], { { label, 0 } }); | ||||
|                             break; | ||||
|                         } | ||||
|                         else if (j == items_cnt) { | ||||
|                             label += " " + above_label(cp_values[j - 1].second.second); | ||||
|                             append_item(EItemType::Rect, cp_values[j - 1].first, label); | ||||
|                             append_item(EItemType::Rect, cp_values[j - 1].first, { { label, 0 } }); | ||||
|                             continue; | ||||
|                         } | ||||
| 
 | ||||
|                         label += " " + fromto_label(cp_values[j - 1].second.second, cp_values[j].second.first); | ||||
|                         append_item(EItemType::Rect, cp_values[j - 1].first, label); | ||||
|                         append_item(EItemType::Rect, cp_values[j - 1].first, { { label, 0 } }); | ||||
|                     } | ||||
|                 } | ||||
|                 extruder_idx++; | ||||
|                 i++; | ||||
|             } | ||||
|         } | ||||
|         if (need_scrollable) | ||||
|             ImGui::EndChild(); | ||||
| 
 | ||||
|         for (auto item : options_items) | ||||
|             append_option_item(item,offsets); | ||||
|             append_option_item(item, offsets); | ||||
| 
 | ||||
|         //BBS display filament change times
 | ||||
|         if (m_print_statistics.total_filamentchanges > 0 && ( total_flushed_filament_m > 0 || total_flushed_filament_g > 0)) { | ||||
|             std::string flushed_filament_title_str = _u8L("Flushed filament"); | ||||
|             std::string flushed_filament_str = _u8L("Filament"); | ||||
|             std::string total_flushed_filament_str = _u8L("Total"); | ||||
|             std::string filament_change_str = _u8L("Filament change times"); | ||||
|             ImGui::Dummy(ImVec2(0.0f, ImGui::GetFontSize() * 0.1)); | ||||
|          | ||||
|         if (m_print_statistics.total_filamentchanges > 0 && ( flushed_filaments_m.size() > 0 || flushed_filaments_g.size() > 0)) { | ||||
|             ImGui::Separator(); | ||||
|             std::vector<std::pair<std::string, float>> columns_offsets; | ||||
|             char buf[64]; | ||||
|             columns_offsets.push_back({ _u8L("Total"), offsets[0] }); | ||||
| 
 | ||||
|             ::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", total_model_used_filament_m, total_model_used_filament_g); | ||||
|             columns_offsets.push_back({ buf, offsets[1] }); | ||||
| 
 | ||||
|             ::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", total_flushed_filament_m, total_flushed_filament_g); | ||||
|             columns_offsets.push_back({ buf, offsets[2] }); | ||||
| 
 | ||||
|             bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; | ||||
|             ::sprintf(buf, imperial_units ? "%.2f in\n%.2f oz" : "%.2f m\n%.2f g", ps.total_used_filament / /*1000*/koef, ps.total_weight / unit_conver); | ||||
|             columns_offsets.push_back({ buf, offsets[4] }); | ||||
| 
 | ||||
|             append_item(EItemType::None, m_tools.m_tool_colors[0], columns_offsets); | ||||
| 
 | ||||
|             //BBS display filament change times
 | ||||
|             ImGui::Dummy({window_padding, window_padding}); | ||||
|             ImGui::SameLine(); | ||||
|             imgui.text(_u8L("Filament change times") + ":"); | ||||
|             ImGui::SameLine(); | ||||
|             ::sprintf(buf, "%d", m_print_statistics.total_filamentchanges); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             //BBS display cost
 | ||||
|             ImGui::Dummy({ window_padding, window_padding }); | ||||
|             ImGui::SameLine(); | ||||
|             imgui.title(flushed_filament_title_str); | ||||
|             //BBS: calculate total flushed filaments data
 | ||||
|             float max_len = 10.0f + ImGui::GetStyle().ItemSpacing.x; | ||||
|             max_len += ImGui::CalcTextSize(filament_change_str.c_str()).x; | ||||
|             for (size_t extruder_id : m_extruder_ids) { | ||||
|                 if (m_print_statistics.flush_per_filament.find(extruder_id) == m_print_statistics.flush_per_filament.end()) continue; | ||||
|                 double volume = m_print_statistics.flush_per_filament.at(extruder_id); | ||||
|                 auto [used_filament_m, used_filament_g] = get_used_filament_from_volume(volume, extruder_id); | ||||
|                 append_item(EItemType::Rect, m_tools.m_tool_colors[extruder_id], flushed_filament_str + " " + std::to_string(extruder_id + 1), true, "", 0.0f, 0.0f, offsets, | ||||
|                     used_filament_m, used_filament_g); | ||||
|             } | ||||
| 
 | ||||
|             //BBS: display total flushed filament
 | ||||
|             { | ||||
|                 ImGui::Dummy({window_padding, window_padding}); | ||||
|                 ImGui::SameLine(); | ||||
|                 imgui.text(total_flushed_filament_str + ":"); | ||||
|                 ImGui::SameLine(offsets[0]); | ||||
|                 char buf[64]; | ||||
|                 ::sprintf(buf, "%.2f m", total_flushed_filament_m); | ||||
|                 imgui.text(buf); | ||||
|                 ImGui::SameLine(offsets[1]); | ||||
|                 ::sprintf(buf, "%.2f g", total_flushed_filament_g); | ||||
|                 imgui.text(buf); | ||||
|             } | ||||
|             //BBS display filament change times
 | ||||
|             { | ||||
|                 ImGui::Dummy({window_padding, window_padding}); | ||||
|                 ImGui::SameLine(); | ||||
|                 imgui.text(filament_change_str + ":"); | ||||
|                 ImGui::SameLine(max_len); | ||||
|                 char temp_buf[64]; | ||||
|                 ::sprintf(temp_buf, "%d", m_print_statistics.total_filamentchanges); | ||||
|                 imgui.text(temp_buf); | ||||
|             } | ||||
|             imgui.text(_u8L("Cost")+":"); | ||||
|             ImGui::SameLine(); | ||||
|             ::sprintf(buf, "%.2f", ps.total_cost); | ||||
|             imgui.text(buf); | ||||
|         } | ||||
| 
 | ||||
|         break; | ||||
|     } | ||||
|     default: { break; } | ||||
|  | @ -5011,10 +4922,12 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         default: { | ||||
|             // title
 | ||||
|             ImGui::Spacing(); | ||||
|             ImGui::Dummy({ window_padding, window_padding }); | ||||
|             ImGui::SameLine(); | ||||
|             imgui.title(_u8L("Wipe")); | ||||
| 
 | ||||
|             // items
 | ||||
|             append_item(EItemType::Line, Wipe_Color, _u8L("Wipe")); | ||||
|             append_item(EItemType::Line, Wipe_Color, { {_u8L("Wipe"), 0} }); | ||||
| 
 | ||||
|             break; | ||||
|         } | ||||
|  | @ -5036,11 +4949,11 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|             available(EMoveType::Seam); | ||||
|     }; | ||||
| 
 | ||||
|     auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) { | ||||
|         const TBuffer& buffer = m_buffers[buffer_id(move_type)]; | ||||
|         if (buffer.visible && buffer.has_data()) | ||||
|             append_item(EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text); | ||||
|     }; | ||||
|     //auto add_option = [this, append_item](EMoveType move_type, EOptionsColors color, const std::string& text) {
 | ||||
|     //    const TBuffer& buffer = m_buffers[buffer_id(move_type)];
 | ||||
|     //    if (buffer.visible && buffer.has_data())
 | ||||
|     //        append_item(EItemType::Circle, Options_Colors[static_cast<unsigned int>(color)], text);
 | ||||
|     //};
 | ||||
| 
 | ||||
|     /* BBS GUI refactor */ | ||||
|     // options section
 | ||||
|  | @ -5120,9 +5033,9 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|     } | ||||
| 
 | ||||
|     // total estimated printing time section
 | ||||
|     if (show_estimated_time) { | ||||
|     if (show_estimated) { | ||||
|         ImGui::Spacing(); | ||||
|         std::string time_title = _u8L("Total Estimation"); | ||||
|         std::string time_title = m_view_type == EViewType::FeatureType ? _u8L("Total Estimation") : _u8L("Time Estimation"); | ||||
|         auto can_show_mode_button = [this](PrintEstimatedStatistics::ETimeMode mode) { | ||||
|             bool show = false; | ||||
|             if (m_print_statistics.modes.size() > 1 && m_print_statistics.modes[static_cast<size_t>(mode)].roles_times.size() > 0) { | ||||
|  | @ -5153,51 +5066,52 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         std::string cost_str = _u8L("Cost"); | ||||
|         std::string prepare_str = _u8L("Prepare time"); | ||||
|         std::string print_str = _u8L("Model printing time"); | ||||
|         std::string total_str = _u8L("Total"); | ||||
|         std::string total_str = _u8L("Total time"); | ||||
| 
 | ||||
|         float max_len = 10.0f + ImGui::GetStyle().ItemSpacing.x; | ||||
|         float max_len = window_padding + 2 * ImGui::GetStyle().ItemSpacing.x; | ||||
|         if (time_mode.layers_times.empty()) | ||||
|             max_len += ImGui::CalcTextSize(total_str.c_str()).x; | ||||
|         else { | ||||
|             max_len += std::max(ImGui::CalcTextSize(cost_str.c_str()).x, | ||||
|                                 std::max(ImGui::CalcTextSize(print_str.c_str()).x, | ||||
|                                          std::max(std::max(ImGui::CalcTextSize(prepare_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x), | ||||
|                                                   ImGui::CalcTextSize(filament_str.c_str()).x))); | ||||
|             if (m_view_type == EViewType::FeatureType) | ||||
|                 max_len += std::max(ImGui::CalcTextSize(cost_str.c_str()).x, | ||||
|                     std::max(ImGui::CalcTextSize(print_str.c_str()).x, | ||||
|                         std::max(std::max(ImGui::CalcTextSize(prepare_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x), | ||||
|                             ImGui::CalcTextSize(filament_str.c_str()).x))); | ||||
|             else | ||||
|                 max_len += std::max(ImGui::CalcTextSize(print_str.c_str()).x, | ||||
|                     (std::max(ImGui::CalcTextSize(prepare_str.c_str()).x, ImGui::CalcTextSize(total_str.c_str()).x))); | ||||
|         } | ||||
| 
 | ||||
|         //BBS display filament cost
 | ||||
|         ImGui::Dummy({ window_padding, window_padding }); | ||||
|         ImGui::SameLine(); | ||||
|         imgui.text(filament_str + ":"); | ||||
|         ImGui::SameLine(max_len); | ||||
|         if (m_view_type == EViewType::FeatureType) { | ||||
|             //BBS display filament cost
 | ||||
|             ImGui::Dummy({ window_padding, window_padding }); | ||||
|             ImGui::SameLine(); | ||||
|             imgui.text(filament_str + ":"); | ||||
|             ImGui::SameLine(max_len); | ||||
| 
 | ||||
|         //BBS: use current plater's print statistics
 | ||||
|         const PrintStatistics& ps = wxGetApp().plater()->get_partplate_list().get_current_fff_print().print_statistics(); | ||||
|         bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; | ||||
|         char buf[64]; | ||||
|         double koef = imperial_units ? GizmoObjectManipulation::in_to_mm : 1000.0; | ||||
|         ::sprintf(buf, imperial_units ? "%.2f in" : "%.2f m", ps.total_used_filament / /*1000*/koef); | ||||
|         imgui.text(buf); | ||||
|         ImGui::SameLine(); | ||||
|         double unit_conver = imperial_units ? GizmoObjectManipulation::oz_to_g : 1; | ||||
|         ::sprintf(buf, imperial_units ?"  %.2f oz":"  %.2f g", ps.total_weight / unit_conver); | ||||
|         imgui.text(buf); | ||||
|             //BBS: use current plater's print statistics
 | ||||
|             bool imperial_units = wxGetApp().app_config->get("use_inches") == "1"; | ||||
|             char buf[64]; | ||||
|             ::sprintf(buf, imperial_units ? "%.2f in" : "%.2f m", ps.total_used_filament / /*1000*/koef); | ||||
|             imgui.text(buf); | ||||
|             ImGui::SameLine(); | ||||
|             ::sprintf(buf, imperial_units ? "  %.2f oz" : "  %.2f g", ps.total_weight / unit_conver); | ||||
|             imgui.text(buf); | ||||
| 
 | ||||
|             //BBS: display cost of filaments
 | ||||
|             ImGui::Dummy({ window_padding, window_padding }); | ||||
|             ImGui::SameLine(); | ||||
|             imgui.text(cost_str + ":"); | ||||
|             ImGui::SameLine(max_len); | ||||
| 
 | ||||
|             ::sprintf(buf, "%.2f", ps.total_cost); | ||||
|             imgui.text(buf); | ||||
|         } | ||||
| 
 | ||||
|         auto role_time = [time_mode](ExtrusionRole role) { | ||||
|             auto it = std::find_if(time_mode.roles_times.begin(), time_mode.roles_times.end(), [role](const std::pair<ExtrusionRole, float>& item) { return role == item.first; }); | ||||
|             return (it != time_mode.roles_times.end()) ? it->second : 0.0f; | ||||
|         }; | ||||
| 
 | ||||
|         //BBS: display cost of filaments
 | ||||
|         ImGui::Dummy({window_padding, window_padding}); | ||||
|         ImGui::SameLine(); | ||||
|         imgui.text(cost_str + ":"); | ||||
|         ImGui::SameLine(max_len); | ||||
| 
 | ||||
|         //char   buf[64];
 | ||||
|         ::sprintf(buf, "%.2f", ps.total_cost); | ||||
|         imgui.text(buf); | ||||
| 
 | ||||
|         //BBS: start gcode is prepeare time
 | ||||
|         if (role_time(erCustom) != 0.0f) { | ||||
|             ImGui::Dummy({ window_padding, window_padding }); | ||||
|  | @ -5243,6 +5157,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv | |||
|         default : { assert(false); break; } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     legend_height = ImGui::GetCurrentWindow()->Size.y; | ||||
|     ImGui::Dummy({ window_padding, window_padding}); | ||||
|     imgui.end(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 liz.li
						liz.li