Menus related to the TopBar's buttons are extracted to the separate class.

+ Updated top bar layout in respect to the mode
+ Linux specific: Don`t show down arrow for buttons with PopupMenu
+ MainFrame: Use TopBar instead wxBookCtrlBase
This commit is contained in:
YuSanka 2024-04-17 14:05:38 +02:00 committed by Lukas Matena
parent c95bc97435
commit cd5d30d3b1
10 changed files with 303 additions and 164 deletions

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

@ -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

@ -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
@ -2474,7 +2475,8 @@ void GUI_App::update_mode()
{
sidebar().update_mode();
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

@ -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"
@ -350,6 +349,7 @@ void MainFrame::update_layout()
m_settings_dialog.Close();
m_tabpanel->Hide();
m_tmp_top_bar->Hide();
m_plater->Hide();
Layout();
@ -398,11 +398,13 @@ void MainFrame::update_layout()
{
m_plater->Reparent(m_tabpanel);
m_plater->Layout();
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)
@ -411,11 +413,20 @@ void MainFrame::update_layout()
}
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();
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:
@ -578,9 +589,15 @@ void MainFrame::init_tabpanel()
{
wxGetApp().update_ui_colours_from_appconfig();
if (wxGetApp().is_editor()) {
m_tmp_top_bar = new TopBar(this, &m_bar_menus);
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.
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();
@ -721,7 +738,7 @@ void MainFrame::add_connect_webview_tab()
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;
}
@ -733,7 +750,7 @@ void MainFrame::remove_connect_webview_tab()
// connect tab should always be at position 4
if (m_tabpanel->GetSelection() == 4)
m_tabpanel->SetSelection(0);
dynamic_cast<TopBar*>(m_tabpanel)->RemovePage(4);
m_tabpanel->RemovePage(4);
m_connect_webview_added = false;
m_connect_webview->logout();
}
@ -781,7 +798,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();
}
@ -792,7 +809,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)
{
@ -822,7 +839,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 /*= ""*/)
@ -832,7 +851,7 @@ 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))
dynamic_cast<TopBar*>(m_tabpanel)->AddNewPage(panel, panel->title(), bmp_name);
m_tabpanel->AddNewPage(panel, panel->title(), bmp_name);
}
bool MainFrame::is_active_and_shown_tab(Tab* tab)
@ -1013,7 +1032,7 @@ void MainFrame::on_dpi_changed(const wxRect& suggested_rect)
#ifdef _WIN32
// update common mode sizer
dynamic_cast<TopBar*>(m_tabpanel)->Rescale();
m_tabpanel->Rescale();
#endif
// update Plater
@ -1059,7 +1078,7 @@ void MainFrame::on_sys_color_changed()
#ifdef __WXMSW__
wxGetApp().UpdateDarkUI(m_tabpanel);
#endif
dynamic_cast<TopBar*>(m_tabpanel)->OnColorsChanged();
m_tabpanel->OnColorsChanged();
// update Plater
wxGetApp().plater()->sys_color_changed();
@ -1083,7 +1102,8 @@ void MainFrame::on_sys_color_changed()
void MainFrame::update_mode_markers()
{
// update markers in common mode sizer
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)
@ -1509,22 +1529,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
@ -2184,7 +2203,7 @@ void SettingsDialog::on_dpi_changed(const wxRect& suggested_rect)
const wxSize& size = wxSize(85 * em, 50 * em);
#ifdef _WIN32
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
@ -228,7 +231,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

@ -1,10 +1,10 @@
#include "TopBar.hpp"
#include "TopBarMenus.hpp"
#include "GUI_App.hpp"
#include "Plater.hpp"
#include "Search.hpp"
#include "UserAccount.hpp"
//#include "wxExtensions.hpp"
#include "format.hpp"
#include "I18N.hpp"
@ -196,7 +196,10 @@ void TopBarItemsCtrl::ButtonWithPopup::SetLabel(const wxString& label)
}
}
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,80 +207,10 @@ 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);
const wxString user_name = user_account->is_logged() ? from_u8(user_account->get_username()) : _L("Anonymous");
m_account_btn->SetLabel(user_name);
#ifdef __linux__
if (avatar) {
@ -311,6 +244,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,
@ -332,12 +273,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*/) :
wxControl(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE | wxTAB_TRAVERSAL)
,m_menus(menus)
{
#ifdef __WINDOWS__
SetDoubleBuffered(true);
@ -360,57 +302,51 @@ 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
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();
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);
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 +368,7 @@ void TopBarItemsCtrl::UpdateMode()
m_workspace_btn->SetBitmapBundle(bmp);
#endif
m_workspace_btn->SetLabel(get_workspace_name(mode));
m_workspace_btn->SetLabel(m_menus->get_workspace_name(mode));
this->Layout();
}
@ -472,7 +408,7 @@ void TopBarItemsCtrl::OnColorsChanged()
void TopBarItemsCtrl::UpdateModeMarkers()
{
UpdateMode();
ApplyWorkspacesMenu();
m_menus->ApplyWorkspacesMenu();
}
void TopBarItemsCtrl::UpdateSelection()
@ -486,9 +422,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();
@ -538,12 +474,22 @@ 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();
m_account_btn->Show();
UpdateAccountButton();
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());
});
}
void TopBarItemsCtrl::AppendMenuSeparaorItem()
void TopBarItemsCtrl::ShowJustMode()
{
m_main_menu.AppendSeparator();
if (m_menu_btn)
m_menu_btn->Hide();
m_account_btn->Hide();
m_menus->set_cb_on_user_item(nullptr);
}

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,17 @@ 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 };
public:
TopBarItemsCtrl(wxWindow* parent);
TopBarItemsCtrl(wxWindow* parent,
TopBarMenus* menus = nullptr);
~TopBarItemsCtrl() {}
void OnPaint(wxPaintEvent&);
void SetSelection(int sel);
void SetSelection(int sel, bool force = false);
void UpdateMode();
void Rescale();
void OnColorsChanged();
@ -88,12 +78,12 @@ 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();
wxWindow* GetSearchCtrl() { return m_search->GetTextCtrl(); }
@ -124,16 +114,26 @@ public:
Create(parent, winid, pos, size, style);
}
TopBar( wxWindow * parent,
TopBarMenus* menus)
{
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);
}
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)
{
if (!wxBookCtrlBase::Create(parent, winid, pos, size, style | wxBK_TOP))
return false;
m_bookctrl = new TopBarItemsCtrl(this);
m_bookctrl = new TopBarItemsCtrl(this, menus);
wxSizer* mainSizer = new wxBoxSizer(IsVertical() ? wxVERTICAL : wxHORIZONTAL);
@ -250,7 +250,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 +258,9 @@ public:
if (page != n)
m_pages[page]->Hide();
if (!m_pages[n]->IsShown())
m_pages[n]->Show();
return ret;
}
@ -418,13 +421,15 @@ 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();
};
protected:
virtual void UpdateSelectedPage(size_t WXUNUSED(newsel)) override

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_