Change the legacy GUI tabs to be more like slic3r.

This commit is contained in:
remi durand 2021-03-27 23:52:58 +01:00
parent acc7720066
commit 80bee28b84
8 changed files with 150 additions and 60 deletions

View File

@ -1292,6 +1292,12 @@ void GLCanvas3D::set_as_dirty()
m_dirty = true;
}
void GLCanvas3D::set_items_show(bool show_volumes, bool show_gcode)
{
m_show_volume = show_volumes;
m_show_gcode = show_gcode;
}
unsigned int GLCanvas3D::get_volumes_count() const
{
return (unsigned int)m_volumes.volumes.size();
@ -1661,9 +1667,9 @@ void GLCanvas3D::render()
// draw scene
glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
_render_background();
_render_objects();
if (!m_main_toolbar.is_enabled())
if(m_show_volume)
_render_objects();
if (m_show_gcode && !m_main_toolbar.is_enabled())
_render_gcode();
_render_sla_slices();
_render_selection();

View File

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

View File

@ -57,6 +57,9 @@ View3D::~View3D()
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 */))
return false;
@ -195,6 +198,10 @@ Preview::Preview(
bool Preview::init(wxWindow* parent, Model* model)
{
name = "Preview";
title = "Gcode Preview";
if (!Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* disable wxTAB_TRAVERSAL */))
return false;
@ -921,6 +928,7 @@ void Preview::load_print_as_fff(bool keep_z_range)
GCodeViewer::EViewType gcode_view_type = m_canvas->get_gcode_view_preview_type();
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.
std::vector<std::string> colors;
std::vector<CustomGCode::Item> color_print_values = {};
@ -934,7 +942,6 @@ void Preview::load_print_as_fff(bool keep_z_range)
}
}
else if (gcode_view_type == GCodeViewer::EViewType::Filament)
{
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"));
@ -954,7 +961,6 @@ void Preview::load_print_as_fff(bool keep_z_range)
color_print_values.clear();
}
else if (gcode_preview_data_valid || (gcode_view_type == GCodeViewer::EViewType::Tool))
{
colors = wxGetApp().plater()->get_extruder_colors_from_plater_config();
color_print_values.clear();
@ -962,9 +968,15 @@ void Preview::load_print_as_fff(bool keep_z_range)
if (IsShown()) {
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);
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.
m_canvas->load_gcode_preview(*m_gcode_result);
m_canvas->refresh_gcode_preview(*m_gcode_result, colors);

View File

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

View File

@ -263,8 +263,14 @@ void MainFrame::update_layout()
// On Linux m_plater needs to be removed from m_tabpanel before to reparent it
int plater_page_id = m_tabpanel->FindPage(m_plater);
if (plater_page_id != wxNOT_FOUND)
while (plater_page_id != wxNOT_FOUND) {
m_tabpanel->RemovePage(plater_page_id);
plater_page_id = m_tabpanel->FindPage(m_plater);
}
for (int i = 0; i < m_tabpanel->GetPageCount(); i++) {
m_tabpanel->SetPageImage(i, -1);
}
m_tabpanel->SetImageList(nullptr); //clear
if (m_plater->GetParent() != this)
m_plater->Reparent(this);
@ -286,6 +292,8 @@ void MainFrame::update_layout()
m_tabpanel->Hide();
m_plater->Hide();
m_plater->enable_view_toolbar(true);
m_plater->force_preview(Preview::ForceState::NoForce);
Layout();
};
@ -305,6 +313,8 @@ void MainFrame::update_layout()
// Remove old settings
if (m_layout != ESettingsLayout::Unknown)
restore_to_creation();
else //init with view_toolbar by default
m_plater->enable_view_toolbar(true);
#ifdef __WXMSW__
enum class State {
@ -331,8 +341,27 @@ void MainFrame::update_layout()
}
case ESettingsLayout::Old:
{
// don't use view_toolbar here
m_plater->enable_view_toolbar(false);
m_plater->Reparent(m_tabpanel);
m_tabpanel->InsertPage(0, m_plater, _L("Plater"));
// icons for ESettingsLayout::Old
wxImageList* img_list = nullptr;
for (std::string icon_name : {"editor_menu", "layers", "preview_menu", "cog"}) {
const wxBitmap& bmp = create_scaled_bitmap(icon_name, this, 32);
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, m_plater, _L("3D view"));
m_tabpanel->InsertPage(1, m_plater, _L("Sliced preview"));
m_tabpanel->InsertPage(2, m_plater, _L("Gcode preview"));
m_tabpanel->SetPageImage(0, 0);
m_tabpanel->SetPageImage(1, 1);
m_tabpanel->SetPageImage(2, 2);
m_tabpanel->SetPageImage(3, 3);
m_tabpanel->SetPageImage(4, 3);
m_tabpanel->SetPageImage(5, 3);
m_main_sizer->Add(m_tabpanel, 1, wxEXPAND);
m_plater->Show();
m_tabpanel->Show();
@ -538,6 +567,7 @@ void MainFrame::init_tabpanel()
m_tabpanel->Hide();
m_settings_dialog.set_tabpanel(m_tabpanel);
m_tabpanel->Bind(wxEVT_NOTEBOOK_PAGE_CHANGED, [this](wxEvent&) {
wxWindow* panel = m_tabpanel->GetCurrentPage();
Tab* tab = dynamic_cast<Tab*>(panel);
@ -547,13 +577,27 @@ void MainFrame::init_tabpanel()
return;
auto& tabs_list = wxGetApp().tabs_list;
int last_selected_tab = m_last_selected_tab;
if (tab && std::find(tabs_list.begin(), tabs_list.end(), tab) != tabs_list.end()) {
// On GTK, the wxEVT_NOTEBOOK_PAGE_CHANGED event is triggered
// before the MainFrame is fully set up.
tab->OnActivate();
m_last_selected_tab = m_tabpanel->GetSelection();
}
else
else if (this->m_layout == ESettingsLayout::Old) {
if (m_tabpanel->GetSelection() == 0)
this->m_plater->select_view_3D("3D");
else if (m_tabpanel->GetSelection() == 1) {
this->m_plater->force_preview(Preview::ForceState::ForceExtrusions);
this->m_plater->select_view_3D("Preview");
this->m_plater->refresh_print();
}
else if (m_tabpanel->GetSelection() == 2) {
this->m_plater->force_preview(Preview::ForceState::ForceGcode);
this->m_plater->select_view_3D("Preview");
this->m_plater->refresh_print();
}
}else
select_tab(size_t(0)); // select Plater
});
@ -565,7 +609,7 @@ void MainFrame::init_tabpanel()
wxGetApp().obj_list()->create_popup_menus();
if (wxGetApp().is_editor())
create_preset_tabs();
create_preset_tabs();
if (m_plater) {
// load initial config

View File

@ -1634,8 +1634,8 @@ struct Plater::priv
// GUI elements
wxSizer* panel_sizer{ nullptr };
wxPanel* current_panel{ nullptr };
std::vector<wxPanel*> panels;
wxTitledPanel* current_panel{ nullptr };
std::vector<wxTitledPanel*> panels;
Sidebar *sidebar;
Bed3D bed;
Camera camera;
@ -1839,7 +1839,7 @@ struct Plater::priv
void reload_all_from_disk();
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_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->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())
preview->hide_layers_slider();
@ -2267,28 +2267,33 @@ void Plater::priv::update(unsigned int flags)
void Plater::priv::select_view(const std::string& direction)
{
if (current_panel == view3D)
view3D->select_view(direction);
else if (current_panel == preview)
preview->select_view(direction);
if(current_panel != nullptr)
current_panel->select_view(direction);
}
void Plater::priv::select_view_3D(const std::string& name)
{
if (name == "3D")
set_current_panel(view3D);
else if (name == "Preview")
set_current_panel(preview);
for (wxTitledPanel* panel : panels) {
if (panel->name == name) {
set_current_panel(panel);
break;
}
}
wxGetApp().update_ui_from_settings(false);
}
void Plater::priv::select_next_view_3D()
{
if (current_panel == view3D)
set_current_panel(preview);
else if (current_panel == preview)
set_current_panel(view3D);
for (int i = 0; i < panels.size(); i++) {
if (panels[i] == current_panel) {
if (i + 1 == panels.size()) {
set_current_panel(panels[0]);
} else {
set_current_panel(panels[i+1]);
}
return;
}
}
}
void Plater::priv::collapse_sidebar(bool collapse)
@ -3488,7 +3493,7 @@ void Plater::priv::fix_through_netfabb(const int obj_idx, const int vol_idx/* =
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())
return;
@ -3500,7 +3505,7 @@ void Plater::priv::set_current_panel(wxPanel* panel)
if (current_panel == panel)
return;
wxPanel* old_panel = current_panel;
wxTitledPanel* old_panel = current_panel;
current_panel = panel;
// to reduce flickering when changing view, first set as visible the new current panel
for (wxPanel* p : panels) {
@ -3525,12 +3530,12 @@ void Plater::priv::set_current_panel(wxPanel* panel)
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 (old_panel == preview)
preview->get_canvas3d()->unbind_event_handlers();
view3D->get_canvas3d()->bind_event_handlers();
if (view3D->is_reload_delayed()) {
// Delayed loading of the 3D scene.
if (this->printer_technology == ptSLA) {
@ -3540,19 +3545,8 @@ void Plater::priv::set_current_panel(wxPanel* panel)
} else
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) {
if (old_panel == view3D)
view3D->get_canvas3d()->unbind_event_handlers();
preview->get_canvas3d()->bind_event_handlers();
// 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
bool export_in_progress = this->background_process.is_export_scheduled();
@ -3561,14 +3555,17 @@ void Plater::priv::set_current_panel(wxPanel* panel)
this->q->reslice();
// keeps current gcode preview, if any
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)
@ -4287,7 +4284,6 @@ bool Plater::priv::init_view_toolbar()
return false;
view_toolbar.select_item("3D");
view_toolbar.set_enabled(true);
return true;
}
@ -5221,6 +5217,11 @@ 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::force_preview(Preview::ForceState force) {
if (p->preview)
p->preview->set_force_state(force);
}
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_view3D_shown() const { return p->is_view3D_shown(); }

View File

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

View File

@ -561,8 +561,8 @@ void PreferencesDialog::create_icon_size_slider()
void PreferencesDialog::create_settings_mode_widget()
{
wxString choices[] = { _L("Old regular layout with the tab bar"),
_L("New layout, access via settings button in the top menu"),
wxString choices[] = { _L("Regular layout with the tab bar"),
_L("Access via settings button in the top menu"),
_L("Settings in non-modal window") };
auto app_config = get_app_config();