Add a gui option to have plater tabs in the top tab bar

also add icons to tabs
This commit is contained in:
remi durand 2021-03-27 23:52:58 +01:00
parent ff57ca240f
commit 7580de9da5
17 changed files with 731 additions and 150 deletions

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 16 16"
enable-background="new 0 0 16 16"
xml:space="preserve"
sodipodi:docname="printer_settings.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata22"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs20"><pattern
y="0"
x="0"
height="6"
width="6"
patternUnits="userSpaceOnUse"
id="EMFhbasepattern" /></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1517"
inkscape:window-height="980"
id="namedview18"
showgrid="false"
inkscape:zoom="20.85965"
inkscape:cx="3.0277352"
inkscape:cy="7.4276381"
inkscape:window-x="573"
inkscape:window-y="270"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" />
<g
id="machine_x2B_cog"
transform="matrix(0.83360586,0,0,0.83360586,-0.58820988,-0.64530384)"><path
style="fill:#808080;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="M 13.77,6.39 C 13.64,5.92 13.45,5.47 13.22,5.06 l 0.43,-1.3 -1.41,-1.41 -1.3,0.43 C 10.52,2.55 10.08,2.36 9.61,2.23 L 9,1 H 7 L 6.39,2.23 C 5.92,2.36 5.47,2.54 5.06,2.78 L 3.76,2.35 2.34,3.76 2.77,5.06 C 2.54,5.47 2.36,5.92 2.23,6.39 L 1,7 v 2 l 1.23,0.61 c 0.13,0.47 0.32,0.92 0.55,1.33 l -0.43,1.3 1.41,1.41 1.3,-0.43 c 0.42,0.23 0.86,0.42 1.33,0.55 L 7,15 h 2 l 0.61,-1.23 c 0.47,-0.13 0.92,-0.32 1.33,-0.55 l 1.3,0.43 1.41,-1.41 -0.43,-1.3 c 0.23,-0.42 0.42,-0.86 0.55,-1.33 L 15,9 V 7 Z M 8,13 C 5.24,13 3,10.76 3,8 3,5.24 5.24,3 8,3 c 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z"
id="path2" /><path
style="fill:#2172eb"
inkscape:connector-curvature="0"
d="M 11.3,7.08 C 11.23,6.81 11.12,6.56 10.99,6.32 L 11.24,5.58 10.43,4.77 9.68,5.01 C 9.45,4.88 9.19,4.78 8.92,4.7 L 8.57,4 H 7.43 L 7.08,4.7 C 6.81,4.78 6.55,4.88 6.32,5.01 L 5.58,4.77 4.77,5.58 5.02,6.32 C 4.88,6.55 4.78,6.81 4.7,7.08 L 4,7.43 v 1.14 l 0.7,0.35 c 0.07,0.27 0.18,0.52 0.31,0.76 l -0.25,0.74 0.81,0.81 0.74,-0.25 c 0.24,0.13 0.49,0.24 0.76,0.31 L 7.43,12 h 1.14 l 0.35,-0.7 c 0.27,-0.07 0.52,-0.18 0.76,-0.31 l 0.74,0.25 0.81,-0.81 -0.25,-0.74 C 11.11,9.45 11.22,9.2 11.29,8.93 L 12,8.57 V 7.43 Z M 8,10.86 C 6.42,10.86 5.14,9.58 5.14,8 5.14,6.42 6.42,5.14 8,5.14 c 1.58,0 2.86,1.28 2.86,2.86 0,1.58 -1.28,2.86 -2.86,2.86 z"
id="path4" /></g><g
id="printer"
transform="matrix(0.791121,0,0,0.791121,3.133185,3.133185)">
<rect
x="1"
y="1"
width="1"
height="14"
id="rect2"
style="fill:#808080" />
<rect
x="14"
y="1"
width="1"
height="14"
id="rect4"
style="fill:#808080" />
<rect
x="7.5"
y="-1.5"
transform="rotate(90,8,5.5)"
width="1"
height="14"
id="rect6"
style="fill:#808080" />
<rect
x="7.5"
y="-5.5"
transform="rotate(90,8,1.5)"
width="1"
height="14"
id="rect8"
style="fill:#808080" />
<rect
x="7"
y="7"
transform="rotate(90,8,14)"
width="2"
height="14"
id="rect10"
style="fill:#808080" />
<rect
x="8.3571119"
y="4"
width="4"
height="4"
id="rect12"
style="fill:#2172eb" />
<polygon
points="5,9 4,8 6,8 "
id="polygon14"
transform="translate(5.2852025)"
style="fill:#2172eb" />
</g></svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 23.0.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 16 16"
enable-background="new 0 0 16 16"
xml:space="preserve"
sodipodi:docname="spool_settings.svg"
inkscape:version="0.92.4 (5da689c313, 2019-01-14)"><metadata
id="metadata22"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs20" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1170"
inkscape:window-height="825"
id="namedview18"
showgrid="false"
inkscape:zoom="10.429825"
inkscape:cx="-2.7452046"
inkscape:cy="18.585777"
inkscape:window-x="626"
inkscape:window-y="283"
inkscape:window-maximized="0"
inkscape:current-layer="Layer_1" />
<g
id="machine_x2B_cog"
transform="matrix(0.83360586,0,0,0.83360586,-0.53099627,-0.47101916)"><path
style="fill:#808080;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="M 13.77,6.39 C 13.64,5.92 13.45,5.47 13.22,5.06 l 0.43,-1.3 -1.41,-1.41 -1.3,0.43 C 10.52,2.55 10.08,2.36 9.61,2.23 L 9,1 H 7 L 6.39,2.23 C 5.92,2.36 5.47,2.54 5.06,2.78 L 3.76,2.35 2.34,3.76 2.77,5.06 C 2.54,5.47 2.36,5.92 2.23,6.39 L 1,7 v 2 l 1.23,0.61 c 0.13,0.47 0.32,0.92 0.55,1.33 l -0.43,1.3 1.41,1.41 1.3,-0.43 c 0.42,0.23 0.86,0.42 1.33,0.55 L 7,15 h 2 l 0.61,-1.23 c 0.47,-0.13 0.92,-0.32 1.33,-0.55 l 1.3,0.43 1.41,-1.41 -0.43,-1.3 c 0.23,-0.42 0.42,-0.86 0.55,-1.33 L 15,9 V 7 Z M 8,13 C 5.24,13 3,10.76 3,8 3,5.24 5.24,3 8,3 c 2.76,0 5,2.24 5,5 0,2.76 -2.24,5 -5,5 z"
id="path2" /><path
style="fill:#2172eb"
inkscape:connector-curvature="0"
d="M 11.3,7.08 C 11.23,6.81 11.12,6.56 10.99,6.32 L 11.24,5.58 10.43,4.77 9.68,5.01 C 9.45,4.88 9.19,4.78 8.92,4.7 L 8.57,4 H 7.43 L 7.08,4.7 C 6.81,4.78 6.55,4.88 6.32,5.01 L 5.58,4.77 4.77,5.58 5.02,6.32 C 4.88,6.55 4.78,6.81 4.7,7.08 L 4,7.43 v 1.14 l 0.7,0.35 c 0.07,0.27 0.18,0.52 0.31,0.76 l -0.25,0.74 0.81,0.81 0.74,-0.25 c 0.24,0.13 0.49,0.24 0.76,0.31 L 7.43,12 h 1.14 l 0.35,-0.7 c 0.27,-0.07 0.52,-0.18 0.76,-0.31 l 0.74,0.25 0.81,-0.81 -0.25,-0.74 C 11.11,9.45 11.22,9.2 11.29,8.93 L 12,8.57 V 7.43 Z M 8,10.86 C 6.42,10.86 5.14,9.58 5.14,8 5.14,6.42 6.42,5.14 8,5.14 c 1.58,0 2.86,1.28 2.86,2.86 0,1.58 -1.28,2.86 -2.86,2.86 z"
id="path4" /></g><g
id="spool"
transform="matrix(0.7671546,0,0,0.7671546,3.4927042,3.4959972)">
<line
stroke-miterlimit="10"
x1="2"
y1="2"
x2="2"
y2="14"
id="line2"
style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10" />
<line
stroke-miterlimit="10"
x1="14"
y1="2"
x2="14"
y2="14"
id="line4"
style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:round;stroke-miterlimit:10" />
<line
stroke-miterlimit="10"
x1="4"
y1="3"
x2="4"
y2="13"
id="line6"
style="fill:none;stroke:#2172eb;stroke-width:1.5;stroke-linecap:round;stroke-miterlimit:10" />
<line
stroke-miterlimit="10"
x1="6"
y1="3"
x2="6"
y2="13"
id="line8"
style="fill:none;stroke:#2172eb;stroke-width:1.5;stroke-linecap:round;stroke-miterlimit:10" />
<line
stroke-miterlimit="10"
x1="8"
y1="3"
x2="8"
y2="13"
id="line10"
style="fill:none;stroke:#2172eb;stroke-width:1.5;stroke-linecap:round;stroke-miterlimit:10" />
<line
stroke-miterlimit="10"
x1="10"
y1="3"
x2="10"
y2="13"
id="line12"
style="fill:none;stroke:#2172eb;stroke-width:1.5;stroke-linecap:round;stroke-miterlimit:10" />
<line
stroke-miterlimit="10"
x1="12"
y1="3"
x2="12"
y2="13"
id="line14"
style="fill:none;stroke:#2172eb;stroke-width:1.5;stroke-linecap:round;stroke-miterlimit:10" />
</g></svg>

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -63,6 +63,9 @@ void AppConfig::set_defaults()
if (get("freecad_path").empty()) if (get("freecad_path").empty())
set("freecad_path", "."); set("freecad_path", ".");
if (get("tab_icon_size").empty())
set("tab_icon_size", "32");
if (get("color_very_dark").empty()) if (get("color_very_dark").empty())
set("color_very_dark", "0047c7"); set("color_very_dark", "0047c7");

View File

@ -112,16 +112,18 @@ void Field::PostInitialize()
BUILD(); BUILD();
// For the mode, when settings are in non-modal dialog, neither dialog nor tabpanel doesn't receive wxEVT_KEY_UP event, when some field is selected. // For the mode, when settings are in non-modal dialog, neither dialog nor tabpanel doesn't receive wxEVT_KEY_UP event, when some field is selected.
// So, like a workaround check wxEVT_KEY_UP event for the Filed and switch between tabs if Ctrl+(1-4) was pressed // So, like a workaround check wxEVT_KEY_UP event for the Filed and switch between tabs if Ctrl+(1-6) was pressed
if (getWindow()) if (getWindow())
getWindow()->Bind(wxEVT_KEY_UP, [](wxKeyEvent& evt) { getWindow()->Bind(wxEVT_KEY_UP, [](wxKeyEvent& evt) {
if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) { if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) {
int tab_id = -1; MainFrame::ETabType tab_id = MainFrame::ETabType::Any;
switch (evt.GetKeyCode()) { switch (evt.GetKeyCode()) {
case '1': { tab_id = 0; break; } case '1': { tab_id = MainFrame::ETabType::Plater3D; break; }
case '2': { tab_id = 1; break; } case '2': { tab_id = MainFrame::ETabType::PlaterPreview; break; }
case '3': { tab_id = 2; break; } case '3': { tab_id = MainFrame::ETabType::PlaterGcode; break; }
case '4': { tab_id = 3; break; } case '4': { tab_id = MainFrame::ETabType::PrintSettings; break; }
case '5': { tab_id = MainFrame::ETabType::FilamentSettings; break; }
case '6': { tab_id = MainFrame::ETabType::PrintSettings; break; }
#ifdef __APPLE__ #ifdef __APPLE__
case 'f': case 'f':
#else /* __APPLE__ */ #else /* __APPLE__ */
@ -130,9 +132,11 @@ void Field::PostInitialize()
case 'F': { wxGetApp().plater()->search(false); break; } case 'F': { wxGetApp().plater()->search(false); break; }
default: break; default: break;
} }
if (tab_id >= 0) if (tab_id < MainFrame::ETabType::Any)
wxGetApp().mainframe->select_tab(tab_id); wxGetApp().mainframe->select_tab(tab_id);
if (tab_id > 0) if (wxGetApp().mainframe->get_layout() == MainFrame::ESettingsLayout::Tabs
|| wxGetApp().mainframe->get_layout() == MainFrame::ESettingsLayout::Old
|| tab_id >= MainFrame::ETabType::PrintSettings)
// tab panel should be focused for correct navigation between tabs // tab panel should be focused for correct navigation between tabs
wxGetApp().tab_panel()->SetFocus(); wxGetApp().tab_panel()->SetFocus();
} }

View File

@ -1292,6 +1292,12 @@ void GLCanvas3D::set_as_dirty()
m_dirty = true; m_dirty = true;
} }
void GLCanvas3D::set_items_show(bool show_objects, bool show_gcode)
{
m_show_objects = show_objects;
m_show_gcode = show_gcode;
}
unsigned int GLCanvas3D::get_volumes_count() const unsigned int GLCanvas3D::get_volumes_count() const
{ {
return (unsigned int)m_volumes.volumes.size(); return (unsigned int)m_volumes.volumes.size();
@ -1661,9 +1667,9 @@ void GLCanvas3D::render()
// draw scene // draw scene
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
_render_background(); _render_background();
if(m_show_objects)
_render_objects(); _render_objects();
if (!m_main_toolbar.is_enabled()) if (m_show_gcode && !m_main_toolbar.is_enabled())
_render_gcode(); _render_gcode();
_render_sla_slices(); _render_sla_slices();
_render_selection(); _render_selection();
@ -3867,9 +3873,9 @@ void GLCanvas3D::msw_rescale()
void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar() void GLCanvas3D::update_tooltip_for_settings_item_in_main_toolbar()
{ {
std::string new_tooltip = _u8L("Switch to Settings") + std::string new_tooltip = _u8L("Switch to Settings") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Print Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "5] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ; "\n" + "[" + GUI::shortkey_ctrl_prefix() + "6] - " + _u8L("Printer Settings Tab") ;
m_main_toolbar.set_tooltip(get_main_toolbar_item_id("settings"), new_tooltip); m_main_toolbar.set_tooltip(get_main_toolbar_item_id("settings"), new_tooltip);
} }
@ -4607,14 +4613,14 @@ bool GLCanvas3D::_init_main_toolbar()
item.name = "settings"; item.name = "settings";
item.icon_filename = "settings.svg"; item.icon_filename = "settings.svg";
item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") + item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Print Settings Tab") +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "3] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "5] - " + (m_process->current_printer_technology() == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab") ; "\n" + "[" + GUI::shortkey_ctrl_prefix() + "6] - " + _u8L("Printer Settings Tab") ;
item.sprite_id = 10; item.sprite_id = 10;
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback; item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
item.visibility_callback = [this]() { return (wxGetApp().app_config->get("new_settings_layout_mode") == "1" || item.visibility_callback = [this]() { return (wxGetApp().app_config->get("new_settings_layout_mode") == "1" ||
wxGetApp().app_config->get("dlg_settings_layout_mode") == "1"); }; wxGetApp().app_config->get("dlg_settings_layout_mode") == "1"); };
item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(); }; item.left.action_callback = [this]() { wxGetApp().mainframe->select_tab(MainFrame::ETabType::LastSettings); };
if (!m_main_toolbar.add_item(item)) if (!m_main_toolbar.add_item(item))
return false; return false;
@ -5756,8 +5762,8 @@ void GLCanvas3D::_load_print_toolpaths()
GLVolume &vol = *volume; GLVolume &vol = *volume;
volume = m_volumes.new_toolpath_volume(vol.color); volume = m_volumes.new_toolpath_volume(vol.color);
reserve_new_volume_finalize_old_volume(*volume, vol, m_initialized); reserve_new_volume_finalize_old_volume(*volume, vol, m_initialized);
}
} }
}
volume->indexed_vertex_array.finalize_geometry(m_initialized); volume->indexed_vertex_array.finalize_geometry(m_initialized);
} }

View File

@ -457,7 +457,9 @@ private:
int m_extra_frame_requested_delayed { std::numeric_limits<int>::max() }; int m_extra_frame_requested_delayed { std::numeric_limits<int>::max() };
bool m_event_handlers_bound{ false }; bool m_event_handlers_bound{ false };
bool m_show_objects = true;
mutable GLVolumeCollection m_volumes; mutable GLVolumeCollection m_volumes;
bool m_show_gcode = true;
GCodeViewer m_gcode_viewer; GCodeViewer m_gcode_viewer;
RenderTimer m_render_timer; RenderTimer m_render_timer;
@ -552,6 +554,7 @@ public:
void post_event(wxEvent &&event); void post_event(wxEvent &&event);
void set_as_dirty(); void set_as_dirty();
void set_items_show(bool show_objects, bool show_gcode);
unsigned int get_volumes_count() const; unsigned int get_volumes_count() const;
const GLVolumeCollection& get_volumes() const { return m_volumes; } const GLVolumeCollection& get_volumes() const { return m_volumes; }

View File

@ -905,7 +905,7 @@ bool GUI_App::on_init_inner()
mainframe = new MainFrame(); mainframe = new MainFrame();
// hide settings tabs after first Layout // hide settings tabs after first Layout
if (is_editor()) if (is_editor())
mainframe->select_tab(size_t(0)); mainframe->select_tab(MainFrame::ETabType::LastPlater);
sidebar().obj_list()->init_objects(); // propagate model objects to object list sidebar().obj_list()->init_objects(); // propagate model objects to object list
// update_mode(); // !!! do that later // update_mode(); // !!! do that later
@ -1173,7 +1173,7 @@ void GUI_App::recreate_GUI(const wxString& msg_name)
mainframe = new MainFrame(); mainframe = new MainFrame();
if (is_editor()) if (is_editor())
// hide settings tabs after first Layout // hide settings tabs after first Layout
mainframe->select_tab(size_t(0)); mainframe->select_tab(MainFrame::ETabType::LastPlater);
// Propagate model objects to object list. // Propagate model objects to object list.
sidebar().obj_list()->init_objects(); sidebar().obj_list()->init_objects();
SetTopWindow(mainframe); SetTopWindow(mainframe);
@ -1806,7 +1806,7 @@ void GUI_App::add_config_menu(wxMenuBar *menu)
// hide full main_sizer for mainFrame // hide full main_sizer for mainFrame
mainframe->GetSizer()->Show(false); mainframe->GetSizer()->Show(false);
mainframe->update_layout(); mainframe->update_layout();
mainframe->select_tab(size_t(0)); mainframe->select_tab(MainFrame::ETabType::LastPlater);
} }
break; break;
} }

View File

@ -57,6 +57,9 @@ View3D::~View3D()
bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process) bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process)
{ {
name = "3D";
title = "3D view";
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
return false; return false;
@ -195,6 +198,10 @@ Preview::Preview(
bool Preview::init(wxWindow* parent, Model* model) bool Preview::init(wxWindow* parent, Model* model)
{ {
name = "Preview";
title = "Gcode Preview";
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */)) if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
return false; return false;
@ -489,6 +496,22 @@ void Preview::hide_layers_slider()
Layout(); Layout();
} }
bool Preview::can_display_gcode()
{
return !m_gcode_result->moves.empty();
}
bool Preview::can_display_volume()
{
const Print* print = m_canvas->fff_print();
if (print == nullptr)
return false;
if (!print->is_step_done(psSkirt) || !print->is_step_done(psBrim))
return false;
return true;
}
void Preview::on_size(wxSizeEvent& evt) void Preview::on_size(wxSizeEvent& evt)
{ {
evt.Skip(); evt.Skip();
@ -921,6 +944,7 @@ void Preview::load_print_as_fff(bool keep_z_range)
GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type(); GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type();
bool gcode_preview_data_valid = !m_gcode_result->moves.empty(); bool gcode_preview_data_valid = !m_gcode_result->moves.empty();
gcode_preview_data_valid = gcode_preview_data_valid && current_force_state != ForceState::ForceExtrusions;
// Collect colors per extruder. // Collect colors per extruder.
std::vector<std::string> colors; std::vector<std::string> colors;
std::vector<CustomGCode::Item> color_print_values = {}; std::vector<CustomGCode::Item> color_print_values = {};
@ -934,7 +958,6 @@ void Preview::load_print_as_fff(bool keep_z_range)
} }
} }
else if (gcode_view_type == GCodeViewer::EViewType::Filament) else if (gcode_view_type == GCodeViewer::EViewType::Filament)
{ {
const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("extruder_colour")); const ConfigOptionStrings* extruders_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("extruder_colour"));
const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("filament_colour")); const ConfigOptionStrings* filamemts_opt = dynamic_cast<const ConfigOptionStrings*>(m_config->option("filament_colour"));
@ -954,7 +977,6 @@ void Preview::load_print_as_fff(bool keep_z_range)
color_print_values.clear(); color_print_values.clear();
} }
else if (gcode_preview_data_valid || (gcode_view_type == GCodeViewer::EViewType::Tool)) else if (gcode_preview_data_valid || (gcode_view_type == GCodeViewer::EViewType::Tool))
{ {
colors = wxGetApp().plater()->get_extruder_colors_from_plater_config(); colors = wxGetApp().plater()->get_extruder_colors_from_plater_config();
color_print_values.clear(); color_print_values.clear();
@ -962,9 +984,15 @@ void Preview::load_print_as_fff(bool keep_z_range)
if (IsShown()) { if (IsShown()) {
std::vector<double> zs; std::vector<double> zs;
if (current_force_state == ForceState::ForceGcode)
m_canvas->set_items_show(false, true);
else if (current_force_state == ForceState::ForceExtrusions)
m_canvas->set_items_show(true, false);
else
m_canvas->set_items_show(true, true);
m_canvas->set_selected_extruder(0); m_canvas->set_selected_extruder(0);
if (gcode_preview_data_valid) { if (current_force_state == ForceState::ForceGcode || (gcode_preview_data_valid && current_force_state != ForceState::ForceExtrusions)) {
// Load the real G-code preview. // Load the real G-code preview.
m_canvas->load_gcode_preview(*m_gcode_result); m_canvas->load_gcode_preview(*m_gcode_result);
m_canvas->refresh_gcode_preview(*m_gcode_result, colors); m_canvas->refresh_gcode_preview(*m_gcode_result, colors);

View File

@ -39,7 +39,20 @@ class Bed3D;
struct Camera; struct Camera;
class Plater; class Plater;
class View3D : public wxPanel // ----------------------------------------------------------------------------
// titlepanel
// ----------------------------------------------------------------------------
class wxTitledPanel : public wxPanel
{
public:
std::string name;
std::string title;
virtual GLCanvas3D* get_canvas3d() = 0;
virtual void set_as_dirty() = 0;
virtual void select_view(const std::string& direction) = 0;
};
class View3D : public wxTitledPanel
{ {
wxGLCanvas* m_canvas_widget; wxGLCanvas* m_canvas_widget;
GLCanvas3D* m_canvas; GLCanvas3D* m_canvas;
@ -49,12 +62,12 @@ public:
virtual ~View3D(); virtual ~View3D();
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
GLCanvas3D* get_canvas3d() { return m_canvas; } GLCanvas3D* get_canvas3d() override { return m_canvas; }
void set_as_dirty(); void set_as_dirty() override;
void bed_shape_changed(); void bed_shape_changed();
void select_view(const std::string& direction); void select_view(const std::string& direction) override;
void select_all(); void select_all();
void deselect_all(); void deselect_all();
void delete_selected(); void delete_selected();
@ -76,7 +89,7 @@ private:
bool init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process); bool init(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process);
}; };
class Preview : public wxPanel class Preview : public wxTitledPanel
{ {
wxGLCanvas* m_canvas_widget { nullptr }; wxGLCanvas* m_canvas_widget { nullptr };
GLCanvas3D* m_canvas { nullptr }; GLCanvas3D* m_canvas { nullptr };
@ -140,12 +153,18 @@ public:
Legend Legend
}; };
enum class ForceState : unsigned int {
NoForce,
ForceExtrusions,
ForceGcode
};
Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process, Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSlicingProcess* process,
GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process = []() {}); GCodeProcessor::Result* gcode_result, std::function<void()> schedule_background_process = []() {});
virtual ~Preview(); virtual ~Preview();
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
GLCanvas3D* get_canvas3d() { return m_canvas; } GLCanvas3D* get_canvas3d() override { return m_canvas; }
void set_as_dirty(); void set_as_dirty();
@ -159,6 +178,8 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSl
void load_print(bool keep_z_range = false); void load_print(bool keep_z_range = false);
void reload_print(bool keep_volumes = false); void reload_print(bool keep_volumes = false);
void refresh_print(); void refresh_print();
void set_force_state(ForceState new_force_state = ForceState::NoForce) { current_force_state = new_force_state; }
ForceState get_force_state() { return current_force_state; }
void msw_rescale(); void msw_rescale();
void jump_layers_slider(wxKeyEvent& evt); void jump_layers_slider(wxKeyEvent& evt);
@ -179,7 +200,12 @@ Preview(wxWindow* parent, Model* model, DynamicPrintConfig* config, BackgroundSl
#endif // ENABLE_ARROW_KEYS_WITH_SLIDERS #endif // ENABLE_ARROW_KEYS_WITH_SLIDERS
void hide_layers_slider(); void hide_layers_slider();
bool can_display_gcode();
bool can_display_volume();
private: private:
ForceState current_force_state = ForceState::NoForce;
bool init(wxWindow* parent, Model* model); bool init(wxWindow* parent, Model* model);
void bind_event_handlers(); void bind_event_handlers();

View File

@ -97,12 +97,12 @@ void KBShortcutsDialog::fill_shortcuts()
#endif // __APPLE__ #endif // __APPLE__
{ ctrl + "F", L("Search") }, { ctrl + "F", L("Search") },
// Window // Window
{ ctrl + "1", L("Select Plater Tab") }, { ctrl + "1", L("Select 3d editor Tab") },
{ ctrl + "2", L("Select Print Settings Tab") }, { ctrl + "2", L("Select Layer Preview Tab") },
{ ctrl + "3", L("Select Filament Settings Tab") }, { ctrl + "3", L("Select Gcode preview Tab") },
{ ctrl + "4", L("Select Printer Settings Tab") }, { ctrl + "4", L("Select Print Settings Tab") },
{ ctrl + "5", L("Switch to 3D") }, { ctrl + "5", L("Select Filament Settings Tab") },
{ ctrl + "6", L("Switch to Preview") }, { ctrl + "6", L("Select Printer Settings Tab") },
{ ctrl + "J", L("Print host upload queue") }, { ctrl + "J", L("Print host upload queue") },
{ ctrl + "Shift+" + "I", L("Open new instance") }, { ctrl + "Shift+" + "I", L("Open new instance") },
// View // View

View File

@ -262,6 +262,8 @@ void MainFrame::update_layout()
}; };
// On Linux m_plater needs to be removed from m_tabpanel before to reparent it // On Linux m_plater needs to be removed from m_tabpanel before to reparent it
//clear if previous was old
m_tabpanel_stop_event = true;
int plater_page_id = m_tabpanel->FindPage(m_plater); int plater_page_id = m_tabpanel->FindPage(m_plater);
if (plater_page_id != wxNOT_FOUND) if (plater_page_id != wxNOT_FOUND)
m_tabpanel->RemovePage(plater_page_id); m_tabpanel->RemovePage(plater_page_id);
@ -269,15 +271,33 @@ void MainFrame::update_layout()
if (m_plater->GetParent() != this) if (m_plater->GetParent() != this)
m_plater->Reparent(this); m_plater->Reparent(this);
for (int i = 0; i < m_tabpanel->GetPageCount(); i++) {
m_tabpanel->SetPageImage(i, -1);
}
m_tabpanel->SetImageList(nullptr); //clear
if (m_tabpanel->GetParent() != this) if (m_tabpanel->GetParent() != this)
m_tabpanel->Reparent(this); m_tabpanel->Reparent(this);
//clear if previous was hidden
plater_page_id = (m_plater_page != nullptr) ? m_tabpanel->FindPage(m_plater_page) : wxNOT_FOUND; plater_page_id = (m_plater_page != nullptr) ? m_tabpanel->FindPage(m_plater_page) : wxNOT_FOUND;
if (plater_page_id != wxNOT_FOUND) { if (plater_page_id != wxNOT_FOUND) {
m_tabpanel->DeletePage(plater_page_id); m_tabpanel->DeletePage(plater_page_id);
m_plater_page = nullptr; m_plater_page = nullptr;
} }
//clear if previous was tabs
for (int i = 0; i < m_tabpanel->GetPageCount(); i++)
if (m_tabpanel->GetPage(i)->GetChildren().empty() && m_tabpanel->GetPage(i)->GetSizer()->GetItemCount() > 0) {
clean_sizer(m_tabpanel->GetPage(i)->GetSizer());
}
if (m_tabpanel->GetPage(0)->GetChildren().size() == 0 && m_tabpanel->GetPage(1)->GetChildren().size() == 0 && m_tabpanel->GetPage(2)->GetChildren().size() == 0) {
m_tabpanel->DeletePage(2);
m_tabpanel->DeletePage(1);
m_tabpanel->DeletePage(0);
}
clean_sizer(m_main_sizer); clean_sizer(m_main_sizer);
clean_sizer(m_settings_dialog.GetSizer()); clean_sizer(m_settings_dialog.GetSizer());
@ -285,15 +305,19 @@ void MainFrame::update_layout()
m_settings_dialog.Close(); m_settings_dialog.Close();
m_tabpanel->Hide(); m_tabpanel->Hide();
m_tabpanel_stop_event = false;
m_plater->Hide(); m_plater->Hide();
m_plater->enable_view_toolbar(true);
m_plater->set_force_preview(Preview::ForceState::NoForce);
Layout(); Layout();
}; };
ESettingsLayout layout = wxGetApp().is_gcode_viewer() ? ESettingsLayout::GCodeViewer : ESettingsLayout layout = wxGetApp().is_gcode_viewer() ? ESettingsLayout::GCodeViewer :
(wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old : (wxGetApp().app_config->get("old_settings_layout_mode") == "1" ? ESettingsLayout::Old :
wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::New : wxGetApp().app_config->get("tab_settings_layout_mode") == "1" ? ESettingsLayout::Tabs :
wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Old); wxGetApp().app_config->get("new_settings_layout_mode") == "1" ? ESettingsLayout::Hidden :
wxGetApp().app_config->get("dlg_settings_layout_mode") == "1" ? ESettingsLayout::Dlg : ESettingsLayout::Tabs);
if (m_layout == layout) if (m_layout == layout)
return; return;
@ -305,6 +329,8 @@ void MainFrame::update_layout()
// Remove old settings // Remove old settings
if (m_layout != ESettingsLayout::Unknown) if (m_layout != ESettingsLayout::Unknown)
restore_to_creation(); restore_to_creation();
else //init with view_toolbar by default
m_plater->enable_view_toolbar(true);
#ifdef __WXMSW__ #ifdef __WXMSW__
enum class State { enum class State {
@ -319,8 +345,11 @@ void MainFrame::update_layout()
m_layout = layout; m_layout = layout;
m_layerpreview_menu_item->Enable(m_layout == ESettingsLayout::Tabs || m_layout == ESettingsLayout::Old);
// From the very beginning the Print settings should be selected // From the very beginning the Print settings should be selected
m_last_selected_tab = m_layout == ESettingsLayout::Dlg ? 0 : 1; m_last_selected_setting_tab = 0;
m_last_selected_plater_tab = 999;
// Set new settings // Set new settings
switch (m_layout) switch (m_layout)
@ -328,17 +357,92 @@ void MainFrame::update_layout()
case ESettingsLayout::Unknown: case ESettingsLayout::Unknown:
{ {
break; break;
} }case ESettingsLayout::Old:
case ESettingsLayout::Old:
{ {
// don't use view_toolbar here
m_plater->enable_view_toolbar(false);
//layout
m_plater->Reparent(m_tabpanel); m_plater->Reparent(m_tabpanel);
m_tabpanel->InsertPage(0, m_plater, _L("Plater")); m_tabpanel->InsertPage(0, m_plater, _L("Plater"));
m_main_sizer->Add(m_tabpanel, 1, wxEXPAND); m_main_sizer->Add(m_tabpanel, 1, wxEXPAND);
// icons for ESettingsLayout::Old
wxImageList* img_list = nullptr;
int icon_size = 0;
try {
icon_size = atoi(wxGetApp().app_config->get("tab_icon_size").c_str());
}
catch (std::exception e) {}
if (icon_size >= 8) {
std::initializer_list<std::string> icon_list = { "plater", "cog", "spool_cog", "printer_cog" };
if (icon_size < 16)
icon_list = { "plater", "cog", "spool", "printer" };
for (std::string icon_name : icon_list) {
const wxBitmap& bmp = create_scaled_bitmap(icon_name, this, icon_size);
if (img_list == nullptr)
img_list = new wxImageList(bmp.GetWidth(), bmp.GetHeight());
img_list->Add(bmp);
}
}
m_tabpanel->AssignImageList(img_list);
if (icon_size >= 8)
{
m_tabpanel->SetPageImage(0, 0);
m_tabpanel->SetPageImage(1, 1);
m_tabpanel->SetPageImage(2, 2);
m_tabpanel->SetPageImage(3, 3);
}
// show
m_plater->Show();
m_tabpanel->Show();
break;
}
case ESettingsLayout::Tabs:
{
// don't use view_toolbar here
m_plater->enable_view_toolbar(false);
// icons for ESettingsLayout::Tabs
wxImageList* img_list = nullptr;
int icon_size = 0;
try {
icon_size = atoi(wxGetApp().app_config->get("tab_icon_size").c_str());
}
catch (std::exception e) {}
if (icon_size >= 8) {
std::initializer_list<std::string> icon_list = { "editor_menu", "layers", "preview_menu", "cog", "spool_cog", "printer_cog" };
if (icon_size < 16)
icon_list = { "editor_menu", "layers", "preview_menu", "cog", "spool", "printer" };
for (std::string icon_name : icon_list) {
const wxBitmap& bmp = create_scaled_bitmap(icon_name, this, icon_size);
if (img_list == nullptr)
img_list = new wxImageList(bmp.GetWidth(), bmp.GetHeight());
img_list->Add(bmp);
}
}
m_tabpanel->AssignImageList(img_list);
m_tabpanel->InsertPage(0, new wxPanel(m_tabpanel), _L("3D view"));
m_tabpanel->InsertPage(1, new wxPanel(m_tabpanel), _L("Sliced preview"));
m_tabpanel->InsertPage(2, new wxPanel(m_tabpanel), _L("Gcode preview"));
m_tabpanel->GetPage(0)->SetSizer(new wxBoxSizer(wxVERTICAL));
m_tabpanel->GetPage(1)->SetSizer(new wxBoxSizer(wxVERTICAL));
m_tabpanel->GetPage(2)->SetSizer(new wxBoxSizer(wxVERTICAL));
if (icon_size >= 8)
{
m_tabpanel->SetPageImage(0, 0);
m_tabpanel->SetPageImage(1, 1);
m_tabpanel->SetPageImage(2, 2);
m_tabpanel->SetPageImage(3, 3);
m_tabpanel->SetPageImage(4, 4);
m_tabpanel->SetPageImage(5, 5);
}
m_plater->Reparent(m_tabpanel->GetPage(0));
m_tabpanel->GetPage(0)->GetSizer()->Add(m_plater, 1, wxEXPAND);
m_tabpanel->ChangeSelection(0);
m_main_sizer->Add(m_tabpanel, 1, wxEXPAND);
m_plater->Show(); m_plater->Show();
m_tabpanel->Show(); m_tabpanel->Show();
break; break;
} }
case ESettingsLayout::New: case ESettingsLayout::Hidden:
{ {
m_main_sizer->Add(m_plater, 1, wxEXPAND); m_main_sizer->Add(m_plater, 1, wxEXPAND);
m_tabpanel->Hide(); m_tabpanel->Hide();
@ -404,7 +508,7 @@ void MainFrame::update_layout()
// // So, if we haven't possibility to set MinSize() for the MainFrame, // // So, if we haven't possibility to set MinSize() for the MainFrame,
// // set the MinSize() as a half of regular for the m_plater and m_tabpanel, when settings layout is in slNew mode // // set the MinSize() as a half of regular for the m_plater and m_tabpanel, when settings layout is in slNew mode
// // Otherwise, MainFrame will be maximized by height // // Otherwise, MainFrame will be maximized by height
// if (m_layout == ESettingsLayout::New) { // if (m_layout == ESettingsLayout::Hidden) {
// wxSize size = wxGetApp().get_min_size(); // wxSize size = wxGetApp().get_min_size();
// size.SetHeight(int(0.5 * size.GetHeight())); // size.SetHeight(int(0.5 * size.GetHeight()));
// m_plater->SetMinSize(size); // m_plater->SetMinSize(size);
@ -413,7 +517,7 @@ void MainFrame::update_layout()
//#endif //#endif
#ifdef __APPLE__ #ifdef __APPLE__
m_plater->sidebar().change_top_border_for_mode_sizer(m_layout != ESettingsLayout::Old); m_plater->sidebar().change_top_border_for_mode_sizer(m_layout != ESettingsLayout::Tabs && m_layout != ESettingsLayout::Old);
#endif #endif
Layout(); Layout();
@ -538,7 +642,10 @@ void MainFrame::init_tabpanel()
m_tabpanel->Hide(); m_tabpanel->Hide();
m_settings_dialog.set_tabpanel(m_tabpanel); m_settings_dialog.set_tabpanel(m_tabpanel);
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) { m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
if (m_tabpanel_stop_event)
return;
wxWindow* panel = m_tabpanel->GetCurrentPage(); wxWindow* panel = m_tabpanel->GetCurrentPage();
Tab* tab = dynamic_cast<Tab*>(panel); Tab* tab = dynamic_cast<Tab*>(panel);
@ -546,15 +653,79 @@ void MainFrame::init_tabpanel()
if (panel == nullptr || (tab != nullptr && !tab->supports_printer_technology(m_plater->printer_technology()))) if (panel == nullptr || (tab != nullptr && !tab->supports_printer_technology(m_plater->printer_technology())))
return; return;
auto& tabs_list = wxGetApp().tabs_list; std::vector<Tab*>& tabs_list = wxGetApp().tabs_list;
int last_selected_plater_tab = m_last_selected_plater_tab;
int last_selected_setting_tab = m_last_selected_setting_tab;
if (tab && std::find(tabs_list.begin(), tabs_list.end(), tab) != tabs_list.end()) { if (tab && std::find(tabs_list.begin(), tabs_list.end(), tab) != tabs_list.end()) {
// On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered // On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered
// before the MainFrame is fully set up. // before the MainFrame is fully set up.
tab->OnActivate(); tab->OnActivate();
m_last_selected_tab = m_tabpanel->GetSelection(); if (this->m_layout == ESettingsLayout::Tabs)
last_selected_setting_tab = m_tabpanel->GetSelection() - 3;
if (this->m_layout == ESettingsLayout::Dlg)
last_selected_setting_tab = m_tabpanel->GetSelection();
else
last_selected_setting_tab = m_tabpanel->GetSelection() - 1;
}
else if (this->m_layout == ESettingsLayout::Tabs) {
if (last_selected_plater_tab == m_tabpanel->GetSelection()) {
std::cout << "Page changed to the same one (" << m_last_selected_plater_tab << ") no need to do anything\n";
return;
}
bool need_freeze = !this->IsFrozen();
if(need_freeze) Freeze();
std::cout << "I switched to tab " << m_tabpanel->GetSelection() << " and so i need to change the panel position & content\n";
size_t new_tab = m_tabpanel->GetSelection();
size_t max = 0;
for (int i = 0; i < 3; i++)
max = std::max(max, m_tabpanel->GetPage(i)->GetSizer()->GetItemCount());
std::cout << " 1 - hide & clear the sizers: " << max << "->";
for(int i=0;i<3;i++)
m_tabpanel->GetPage(i)->GetSizer()->Clear();
max = 0;
for (int i = 0; i < 3; i++)
max = std::max(max, m_tabpanel->GetPage(i)->GetSizer()->GetItemCount());
std::cout << max << "\n";
m_plater->Reparent(m_tabpanel->GetCurrentPage());
std::cout << " 2 - change parent from tab " << m_last_selected_plater_tab << " to tab " << m_tabpanel->GetSelection() << "\n";
if (m_tabpanel->GetSelection() == 0)
this->m_plater->select_view_3D("3D");
else if (m_tabpanel->GetSelection() == 1) {
if (this->m_plater->get_force_preview() != Preview::ForceState::ForceExtrusions) {
this->m_plater->set_force_preview(Preview::ForceState::ForceExtrusions);
this->m_plater->select_view_3D("Preview");
this->m_plater->refresh_print();
}else
this->m_plater->select_view_3D("Preview");
}
else if (m_tabpanel->GetSelection() == 2) {
if (this->m_plater->get_force_preview() != Preview::ForceState::ForceGcode) {
this->m_plater->set_force_preview(Preview::ForceState::ForceGcode);
this->m_plater->select_view_3D("Preview");
this->m_plater->refresh_print();
}else
this->m_plater->select_view_3D("Preview");
}
std::cout << " 3 - redraw\n";
std::cout << " 4 - add to new sizer: " << m_tabpanel->GetCurrentPage()->GetSizer()->GetItemCount() << "->";
m_tabpanel->GetCurrentPage()->GetSizer()->Add(m_plater, 1, wxEXPAND);
std::cout << m_tabpanel->GetCurrentPage()->GetSizer()->GetItemCount() << "\n";
m_plater->Show();
std::cout << "End of change for the panel position & content, tab is "<< m_tabpanel->GetSelection() <<"\n";
m_last_selected_plater_tab = m_tabpanel->GetSelection();
if (need_freeze) Thaw();
#ifdef __APPLE__
m_tabpanel->ChangeSelection(new_tab);
m_tabpanel->Refresh();
std::cout << "Macos: force tab selection to "<< new_tab <<" : " << m_tabpanel->GetSelection() << "\n";
#endif
} else {
select_tab(MainFrame::ETabType::LastPlater); // select Plater
m_last_selected_plater_tab = 999;
} }
else
select_tab(size_t(0)); // select Plater
}); });
m_plater = new Plater(this, this); m_plater = new Plater(this, this);
@ -565,7 +736,7 @@ void MainFrame::init_tabpanel()
wxGetApp().obj_list()->create_popup_menus(); wxGetApp().obj_list()->create_popup_menus();
if (wxGetApp().is_editor()) if (wxGetApp().is_editor())
create_preset_tabs(); create_preset_tabs();
if (m_plater) { if (m_plater) {
// load initial config // load initial config
@ -666,7 +837,7 @@ bool MainFrame::is_active_and_shown_tab(Tab* tab)
if (m_layout == ESettingsLayout::Dlg) if (m_layout == ESettingsLayout::Dlg)
return m_settings_dialog.IsShown(); return m_settings_dialog.IsShown();
if (m_layout == ESettingsLayout::New) if (m_layout == ESettingsLayout::Hidden)
return m_main_sizer->IsShown(m_tabpanel); return m_main_sizer->IsShown(m_tabpanel);
return true; return true;
@ -767,9 +938,10 @@ bool MainFrame::can_change_view() const
switch (m_layout) switch (m_layout)
{ {
default: { return false; } default: { return false; }
case ESettingsLayout::New: { return m_plater->IsShown(); } case ESettingsLayout::Hidden: { return m_plater->IsShown(); }
case ESettingsLayout::Dlg: { return true; } case ESettingsLayout::Dlg: { return true; }
case ESettingsLayout::Old: { case ESettingsLayout::Old:
case ESettingsLayout::Tabs: {
int page_id = m_tabpanel->GetSelection(); int page_id = m_tabpanel->GetSelection();
return page_id != wxNOT_FOUND && dynamic_cast<const Slic3r::GUI::Plater*>(m_tabpanel->GetPage((size_t)page_id)) != nullptr; return page_id != wxNOT_FOUND && dynamic_cast<const Slic3r::GUI::Plater*>(m_tabpanel->GetPage((size_t)page_id)) != nullptr;
} }
@ -1177,31 +1349,28 @@ void MainFrame::init_menubar_as_editor()
auto windowMenu = new wxMenu(); auto windowMenu = new wxMenu();
{ {
if (m_plater) { if (m_plater) {
append_menu_item(windowMenu, wxID_HIGHEST + 1, _L("&Plater Tab") + "\tCtrl+1", _L("Show the plater"), append_menu_item(windowMenu, wxID_HIGHEST + 1, _L("3D &Plater Tab") + "\tCtrl+1", _L("Show the editor of the input models"),
[this](wxCommandEvent&) { select_tab(size_t(0)); }, "plater", nullptr, [this](wxCommandEvent&) { select_tab(ETabType::Plater3D); }, "editor_menu", nullptr,
[]() {return true; }, this);
m_layerpreview_menu_item = append_menu_item(windowMenu, wxID_HIGHEST + 2, _L("Layer previe&w Tab") + "\tCtrl+2", _L("Show the layers from the slicing process"),
[this](wxCommandEvent&) { select_tab(ETabType::PlaterPreview); }, "layers", nullptr,
[]() {return true; }, this);
append_menu_item(windowMenu, wxID_HIGHEST + 3, _L("GCode Pre&view Tab") + "\tCtrl+3", _L("Show the preview of the gcode output"),
[this](wxCommandEvent&) { select_tab(ETabType::PlaterGcode); }, "preview_menu", nullptr,
[]() {return true; }, this); []() {return true; }, this);
windowMenu->AppendSeparator(); windowMenu->AppendSeparator();
} }
append_menu_item(windowMenu, wxID_HIGHEST + 2, _L("P&rint Settings Tab") + "\tCtrl+2", _L("Show the print settings"), append_menu_item(windowMenu, wxID_HIGHEST + 4, _L("P&rint Settings Tab") + "\tCtrl+4", _L("Show the print settings"),
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(1); }, "cog", nullptr, [this/*, tab_offset*/](wxCommandEvent&) { select_tab(ETabType::PrintSettings); }, "cog", nullptr,
[]() {return true; }, this); []() {return true; }, this);
wxMenuItem* item_material_tab = append_menu_item(windowMenu, wxID_HIGHEST + 3, _L("&Filament Settings Tab") + "\tCtrl+3", _L("Show the filament settings"), wxMenuItem* item_material_tab = append_menu_item(windowMenu, wxID_HIGHEST + 5, _L("&Filament Settings Tab") + "\tCtrl+5", _L("Show the filament settings"),
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(2); }, "spool", nullptr, [this/*, tab_offset*/](wxCommandEvent&) { select_tab(ETabType::FilamentSettings); }, "spool", nullptr,
[]() {return true; }, this); []() {return true; }, this);
m_changeable_menu_items.push_back(item_material_tab); m_changeable_menu_items.push_back(item_material_tab);
wxMenuItem* item_printer_tab = append_menu_item(windowMenu, wxID_HIGHEST + 4, _L("Print&er Settings Tab") + "\tCtrl+4", _L("Show the printer settings"), wxMenuItem* item_printer_tab = append_menu_item(windowMenu, wxID_HIGHEST + 6, _L("Print&er Settings Tab") + "\tCtrl+6", _L("Show the printer settings"),
[this/*, tab_offset*/](wxCommandEvent&) { select_tab(3); }, "printer", nullptr, [this/*, tab_offset*/](wxCommandEvent&) { select_tab(ETabType::PrinterSettings); }, "printer", nullptr,
[]() {return true; }, this); []() {return true; }, this);
m_changeable_menu_items.push_back(item_printer_tab); m_changeable_menu_items.push_back(item_printer_tab);
if (m_plater) {
windowMenu->AppendSeparator();
append_menu_item(windowMenu, wxID_HIGHEST + 5, _L("3&D") + "\tCtrl+5", _L("Show the 3D editing view"),
[this](wxCommandEvent&) { m_plater->select_view_3D("3D"); }, "editor_menu", nullptr,
[this](){return can_change_view(); }, this);
append_menu_item(windowMenu, wxID_HIGHEST + 6, _L("Pre&view") + "\tCtrl+6", _L("Show the 3D slices preview"),
[this](wxCommandEvent&) { m_plater->select_view_3D("Preview"); }, "preview_menu", nullptr,
[this](){return can_change_view(); }, this);
}
windowMenu->AppendSeparator(); windowMenu->AppendSeparator();
append_menu_item(windowMenu, wxID_ANY, _L("Print &Host Upload Queue") + "\tCtrl+J", _L("Display the Print Host Upload Queue window"), append_menu_item(windowMenu, wxID_ANY, _L("Print &Host Upload Queue") + "\tCtrl+J", _L("Display the Print Host Upload Queue window"),
@ -1689,13 +1858,16 @@ void MainFrame::select_tab(Tab* tab)
{ {
if (!tab) if (!tab)
return; return;
int page_idx = m_tabpanel->FindPage(tab); std::vector<Tab*>& tabs_list = wxGetApp().tabs_list;
if (page_idx != wxNOT_FOUND && m_layout == ESettingsLayout::Dlg) std::vector<Tab*>::iterator it_tab = std::find(tabs_list.begin(), tabs_list.end(), tab);
page_idx++; if (it_tab != tabs_list.end()) {
select_tab(size_t(page_idx)); select_tab((ETabType)((uint8_t)ETabType::PrintSettings + uint8_t(it_tab - tabs_list.begin())));
}
select_tab(ETabType::LastSettings);
} }
void MainFrame::select_tab(size_t tab/* = size_t(-1)*/) void MainFrame::select_tab(ETabType tab /* = Any*/, bool keep_tab_type)
{ {
bool tabpanel_was_hidden = false; bool tabpanel_was_hidden = false;
@ -1703,7 +1875,26 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
// We should select/activate tab before its showing to avoid an UI-flickering // We should select/activate tab before its showing to avoid an UI-flickering
auto select = [this, tab](bool was_hidden) { auto select = [this, tab](bool was_hidden) {
// when tab == -1, it means we should show the last selected tab // when tab == -1, it means we should show the last selected tab
size_t new_selection = tab == (size_t)(-1) ? m_last_selected_tab : (m_layout == ESettingsLayout::Dlg && tab != 0) ? tab - 1 : tab; size_t new_selection = 0;
if (tab <= ETabType::LastPlater) {
//select plater
new_selection = (uint8_t)tab;
if (tab == ETabType::LastPlater)
new_selection = m_last_selected_plater_tab > 2 ? 0 : m_last_selected_plater_tab;
if (m_layout != ESettingsLayout::Tabs)
new_selection = 0;
} else if (tab <= ETabType::LastSettings) {
//select setting
new_selection = (uint8_t)tab - (uint8_t)ETabType::PrintSettings;
if (tab == ETabType::LastSettings)
new_selection = m_last_selected_setting_tab > 2 ? 0 : m_last_selected_setting_tab;
//push to the correct position
if (m_layout == ESettingsLayout::Tabs)
new_selection = m_last_selected_setting_tab + 3;
else if (m_layout != ESettingsLayout::Dlg)
new_selection = new_selection + 1;
}
if (m_tabpanel->GetSelection() != (int)new_selection) if (m_tabpanel->GetSelection() != (int)new_selection)
m_tabpanel->SetSelection(new_selection); m_tabpanel->SetSelection(new_selection);
@ -1714,8 +1905,20 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
} }
}; };
if (m_layout != ESettingsLayout::Tabs) {
if (tab == ETabType::Plater3D || (tab == ETabType::LastPlater && m_last_selected_plater_tab == 0)) {
m_plater->select_view_3D("3D");
} else if (tab == ETabType::PlaterPreview || (tab == ETabType::LastPlater && m_last_selected_plater_tab == 1)) {
m_plater->select_view_3D("Preview");
} else if (tab == ETabType::PlaterGcode || (tab == ETabType::LastPlater && m_last_selected_plater_tab == 2)) {
m_plater->select_view_3D("Preview");
}
}
if (m_layout == ESettingsLayout::Dlg) { if (m_layout == ESettingsLayout::Dlg) {
if (tab==0) { if (keep_tab_type)
return;
if (tab <= ETabType::LastPlater) {
if (m_settings_dialog.IsShown()) if (m_settings_dialog.IsShown())
this->SetFocus(); this->SetFocus();
// plater should be focused for correct navigation inside search window // plater should be focused for correct navigation inside search window
@ -1746,21 +1949,35 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
} }
#endif #endif
} }
else if (m_layout == ESettingsLayout::New) { else if (m_layout == ESettingsLayout::Hidden) {
m_main_sizer->Show(m_plater, tab == 0); if (keep_tab_type && m_tabpanel->GetSelection()>0)
return;
m_main_sizer->Show(m_plater, tab <= ETabType::LastPlater);
tabpanel_was_hidden = !m_main_sizer->IsShown(m_tabpanel); tabpanel_was_hidden = !m_main_sizer->IsShown(m_tabpanel);
select(tabpanel_was_hidden); select(tabpanel_was_hidden);
m_main_sizer->Show(m_tabpanel, tab != 0); m_main_sizer->Show(m_tabpanel, tab > ETabType::LastPlater);
// plater should be focused for correct navigation inside search window // plater should be focused for correct navigation inside search window
if (tab == 0 && m_plater->canvas3D()->is_search_pressed()) if (tab <= ETabType::LastPlater && m_plater->canvas3D()->is_search_pressed())
m_plater->SetFocus(); m_plater->SetFocus();
Layout(); Layout();
} }
else if (m_layout == ESettingsLayout::Old) {
if (keep_tab_type && m_tabpanel->GetSelection() > 0)
return;
else
select(false);
}
else if (m_layout == ESettingsLayout::Tabs) {
if (keep_tab_type && ( (m_tabpanel->GetSelection() >=3 && tab <= ETabType::LastPlater) || (m_tabpanel->GetSelection() < 3 && tab > ETabType::LastPlater)))
return;
else
select(false);
}
else else
select(false); select(false);
// When we run application in ESettingsLayout::New or ESettingsLayout::Dlg mode, tabpanel is hidden from the very beginning // When we run application in ESettingsLayout::Hidden or ESettingsLayout::Dlg mode, tabpanel is hidden from the very beginning
// and as a result Tab::update_changed_tree_ui() function couldn't update m_is_nonsys_values values, // and as a result Tab::update_changed_tree_ui() function couldn't update m_is_nonsys_values values,
// which are used for update TreeCtrl and "revert_buttons". // which are used for update TreeCtrl and "revert_buttons".
// So, force the call of this function for Tabs, if tab panel was hidden // So, force the call of this function for Tabs, if tab panel was hidden
@ -1918,10 +2135,12 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
auto key_up_handker = [this](wxKeyEvent& evt) { auto key_up_handker = [this](wxKeyEvent& evt) {
if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) { if ((evt.GetModifiers() & wxMOD_CONTROL) != 0) {
switch (evt.GetKeyCode()) { switch (evt.GetKeyCode()) {
case '1': { m_main_frame->select_tab(size_t(0)); break; } case '1': { m_main_frame->select_tab(MainFrame::ETabType::Plater3D); break; }
case '2': { m_main_frame->select_tab(1); break; } case '2': { m_main_frame->select_tab(MainFrame::ETabType::Plater3D); break; }
case '3': { m_main_frame->select_tab(2); break; } case '3': { m_main_frame->select_tab(MainFrame::ETabType::PlaterGcode); break; }
case '4': { m_main_frame->select_tab(3); break; } case '4': { m_main_frame->select_tab(MainFrame::ETabType::PrintSettings); break; }
case '5': { m_main_frame->select_tab(MainFrame::ETabType::FilamentSettings); break; }
case '6': { m_main_frame->select_tab(MainFrame::ETabType::PrinterSettings); break; }
#ifdef __APPLE__ #ifdef __APPLE__
case 'f': case 'f':
#else /* __APPLE__ */ #else /* __APPLE__ */

View File

@ -81,7 +81,8 @@ class MainFrame : public DPIFrame
size_t m_last_selected_tab; size_t m_last_selected_plater_tab;
size_t m_last_selected_setting_tab;
std::string get_base_name(const wxString &full_name, const char *extension = nullptr) const; std::string get_base_name(const wxString &full_name, const char *extension = nullptr) const;
std::string get_dir_name(const wxString &full_name) const; std::string get_dir_name(const wxString &full_name) const;
@ -117,18 +118,37 @@ class MainFrame : public DPIFrame
// vector of a MenuBar items changeable in respect to printer technology // vector of a MenuBar items changeable in respect to printer technology
std::vector<wxMenuItem*> m_changeable_menu_items; std::vector<wxMenuItem*> m_changeable_menu_items;
wxMenuItem* m_layerpreview_menu_item;
wxFileHistory m_recent_projects; wxFileHistory m_recent_projects;
public:
enum class ESettingsLayout enum class ESettingsLayout
{ {
Unknown, Unknown,
Old, Old,
New, Tabs,
Hidden,
Dlg, Dlg,
GCodeViewer GCodeViewer
}; };
enum class ETabType : uint8_t
{
Plater3D,
PlaterPreview,
PlaterGcode,
LastPlater,
PrintSettings,
FilamentSettings,
PrinterSettings,
LastSettings,
Any
};
private:
ESettingsLayout m_layout{ ESettingsLayout::Unknown }; ESettingsLayout m_layout{ ESettingsLayout::Unknown };
protected: protected:
@ -136,6 +156,7 @@ protected:
virtual void on_sys_color_changed() override; virtual void on_sys_color_changed() override;
public: public:
MainFrame(); MainFrame();
~MainFrame() = default; ~MainFrame() = default;
@ -162,7 +183,7 @@ public:
void update_ui_from_settings(bool apply_free_camera_correction = true); void update_ui_from_settings(bool apply_free_camera_correction = true);
bool is_loaded() const { return m_loaded; } bool is_loaded() const { return m_loaded; }
bool is_last_input_file() const { return !m_qs_last_input_file.IsEmpty(); } bool is_last_input_file() const { return !m_qs_last_input_file.IsEmpty(); }
bool is_dlg_layout() const { return m_layout == ESettingsLayout::Dlg; } ESettingsLayout get_layout() const { return m_layout; }
void quick_slice(const int qs = qsUndef); void quick_slice(const int qs = qsUndef);
void reslice_now(); void reslice_now();
@ -177,8 +198,9 @@ public:
void load_config(const DynamicPrintConfig& config); void load_config(const DynamicPrintConfig& config);
// Select tab in m_tabpanel // Select tab in m_tabpanel
// When tab == -1, will be selected last selected tab // When tab == -1, will be selected last selected tab
// 0 = a plater tab, 1 = print setting, 2 = filament settign, 3 = printer setting
void select_tab(Tab* tab); void select_tab(Tab* tab);
void select_tab(size_t tab = size_t(-1)); void select_tab(ETabType tab = ETabType::Any, bool keep_tab_type = false);
void select_view(const std::string& direction); void select_view(const std::string& direction);
// Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig // Propagate changed configuration from the Tab to the Plater and save changes to the AppConfig
void on_config_changed(DynamicPrintConfig* cfg) const ; void on_config_changed(DynamicPrintConfig* cfg) const ;
@ -189,6 +211,7 @@ public:
Plater* m_plater { nullptr }; Plater* m_plater { nullptr };
wxNotebook* m_tabpanel { nullptr }; wxNotebook* m_tabpanel { nullptr };
bool m_tabpanel_stop_event = false;
SettingsDialog m_settings_dialog; SettingsDialog m_settings_dialog;
wxWindow* m_plater_page{ nullptr }; wxWindow* m_plater_page{ nullptr };
wxProgressDialog* m_progress_dialog { nullptr }; wxProgressDialog* m_progress_dialog { nullptr };

View File

@ -799,7 +799,6 @@ Sidebar::Sidebar(Plater *parent)
p->plater->export_gcode(true); p->plater->export_gcode(true);
else else
p->plater->reslice(); p->plater->reslice();
p->plater->select_view_3D("Preview");
}); });
p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); }); p->btn_send_gcode->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->send_gcode(); });
// p->btn_eject_device->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->eject_drive(); }); // p->btn_eject_device->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { p->plater->eject_drive(); });
@ -993,7 +992,7 @@ void Sidebar::jump_to_option(size_t selected)
wxGetApp().get_tab(opt.type)->activate_option(boost::nowide::narrow(opt.opt_key), boost::nowide::narrow(opt.category)); wxGetApp().get_tab(opt.type)->activate_option(boost::nowide::narrow(opt.opt_key), boost::nowide::narrow(opt.category));
// Switch to the Settings NotePad // Switch to the Settings NotePad
// wxGetApp().mainframe->select_tab(); // wxGetApp().mainframe->select_tab(MainFrame::ETabType::LastSettings);
} }
ObjectManipulation* Sidebar::obj_manipul() ObjectManipulation* Sidebar::obj_manipul()
@ -1634,8 +1633,8 @@ struct Plater::priv
// GUI elements // GUI elements
wxSizer* panel_sizer{ nullptr }; wxSizer* panel_sizer{ nullptr };
wxPanel* current_panel{ nullptr }; wxTitledPanel* current_panel{ nullptr };
std::vector<wxPanel*> panels; std::vector<wxTitledPanel*> panels;
Sidebar *sidebar; Sidebar *sidebar;
Bed3D bed; Bed3D bed;
Camera camera; Camera camera;
@ -1651,6 +1650,7 @@ struct Plater::priv
BackgroundSlicingProcess background_process; BackgroundSlicingProcess background_process;
bool suppressed_backround_processing_update { false }; bool suppressed_backround_processing_update { false };
std::function<void(int)> process_done_callback = [](int) {};
// Jobs defined inside the group class will be managed so that only one can // Jobs defined inside the group class will be managed so that only one can
// run at a time. Also, the background process will be stopped if a job is // run at a time. Also, the background process will be stopped if a job is
@ -1839,7 +1839,7 @@ struct Plater::priv
void reload_all_from_disk(); void reload_all_from_disk();
void fix_through_netfabb(const int obj_idx, const int vol_idx = -1); void fix_through_netfabb(const int obj_idx, const int vol_idx = -1);
void set_current_panel(wxPanel* panel); void set_current_panel(wxTitledPanel* panel);
void on_select_preset(wxCommandEvent&); void on_select_preset(wxCommandEvent&);
void on_slicing_update(SlicingStatusEvent&); void on_slicing_update(SlicingStatusEvent&);
@ -2142,7 +2142,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership
q->Layout(); q->Layout();
set_current_panel(wxGetApp().is_editor() ? static_cast<wxPanel*>(view3D) : static_cast<wxPanel*>(preview)); set_current_panel(wxGetApp().is_editor() ? static_cast<wxTitledPanel*>(view3D) : static_cast<wxTitledPanel*>(preview));
if (wxGetApp().is_gcode_viewer()) if (wxGetApp().is_gcode_viewer())
preview->hide_layers_slider(); preview->hide_layers_slider();
@ -2267,28 +2267,33 @@ void Plater::priv::update(unsigned int flags)
void Plater::priv::select_view(const std::string& direction) void Plater::priv::select_view(const std::string& direction)
{ {
if (current_panel == view3D) if(current_panel != nullptr)
view3D->select_view(direction); current_panel->select_view(direction);
else if (current_panel == preview)
preview->select_view(direction);
} }
void Plater::priv::select_view_3D(const std::string& name) void Plater::priv::select_view_3D(const std::string& name)
{ {
if (name == "3D") for (wxTitledPanel* panel : panels) {
set_current_panel(view3D); if (panel->name == name) {
else if (name == "Preview") set_current_panel(panel);
set_current_panel(preview); break;
}
}
wxGetApp().update_ui_from_settings(false); wxGetApp().update_ui_from_settings(false);
} }
void Plater::priv::select_next_view_3D() void Plater::priv::select_next_view_3D()
{ {
if (current_panel == view3D) for (int i = 0; i < panels.size(); i++) {
set_current_panel(preview); if (panels[i] == current_panel) {
else if (current_panel == preview) if (i + 1 == panels.size()) {
set_current_panel(view3D); set_current_panel(panels[0]);
} else {
set_current_panel(panels[i+1]);
}
return;
}
}
} }
void Plater::priv::collapse_sidebar(bool collapse) void Plater::priv::collapse_sidebar(bool collapse)
@ -3089,6 +3094,16 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool
show_action_buttons(true); show_action_buttons(true);
} }
//update tab if needed
if (invalidated != Print::ApplyStatus::APPLY_STATUS_UNCHANGED)
{
if (this->preview->can_display_gcode())
main_frame->select_tab(MainFrame::ETabType::PlaterGcode, true);
else if (this->preview->can_display_volume())
main_frame->select_tab(MainFrame::ETabType::PlaterPreview, true);
else
main_frame->select_tab(MainFrame::ETabType::Plater3D, true);
}
return return_state; return return_state;
} }
@ -3488,7 +3503,7 @@ void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* =
this->schedule_background_process(); this->schedule_background_process();
} }
void Plater::priv::set_current_panel(wxPanel* panel) void Plater::priv::set_current_panel(wxTitledPanel* panel)
{ {
if (std::find(panels.begin(), panels.end(), panel) == panels.end()) if (std::find(panels.begin(), panels.end(), panel) == panels.end())
return; return;
@ -3500,7 +3515,7 @@ void Plater::priv::set_current_panel(wxPanel* panel)
if (current_panel == panel) if (current_panel == panel)
return; return;
wxPanel* old_panel = current_panel; wxTitledPanel* old_panel = current_panel;
current_panel = panel; current_panel = panel;
// to reduce flickering when changing view, first set as visible the new current panel // to reduce flickering when changing view, first set as visible the new current panel
for (wxPanel* p : panels) { for (wxPanel* p : panels) {
@ -3525,12 +3540,12 @@ void Plater::priv::set_current_panel(wxPanel* panel)
panel_sizer->Layout(); panel_sizer->Layout();
if(old_panel)
old_panel->get_canvas3d()->unbind_event_handlers();
if (current_panel)
current_panel->get_canvas3d()->bind_event_handlers();
if (current_panel == view3D) { if (current_panel == view3D) {
if (old_panel == preview)
preview->get_canvas3d()->unbind_event_handlers();
view3D->get_canvas3d()->bind_event_handlers();
if (view3D->is_reload_delayed()) { if (view3D->is_reload_delayed()) {
// Delayed loading of the 3D scene. // Delayed loading of the 3D scene.
if (this->printer_technology == ptSLA) { if (this->printer_technology == ptSLA) {
@ -3540,19 +3555,8 @@ void Plater::priv::set_current_panel(wxPanel* panel)
} else } else
view3D->reload_scene(true); view3D->reload_scene(true);
} }
// sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably)
view3D->set_as_dirty();
view_toolbar.select_item("3D");
if(notification_manager != nullptr)
notification_manager->set_in_preview(false);
} }
else if (current_panel == preview) { else if (current_panel == preview) {
if (old_panel == view3D)
view3D->get_canvas3d()->unbind_event_handlers();
preview->get_canvas3d()->bind_event_handlers();
// see: Plater::priv::object_list_changed() // see: Plater::priv::object_list_changed()
// FIXME: it may be better to have a single function making this check and let it be called wherever needed // FIXME: it may be better to have a single function making this check and let it be called wherever needed
bool export_in_progress = this->background_process.is_export_scheduled(); bool export_in_progress = this->background_process.is_export_scheduled();
@ -3561,14 +3565,17 @@ void Plater::priv::set_current_panel(wxPanel* panel)
this->q->reslice(); this->q->reslice();
// keeps current gcode preview, if any // keeps current gcode preview, if any
preview->reload_print(true); preview->reload_print(true);
preview->set_as_dirty();
view_toolbar.select_item("Preview");
if (notification_manager != nullptr)
notification_manager->set_in_preview(true);
} }
current_panel->SetFocusFromKbd(); if (current_panel) {
// sets the canvas as dirty to force a render at the 1st idle event (wxWidgets IsShownOnScreen() is buggy and cannot be used reliably)
current_panel->set_as_dirty();
view_toolbar.select_item(current_panel->name);
if (notification_manager != nullptr)
notification_manager->set_in_preview(current_panel == preview);
current_panel->SetFocusFromKbd();
}
} }
void Plater::priv::on_select_preset(wxCommandEvent &evt) void Plater::priv::on_select_preset(wxCommandEvent &evt)
@ -3701,6 +3708,7 @@ void Plater::priv::on_slicing_update(SlicingStatusEvent &evt)
void Plater::priv::on_slicing_completed(wxCommandEvent & evt) void Plater::priv::on_slicing_completed(wxCommandEvent & evt)
{ {
notification_manager->push_slicing_complete_notification(evt.GetInt(), is_sidebar_collapsed()); notification_manager->push_slicing_complete_notification(evt.GetInt(), is_sidebar_collapsed());
main_frame->select_tab(MainFrame::ETabType::PlaterPreview);
switch (this->printer_technology) { switch (this->printer_technology) {
case ptFFF: case ptFFF:
this->update_fff_scene(); this->update_fff_scene();
@ -3780,6 +3788,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt)
this->background_process.stop(); this->background_process.stop();
this->statusbar()->reset_cancel_callback(); this->statusbar()->reset_cancel_callback();
this->statusbar()->stop_busy(); this->statusbar()->stop_busy();
main_frame->select_tab(MainFrame::ETabType::PlaterGcode);
// Reset the "export G-code path" name, so that the automatic background processing will be enabled again. // Reset the "export G-code path" name, so that the automatic background processing will be enabled again.
this->background_process.reset_export(); this->background_process.reset_export();
@ -4272,7 +4281,7 @@ bool Plater::priv::init_view_toolbar()
item.name = "3D"; item.name = "3D";
item.icon_filename = "editor.svg"; item.icon_filename = "editor.svg";
item.tooltip = _utf8(L("3D editor view")) + " [" + GUI::shortkey_ctrl_prefix() + "5]"; item.tooltip = _utf8(L("3D editor view")) + " [" + GUI::shortkey_ctrl_prefix() + "1]";
item.sprite_id = 0; item.sprite_id = 0;
item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); }; item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_3D)); };
if (!view_toolbar.add_item(item)) if (!view_toolbar.add_item(item))
@ -4280,14 +4289,13 @@ bool Plater::priv::init_view_toolbar()
item.name = "Preview"; item.name = "Preview";
item.icon_filename = "preview.svg"; item.icon_filename = "preview.svg";
item.tooltip = _utf8(L("Preview")) + " [" + GUI::shortkey_ctrl_prefix() + "6]"; item.tooltip = _utf8(L("Preview")) + " [" + GUI::shortkey_ctrl_prefix() + "3]";
item.sprite_id = 1; item.sprite_id = 1;
item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); }; item.left.action_callback = [this]() { if (this->q != nullptr) wxPostEvent(this->q, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); };
if (!view_toolbar.add_item(item)) if (!view_toolbar.add_item(item))
return false; return false;
view_toolbar.select_item("3D"); view_toolbar.select_item("3D");
view_toolbar.set_enabled(true);
return true; return true;
} }
@ -5221,6 +5229,15 @@ void Plater::select_view(const std::string& direction) { p->select_view(directio
void Plater::select_view_3D(const std::string& name) { p->select_view_3D(name); } void Plater::select_view_3D(const std::string& name) { p->select_view_3D(name); }
void Plater::set_force_preview(Preview::ForceState force) {
if (p->preview)
p->preview->set_force_state(force);
}
Preview::ForceState Plater::get_force_preview() {
return p->preview->get_force_state();
}
bool Plater::is_preview_shown() const { return p->is_preview_shown(); } bool Plater::is_preview_shown() const { return p->is_preview_shown(); }
bool Plater::is_preview_loaded() const { return p->is_preview_loaded(); } bool Plater::is_preview_loaded() const { return p->is_preview_loaded(); }
bool Plater::is_view3D_shown() const { return p->is_view3D_shown(); } bool Plater::is_view3D_shown() const { return p->is_view3D_shown(); }

View File

@ -14,6 +14,7 @@
#include "libslic3r/GCode/GCodeProcessor.hpp" #include "libslic3r/GCode/GCodeProcessor.hpp"
#include "Jobs/Job.hpp" #include "Jobs/Job.hpp"
#include "Search.hpp" #include "Search.hpp"
#include "GUI_Preview.hpp"
class wxButton; class wxButton;
class ScalableButton; class ScalableButton;
@ -166,6 +167,8 @@ public:
void stop_jobs(); void stop_jobs();
void select_view(const std::string& direction); void select_view(const std::string& direction);
void select_view_3D(const std::string& name); void select_view_3D(const std::string& name);
void set_force_preview(Preview::ForceState force);
Preview::ForceState get_force_preview();
bool is_preview_shown() const; bool is_preview_shown() const;
bool is_preview_loaded() const; bool is_preview_loaded() const;

View File

@ -304,6 +304,8 @@ void PreferencesDialog::build()
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : ""; m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "";
else if (opt_key.find("color") != std::string::npos) else if (opt_key.find("color") != std::string::npos)
m_values[opt_key] = boost::any_cast<std::string>(value); m_values[opt_key] = boost::any_cast<std::string>(value);
else if (opt_key.find("tab_icon_size") != std::string::npos)
m_values[opt_key] = std::to_string(boost::any_cast<int>(value));
else else
m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0"; m_values[opt_key] = boost::any_cast<bool>(value) ? "1" : "0";
@ -345,6 +347,15 @@ void PreferencesDialog::build()
def.set_default_value(new ConfigOptionBool{ app_config->get("use_custom_toolbar_size") == "1" }); def.set_default_value(new ConfigOptionBool{ app_config->get("use_custom_toolbar_size") == "1" });
option = Option(def, "use_custom_toolbar_size"); option = Option(def, "use_custom_toolbar_size");
m_optgroup_gui->append_single_option_line(option); m_optgroup_gui->append_single_option_line(option);
def.label = L("Tab icon size");
def.type = coInt;
def.tooltip = std::string(L("Size of the tab icons, in pixels. Set to 0 to remove icons."))
+ std::string(L("\nYou have to restart the application before any change will be taken into account."));
def.set_default_value(new ConfigOptionInt{ atoi(app_config->get("tab_icon_size").c_str()) });
option = Option(def, "tab_icon_size");
option.opt.width = 6;
m_optgroup_gui->append_single_option_line(option);
} }
@ -469,7 +480,7 @@ void PreferencesDialog::accept()
if (it != m_values.end() && app_config->get(key) != it->second) { if (it != m_values.end() && app_config->get(key) != it->second) {
m_settings_layout_changed = true; m_settings_layout_changed = true;
break; break;
} }
} }
for (const std::string& key : {"default_action_on_close_application", "default_action_on_select_preset"}) { for (const std::string& key : {"default_action_on_close_application", "default_action_on_select_preset"}) {
@ -574,27 +585,30 @@ void PreferencesDialog::create_icon_size_slider()
void PreferencesDialog::create_settings_mode_widget() void PreferencesDialog::create_settings_mode_widget()
{ {
wxString choices[] = { _L("Old regular layout with the tab bar"), wxString choices[] = { _L("Regular layout with the tab bar"),
_L("New layout, access via settings button in the top menu"), _L("Old PrusaSlicer layout"),
_L("Access via settings button in the top menu"),
_L("Settings in non-modal window") }; _L("Settings in non-modal window") };
auto app_config = get_app_config(); auto app_config = get_app_config();
int selection = app_config->get("old_settings_layout_mode") == "1" ? 0 : int selection = app_config->get("tab_settings_layout_mode") == "1" ? 0 :
app_config->get("new_settings_layout_mode") == "1" ? 1 : app_config->get("old_settings_layout_mode") == "1" ? 1 :
app_config->get("dlg_settings_layout_mode") == "1" ? 2 : 0; app_config->get("new_settings_layout_mode") == "1" ? 2 :
app_config->get("dlg_settings_layout_mode") == "1" ? 3 : 1;
wxWindow* parent = m_optgroup_gui->parent(); wxWindow* parent = m_optgroup_gui->parent();
m_layout_mode_box = new wxRadioBox(parent, wxID_ANY, _L("Layout Options"), wxDefaultPosition, wxDefaultSize, m_layout_mode_box = new wxRadioBox(parent, wxID_ANY, _L("Layout Options"), wxDefaultPosition, wxDefaultSize,
WXSIZEOF(choices), choices, 3, wxRA_SPECIFY_ROWS); WXSIZEOF(choices), choices, 4, wxRA_SPECIFY_ROWS);
m_layout_mode_box->SetFont(wxGetApp().normal_font()); m_layout_mode_box->SetFont(wxGetApp().normal_font());
m_layout_mode_box->SetSelection(selection); m_layout_mode_box->SetSelection(selection);
m_layout_mode_box->Bind(wxEVT_RADIOBOX, [this](wxCommandEvent& e) { m_layout_mode_box->Bind(wxEVT_RADIOBOX, [this](wxCommandEvent& e) {
int selection = e.GetSelection(); int selection = e.GetSelection();
m_values["old_settings_layout_mode"] = boost::any_cast<bool>(selection == 0) ? "1" : "0"; m_values["tab_settings_layout_mode"] = boost::any_cast<bool>(selection == 0) ? "1" : "0";
m_values["new_settings_layout_mode"] = boost::any_cast<bool>(selection == 1) ? "1" : "0"; m_values["old_settings_layout_mode"] = boost::any_cast<bool>(selection == 1) ? "1" : "0";
m_values["dlg_settings_layout_mode"] = boost::any_cast<bool>(selection == 2) ? "1" : "0"; m_values["new_settings_layout_mode"] = boost::any_cast<bool>(selection == 2) ? "1" : "0";
m_values["dlg_settings_layout_mode"] = boost::any_cast<bool>(selection == 3) ? "1" : "0";
}); });
auto sizer = new wxBoxSizer(wxHORIZONTAL); auto sizer = new wxBoxSizer(wxHORIZONTAL);

View File

@ -696,7 +696,7 @@ bool PlaterPresetComboBox::switch_to_tab()
wxGetApp().tab_panel()->SetSelection(page_id); wxGetApp().tab_panel()->SetSelection(page_id);
// Switch to Settings NotePad // Switch to Settings NotePad
wxGetApp().mainframe->select_tab(); wxGetApp().mainframe->select_tab(MainFrame::ETabType::LastSettings);
return true; return true;
} }

View File

@ -559,7 +559,7 @@ UnsavedChangesDialog::UnsavedChangesDialog(Preset::Type type, PresetCollection*
const std::string& def_action = wxGetApp().app_config->get(m_app_config_key); const std::string& def_action = wxGetApp().app_config->get(m_app_config_key);
if (def_action == "none") { if (def_action == "none") {
if (wxGetApp().mainframe->is_dlg_layout() && wxGetApp().mainframe->m_settings_dialog.HasFocus()) if (wxGetApp().mainframe->get_layout() == MainFrame::ESettingsLayout::Dlg && wxGetApp().mainframe->m_settings_dialog.HasFocus())
this->SetPosition(wxGetApp().mainframe->m_settings_dialog.GetPosition()); this->SetPosition(wxGetApp().mainframe->m_settings_dialog.GetPosition());
this->CenterOnScreen(); this->CenterOnScreen();
} }