Merge branch 'ys_tb_layout'

This commit is contained in:
Lukas Matena 2024-04-24 10:50:17 +02:00
commit 46e08ca9f1
19 changed files with 597 additions and 505 deletions

View File

@ -37,7 +37,7 @@
</g>
<g>
<g>
<path fill="#FFFFFF" d="M97.4,122.5h-7.98c-2.11,0-3.83-1.72-3.83-3.83v-2.81c-0.86-0.3-1.71-0.65-2.53-1.05l-1.99,1.99
<path fill="#808080" d="M97.4,122.5h-7.98c-2.11,0-3.83-1.72-3.83-3.83v-2.81c-0.86-0.3-1.71-0.65-2.53-1.05l-1.99,1.99
c-1.49,1.49-3.92,1.49-5.41,0l-5.64-5.65c-0.72-0.72-1.12-1.68-1.12-2.71c0-1.02,0.4-1.98,1.12-2.71l1.99-1.99
c-0.4-0.82-0.75-1.67-1.05-2.53h-2.81c-2.11,0-3.83-1.72-3.83-3.83v-7.98c0-2.11,1.72-3.83,3.83-3.83h2.81
c0.3-0.86,0.65-1.71,1.05-2.53l-1.99-1.99c-1.49-1.49-1.49-3.92,0-5.41l5.64-5.64c1.49-1.49,3.92-1.49,5.41,0L83.06,72
@ -59,7 +59,7 @@
C104.52,72.39,104.52,72.39,104.52,72.39z"/>
</g>
<g>
<path fill="#FFFFFF" d="M93.41,106.54c-7.24,0-13.14-5.89-13.14-13.14s5.89-13.14,13.14-13.14s13.14,5.89,13.14,13.14
<path fill="#808080" d="M93.41,106.54c-7.24,0-13.14-5.89-13.14-13.14s5.89-13.14,13.14-13.14s13.14,5.89,13.14,13.14
S100.65,106.54,93.41,106.54z M93.41,85.27c-4.49,0-8.14,3.65-8.14,8.14s3.65,8.14,8.14,8.14s8.14-3.65,8.14-8.14
S97.89,85.27,93.41,85.27z"/>
</g>

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@ -109,6 +109,8 @@ src/slic3r/GUI/SurfaceDrag.cpp
src/slic3r/GUI/SysInfoDialog.cpp
src/slic3r/GUI/Tab.cpp
src/slic3r/GUI/Tab.hpp
src/slic3r/GUI/TopBar.cpp
src/slic3r/GUI/TopBarMenu.cpp
src/slic3r/GUI/UnsavedChangesDialog.cpp
src/slic3r/GUI/UpdateDialogs.cpp
src/slic3r/GUI/WifiConfigDialog.cpp

View File

@ -101,9 +101,6 @@ void AppConfig::set_defaults()
if (get("associate_stl").empty())
set("associate_stl", "0");
if (get("tabs_as_menu").empty())
set("tabs_as_menu", "0");
if (get("suppress_round_corners").empty())
set("suppress_round_corners", "1");
#endif // _WIN32

View File

@ -258,6 +258,8 @@ set(SLIC3R_GUI_SOURCES
GUI/Notebook.hpp
GUI/TopBar.cpp
GUI/TopBar.hpp
GUI/TopBarMenus.cpp
GUI/TopBarMenus.hpp
GUI/ObjectDataViewModel.cpp
GUI/ObjectDataViewModel.hpp
GUI/InstanceCheck.cpp

View File

@ -5137,7 +5137,7 @@ bool GLCanvas3D::_init_main_toolbar()
if (!m_main_toolbar.add_separator())
return false;
/*
item.name = "settings";
item.icon_filename = "settings.svg";
item.tooltip = _u8L("Switch to Settings") + "\n" + "[" + GUI::shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") +
@ -5145,12 +5145,11 @@ bool GLCanvas3D::_init_main_toolbar()
"\n" + "[" + GUI::shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab")) ;
item.sprite_id = 10;
item.enabling_callback = GLToolbarItem::Default_Enabling_Callback;
item.visibility_callback = []() { return wxGetApp().app_config->get_bool("new_settings_layout_mode") ||
wxGetApp().app_config->get_bool("dlg_settings_layout_mode"); };
item.visibility_callback = []() { return wxGetApp().app_config->get_bool("dlg_settings_layout_mode"); };
item.left.action_callback = []() { wxGetApp().mainframe->select_tab(); };
if (!m_main_toolbar.add_item(item))
return false;
*/
if (!m_main_toolbar.add_separator())
return false;

View File

@ -12,6 +12,7 @@
#include "GUI_ObjectList.hpp"
#include "GUI_ObjectManipulation.hpp"
#include "GUI_Factories.hpp"
#include "TopBar.hpp"
#include "format.hpp"
// Localization headers: include libslic3r version first so everything in this file
@ -1111,11 +1112,16 @@ void GUI_App::jump_to_option(const std::string& composite_key)
}
}
void GUI_App::update_search_lines()
{
mainframe->update_search_lines(m_searcher->search_string());
}
void GUI_App::show_search_dialog()
{
// To avoid endless loop caused by mutual lose focuses from serch_input and search_dialog
// invoke killFocus for serch_input by set focus to tab_panel
GUI::wxGetApp().tab_panel()->SetFocus();
m_searcher->set_focus_to_parent();
check_and_update_searcher(get_mode());
m_searcher->show_dialog();
@ -1823,11 +1829,6 @@ void GUI_App::set_mode_palette(const std::vector<wxColour>& palette)
}
}
bool GUI_App::tabs_as_menu() const
{
return app_config->get_bool("tabs_as_menu"); // || dark_mode();
}
bool GUI_App::suppress_round_corners() const
{
return true;// app_config->get("suppress_round_corners") == "1";
@ -2479,8 +2480,8 @@ void GUI_App::update_mode()
{
sidebar().update_mode();
if (!wxGetApp().tabs_as_menu())
dynamic_cast<TopBar*>(mainframe->m_tabpanel)->UpdateMode();
mainframe->m_tmp_top_bar->UpdateMode();
mainframe->m_tabpanel->UpdateMode();
for (auto tab : tabs_list)
tab->update_mode();

View File

@ -203,6 +203,7 @@ public:
void jump_to_option(const std::string& opt_key, Preset::Type type, const std::wstring& category);
// jump to option which is represented by composite key : "opt_key;tab_name"
void jump_to_option(const std::string& composite_key);
void update_search_lines();
void show_search_dialog();
// To be called after the GUI is fully built up.
@ -265,7 +266,6 @@ public:
const wxFont& code_font() { return m_code_font; }
const wxFont& link_font() { return m_link_font; }
int em_unit() const { return m_em_unit; }
bool tabs_as_menu() const;
bool suppress_round_corners() const;
wxSize get_min_size(wxWindow* display_win) const;
int get_max_font_pt_size();

View File

@ -57,7 +57,6 @@
#include "GUI_App.hpp"
#include "UnsavedChangesDialog.hpp"
#include "MsgDialog.hpp"
//#include "Notebook.hpp"
#include "TopBar.hpp"
#include "GUI_Factories.hpp"
#include "GUI_ObjectList.hpp"
@ -278,26 +277,32 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
event.Skip();
});
#ifdef _WIN32
Bind(wxEVT_SIZE, [this](wxSizeEvent& event) {
event.Skip();
#ifdef _WIN32
// Update window property to mainframe so other instances can indentify it.
wxGetApp().other_instance_message_handler()->update_windows_properties(this);
});
#endif //WIN32
if (m_layout == ESettingsLayout::Dlg || m_layout == ESettingsLayout::Old) {
if (m_layout == ESettingsLayout::Old)
m_tabpanel->UpdateSearchSizeAndPosition();
else
m_tmp_top_bar->UpdateSearchSizeAndPosition();
}
});
Bind(wxEVT_MOVE, [](wxMoveEvent& event) {
// OSX specific issue:
// When we move application between Retina and non-Retina displays, The legend on a canvas doesn't redraw
// So, redraw explicitly canvas, when application is moved
//FIXME maybe this is useful for __WXGTK3__ as well?
#if __APPLE__
Bind(wxEVT_MOVE, [](wxMoveEvent& event) {
wxGetApp().plater()->get_current_canvas3D()->set_as_dirty();
wxGetApp().plater()->get_current_canvas3D()->request_extra_frame();
#endif
wxGetApp().searcher().update_dialog_position();
event.Skip();
});
#endif
wxGetApp().persist_window_geometry(this, true);
wxGetApp().persist_window_geometry(&m_settings_dialog, true);
@ -317,91 +322,6 @@ DPIFrame(NULL, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_S
}
}
#ifdef _MSW_DARK_MODE
static wxString pref() { return " [ "; }
static wxString suff() { return " ] "; }
static void append_tab_menu_items_to_menubar(wxMenuBar* bar, PrinterTechnology pt, bool is_mainframe_menu)
{
if (is_mainframe_menu)
bar->Append(new wxMenu(), pref() + _L("Plater") + suff());
for (const wxString& title : { is_mainframe_menu ? _L("Print Settings") : pref() + _L("Print Settings") + suff(),
pt == ptSLA ? _L("Material Settings") : _L("Filament Settings"),
_L("Printer Settings") })
bar->Append(new wxMenu(), title);
}
// update markers for selected/unselected menu items
static void update_marker_for_tabs_menu(wxMenuBar* bar, const wxString& title, bool is_mainframe_menu)
{
if (!bar)
return;
size_t items_cnt = bar->GetMenuCount();
for (size_t id = items_cnt - (is_mainframe_menu ? 4 : 3); id < items_cnt; id++) {
wxString label = bar->GetMenuLabel(id);
if (label.First(pref()) == 0) {
if (label == pref() + title + suff())
return;
label.Remove(size_t(0), pref().Len());
label.RemoveLast(suff().Len());
bar->SetMenuLabel(id, label);
break;
}
}
if (int id = bar->FindMenu(title); id != wxNOT_FOUND)
bar->SetMenuLabel(id, pref() + title + suff());
}
static void add_tabs_as_menu(wxMenuBar* bar, MainFrame* main_frame, wxWindow* bar_parent)
{
PrinterTechnology pt = main_frame->plater() ? main_frame->plater()->printer_technology() : ptFFF;
bool is_mainframe_menu = bar_parent == main_frame;
if (!is_mainframe_menu)
append_tab_menu_items_to_menubar(bar, pt, is_mainframe_menu);
bar_parent->Bind(wxEVT_MENU_OPEN, [main_frame, bar, is_mainframe_menu](wxMenuEvent& event) {
wxMenu* const menu = event.GetMenu();
if (!menu || menu->GetMenuItemCount() > 0) {
// If we are here it means that we open regular menu and not a tab used as a menu
event.Skip(); // event.Skip() is verry important to next processing of the wxEVT_UPDATE_UI by this menu items.
// If wxEVT_MENU_OPEN will not be pocessed in next event queue then MenuItems of this menu will never caught wxEVT_UPDATE_UI
// and, as a result, "check/radio value" will not be updated
return;
}
// update tab selection
const wxString& title = menu->GetTitle();
if (title == _L("Plater"))
main_frame->select_tab(size_t(0));
else if (title == _L("Print Settings"))
main_frame->select_tab(wxGetApp().get_tab(main_frame->plater()->printer_technology() == ptFFF ? Preset::TYPE_PRINT : Preset::TYPE_SLA_PRINT));
else if (title == _L("Filament Settings"))
main_frame->select_tab(wxGetApp().get_tab(Preset::TYPE_FILAMENT));
else if (title == _L("Material Settings"))
main_frame->select_tab(wxGetApp().get_tab(Preset::TYPE_SLA_MATERIAL));
else if (title == _L("Printer Settings"))
main_frame->select_tab(wxGetApp().get_tab(Preset::TYPE_PRINTER));
// update markers for selected/unselected menu items
update_marker_for_tabs_menu(bar, title, is_mainframe_menu);
});
}
void MainFrame::show_tabs_menu(bool show)
{
if (!m_menubar)
return;
if (show)
append_tab_menu_items_to_menubar(m_menubar, plater() ? plater()->printer_technology() : ptFFF, true);
else
while (m_menubar->GetMenuCount() >= 8) {
if (wxMenu* menu = m_menubar->Remove(7))
delete menu;
}
}
#endif // _MSW_DARK_MODE
void MainFrame::update_layout()
{
auto restore_to_creation = [this]() {
@ -435,6 +355,7 @@ void MainFrame::update_layout()
m_settings_dialog.Close();
m_tabpanel->Hide();
m_tmp_top_bar->Hide();
m_plater->Hide();
Layout();
@ -442,7 +363,6 @@ void MainFrame::update_layout()
ESettingsLayout layout = wxGetApp().is_gcode_viewer() ? ESettingsLayout::GCodeViewer :
(wxGetApp().app_config->get_bool("old_settings_layout_mode") ? ESettingsLayout::Old :
wxGetApp().app_config->get_bool("new_settings_layout_mode") ? ( wxGetApp().tabs_as_menu() ? ESettingsLayout::Old : ESettingsLayout::New) :
wxGetApp().app_config->get_bool("dlg_settings_layout_mode") ? ESettingsLayout::Dlg : ESettingsLayout::Old);
if (m_layout == layout)
@ -484,54 +404,35 @@ void MainFrame::update_layout()
{
m_plater->Reparent(m_tabpanel);
m_plater->Layout();
#ifdef _WIN32
if (wxGetApp().tabs_as_menu())
m_tabpanel->InsertPage(0, m_plater, _L("Plater"));
else
#endif
dynamic_cast<TopBar*>(m_tabpanel)->InsertNewPage(0, m_plater, _L("Plater"), std::string("plater"), true);
m_tabpanel->InsertNewPage(0, m_plater, _L("Plater"), std::string("plater"), true);
m_main_sizer->Add(m_tabpanel, 1, wxEXPAND | wxTOP, 1);
m_plater->Show();
m_tabpanel->Show();
m_tabpanel->ShowFull();
m_tmp_top_bar->Hide();
// update Tabs
if (old_layout == ESettingsLayout::Dlg)
if (int sel = m_tabpanel->GetSelection(); sel != wxNOT_FOUND)
m_tabpanel->SetSelection(sel+1);// call SetSelection to correct layout after switching from Dlg to Old mode
#ifdef _MSW_DARK_MODE
if (wxGetApp().tabs_as_menu())
show_tabs_menu(true);
#endif
break;
}
case ESettingsLayout::New:
{
m_main_sizer->Add(m_plater, 1, wxEXPAND);
m_tabpanel->Hide();
m_main_sizer->Add(m_tabpanel, 1, wxEXPAND);
m_plater_page = new wxPanel(m_tabpanel);
#ifdef _WIN32
if (wxGetApp().tabs_as_menu())
m_tabpanel->InsertPage(0, m_plater_page, _L("Plater")); // empty panel just for Plater tab
else
#endif
dynamic_cast<TopBar*>(m_tabpanel)->InsertNewPage(0, m_plater_page, _L("Plater"), std::string("plater"), true);
m_plater->Show();
break;
}
case ESettingsLayout::Dlg:
{
m_main_sizer->Add(m_plater, 1, wxEXPAND);
m_tabpanel->Reparent(&m_settings_dialog);
m_settings_dialog.GetSizer()->Add(m_tabpanel, 1, wxEXPAND | wxTOP, 2);
m_tabpanel->Show();
const int sel = m_tabpanel->GetSelection();
m_plater->Reparent(this);
m_main_sizer->Add(m_tmp_top_bar, 0, wxEXPAND | wxTOP, 1);
m_main_sizer->Add(m_plater, 1, wxEXPAND | wxTOP, 1);
m_plater->Layout();
m_tmp_top_bar->ShowFull();
m_plater->Show();
#ifdef _WIN32
if (wxGetApp().tabs_as_menu())
show_tabs_menu(false);
#endif
m_tabpanel->Reparent(&m_settings_dialog);
m_tabpanel->SetSelection(sel > 0 ? (sel - 1) : 0);
m_tabpanel->ShowJustMode();
m_settings_dialog.GetSizer()->Add(m_tabpanel, 1, wxEXPAND | wxTOP, 2);
m_settings_dialog.Layout();
break;
}
case ESettingsLayout::GCodeViewer:
@ -574,20 +475,6 @@ void MainFrame::update_layout()
}
}
#endif //__WXMSW__
//#ifdef __APPLE__
// // Using SetMinSize() on Mac messes up the window position in some cases
// // cf. https://groups.google.com/forum/#!topic/wx-users/yUKPBBfXWO0
// // 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
// // Otherwise, MainFrame will be maximized by height
// if (m_layout == ESettingsLayout::New) {
// wxSize size = wxGetApp().get_min_size();
// size.SetHeight(int(0.5 * size.GetHeight()));
// m_plater->SetMinSize(size);
// m_tabpanel->SetMinSize(size);
// }
//#endif
Layout();
Thaw();
@ -704,20 +591,27 @@ void MainFrame::update_title()
SetTitle(title);
}
static wxString GetTooltipForSettingsButton(PrinterTechnology pt)
{
std::string tooltip = _u8L("Switch to Settings") + "\n" + "[" + shortkey_ctrl_prefix() + "2] - " + _u8L("Print Settings Tab") +
"\n" + "[" + shortkey_ctrl_prefix() + "3] - " + (pt == ptFFF ? _u8L("Filament Settings Tab") : _u8L("Material Settings Tab")) +
"\n" + "[" + shortkey_ctrl_prefix() + "4] - " + _u8L("Printer Settings Tab");
return from_u8(tooltip);
}
void MainFrame::init_tabpanel()
{
wxGetApp().update_ui_colours_from_appconfig();
if (wxGetApp().is_editor()) {
m_tmp_top_bar = new TopBar(this, &m_bar_menus, false);
m_tmp_top_bar->SetFont(Slic3r::GUI::wxGetApp().normal_font());
m_tmp_top_bar->Hide();
}
// wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
// with multiple high resolution displays connected.
#ifdef _MSW_DARK_MODE
if (wxGetApp().tabs_as_menu()) {
m_tabpanel = new wxSimplebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
// wxGetApp().UpdateDarkUI(m_tabpanel);
}
else
#endif
m_tabpanel = new TopBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME);
m_tabpanel = new TopBar(this, &m_bar_menus);
m_tabpanel->SetFont(Slic3r::GUI::wxGetApp().normal_font());
m_tabpanel->Hide();
@ -748,10 +642,6 @@ void MainFrame::init_tabpanel()
// before the MainFrame is fully set up.
tab->OnActivate();
m_last_selected_tab = m_tabpanel->GetSelection();
#ifdef _MSW_DARK_MODE
if (wxGetApp().tabs_as_menu())
tab->SetFocus();
#endif
}
else
select_tab(size_t(0)); // select Plater
@ -775,6 +665,9 @@ void MainFrame::init_tabpanel()
if (full_config.has("nozzle_diameter")) {
m_plater->sidebar().set_extruders_count(full_config.option<ConfigOptionFloats>("nozzle_diameter")->values.size());
}
if (wxGetApp().is_editor())
m_tmp_top_bar->SetSettingsButtonTooltip(GetTooltipForSettingsButton(m_plater->printer_technology()));
}
}
@ -854,15 +747,17 @@ void MainFrame::add_connect_webview_tab()
{
if (m_connect_webview_added) {
return;
} // parameters of InsertNewPage (to prevent ambigous overloaded function)
// insert to positon 4, if physical printer is already added, it moves to 5
}
// parameters of InsertNewPage (to prevent ambigous overloaded function)
// insert "Connect" tab to position next to "Printer" tab
// order of tabs: Plater - Print Settings - Filaments - Printers - Prusa Connect - Prusa Link
size_t n = 4;
int n = m_tabpanel->FindPage(wxGetApp().get_tab(Preset::TYPE_PRINTER)) + 1;
wxWindow* page = m_connect_webview;
const wxString text(L"Prusa Connect");
const std::string bmp_name = "";
bool bSelect = false;
dynamic_cast<TopBar*>(m_tabpanel)->InsertNewPage(n, page, text, bmp_name, bSelect);
m_tabpanel->InsertNewPage(n, page, text, bmp_name, bSelect);
m_connect_webview->load_default_url_delayed();
m_connect_webview_added = true;
}
@ -871,10 +766,10 @@ void MainFrame::remove_connect_webview_tab()
if (!m_connect_webview_added) {
return;
}
// connect tab should always be at position 4
if (m_tabpanel->GetSelection() == 4)
int n = m_tabpanel->FindPage(m_connect_webview);
if (m_tabpanel->GetSelection() == n)
m_tabpanel->SetSelection(0);
dynamic_cast<TopBar*>(m_tabpanel)->RemovePage(4);
m_tabpanel->RemovePage(size_t(n));
m_connect_webview_added = false;
m_connect_webview->logout();
}
@ -922,7 +817,7 @@ void MainFrame::add_printer_webview_tab(const wxString& url)
}
m_printer_webview_added = true;
// add as the last (rightmost) panel
dynamic_cast<TopBar*>(m_tabpanel)->AddNewPage(m_printer_webview, _L("Physical Printer"), "");
m_tabpanel->AddNewPage(m_printer_webview, _L("Physical Printer"), "");
m_printer_webview->set_default_url(url);
m_printer_webview->load_default_url_delayed();
}
@ -933,7 +828,7 @@ void MainFrame::remove_printer_webview_tab()
}
m_printer_webview_added = false;
m_printer_webview->Hide();
dynamic_cast<TopBar*>(m_tabpanel)->RemovePage(m_tabpanel->FindPage(m_printer_webview));
m_tabpanel->RemovePage(m_tabpanel->FindPage(m_printer_webview));
}
void MainFrame::set_printer_webview_tab_url(const wxString& url)
{
@ -963,7 +858,9 @@ void MainFrame::set_printer_webview_credentials(const std::string& usr, const st
void Slic3r::GUI::MainFrame::refresh_account_menu(bool avatar/* = false */)
{
// Update User name in TopBar
dynamic_cast<TopBar*>(m_tabpanel)->GetTopBarItemsCtrl()->UpdateAccountMenu(avatar);
m_bar_menus.UpdateAccountMenu(m_plater->get_user_account());
m_tabpanel->GetTopBarItemsCtrl()->UpdateAccountButton(avatar);
m_tmp_top_bar->GetTopBarItemsCtrl()->UpdateAccountButton(avatar);
}
void MainFrame::add_created_tab(Tab* panel, const std::string& bmp_name /*= ""*/)
@ -972,14 +869,8 @@ void MainFrame::add_created_tab(Tab* panel, const std::string& bmp_name /*= ""*
const auto printer_tech = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology();
if (panel->supports_printer_technology(printer_tech)) {
#ifdef _WIN32
if (wxGetApp().tabs_as_menu())
m_tabpanel->AddPage(panel, panel->title());
else
#endif
dynamic_cast<TopBar*>(m_tabpanel)->AddNewPage(panel, panel->title(), bmp_name);
}
if (panel->supports_printer_technology(printer_tech))
m_tabpanel->AddNewPage(panel, panel->title(), bmp_name);
}
bool MainFrame::is_active_and_shown_tab(Tab* tab)
@ -991,9 +882,6 @@ bool MainFrame::is_active_and_shown_tab(Tab* tab)
if (m_layout == ESettingsLayout::Dlg)
return m_settings_dialog.IsShown();
if (m_layout == ESettingsLayout::New)
return m_main_sizer->IsShown(m_tabpanel);
return true;
}
@ -1122,7 +1010,6 @@ bool MainFrame::can_change_view() const
switch (m_layout)
{
default: { return false; }
case ESettingsLayout::New: { return m_plater->IsShown(); }
case ESettingsLayout::Dlg: { return true; }
case ESettingsLayout::Old: {
int page_id = m_tabpanel->GetSelection();
@ -1164,8 +1051,7 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect)
#ifdef _WIN32
// update common mode sizer
if (!wxGetApp().tabs_as_menu())
dynamic_cast<TopBar*>(m_tabpanel)->Rescale();
m_tabpanel->Rescale();
#endif
// update Plater
@ -1210,9 +1096,10 @@ void MainFrame::on_sys_color_changed()
wxGetApp().update_ui_colours_from_appconfig();
#ifdef __WXMSW__
wxGetApp().UpdateDarkUI(m_tabpanel);
if (!wxGetApp().tabs_as_menu())
wxGetApp().UpdateDarkUI(m_tmp_top_bar);
#endif
dynamic_cast<TopBar*>(m_tabpanel)->OnColorsChanged();
m_tabpanel->OnColorsChanged();
m_tmp_top_bar->OnColorsChanged();
// update Plater
wxGetApp().plater()->sys_color_changed();
@ -1236,8 +1123,8 @@ void MainFrame::on_sys_color_changed()
void MainFrame::update_mode_markers()
{
// update markers in common mode sizer
if (!wxGetApp().tabs_as_menu())
dynamic_cast<TopBar*>(m_tabpanel)->UpdateModeMarkers();
m_tmp_top_bar->UpdateModeMarkers();
m_tabpanel->UpdateModeMarkers();
// update mode markers in tabs
for (auto tab : wxGetApp().tabs_list)
@ -1663,22 +1550,21 @@ void MainFrame::init_menubar_as_editor()
#ifndef __APPLE__
// append menus for Menu button from TopBar
TopBar* top_bar = dynamic_cast<TopBar*>(m_tabpanel);
top_bar->AppendMenuItem(fileMenu, _L("&File"));
m_bar_menus.AppendMenuItem(fileMenu, _L("&File"));
if (editMenu)
top_bar->AppendMenuItem(editMenu, _L("&Edit"));
m_bar_menus.AppendMenuItem(editMenu, _L("&Edit"));
top_bar->AppendMenuSeparaorItem();
m_bar_menus.AppendMenuSeparaorItem();
top_bar->AppendMenuItem(windowMenu, _L("&Window"));
m_bar_menus.AppendMenuItem(windowMenu, _L("&Window"));
if (viewMenu)
top_bar->AppendMenuItem(viewMenu, _L("&View"));
m_bar_menus.AppendMenuItem(viewMenu, _L("&View"));
top_bar->AppendMenuItem(wxGetApp().get_config_menu(), _L("&Configuration"));
m_bar_menus.AppendMenuItem(wxGetApp().get_config_menu(), _L("&Configuration"));
top_bar->AppendMenuSeparaorItem();
m_bar_menus.AppendMenuSeparaorItem();
top_bar->AppendMenuItem(helpMenu, _L("&Help"));
m_bar_menus.AppendMenuItem(helpMenu, _L("&Help"));
#else
@ -2071,6 +1957,13 @@ void MainFrame::load_config(const DynamicPrintConfig& config)
#endif
}
void MainFrame::update_search_lines(const std::string search_line)
{
wxString search = from_u8(search_line);
m_tabpanel ->UpdateSearch(search);
m_tmp_top_bar->UpdateSearch(search);
}
void MainFrame::select_tab(Tab* tab)
{
if (!tab)
@ -2095,14 +1988,7 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
if (m_tabpanel->GetSelection() != (int)new_selection)
m_tabpanel->SetSelection(new_selection);
#ifdef _MSW_DARK_MODE
if (wxGetApp().tabs_as_menu()) {
if (Tab* cur_tab = dynamic_cast<Tab*>(m_tabpanel->GetPage(new_selection)))
update_marker_for_tabs_menu((m_layout == ESettingsLayout::Old ? m_menubar : m_settings_dialog.menubar()), cur_tab->title(), m_layout == ESettingsLayout::Old);
else if (tab == 0 && m_layout == ESettingsLayout::Old)
m_plater->get_current_canvas3D()->render();
}
#endif
if (tab == 0 && m_layout == ESettingsLayout::Old)
m_plater->canvas3D()->render();
else if (was_hidden) {
@ -2143,26 +2029,11 @@ void MainFrame::select_tab(size_t tab/* = size_t(-1)*/)
if (m_settings_dialog.IsIconized())
m_settings_dialog.Iconize(false);
}
else if (m_layout == ESettingsLayout::New) {
m_main_sizer->Show(m_plater, tab == 0);
tabpanel_was_hidden = !m_main_sizer->IsShown(m_tabpanel);
select(tabpanel_was_hidden);
m_main_sizer->Show(m_tabpanel, tab != 0);
// plater should be focused for correct navigation inside search window
if (tab == 0)
m_plater->SetFocus();
Layout();
}
else {
select(false);
#ifdef _MSW_DARK_MODE
if (wxGetApp().tabs_as_menu() && tab == 0)
m_plater->SetFocus();
#endif
}
// When we run application in ESettingsLayout::New or ESettingsLayout::Dlg mode, tabpanel is hidden from the very beginning
// When we run application in 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,
// which are used for update TreeCtrl and "revert_buttons".
// So, force the call of this function for Tabs, if tab panel was hidden
@ -2233,10 +2104,12 @@ void MainFrame::add_to_recent_projects(const wxString& filename)
void MainFrame::technology_changed()
{
PrinterTechnology pt = plater()->printer_technology();
m_tmp_top_bar->SetSettingsButtonTooltip(GetTooltipForSettingsButton(pt));
if (!m_menubar)
return;
// update menu titles
PrinterTechnology pt = plater()->printer_technology();
if (int id = m_menubar->FindMenu(pt == ptFFF ? _L("Material Settings") : _L("Filament Settings")); id != wxNOT_FOUND)
m_menubar->SetMenuLabel(id , pt == ptSLA ? _L("Material Settings") : _L("Filament Settings"));
@ -2318,6 +2191,8 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
default:break;
}
}
evt.Skip();
};
if (evt.IsShown()) {
@ -2333,14 +2208,11 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
//just hide the Frame on closing
this->Bind(wxEVT_CLOSE_WINDOW, [this](wxCloseEvent& evt) { this->Hide(); });
#ifdef _MSW_DARK_MODE
if (wxGetApp().tabs_as_menu()) {
// menubar
m_menubar = new wxMenuBar();
add_tabs_as_menu(m_menubar, mainframe, this);
this->SetMenuBar(m_menubar);
}
#endif
this->Bind(wxEVT_SIZE, [this](wxSizeEvent& event) {
event.Skip();
if (m_tabpanel)
m_tabpanel->UpdateSearchSizeAndPosition();
});
// initialize layout
auto sizer = new wxBoxSizer(wxVERTICAL);
@ -2358,6 +2230,11 @@ SettingsDialog::SettingsDialog(MainFrame* mainframe)
SetSize(GetMinSize());
#endif
Layout();
Bind(wxEVT_MOVE, [](wxMoveEvent& event) {
wxGetApp().searcher().update_dialog_position();
event.Skip();
});
}
void SettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
@ -2369,9 +2246,7 @@ void SettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
const wxSize& size = wxSize(85 * em, 50 * em);
#ifdef _WIN32
// update common mode sizer
if (!wxGetApp().tabs_as_menu())
dynamic_cast<TopBar*>(m_tabpanel)->Rescale();
m_tabpanel->Rescale();
#endif
// update Tabs

View File

@ -29,7 +29,9 @@
#include "UnsavedChangesDialog.hpp"
#include "Search.hpp"
class wxBookCtrlBase;
#include "TopBarMenus.hpp"
class TopBar;
class wxProgressDialog;
namespace Slic3r {
@ -67,13 +69,13 @@ struct PresetTab {
class SettingsDialog : public DPIFrame//DPIDialog
{
wxBookCtrlBase* m_tabpanel { nullptr };
TopBar* m_tabpanel { nullptr };
MainFrame* m_main_frame { nullptr };
wxMenuBar* m_menubar{ nullptr };
public:
SettingsDialog(MainFrame* mainframe);
~SettingsDialog() = default;
void set_tabpanel(wxBookCtrlBase* tabpanel) { m_tabpanel = tabpanel; }
void set_tabpanel(TopBar* tabpanel) { m_tabpanel = tabpanel; }
wxMenuBar* menubar() { return m_menubar; }
protected:
@ -88,6 +90,7 @@ class MainFrame : public DPIFrame
wxString m_qs_last_output_file = wxEmptyString;
wxString m_last_config = wxEmptyString;
wxMenuBar* m_menubar{ nullptr };
TopBarMenus m_bar_menus;
#if 0
wxMenuItem* m_menu_item_repeat { nullptr }; // doesn't used now
@ -143,7 +146,6 @@ class MainFrame : public DPIFrame
{
Unknown,
Old,
New,
Dlg,
GCodeViewer
};
@ -181,9 +183,6 @@ public:
void update_menubar();
// Open item in menu by menu and item name (in actual language)
void open_menubar_item(const wxString& menu_name,const wxString& item_name);
#ifdef _WIN32
void show_tabs_menu(bool show);
#endif
void update_ui_from_settings();
bool is_loaded() const { return m_loaded; }
bool is_last_input_file() const { return !m_qs_last_input_file.IsEmpty(); }
@ -199,6 +198,7 @@ public:
void export_configbundle(bool export_physical_printers = false);
void load_configbundle(wxString file = wxEmptyString);
void load_config(const DynamicPrintConfig& config);
void update_search_lines(const std::string search_line);
// Select tab in m_tabpanel
// When tab == -1, will be selected last selected tab
void select_tab(Tab* tab);
@ -232,7 +232,8 @@ public:
PrintHostQueueDialog* printhost_queue_dlg() { return m_printhost_queue_dlg; }
Plater* m_plater { nullptr };
wxBookCtrlBase* m_tabpanel { nullptr };
TopBar* m_tmp_top_bar { nullptr };
TopBar* m_tabpanel { nullptr };
SettingsDialog m_settings_dialog;
DiffPresetDialog diff_dialog;
wxWindow* m_plater_page{ nullptr };

View File

@ -1167,7 +1167,7 @@ wxString OptionsGroup::get_url(const std::string& path_end)
bool OptionsGroup::launch_browser(const std::string& path_end)
{
return wxGetApp().open_browser_with_warning_dialog(OptionsGroup::get_url(path_end), wxGetApp().mainframe->m_tabpanel);
return wxGetApp().open_browser_with_warning_dialog(OptionsGroup::get_url(path_end), wxGetApp().tab_panel());
}
// list of options, which doesn't have a related filed

View File

@ -502,15 +502,6 @@ void PreferencesDialog::build()
wxGetApp().plater()->get_current_canvas3D()->render();
return;
}
if (opt_key == "tabs_as_menu") {
bool disable_new_layout = boost::any_cast<bool>(value);
m_rb_new_settings_layout_mode->Show(!disable_new_layout);
if (disable_new_layout && m_rb_new_settings_layout_mode->GetValue()) {
m_rb_new_settings_layout_mode->SetValue(false);
m_rb_old_settings_layout_mode->SetValue(true);
}
refresh_og(m_optgroup_gui);
}
if (auto it = m_values.find(opt_key); it != m_values.end()) {
m_values.erase(it); // we shouldn't change value, if some of those parameters were selected, and then deselected
@ -564,13 +555,6 @@ void PreferencesDialog::build()
L("If enabled, related notification will be shown, when sliced object looks like a logo or a sign."),
app_config->get_bool("allow_auto_color_change"));
#ifdef _MSW_DARK_MODE
append_bool_option(m_optgroup_gui, "tabs_as_menu",
L("Set settings tabs as menu items"),
L("If enabled, Settings Tabs will be placed as menu items. If disabled, old UI will be used."),
app_config->get_bool("tabs_as_menu"));
#endif
m_optgroup_gui->append_separator();
/*
append_bool_option(m_optgroup_gui, "suppress_round_corners",
@ -766,7 +750,7 @@ void PreferencesDialog::accept(wxEvent&)
#endif //(__linux__) && defined(SLIC3R_DESKTOP_INTEGRATION)
}
std::vector<std::string> options_to_recreate_GUI = { "no_defaults", "tabs_as_menu", "sys_menu_enabled", "font_pt_size", "suppress_round_corners" };
std::vector<std::string> options_to_recreate_GUI = { "no_defaults", "sys_menu_enabled", "font_pt_size", "suppress_round_corners" };
for (const std::string& option : options_to_recreate_GUI) {
if (m_values.find(option) != m_values.end()) {
@ -797,7 +781,6 @@ void PreferencesDialog::accept(wxEvent&)
m_settings_layout_changed = false;
for (const std::string& key : { "old_settings_layout_mode",
"new_settings_layout_mode",
"dlg_settings_layout_mode" })
{
auto it = m_values.find(key);
@ -875,11 +858,6 @@ void PreferencesDialog::revert(wxEvent&)
m_settings_layout_changed = false;
continue;
}
if (key == "new_settings_layout_mode") {
m_rb_new_settings_layout_mode->SetValue(app_config->get_bool(key));
m_settings_layout_changed = false;
continue;
}
if (key == "dlg_settings_layout_mode") {
m_rb_dlg_settings_layout_mode->SetValue(app_config->get_bool(key));
m_settings_layout_changed = false;
@ -897,11 +875,6 @@ void PreferencesDialog::revert(wxEvent&)
if (opt_group->set_value(key, app_config->get_bool(key)))
break;
}
if (key == "tabs_as_menu") {
m_rb_new_settings_layout_mode->Show(!app_config->get_bool(key));
refresh_og(m_optgroup_gui);
continue;
}
}
clear_cache();
@ -1026,7 +999,6 @@ void PreferencesDialog::create_settings_mode_widget()
auto app_config = get_app_config();
std::vector<wxString> choices = { _L("Old regular layout with the tab bar"),
_L("New layout, access via settings button in the top menu"),
_L("Settings in non-modal window") };
int id = -1;
auto add_radio = [this, parent, stb_sizer, choices](wxRadioButton** rb, int id, bool select) {
@ -1035,25 +1007,13 @@ void PreferencesDialog::create_settings_mode_widget()
(*rb)->SetValue(select);
(*rb)->Bind(wxEVT_RADIOBUTTON, [this, id](wxCommandEvent&) {
m_values["old_settings_layout_mode"] = (id == 0) ? "1" : "0";
m_values["new_settings_layout_mode"] = (id == 1) ? "1" : "0";
m_values["dlg_settings_layout_mode"] = (id == 2) ? "1" : "0";
m_values["dlg_settings_layout_mode"] = (id == 1) ? "1" : "0";
});
};
add_radio(&m_rb_old_settings_layout_mode, ++id, app_config->get_bool("old_settings_layout_mode"));
add_radio(&m_rb_new_settings_layout_mode, ++id, app_config->get_bool("new_settings_layout_mode"));
add_radio(&m_rb_dlg_settings_layout_mode, ++id, app_config->get_bool("dlg_settings_layout_mode"));
#ifdef _MSW_DARK_MODE
if (app_config->get_bool("tabs_as_menu")) {
m_rb_new_settings_layout_mode->Hide();
if (m_rb_new_settings_layout_mode->GetValue()) {
m_rb_new_settings_layout_mode->SetValue(false);
m_rb_old_settings_layout_mode->SetValue(true);
}
}
#endif
std::string opt_key = "settings_layout_mode";
m_blinkers[opt_key] = new BlinkingBitmap(parent);

View File

@ -57,7 +57,6 @@ class PreferencesDialog : public DPIDialog
wxSizer* m_icon_size_sizer {nullptr};
wxSlider* m_icon_size_slider {nullptr};
wxRadioButton* m_rb_old_settings_layout_mode {nullptr};
wxRadioButton* m_rb_new_settings_layout_mode {nullptr};
wxRadioButton* m_rb_dlg_settings_layout_mode {nullptr};
wxColourPickerCtrl* m_sys_colour {nullptr};

View File

@ -441,11 +441,25 @@ static bool has_focus(wxWindow* win)
void OptionsSearcher::update_dialog_position()
{
if (search_dialog) {
search_dialog->CenterOnParent(wxHORIZONTAL);
search_dialog->SetPosition({ search_dialog->GetPosition().x, search_input->GetScreenPosition().y + search_input->GetSize().y });
wxPoint old_pos = search_dialog->GetPosition();
wxPoint pos = search_input->GetScreenPosition() + wxPoint(-5, search_input->GetSize().y);
if (old_pos != pos)
search_dialog->SetPosition(pos);
}
}
void OptionsSearcher::check_and_hide_dialog()
{
if (search_dialog && search_dialog->IsShown() && !has_focus(search_dialog))
show_dialog(false);
}
void OptionsSearcher::set_focus_to_parent()
{
if (search_input)
search_input->GetParent()->SetFocus();
}
void OptionsSearcher::show_dialog(bool show /*= true*/)
{
if (search_dialog && !show) {
@ -455,7 +469,6 @@ void OptionsSearcher::show_dialog(bool show /*= true*/)
if (!search_dialog) {
search_dialog = new SearchDialog(this, search_input);
update_dialog_position();
search_dialog->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e)
{
@ -463,14 +476,8 @@ void OptionsSearcher::show_dialog(bool show /*= true*/)
show_dialog(false);
e.Skip();
});
search_input->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e)
{
e.Skip();
if (search_dialog->IsShown() && !has_focus(search_dialog))
show_dialog(false);
});
}
update_dialog_position();
search_string();
search_input->SetSelection(-1,-1);
@ -492,55 +499,33 @@ void OptionsSearcher::dlg_msw_rescale()
search_dialog->msw_rescale();
}
void OptionsSearcher::edit_search_input()
{
if (!search_input)
return;
if (search_dialog) {
search_dialog->input_text(search_input->GetValue());
if (!search_dialog->IsShown())
search_dialog->Popup();
}
else
GUI::wxGetApp().show_search_dialog();
}
void OptionsSearcher::process_key_down_from_input(wxKeyEvent& e)
{
int key = e.GetKeyCode();
if (key == WXK_ESCAPE)
search_dialog->EndModal(wxID_CLOSE);
else if (search_dialog && (key == WXK_UP || key == WXK_DOWN || key == WXK_NUMPAD_ENTER || key == WXK_RETURN))
search_dialog->KeyDown(e);
}
void OptionsSearcher::set_search_input(TextInput* input_ctrl)
{
search_input = input_ctrl;
search_input->Bind(wxEVT_TEXT, [this](wxEvent& e)
{
if (search_dialog) {
search_dialog->input_text(search_input->GetValue());
if (!search_dialog->IsShown())
search_dialog->Popup();
}
else
GUI::wxGetApp().show_search_dialog();
});
wxTextCtrl* ctrl = search_input->GetTextCtrl();
ctrl->SetToolTip(GUI::format_wxstr(_L("Search in settings [%1%]"), "Ctrl+F"));
ctrl->Bind(wxEVT_KEY_DOWN, [this](wxKeyEvent& e)
{
int key = e.GetKeyCode();
if (key == WXK_TAB)
search_input->Navigate(e.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward);
else if (key == WXK_ESCAPE)
search_dialog->EndModal(wxID_CLOSE);
else if (search_dialog && (key == WXK_UP || key == WXK_DOWN || key == WXK_NUMPAD_ENTER || key == WXK_RETURN))
search_dialog->KeyDown(e);
e.Skip();
});
ctrl->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& event)
{
if (search_input->GetValue() == default_string)
search_input->SetValue("");
event.Skip();
});
ctrl->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent& event) {
GUI::wxGetApp().show_search_dialog();
event.Skip();
});
search_input->Bind(wxEVT_MOVE, [this](wxMoveEvent& event)
{
event.Skip();
update_dialog_position();
});
search_input->SetOnDropDownIcon([](){ GUI::wxGetApp().show_search_dialog(); });
update_dialog_position();
}
void OptionsSearcher::add_key(const std::string& opt_key, Preset::Type type, const wxString& group, const wxString& category)
@ -707,7 +692,7 @@ void SearchDialog::OnKeyDown(wxKeyEvent& event)
if (key == WXK_UP || key == WXK_DOWN)
{
// So, for the next correct navigation, set focus on the search_list
search_list->SetFocus();
// search_list->SetFocus(); // #ys_delete_after_test -> Looks like no need anymore
auto item = search_list->GetSelection();

View File

@ -148,6 +148,10 @@ public:
void sort_options_by_label() { sort_options(); }
void update_dialog_position();
void edit_search_input();
void process_key_down_from_input(wxKeyEvent& e);
void check_and_hide_dialog();
void set_focus_to_parent();
void show_dialog(bool show = true);
void dlg_sys_color_changed();
void dlg_msw_rescale();

View File

@ -3658,13 +3658,7 @@ void Tab::load_current_preset()
}
if (tab->supports_printer_technology(printer_technology))
{
#ifdef _WIN32
if (wxGetApp().tabs_as_menu())
wxGetApp().tab_panel()->InsertPage(wxGetApp().tab_panel()->FindPage(this), tab, tab->title());
else
#endif
dynamic_cast<TopBar*>(wxGetApp().tab_panel())->InsertNewPage(wxGetApp().tab_panel()->FindPage(this), tab, tab->title(),"");
dynamic_cast<TopBar*>(wxGetApp().tab_panel())->InsertNewPage(wxGetApp().tab_panel()->FindPage(this), tab, tab->title(),"");
}
else {
int page_id = wxGetApp().tab_panel()->FindPage(tab);

View File

@ -1,10 +1,11 @@
#include "TopBar.hpp"
#include "TopBarMenus.hpp"
#include "GUI_App.hpp"
#include "MainFrame.hpp"
#include "Plater.hpp"
#include "Search.hpp"
#include "UserAccount.hpp"
//#include "wxExtensions.hpp"
#include "format.hpp"
#include "I18N.hpp"
@ -34,21 +35,18 @@ TopBarItemsCtrl::Button::Button(wxWindow* parent, const wxString& label, const s
{
int btn_margin = em_unit(this);
int x, y;
GetTextExtent(label, &x, &y);
GetTextExtent(label.IsEmpty() ? "a" : label, &x, &y);
wxSize size(x + 4 * btn_margin, y + int(1.5 * btn_margin));
if (icon_name.empty())
this->SetMinSize(size);
#ifdef _WIN32
else if (label.IsEmpty()) {
const int btn_side = px_cnt + btn_margin;
const int btn_side = size.y;
this->SetMinSize(wxSize(btn_side, btn_side));
}
else
#ifdef _WIN32
this->SetMinSize(wxSize(-1, size.y));
#else
else if (label.IsEmpty())
this->SetMinSize(wxSize(px_cnt, px_cnt));
else
this->SetMinSize(wxSize(size.x + px_cnt, size.y));
#endif
@ -130,9 +128,11 @@ void TopBarItemsCtrl::Button::render()
wxPoint pt = { 0, 0 };
wxString text = GetLabelText();
if (m_bmp_bundle.IsOk()) {
wxSize szIcon = get_preferred_size(m_bmp_bundle, this);
pt.x = em;
pt.x = text.IsEmpty() ? ((rc.width - szIcon.x) / 2) : em;
pt.y = (rc.height - szIcon.y) / 2;
#ifdef __WXGTK3__
dc.DrawBitmap(m_bmp_bundle.GetBitmap(szIcon), pt);
@ -144,7 +144,6 @@ void TopBarItemsCtrl::Button::render()
// Draw text
wxString text = GetLabelText();
if (!text.IsEmpty()) {
wxSize labelSize = dc.GetTextExtent(text);
if (labelSize.x > rc.width)
@ -185,18 +184,35 @@ void TopBarItemsCtrl::ButtonWithPopup::SetLabel(const wxString& label)
wxString text = label;
int btn_height = GetMinSize().GetHeight();
if (label.IsEmpty()) {
ScalableButton::SetLabel(label);
SetMinSize(wxSize(btn_height, btn_height));
return;
}
const int label_width = GetTextExtent(text).GetWidth();
bool resize_and_layout{ false };
if (m_fixed_width != wxDefaultCoord) {
const int text_width = m_fixed_width - 2 * btn_height;
const int label_width = GetTextExtent(text).GetWidth();
if (label_width > text_width) {
if (label_width > text_width || GetMinSize().GetWidth() <= btn_height) {
wxWindowDC wdc(this);
text = wxControl::Ellipsize(text, wdc, wxELLIPSIZE_END, text_width);
resize_and_layout = true;
}
}
else if (GetMinSize().GetWidth() <= btn_height)
#ifdef _WIN32
this->SetMinSize(wxSize(-1, btn_height));
#elif __APPLE__
this->SetMinSize(wxSize(label_width + 3 * btn_height, btn_height));
#else
this->SetMinSize(wxSize(label_width + 2 * btn_height, btn_height));
#endif
wxString full_label = " " + text + " " + down_arrow;
wxString full_label = " " + text + " ";
#ifndef __linux__
full_label += down_arrow;
#endif
ScalableButton::SetLabel(full_label);
if (resize_and_layout) {
SetMinSize(wxSize(m_fixed_width, btn_height));
@ -204,81 +220,11 @@ void TopBarItemsCtrl::ButtonWithPopup::SetLabel(const wxString& label)
}
}
static wxString get_workspace_name(Slic3r::ConfigOptionMode mode)
{
return mode == Slic3r::ConfigOptionMode::comSimple ? _L("Beginner mode") :
mode == Slic3r::ConfigOptionMode::comAdvanced ? _L("Normal mode") : _L("Expert mode");
}
void TopBarItemsCtrl::ApplyWorkspacesMenu()
{
wxMenuItemList& items = m_workspaces_menu.GetMenuItems();
if (!items.IsEmpty()) {
for (int id = int(m_workspaces_menu.GetMenuItemCount()) - 1; id >= 0; id--)
m_workspaces_menu.Destroy(items[id]);
}
for (const Slic3r::ConfigOptionMode& mode : { Slic3r::ConfigOptionMode::comSimple,
Slic3r::ConfigOptionMode::comAdvanced,
Slic3r::ConfigOptionMode::comExpert }) {
const wxString label = get_workspace_name(mode);
append_menu_item(&m_workspaces_menu, wxID_ANY, label, label,
[mode](wxCommandEvent&) {
if (wxGetApp().get_mode() != mode)
wxGetApp().save_mode(mode);
}, get_bmp_bundle("mode", 16, -1, wxGetApp().get_mode_btn_color(mode)));
if (mode < Slic3r::ConfigOptionMode::comExpert)
m_workspaces_menu.AppendSeparator();
}
}
void TopBarItemsCtrl::CreateAccountMenu()
{
m_user_menu_item = append_menu_item(&m_account_menu, wxID_ANY, "", "",
[this](wxCommandEvent& e) {
m_account_btn->set_selected(true);
wxGetApp().plater()->PopupMenu(&m_account_menu, m_account_btn->GetPosition());
}, get_bmp_bundle("user", 16));
m_account_menu.AppendSeparator();
#if 0
m_connect_dummy_menu_item = append_menu_item(&m_account_menu, wxID_ANY, _L("PrusaConnect Printers"), "",
[](wxCommandEvent&) { wxGetApp().plater()->get_user_account()->enqueue_connect_printers_action(); },
"", nullptr, []() { return wxGetApp().plater()->get_user_account()->is_logged(); }, this->GetParent());
wxMenuItem* remember_me_menu_item = append_menu_check_item(&m_account_menu, wxID_ANY, _L("Remember me"), ""
, [](wxCommandEvent&) { wxGetApp().plater()->get_user_account()->toggle_remember_session(); }
, &m_account_menu
, []() { return wxGetApp().plater()->get_user_account() ? wxGetApp().plater()->get_user_account()->is_logged() : false; }
, []() { return wxGetApp().plater()->get_user_account() ? wxGetApp().plater()->get_user_account()->get_remember_session() : false; }
, this->GetParent());
#endif // 0
m_login_menu_item = append_menu_item(&m_account_menu, wxID_ANY, "", "",
[](wxCommandEvent&) {
auto user_account = wxGetApp().plater()->get_user_account();
if (user_account->is_logged())
user_account->do_logout();
else
user_account->do_login();
}, get_bmp_bundle("login", 16));
}
void TopBarItemsCtrl::UpdateAccountMenu(bool avatar/* = false*/)
void TopBarItemsCtrl::UpdateAccountButton(bool avatar/* = false*/)
{
auto user_account = wxGetApp().plater()->get_user_account();
if (m_login_menu_item) {
m_login_menu_item->SetItemLabel(user_account->is_logged() ? _L("Prusa Account Log out") : _L("Prusa Account Log in"));
m_login_menu_item->SetBitmap(user_account->is_logged() ? *get_bmp_bundle("logout", 16) : *get_bmp_bundle("login", 16));
}
const wxString user_name = user_account->is_logged() ? from_u8(user_account->get_username()) : _L("Anonymous");
if (m_user_menu_item)
m_user_menu_item->SetItemLabel(user_name);
m_account_btn->SetLabel(user_name);
const wxString user_name = user_account->is_logged() ? from_u8(user_account->get_username()) : _L("Anonymous");
m_account_btn->SetLabel(m_collapsed_btns ? "" : user_name);
#ifdef __linux__
if (avatar) {
if (user_account->is_logged()) {
@ -311,6 +257,14 @@ void TopBarItemsCtrl::UpdateAccountMenu(bool avatar/* = false*/)
m_account_btn->Refresh();
}
void TopBarItemsCtrl::UnselectPopupButtons()
{
if (m_menu_btn)
m_menu_btn ->set_selected(false);
m_workspace_btn ->set_selected(false);
m_account_btn ->set_selected(false);
}
void TopBarItemsCtrl::CreateSearch()
{
// Linux specific: If wxDefaultSize is used in constructor and than set just maxSize,
@ -319,7 +273,105 @@ void TopBarItemsCtrl::CreateSearch()
m_search = new ::TextInput(this, wxGetApp().searcher().default_string, "", "search", wxDefaultPosition, wxSize(2 * em_unit(this), -1), wxTE_PROCESS_ENTER);
m_search->SetMaxSize(wxSize(42*em_unit(this), -1));
wxGetApp().UpdateDarkUI(m_search);
wxGetApp().searcher().set_search_input(m_search);
m_search->Bind(wxEVT_TEXT, [](wxEvent& e)
{
wxGetApp().searcher().edit_search_input();
wxGetApp().update_search_lines();
});
m_search->Bind(wxEVT_MOVE, [](wxMoveEvent& event)
{
event.Skip();
wxGetApp().searcher().update_dialog_position();
});
m_search->SetOnDropDownIcon([this]()
{
wxGetApp().searcher().set_search_input(m_search);
wxGetApp().show_search_dialog();
});
m_search->Bind(wxEVT_KILL_FOCUS, [](wxFocusEvent& e)
{
e.Skip();
wxGetApp().searcher().check_and_hide_dialog();
});
wxTextCtrl* ctrl = m_search->GetTextCtrl();
ctrl->SetToolTip(format_wxstr(_L("Search in settings [%1%]"), "Ctrl+F"));
ctrl->Bind(wxEVT_KEY_DOWN, [this](wxKeyEvent& e)
{
wxGetApp().searcher().set_search_input(m_search);
if (e.GetKeyCode() == WXK_TAB)
m_search->Navigate(e.ShiftDown() ? wxNavigationKeyEvent::IsBackward : wxNavigationKeyEvent::IsForward);
else
wxGetApp().searcher().process_key_down_from_input(e);
e.Skip();
});
ctrl->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& event)
{
wxGetApp().searcher().set_search_input(m_search);
wxGetApp().show_search_dialog();
event.Skip();
});
ctrl->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent& event)
{
if (m_search->GetValue() == wxGetApp().searcher().default_string)
m_search->SetValue("");
event.Skip();
});
}
void TopBarItemsCtrl::UpdateSearchSizeAndPosition()
{
if (!m_workspace_btn || !m_account_btn)
return;
int em = em_unit(this);
int btns_width = 2 * m_btn_margin;
if (m_menu_btn)
btns_width += m_menu_btn->GetSize().GetWidth();
else
btns_width += 4 * em;
if (m_settings_btn)
btns_width += m_settings_btn->GetSize().GetWidth() + m_btn_margin;
else {
for (const Button* btn : m_pageButtons)
btns_width += btn->GetSize().GetWidth() + m_btn_margin;
}
wxWindow* parent_win = GetParent()->GetParent();
int top_win_without_sidebar = parent_win->GetSize().GetWidth() - 42 * em;
bool update_bnts{ false };
if (top_win_without_sidebar - btns_width < 15 * em) {
if (!m_collapsed_btns) {
m_sizer->SetItemMinSize(1, wxSize(20, -1));
m_collapsed_btns = update_bnts = true;
}
}
else if (m_collapsed_btns) {
m_sizer->SetItemMinSize(1, wxSize(42 * em, -1));
m_collapsed_btns = false;
update_bnts = true;
}
if (update_bnts) {
UpdateMode();
UpdateAccountButton();
}
}
void TopBarItemsCtrl::UpdateSearch(const wxString& search)
{
if (search != m_search->GetValue())
m_search->SetValue(search);
}
void TopBarItemsCtrl::update_margins()
@ -332,12 +384,13 @@ void TopBarItemsCtrl::update_margins()
wxPoint TopBarItemsCtrl::ButtonWithPopup::get_popup_pos()
{
wxPoint pos = this->GetPosition();
pos.y = -pos.y + int(0.2 * wxGetApp().em_unit());
pos.y += this->GetSize().GetHeight() + int(0.2 * wxGetApp().em_unit());
return pos;
}
TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent) :
TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent, TopBarMenus* menus/* = nullptr*/, bool is_main/* = true*/) :
wxControl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxTAB_TRAVERSAL)
,m_menus(menus)
{
#ifdef __WINDOWS__
SetDoubleBuffered(true);
@ -360,57 +413,61 @@ TopBarItemsCtrl::TopBarItemsCtrl(wxWindow *parent) :
m_menu_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
m_menu_btn->set_selected(true);
// !!! To popup main menu use native wxPanel::PopupMenu() function
// Don't use wrap function Plater::PopupMenu(), because it's no need in this case
wxGetApp().plater()->wxPanel::PopupMenu(&m_main_menu, m_menu_btn->get_popup_pos());
m_menus->Popup(this, &m_menus->main, m_menu_btn->get_popup_pos());
});
m_main_menu.Bind(wxEVT_MENU_CLOSE, [this](wxMenuEvent&) { m_menu_btn->set_selected(false); });
#endif
if (!is_main) {
m_settings_btn = new Button(this, _L("Settings"/*, "settings"*/));
m_settings_btn->Bind(wxEVT_BUTTON, [](wxCommandEvent& event) {
wxGetApp().mainframe->select_tab();
});
left_sizer->Add(m_settings_btn, 0, wxALIGN_CENTER_VERTICAL);
}
m_buttons_sizer = new wxFlexGridSizer(1, m_btn_margin, m_btn_margin);
left_sizer->Add(m_buttons_sizer, 0, wxALIGN_CENTER_VERTICAL/* | wxLEFT*/ | wxRIGHT, 2 * m_btn_margin);
left_sizer->Add(m_buttons_sizer, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, m_btn_margin);
CreateSearch();
if (!is_main)
wxGetApp().searcher().set_search_input(m_search);
wxBoxSizer* search_sizer = new wxBoxSizer(wxVERTICAL);
search_sizer->Add(m_search, 1, wxEXPAND | wxALIGN_RIGHT);
left_sizer->Add(search_sizer, 1, wxALIGN_CENTER_VERTICAL);
left_sizer->Add(search_sizer, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, m_btn_margin);
m_sizer->Add(left_sizer, 1, wxEXPAND);
wxBoxSizer* right_sizer = new wxBoxSizer(wxHORIZONTAL);
// create modes menu
ApplyWorkspacesMenu();
m_workspace_btn = new ButtonWithPopup(this, _L("Workspace"), "mode_simple");
right_sizer->AddStretchSpacer(20);
right_sizer->Add(m_workspace_btn, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT);
right_sizer->Add(m_workspace_btn, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, m_btn_margin);
m_workspace_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
m_workspace_btn->set_selected(true);
wxGetApp().plater()->wxPanel::PopupMenu(&m_workspaces_menu, m_workspace_btn->get_popup_pos());
m_menus->Popup(this, &m_menus->workspaces, m_workspace_btn->get_popup_pos());
});
m_workspaces_menu.Bind(wxEVT_MENU_CLOSE, [this](wxMenuEvent&) { m_workspace_btn->set_selected(false); });
// create Account menu
CreateAccountMenu();
m_account_btn = new ButtonWithPopup(this, _L("Anonymous"), "user", wxSize(18 * em_unit(this), -1));
right_sizer->Add(m_account_btn, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxRIGHT | wxLEFT, m_btn_margin);
right_sizer->Add(m_account_btn, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxRIGHT, m_btn_margin);
m_account_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
UpdateAccountMenu();
m_account_btn->set_selected(true);
wxGetApp().plater()->wxPanel::PopupMenu(&m_account_menu, m_account_btn->get_popup_pos());
});
m_account_menu.Bind(wxEVT_MENU_CLOSE, [this](wxMenuEvent&) { m_account_btn->set_selected(false); });
m_menus->Popup(this, &m_menus->account, m_account_btn->get_popup_pos());
});
m_sizer->Add(right_sizer, 0, wxALIGN_CENTER_VERTICAL);
m_sizer->SetItemMinSize(1, wxSize(42 * wxGetApp().em_unit(), -1));
this->Bind(wxEVT_PAINT, &TopBarItemsCtrl::OnPaint, this);
this->Bind(wxEVT_UPDATE_UI, [](wxUpdateUIEvent& evt) {
auto user_account = wxGetApp().plater()->get_user_account();
evt.Enable(user_account ? user_account->is_logged() : false);
evt.Check (user_account ? user_account->get_remember_session() : false);
}, m_menus->remember_me_item_id);
}
void TopBarItemsCtrl::OnPaint(wxPaintEvent&)
@ -432,7 +489,7 @@ void TopBarItemsCtrl::UpdateMode()
m_workspace_btn->SetBitmapBundle(bmp);
#endif
m_workspace_btn->SetLabel(get_workspace_name(mode));
m_workspace_btn->SetLabel(m_collapsed_btns ? "" : m_menus->get_workspace_name(mode));
this->Layout();
}
@ -450,6 +507,7 @@ void TopBarItemsCtrl::Rescale()
m_buttons_sizer->SetVGap(m_btn_margin);
m_buttons_sizer->SetHGap(m_btn_margin);
UpdateSearchSizeAndPosition();
m_sizer->Layout();
}
@ -458,6 +516,8 @@ void TopBarItemsCtrl::OnColorsChanged()
wxGetApp().UpdateDarkUI(this);
if (m_menu_btn)
m_menu_btn->sys_color_changed();
if (m_settings_btn)
m_settings_btn->sys_color_changed();
m_workspace_btn->sys_color_changed();
m_account_btn->sys_color_changed();
@ -472,7 +532,7 @@ void TopBarItemsCtrl::OnColorsChanged()
void TopBarItemsCtrl::UpdateModeMarkers()
{
UpdateMode();
ApplyWorkspacesMenu();
m_menus->ApplyWorkspacesMenu();
}
void TopBarItemsCtrl::UpdateSelection()
@ -486,9 +546,9 @@ void TopBarItemsCtrl::UpdateSelection()
Refresh();
}
void TopBarItemsCtrl::SetSelection(int sel)
void TopBarItemsCtrl::SetSelection(int sel, bool force /*= false*/)
{
if (m_selection == sel)
if (m_selection == sel && !force)
return;
m_selection = sel;
UpdateSelection();
@ -510,6 +570,8 @@ bool TopBarItemsCtrl::InsertPage(size_t n, const wxString& text, bool bSelect/*
m_pageButtons.insert(m_pageButtons.begin() + n, btn);
m_buttons_sizer->Insert(n, new wxSizerItem(btn, 0, wxALIGN_CENTER_VERTICAL));
m_buttons_sizer->SetCols(m_buttons_sizer->GetCols() + 1);
UpdateSearchSizeAndPosition();
m_sizer->Layout();
return true;
}
@ -523,6 +585,8 @@ void TopBarItemsCtrl::RemovePage(size_t n)
// Under OSX call of btn->Reparent(nullptr) causes a crash, so as a workaround use RemoveChild() instead
this->RemoveChild(btn);
btn->Destroy();
UpdateSearchSizeAndPosition();
m_sizer->Layout();
}
@ -530,6 +594,7 @@ void TopBarItemsCtrl::SetPageText(size_t n, const wxString& strText)
{
ScalableButton* btn = m_pageButtons[n];
btn->SetLabel(strText);
UpdateSearchSizeAndPosition();
}
wxString TopBarItemsCtrl::GetPageText(size_t n) const
@ -538,12 +603,35 @@ wxString TopBarItemsCtrl::GetPageText(size_t n) const
return btn->GetLabel();
}
void TopBarItemsCtrl::AppendMenuItem(wxMenu* menu, const wxString& title)
void TopBarItemsCtrl::ShowFull()
{
append_submenu(&m_main_menu, menu, wxID_ANY, title, "cog");
if (m_menu_btn)
m_menu_btn->Show();
if (m_settings_btn)
m_settings_btn->Show();
m_account_btn->Show();
m_menus->set_cb_on_user_item([this]() {
m_account_btn->set_selected(true);
m_menus->Popup(this, &m_menus->account, m_account_btn->get_popup_pos());
});
UpdateSearchSizeAndPosition();
}
void TopBarItemsCtrl::AppendMenuSeparaorItem()
void TopBarItemsCtrl::ShowJustMode()
{
m_main_menu.AppendSeparator();
if (m_menu_btn)
m_menu_btn->Hide();
if (m_settings_btn)
m_settings_btn->Hide();
m_account_btn->Hide();
m_menus->set_cb_on_user_item(nullptr);
UpdateSearchSizeAndPosition();
}
void TopBarItemsCtrl::SetSettingsButtonTooltip(const wxString& tooltip)
{
if (m_settings_btn)
m_settings_btn->SetToolTip(tooltip);
}

View File

@ -1,14 +1,11 @@
#ifndef slic3r_TopBar_hpp_
#define slic3r_TopBar_hpp_
//#ifdef _WIN32
#include <wx/bookctrl.h>
#include "wxExtensions.hpp"
#include "Widgets/TextInput.hpp"
class ModeSizer;
//class ScalableButton;
class TopBarMenus;
// custom message the TopBarItemsCtrl sends to its parent (TopBar) to notify a selection change:
wxDECLARE_EVENT(wxCUSTOMEVT_TOPBAR_SEL_CHANGED, wxCommandEvent);
@ -60,24 +57,20 @@ class TopBarItemsCtrl : public wxControl
wxPoint get_popup_pos();
};
wxMenu m_main_menu;
wxMenu m_workspaces_menu;
wxMenu m_account_menu;
// Prusa Account menu items
wxMenuItem* m_user_menu_item{ nullptr };
wxMenuItem* m_login_menu_item{ nullptr };
#if 0
wxMenuItem* m_connect_dummy_menu_item{ nullptr };
#endif // 0
TopBarMenus* m_menus{ nullptr };
::TextInput* m_search{ nullptr };
bool m_collapsed_btns{ false };
public:
TopBarItemsCtrl(wxWindow* parent);
TopBarItemsCtrl(wxWindow* parent,
TopBarMenus* menus = nullptr,
bool is_main = true);
~TopBarItemsCtrl() {}
void OnPaint(wxPaintEvent&);
void SetSelection(int sel);
void SetSelection(int sel, bool force = false);
void UpdateMode();
void Rescale();
void OnColorsChanged();
@ -88,21 +81,25 @@ public:
void SetPageText(size_t n, const wxString& strText);
wxString GetPageText(size_t n) const;
void AppendMenuItem(wxMenu* menu, const wxString& title);
void AppendMenuSeparaorItem();
void ApplyWorkspacesMenu();
void CreateAccountMenu();
void UpdateAccountMenu(bool avatar = false);
void UpdateAccountButton(bool avatar = false);
void UnselectPopupButtons();
void CreateSearch();
void ShowFull();
void ShowJustMode();
void SetSettingsButtonTooltip(const wxString& tooltip);
void UpdateSearchSizeAndPosition();
void UpdateSearch(const wxString& search);
wxWindow* GetSearchCtrl() { return m_search->GetTextCtrl(); }
private:
wxFlexGridSizer* m_buttons_sizer;
wxFlexGridSizer* m_sizer;
ButtonWithPopup* m_menu_btn {nullptr};
ButtonWithPopup* m_menu_btn {nullptr};
ButtonWithPopup* m_workspace_btn {nullptr};
ButtonWithPopup* m_account_btn {nullptr};
ButtonWithPopup* m_account_btn {nullptr};
Button* m_settings_btn {nullptr};
std::vector<Button*> m_pageButtons;
int m_selection {-1};
int m_btn_margin;
@ -124,16 +121,28 @@ public:
Create(parent, winid, pos, size, style);
}
TopBar( wxWindow * parent,
TopBarMenus* menus,
bool is_main = true)
{
Init();
// wxNB_NOPAGETHEME: Disable Windows Vista theme for the Notebook background. The theme performance is terrible on Windows 10
// with multiple high resolution displays connected.
Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_TOP | wxTAB_TRAVERSAL | wxNB_NOPAGETHEME, menus, is_main);
}
bool Create(wxWindow * parent,
wxWindowID winid = wxID_ANY,
const wxPoint & pos = wxDefaultPosition,
const wxSize & size = wxDefaultSize,
long style = 0)
long style = 0,
TopBarMenus* menus = nullptr,
bool is_main = true)
{
if (!wxBookCtrlBase::Create(parent, winid, pos, size, style | wxBK_TOP))
return false;
m_bookctrl = new TopBarItemsCtrl(this);
m_bookctrl = new TopBarItemsCtrl(this, menus, is_main);
wxSizer* mainSizer = new wxBoxSizer(IsVertical() ? wxVERTICAL : wxHORIZONTAL);
@ -250,7 +259,7 @@ public:
virtual int SetSelection(size_t n) override
{
GetTopBarItemsCtrl()->SetSelection(n);
GetTopBarItemsCtrl()->SetSelection(n, true);
int ret = DoSetSelection(n, SetSelection_SendEvent);
// check that only the selected page is visible and others are hidden:
@ -258,6 +267,9 @@ public:
if (page != n)
m_pages[page]->Hide();
if (!m_pages[n]->IsShown())
m_pages[n]->Show();
return ret;
}
@ -418,12 +430,26 @@ public:
// Methods for extensions of this class
void AppendMenuItem(wxMenu* menu, const wxString& title) {
GetTopBarItemsCtrl()->AppendMenuItem(menu, title);
void ShowFull() {
Show();
GetTopBarItemsCtrl()->ShowFull();
}
void AppendMenuSeparaorItem() {
GetTopBarItemsCtrl()->AppendMenuSeparaorItem();
void ShowJustMode() {
Show();
GetTopBarItemsCtrl()->ShowJustMode();
}
void SetSettingsButtonTooltip(const wxString& tooltip) {
GetTopBarItemsCtrl()->SetSettingsButtonTooltip(tooltip);
}
void UpdateSearchSizeAndPosition() {
GetTopBarItemsCtrl()->UpdateSearchSizeAndPosition();
}
void UpdateSearch(const wxString& search) {
GetTopBarItemsCtrl()->UpdateSearch(search);
}
protected:

View File

@ -0,0 +1,111 @@
#include "TopBarMenus.hpp"
#include "TopBar.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "UserAccount.hpp"
#include "I18N.hpp"
using namespace Slic3r::GUI;
TopBarMenus::TopBarMenus()
{
CreateAccountMenu();
ApplyWorkspacesMenu();
UpdateAccountMenu();
BindEvtClose();
}
void TopBarMenus::AppendMenuItem(wxMenu* menu, const wxString& title)
{
append_submenu(&main, menu, wxID_ANY, title, "cog");
}
void TopBarMenus::AppendMenuSeparaorItem()
{
main.AppendSeparator();
}
wxString TopBarMenus::get_workspace_name(const int mode)
{
return mode == Slic3r::ConfigOptionMode::comSimple ? _L("Beginner mode") :
mode == Slic3r::ConfigOptionMode::comAdvanced ? _L("Normal mode") : _L("Expert mode");
}
void TopBarMenus::ApplyWorkspacesMenu()
{
wxMenuItemList& items = workspaces.GetMenuItems();
if (!items.IsEmpty()) {
for (int id = int(workspaces.GetMenuItemCount()) - 1; id >= 0; id--)
workspaces.Destroy(items[id]);
}
for (const Slic3r::ConfigOptionMode& mode : { Slic3r::ConfigOptionMode::comSimple,
Slic3r::ConfigOptionMode::comAdvanced,
Slic3r::ConfigOptionMode::comExpert }) {
const wxString label = get_workspace_name(mode);
append_menu_item(&workspaces, wxID_ANY, label, label,
[mode](wxCommandEvent&) {
if (wxGetApp().get_mode() != mode)
wxGetApp().save_mode(mode);
}, get_bmp_bundle("mode", 16, -1, wxGetApp().get_mode_btn_color(mode)));
if (mode < Slic3r::ConfigOptionMode::comExpert)
workspaces.AppendSeparator();
}
}
void TopBarMenus::CreateAccountMenu()
{
m_user_item = append_menu_item(&account, wxID_ANY, "", "",
[this](wxCommandEvent& e) { if (m_cb_on_user_item) m_cb_on_user_item(); }, get_bmp_bundle("user", 16));
account.AppendSeparator();
remember_me_item_id = wxWindow::NewControlId();
append_menu_check_item(&account, remember_me_item_id, _L("Remember me"), "" ,
[](wxCommandEvent&) { wxGetApp().plater()->get_user_account()->toggle_remember_session(); } , nullptr);
m_login_item = append_menu_item(&account, wxID_ANY, "", "",
[](wxCommandEvent&) {
auto user_account = wxGetApp().plater()->get_user_account();
if (user_account->is_logged())
user_account->do_logout();
else
user_account->do_login();
}, get_bmp_bundle("login", 16));
}
void TopBarMenus::UpdateAccountMenu(Slic3r::GUI::UserAccount* user_account)
{
bool is_logged = user_account && user_account->is_logged();
if (m_login_item) {
m_login_item->SetItemLabel(is_logged ? _L("Prusa Account Log out") : _L("Prusa Account Log in"));
m_login_item->SetBitmap(is_logged ? *get_bmp_bundle("logout", 16) : *get_bmp_bundle("login", 16));
}
const wxString user_name = is_logged ? from_u8(user_account->get_username()) : _L("Anonymous");
if (m_user_item)
m_user_item->SetItemLabel(user_name);
}
void TopBarMenus::Popup(TopBarItemsCtrl* popup_ctrl, wxMenu* menu, wxPoint pos)
{
m_popup_ctrl = popup_ctrl;
m_popup_ctrl->PopupMenu(menu, pos);
}
void TopBarMenus::BindEvtClose()
{
auto close_fn = [this]() {
if (m_popup_ctrl)
m_popup_ctrl->UnselectPopupButtons();
m_popup_ctrl = nullptr;
};
main. Bind(wxEVT_MENU_CLOSE, [close_fn](wxMenuEvent&) { close_fn(); });
workspaces. Bind(wxEVT_MENU_CLOSE, [close_fn](wxMenuEvent&) { close_fn(); });
account. Bind(wxEVT_MENU_CLOSE, [close_fn](wxMenuEvent&) { close_fn(); });
}

View File

@ -0,0 +1,48 @@
#ifndef slic3r_TopBarMenus_hpp_
#define slic3r_TopBarMenus_hpp_
#include <wx/menu.h>
class TopBarItemsCtrl;
class wxString;
namespace Slic3r {
namespace GUI {
class UserAccount;
}
}
class TopBarMenus
{
// Prusa Account menu items
wxMenuItem* m_user_item { nullptr };
wxMenuItem* m_login_item { nullptr };
TopBarItemsCtrl* m_popup_ctrl { nullptr };
std::function<void()> m_cb_on_user_item { nullptr };
public:
wxMenu main;
wxMenu workspaces;
wxMenu account;
wxWindowID remember_me_item_id { wxID_ANY };
TopBarMenus();
~TopBarMenus() = default;
void AppendMenuItem(wxMenu* menu, const wxString& title);
void AppendMenuSeparaorItem();
void ApplyWorkspacesMenu();
void CreateAccountMenu();
void UpdateAccountMenu(Slic3r::GUI::UserAccount* user_account = nullptr);
void Popup(TopBarItemsCtrl* popup_ctrl, wxMenu* menu, wxPoint pos);
void BindEvtClose();
wxString get_workspace_name(const /*ConfigOptionMode*/int mode);
void set_cb_on_user_item (std::function<void()> cb) { m_cb_on_user_item = cb; }
};
#endif // slic3r_TopBarMenus_hpp_