Ensure slice / print buttons visible on frame (Accordion tabs) (#12772)

Fixes
https://github.com/OrcaSlicer/OrcaSlicer/issues/12723#issuecomment-4033223440

## NOTES
• Icons easy to discern so its not an issue
• User will explore this feature while resizing window so its ok as well
• maybe will add a tooltip while button compacted on future

## PROBLEM
print / slice buttons not visible in frame and not usable. bbl machines
uses much more tabs and issue gets worse

**regular printer on minimum window size**
<img width="766" height="96" alt="Screenshot-20260315014602"
src="https://github.com/user-attachments/assets/965e72d2-64d6-462e-abbf-f3c355783da0"
/>

**bbl printer on minimum size**
<img width="764" height="93" alt="Screenshot-20260315014708"
src="https://github.com/user-attachments/assets/1250afd1-45c3-42d9-bda3-334671ec7dc5"
/>

## SOLUTION
tabs uses only icons to reduce space usage dynamically depends on
available space

**regular printer**

![explorer_PoszqO4wyw](https://github.com/user-attachments/assets/848331ee-0206-41a8-961f-e65e68ca5f56)

**bbl printer with multi device enabled**

![explorer_WznxxHVgIJ](https://github.com/user-attachments/assets/3e3a0414-71c2-436d-be3d-d1f380d5d299)

**worst case scenario without issue. (minimum window width + multi
device + Export sliced plate button)**
<img width="772" height="97" alt="Screenshot-20260315015216"
src="https://github.com/user-attachments/assets/8b21d693-4119-4f91-b16d-d734e4633b87"
/>

**adapts automatically to used layout**

![firefox_W80FMQaHee](https://github.com/user-attachments/assets/3f9eed31-2f8d-4763-8911-bf765175d30d)
This commit is contained in:
SoftFever
2026-03-17 18:34:59 +08:00
committed by GitHub
4 changed files with 69 additions and 5 deletions

View File

@@ -475,7 +475,9 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, BORDERLESS_FRAME_
update_edge_panels(); update_edge_panels();
#endif #endif
wxQueueEvent(wxGetApp().plater(), new SimpleEvent(EVT_NOTICE_CHILDE_SIZE_CHANGED)); wxQueueEvent(wxGetApp().plater(), new SimpleEvent(EVT_NOTICE_CHILDE_SIZE_CHANGED));
});
fit_tab_labels(); // ORCA on resize
});
//BBS //BBS
Bind(EVT_SELECT_TAB, [this](wxCommandEvent&evt) { Bind(EVT_SELECT_TAB, [this](wxCommandEvent&evt) {
@@ -1242,6 +1244,7 @@ void MainFrame::init_tabpanel() {
wxPostEvent(m_plater, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW)); wxPostEvent(m_plater, SimpleEvent(EVT_GLVIEWTOOLBAR_PREVIEW));
m_param_panel->OnActivate(); m_param_panel->OnActivate();
} }
fit_tab_labels(); // ORCA on switching prepare / preview
} }
//else if (panel == m_param_panel) //else if (panel == m_param_panel)
// m_param_panel->OnActivate(); // m_param_panel->OnActivate();
@@ -1345,8 +1348,10 @@ void MainFrame::init_tabpanel() {
void MainFrame::show_device(bool bBBLPrinter) { void MainFrame::show_device(bool bBBLPrinter) {
auto idx = -1; auto idx = -1;
if (bBBLPrinter) { if (bBBLPrinter) {
if (m_tabpanel->FindPage(m_monitor) != wxNOT_FOUND) if (m_tabpanel->FindPage(m_monitor) != wxNOT_FOUND) {
fit_tab_labels(); // ORCA on printer change - same button layout
return; return;
}
// Remove printer view // Remove printer view
if ((idx = m_tabpanel->FindPage(m_printer_view)) != wxNOT_FOUND) { if ((idx = m_tabpanel->FindPage(m_printer_view)) != wxNOT_FOUND) {
m_printer_view->Show(false); m_printer_view->Show(false);
@@ -1386,9 +1391,10 @@ void MainFrame::show_device(bool bBBLPrinter) {
#endif // _MSW_DARK_MODE #endif // _MSW_DARK_MODE
} else { } else {
if (m_tabpanel->FindPage(m_printer_view) != wxNOT_FOUND) if (m_tabpanel->FindPage(m_printer_view) != wxNOT_FOUND) {
fit_tab_labels(); // ORCA on printer change - same button layout
return; return;
}
if ((idx = m_tabpanel->FindPage(m_calibration)) != wxNOT_FOUND) { if ((idx = m_tabpanel->FindPage(m_calibration)) != wxNOT_FOUND) {
m_calibration->Show(false); m_calibration->Show(false);
m_tabpanel->RemovePage(idx); m_tabpanel->RemovePage(idx);
@@ -1414,6 +1420,33 @@ void MainFrame::show_device(bool bBBLPrinter) {
m_tabpanel->InsertPage(tpMonitor, m_printer_view, _L("Device"), std::string("tab_monitor_active"), m_tabpanel->InsertPage(tpMonitor, m_printer_view, _L("Device"), std::string("tab_monitor_active"),
std::string("tab_monitor_active")); std::string("tab_monitor_active"));
} }
fit_tab_labels(); // ORCA on printer change
}
void MainFrame::fit_tab_labels()
{
if (!m_tabpanel || !m_slice_option_btn) // ignore layout change while slice/print buttons not visible
return;
auto* ctrl = m_tabpanel->GetBtnsListCtrl();
auto* sizer = ctrl->GetBtnsSizer();
int count = sizer->GetItemCount();
// Restore all
for (size_t i = 1; i < count; ++i)
ctrl->SetCompact(i, false);
m_tabpanel->Refresh();
Layout();
// Compact (last to first)
for (size_t i = count - 1; i >= 1; --i) {
int right = ScreenToClient(m_slice_option_btn->ClientToScreen({})).x;
int left = sizer->GetSize().GetWidth();
if (right - left - FromDIP(15) > 0) return;
ctrl->SetCompact(i, true);
m_tabpanel->Refresh();
Layout();
}
} }
bool MainFrame::preview_only_hint() bool MainFrame::preview_only_hint()
@@ -1790,7 +1823,7 @@ wxBoxSizer* MainFrame::create_side_tools()
update_side_button_style(); update_side_button_style();
m_slice_option_btn->Enable(); m_slice_option_btn->Enable();
m_print_option_btn->Enable(); m_print_option_btn->Enable();
sizer->Add(FromDIP(15), 0, 0, 0, 0); //sizer->Add(FromDIP(15), 0, 0, 0, 0);
sizer->Add(slice_panel); sizer->Add(slice_panel);
sizer->Add(FromDIP(15), 0, 0, 0, 0); sizer->Add(FromDIP(15), 0, 0, 0, 0);
sizer->Add(print_panel); sizer->Add(print_panel);
@@ -1915,6 +1948,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_slice_enable = get_enable_slice_status(); m_slice_enable = get_enable_slice_status();
m_slice_btn->Enable(m_slice_enable); m_slice_btn->Enable(m_slice_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
if(m_slice_option_pop_up) if(m_slice_option_pop_up)
m_slice_option_pop_up->Dismiss(); m_slice_option_pop_up->Dismiss();
}); });
@@ -1925,6 +1959,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_slice_enable = get_enable_slice_status(); m_slice_enable = get_enable_slice_status();
m_slice_btn->Enable(m_slice_enable); m_slice_btn->Enable(m_slice_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
if(m_slice_option_pop_up) if(m_slice_option_pop_up)
m_slice_option_pop_up->Dismiss(); m_slice_option_pop_up->Dismiss();
}); });
@@ -1949,6 +1984,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
@@ -1961,6 +1997,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
@@ -1987,6 +2024,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
@@ -1998,6 +2036,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
@@ -2007,6 +2046,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
@@ -2018,6 +2058,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
@@ -2027,6 +2068,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
@@ -2036,6 +2078,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
@@ -2074,6 +2117,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
p->append_button(print_multi_machine_btn); p->append_button(print_multi_machine_btn);
@@ -2088,6 +2132,7 @@ wxBoxSizer* MainFrame::create_side_tools()
m_print_enable = get_enable_print_status(); m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable); m_print_btn->Enable(m_print_enable);
this->Layout(); this->Layout();
fit_tab_labels(); // ORCA on label change
p->Dismiss(); p->Dismiss();
}); });
p->append_button(export_gcode_btn); p->append_button(export_gcode_btn);
@@ -2400,6 +2445,8 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect)
this->SetSize(sz); this->SetSize(sz);
this->Maximize(is_maximized); this->Maximize(is_maximized);
fit_tab_labels(); // ORCA
} }
void MainFrame::on_sys_color_changed() void MainFrame::on_sys_color_changed()

View File

@@ -359,6 +359,7 @@ public:
//SoftFever //SoftFever
void show_device(bool bBBLPrinter); void show_device(bool bBBLPrinter);
void fit_tab_labels(); // ORCA
PA_Calibration_Dlg* m_pa_calib_dlg{ nullptr }; PA_Calibration_Dlg* m_pa_calib_dlg{ nullptr };
Temp_Calibration_Dlg* m_temp_calib_dlg{ nullptr }; Temp_Calibration_Dlg* m_temp_calib_dlg{ nullptr };

View File

@@ -202,6 +202,7 @@ bool ButtonsListCtrl::InsertPage(size_t n, const wxString &text, bool bSelect /*
}); });
Slic3r::GUI::wxGetApp().UpdateDarkUI(btn); Slic3r::GUI::wxGetApp().UpdateDarkUI(btn);
m_pageButtons.insert(m_pageButtons.begin() + n, btn); m_pageButtons.insert(m_pageButtons.begin() + n, btn);
m_pageLabels.insert(m_pageLabels.begin() + n, text); // ORCA
m_buttons_sizer->Insert(n, new wxSizerItem(btn)); m_buttons_sizer->Insert(n, new wxSizerItem(btn));
m_buttons_sizer->SetCols(m_buttons_sizer->GetCols() + 1); m_buttons_sizer->SetCols(m_buttons_sizer->GetCols() + 1);
m_sizer->Layout(); m_sizer->Layout();
@@ -212,6 +213,7 @@ void ButtonsListCtrl::RemovePage(size_t n)
{ {
Button* btn = m_pageButtons[n]; Button* btn = m_pageButtons[n];
m_pageButtons.erase(m_pageButtons.begin() + n); m_pageButtons.erase(m_pageButtons.begin() + n);
m_pageLabels.erase(m_pageLabels.begin() + n); // ORCA
m_buttons_sizer->Remove(n); m_buttons_sizer->Remove(n);
#if __WXOSX__ #if __WXOSX__
RemoveChild(btn); RemoveChild(btn);
@@ -238,6 +240,17 @@ void ButtonsListCtrl::SetPageText(size_t n, const wxString& strText)
{ {
Button* btn = m_pageButtons[n]; Button* btn = m_pageButtons[n];
btn->SetLabel(strText); btn->SetLabel(strText);
if(!strText.empty()) // ORCA
m_pageLabels[n] = strText;
}
// ORCA
void ButtonsListCtrl::SetCompact(size_t n, bool compact)
{
int em = em_unit(this);
Button* btn = m_pageButtons[n];
btn->SetMinSize({(compact ? 40 : 136) * em / 10, 36 * em / 10});
btn->SetLabel(compact ? "" : (" " + m_pageLabels[n]));
} }
wxString ButtonsListCtrl::GetPageText(size_t n) const wxString ButtonsListCtrl::GetPageText(size_t n) const

View File

@@ -28,7 +28,9 @@ public:
void RemovePage(size_t n); void RemovePage(size_t n);
bool SetPageImage(size_t n, const std::string& bmp_name) const; bool SetPageImage(size_t n, const std::string& bmp_name) const;
void SetPageText(size_t n, const wxString& strText); void SetPageText(size_t n, const wxString& strText);
void SetCompact(size_t n, bool compact); // ORCA
wxString GetPageText(size_t n) const; wxString GetPageText(size_t n) const;
wxFlexGridSizer* GetBtnsSizer(){return m_buttons_sizer;}; // ORCA
private: private:
wxFlexGridSizer* m_buttons_sizer; wxFlexGridSizer* m_buttons_sizer;
@@ -39,6 +41,7 @@ private:
int m_btn_margin; int m_btn_margin;
int m_line_margin; int m_line_margin;
//ModeSizer* m_mode_sizer {nullptr}; //ModeSizer* m_mode_sizer {nullptr};
std::vector<wxString> m_pageLabels; // ORCA
}; };
class Notebook: public wxBookCtrlBase class Notebook: public wxBookCtrlBase