mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-08-01 23:32:10 +00:00
feat: support tab icons
This commit is contained in:
@@ -869,11 +869,11 @@ void AuxiliaryPanel::init_tabpanel()
|
||||
m_assembly_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::ASSEMBLY_GUIDE);
|
||||
m_others_panel = new AuFolderPanel(m_tabpanel, AuxiliaryFolderType::OTHERS);
|
||||
|
||||
m_tabpanel->AddPage(m_designer_panel, _L("Basic Info"), "", true);
|
||||
m_tabpanel->AddPage(m_pictures_panel, _L("Pictures"), "", false);
|
||||
m_tabpanel->AddPage(m_bill_of_materials_panel, _L("Bill of Materials"), "", false);
|
||||
m_tabpanel->AddPage(m_assembly_panel, _L("Assembly Guide"), "", false);
|
||||
m_tabpanel->AddPage(m_others_panel, _L("Others"), "", false);
|
||||
m_tabpanel->AddPage(m_designer_panel, _L("Basic Info"), true);
|
||||
m_tabpanel->AddPage(m_pictures_panel, _L("Pictures"), false);
|
||||
m_tabpanel->AddPage(m_bill_of_materials_panel, _L("Bill of Materials"), false);
|
||||
m_tabpanel->AddPage(m_assembly_panel, _L("Assembly Guide"), false);
|
||||
m_tabpanel->AddPage(m_others_panel, _L("Others"), false);
|
||||
}
|
||||
|
||||
wxWindow *AuxiliaryPanel::create_side_tools()
|
||||
|
||||
@@ -488,7 +488,6 @@ void CalibrationPanel::init_tabpanel() {
|
||||
selected = true;
|
||||
m_tabpanel->AddPage(m_cali_panels[i],
|
||||
get_calibration_type_name(m_cali_panels[i]->get_calibration_mode()),
|
||||
"",
|
||||
selected);
|
||||
}
|
||||
|
||||
|
||||
@@ -1018,8 +1018,8 @@ void MainFrame::update_layout()
|
||||
{
|
||||
const int home_idx = m_tabpanel->FindPageByName(TAB_ID_HOME);
|
||||
const size_t prepare_pos = (home_idx == wxNOT_FOUND) ? 0 : static_cast<size_t>(home_idx) + 1;
|
||||
m_tabpanel->InsertPage(prepare_pos, TAB_ID_PREPARE, m_plater, _L("Prepare"), std::string("tab_3d_active"), std::string("tab_3d_active"), false);
|
||||
m_tabpanel->InsertPage(prepare_pos + 1, TAB_ID_PREVIEW, m_plater, _L("Preview"), std::string("tab_preview_active"), std::string("tab_preview_active"), false);
|
||||
m_tabpanel->InsertPage(prepare_pos, m_plater, _L("Prepare"), false, Notebook::PAGE_PREPARE);
|
||||
m_tabpanel->InsertPage(prepare_pos + 1, m_plater, _L("Preview"), false, Notebook::PAGE_PREVIEW);
|
||||
}
|
||||
m_main_sizer->Add(m_tabpanel, 1, wxEXPAND | wxTOP, 0);
|
||||
|
||||
@@ -1315,7 +1315,7 @@ void MainFrame::init_tabpanel() {
|
||||
select_tab(TAB_ID_HOME);
|
||||
m_webview->load_url(url);
|
||||
});
|
||||
m_tabpanel->AddPage(TAB_ID_HOME, m_webview, "", "tab_home_active", "tab_home_active", false);
|
||||
m_tabpanel->AddPage(m_webview, "", false, Notebook::PAGE_HOME);
|
||||
m_param_panel = new ParamsPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
|
||||
}
|
||||
|
||||
@@ -1330,7 +1330,7 @@ void MainFrame::init_tabpanel() {
|
||||
//BBS add pages
|
||||
m_monitor = new MonitorPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
m_monitor->SetBackgroundColour(*wxWHITE);
|
||||
m_tabpanel->AddPage(TAB_ID_MONITOR, m_monitor, _L("Device"), std::string("tab_monitor_active"), std::string("tab_monitor_active"), false);
|
||||
m_tabpanel->AddPage(m_monitor, _L("Device"), false, Notebook::PAGE_MONITOR);
|
||||
|
||||
m_printer_view = new PrinterWebView(m_tabpanel);
|
||||
Bind(EVT_LOAD_PRINTER_URL, [this](LoadPrinterViewEvent &evt) {
|
||||
@@ -1345,16 +1345,16 @@ void MainFrame::init_tabpanel() {
|
||||
m_multi_machine = new MultiMachinePage(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
m_multi_machine->SetBackgroundColour(*wxWHITE);
|
||||
// TODO: change the bitmap
|
||||
m_tabpanel->AddPage(TAB_ID_MULTI_DEVICE, m_multi_machine, _L("Multi-device"), std::string("tab_multi_active"), std::string("tab_multi_active"), false);
|
||||
m_tabpanel->AddPage(m_multi_machine, _L("Multi-device"), false, Notebook::PAGE_MULTI_DEVICE);
|
||||
}
|
||||
|
||||
m_project = new ProjectPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
m_project->SetBackgroundColour(*wxWHITE);
|
||||
m_tabpanel->AddPage(TAB_ID_PROJECT, m_project, _L("Project"), std::string("tab_auxiliary_active"), std::string("tab_auxiliary_active"), false);
|
||||
m_tabpanel->AddPage(m_project, _L("Project"), false, Notebook::PAGE_PROJECT);
|
||||
|
||||
m_calibration = new CalibrationPanel(m_tabpanel, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
||||
m_calibration->SetBackgroundColour(*wxWHITE);
|
||||
m_tabpanel->AddPage(TAB_ID_CALIBRATION, m_calibration, _L("Calibration"), std::string("tab_calibration_active"), std::string("tab_calibration_active"), false);
|
||||
m_tabpanel->AddPage(m_calibration, _L("Calibration"), false, Notebook::PAGE_CALIBRATION);
|
||||
|
||||
// Plugin pages are appended after the built-in tabs; their ids are namespaced
|
||||
// (plugin.<plugin_key>.<name>) so they can't collide with the built-in TAB_ID_* constants.
|
||||
@@ -1397,7 +1397,7 @@ void MainFrame::show_device(bool bBBLPrinter) {
|
||||
{
|
||||
const int preview_idx = m_tabpanel->FindPageByName(TAB_ID_PREVIEW);
|
||||
const size_t monitor_pos = (preview_idx == wxNOT_FOUND) ? m_tabpanel->GetPageCount() : static_cast<size_t>(preview_idx) + 1;
|
||||
m_tabpanel->InsertPage(monitor_pos, TAB_ID_MONITOR, m_monitor, _L("Device"), std::string("tab_monitor_active"), std::string("tab_monitor_active"));
|
||||
m_tabpanel->InsertPage(monitor_pos, m_monitor, _L("Device"), false, Notebook::PAGE_MONITOR);
|
||||
}
|
||||
|
||||
if (wxGetApp().is_enable_multi_machine()) {
|
||||
@@ -1410,8 +1410,7 @@ void MainFrame::show_device(bool bBBLPrinter) {
|
||||
{
|
||||
const int monitor_idx = m_tabpanel->FindPageByName(TAB_ID_MONITOR);
|
||||
const size_t multi_pos = (monitor_idx == wxNOT_FOUND) ? m_tabpanel->GetPageCount() : static_cast<size_t>(monitor_idx) + 1;
|
||||
m_tabpanel->InsertPage(multi_pos, TAB_ID_MULTI_DEVICE, m_multi_machine, _L("Multi-device"), std::string("tab_multi_active"),
|
||||
std::string("tab_multi_active"), false);
|
||||
m_tabpanel->InsertPage(multi_pos, m_multi_machine, _L("Multi-device"), false, Notebook::PAGE_MULTI_DEVICE);
|
||||
}
|
||||
}
|
||||
if (!m_calibration) {
|
||||
@@ -1422,8 +1421,7 @@ void MainFrame::show_device(bool bBBLPrinter) {
|
||||
// Calibration is always appended last (AddPage), so it lands after whichever of Monitor/Multi-device
|
||||
// actually got inserted above — no longer position-sensitive now that insertion position is computed
|
||||
// from FindPageByName rather than a fixed TabPosition index.
|
||||
m_tabpanel->AddPage(TAB_ID_CALIBRATION, m_calibration, _L("Calibration"), std::string("tab_calibration_active"),
|
||||
std::string("tab_calibration_active"), false);
|
||||
m_tabpanel->AddPage(m_calibration, _L("Calibration"), false, Notebook::PAGE_CALIBRATION);
|
||||
|
||||
#ifdef _MSW_DARK_MODE
|
||||
wxGetApp().UpdateDarkUIWin(this);
|
||||
@@ -1459,8 +1457,7 @@ void MainFrame::show_device(bool bBBLPrinter) {
|
||||
{
|
||||
const int preview_idx = m_tabpanel->FindPageByName(TAB_ID_PREVIEW);
|
||||
const size_t monitor_pos = (preview_idx == wxNOT_FOUND) ? m_tabpanel->GetPageCount() : static_cast<size_t>(preview_idx) + 1;
|
||||
m_tabpanel->InsertPage(monitor_pos, TAB_ID_MONITOR, m_printer_view, _L("Device"), std::string("tab_monitor_active"),
|
||||
std::string("tab_monitor_active"));
|
||||
m_tabpanel->InsertPage(monitor_pos, m_printer_view, _L("Device"), false, Notebook::PAGE_MONITOR);
|
||||
}
|
||||
}
|
||||
fit_tab_labels(); // ORCA on printer change
|
||||
|
||||
@@ -186,17 +186,17 @@ void MonitorPanel::init_tabpanel()
|
||||
|
||||
//m_status_add_machine_panel = new AddMachinePanel(m_tabpanel);
|
||||
m_status_info_panel = new StatusPanel(m_tabpanel);
|
||||
m_tabpanel->AddPage(m_status_info_panel, _L("Status"), "", true);
|
||||
m_tabpanel->AddPage(m_status_info_panel, _L("Status"), true);
|
||||
|
||||
m_media_file_panel = new MediaFilePanel(m_tabpanel);
|
||||
m_tabpanel->AddPage(m_media_file_panel, _L("Storage"), "", false);
|
||||
//m_tabpanel->AddPage(m_media_file_panel, _L("Internal Storage"), "", false);
|
||||
m_tabpanel->AddPage(m_media_file_panel, _L("Storage"), false);
|
||||
//m_tabpanel->AddPage(m_media_file_panel, _L("Internal Storage"), false);
|
||||
|
||||
m_upgrade_panel = new UpgradePanel(m_tabpanel);
|
||||
m_tabpanel->AddPage(m_upgrade_panel, _CTX(L_CONTEXT("Update", "Firmware"), "Firmware"), "", false);
|
||||
m_tabpanel->AddPage(m_upgrade_panel, _CTX(L_CONTEXT("Update", "Firmware"), "Firmware"), false);
|
||||
|
||||
m_hms_panel = new HMSPanel(m_tabpanel);
|
||||
m_tabpanel->AddPage(m_hms_panel, _L("Assistant(HMS)"), "", false);
|
||||
m_tabpanel->AddPage(m_hms_panel, _L("Assistant(HMS)"), false);
|
||||
|
||||
std::string network_ver = Slic3r::NetworkAgent::get_version();
|
||||
if (!network_ver.empty()) {
|
||||
|
||||
@@ -86,9 +86,9 @@ void MultiMachinePage::init_tabpanel()
|
||||
m_cloud_task_manager = new CloudTaskManagerPage(m_tabpanel);
|
||||
m_machine_manager = new MultiMachineManagerPage(m_tabpanel);
|
||||
|
||||
m_tabpanel->AddPage(m_machine_manager, _L("Device"), "", true);
|
||||
m_tabpanel->AddPage(m_local_task_manager, _L("Task Sending"), "", false);
|
||||
m_tabpanel->AddPage(m_cloud_task_manager, _L("Task Sent"), "", false);
|
||||
m_tabpanel->AddPage(m_machine_manager, _L("Device"), true);
|
||||
m_tabpanel->AddPage(m_local_task_manager, _L("Task Sending"), false);
|
||||
m_tabpanel->AddPage(m_cloud_task_manager, _L("Task Sent"), false);
|
||||
}
|
||||
|
||||
void MultiMachinePage::init_timer()
|
||||
|
||||
@@ -132,7 +132,6 @@ void ButtonsListCtrl::SetSelection(int sel)
|
||||
StateColor text_color = StateColor(
|
||||
std::pair{wxColour(254,254, 254), (int) StateColor::Normal}
|
||||
);
|
||||
m_pageButtons[m_selection]->SetSelected(false);
|
||||
m_pageButtons[m_selection]->SetTextColor(text_color);
|
||||
}
|
||||
|
||||
@@ -152,17 +151,20 @@ void ButtonsListCtrl::SetSelection(int sel)
|
||||
StateColor text_color = StateColor(
|
||||
std::pair{wxColour(254, 254, 254), (int) StateColor::Normal}
|
||||
);
|
||||
m_pageButtons[m_selection]->SetSelected(true);
|
||||
m_pageButtons[m_selection]->SetTextColor(text_color);
|
||||
|
||||
Refresh();
|
||||
}
|
||||
|
||||
bool ButtonsListCtrl::InsertPage(size_t n, const wxString &text, bool bSelect /* = false*/, const std::string &bmp_name /* = ""*/, const std::string &inactive_bmp_name)
|
||||
bool ButtonsListCtrl::InsertPage(size_t n, const wxString &text, bool bSelect /* = false*/, const std::string &bmp_name /* = ""*/, int imageId /* = wxBookCtrlBase::NO_IMAGE */)
|
||||
{
|
||||
Button * btn = new Button(this, text.empty() ? text : " " + text, bmp_name, wxNO_BORDER);
|
||||
btn->SetCornerRadius(0);
|
||||
|
||||
if (bmp_name.empty() && m_imageList != nullptr && imageId != wxBookCtrlBase::NO_IMAGE && imageId >= 0 &&
|
||||
imageId < m_imageList->GetImageCount())
|
||||
btn->SetIcon(m_imageList->GetBitmap(imageId));
|
||||
|
||||
int em = em_unit(this);
|
||||
//BBS set size for button
|
||||
btn->SetMinSize({(text.empty() ? 40 : 136) * em / 10, 36 * em / 10});
|
||||
@@ -175,8 +177,6 @@ bool ButtonsListCtrl::InsertPage(size_t n, const wxString &text, bool bSelect /*
|
||||
StateColor text_color = StateColor(
|
||||
std::pair{wxColour(254,254, 254), (int) StateColor::Normal});
|
||||
btn->SetTextColor(text_color);
|
||||
btn->SetInactiveIcon(inactive_bmp_name);
|
||||
btn->SetSelected(false);
|
||||
btn->Bind(wxEVT_BUTTON, [this, btn](wxCommandEvent& event) {
|
||||
if (auto it = std::find(m_pageButtons.begin(), m_pageButtons.end(), btn); it != m_pageButtons.end()) {
|
||||
auto sel = it - m_pageButtons.begin();
|
||||
@@ -232,6 +232,23 @@ bool ButtonsListCtrl::SetPageImage(size_t n, const std::string& bmp_name) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ButtonsListCtrl::SetPageImage(size_t n, int imageId)
|
||||
{
|
||||
if (n >= m_pageButtons.size())
|
||||
return false;
|
||||
|
||||
if (imageId == wxBookCtrlBase::NO_IMAGE) {
|
||||
m_pageButtons[n]->SetIcon(wxBitmap());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (m_imageList == nullptr || imageId < 0 || imageId >= m_imageList->GetImageCount())
|
||||
return false;
|
||||
|
||||
m_pageButtons[n]->SetIcon(m_imageList->GetBitmap(imageId));
|
||||
return true;
|
||||
}
|
||||
|
||||
void ButtonsListCtrl::SetPageText(size_t n, const wxString& strText)
|
||||
{
|
||||
Button* btn = m_pageButtons[n];
|
||||
|
||||
@@ -3,8 +3,11 @@
|
||||
|
||||
//#ifdef _WIN32
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <wx/bookctrl.h>
|
||||
#include <wx/imaglist.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
class ScalableButton;
|
||||
@@ -24,9 +27,11 @@ public:
|
||||
void SetSelection(int sel);
|
||||
void UpdateMode();
|
||||
void Rescale();
|
||||
bool InsertPage(size_t n, const wxString &text, bool bSelect = false, const std::string &bmp_name = "", const std::string &inactive_bmp_name = "");
|
||||
bool InsertPage(size_t n, const wxString &text, bool bSelect = false, const std::string &bmp_name = "", int imageId = wxBookCtrlBase::NO_IMAGE);
|
||||
void RemovePage(size_t n);
|
||||
bool SetPageImage(size_t n, const std::string& bmp_name) const;
|
||||
bool SetPageImage(size_t n, int imageId);
|
||||
void SetImageList(wxImageList* imageList) { m_imageList = imageList; }
|
||||
void SetPageText(size_t n, const wxString& strText);
|
||||
void SetCompact(size_t n, bool compact); // ORCA
|
||||
wxString GetPageText(size_t n) const;
|
||||
@@ -41,11 +46,22 @@ private:
|
||||
int m_btn_margin;
|
||||
int m_line_margin;
|
||||
std::vector<wxString> m_pageLabels; // ORCA
|
||||
wxImageList* m_imageList{nullptr};
|
||||
};
|
||||
|
||||
class Notebook : public wxBookCtrlBase
|
||||
{
|
||||
public:
|
||||
// Negative values below wxBookCtrlBase::NO_IMAGE are reserved for the built-in
|
||||
// tabs. Nonnegative values are wxImageList indices supplied by plugin pages.
|
||||
static constexpr int PAGE_HOME = -2;
|
||||
static constexpr int PAGE_PREPARE = -3;
|
||||
static constexpr int PAGE_PREVIEW = -4;
|
||||
static constexpr int PAGE_MONITOR = -5;
|
||||
static constexpr int PAGE_MULTI_DEVICE = -6;
|
||||
static constexpr int PAGE_PROJECT = -7;
|
||||
static constexpr int PAGE_CALIBRATION = -8;
|
||||
|
||||
Notebook(wxWindow * parent,
|
||||
wxWindowID winid = wxID_ANY,
|
||||
const wxPoint & pos = wxDefaultPosition,
|
||||
@@ -104,7 +120,7 @@ public:
|
||||
// by this control) and show it immediately.
|
||||
bool ShowNewPage(wxWindow * page)
|
||||
{
|
||||
return AddPage(wxString(), page, wxString(), "", "");
|
||||
return AddPage(page, wxString(), false, NO_IMAGE);
|
||||
}
|
||||
|
||||
|
||||
@@ -136,16 +152,10 @@ public:
|
||||
|
||||
// Implement base class pure virtual methods.
|
||||
|
||||
// adds a new page to the control
|
||||
bool AddPage(const wxString& id,
|
||||
wxWindow* page,
|
||||
const wxString& text,
|
||||
const std::string& bmp_name,
|
||||
const std::string& inactive_bmp_name,
|
||||
bool bSelect = false)
|
||||
bool AddPage(wxWindow* page, const wxString& text, bool bSelect = false, int imageId = NO_IMAGE) override
|
||||
{
|
||||
DoInvalidateBestSize();
|
||||
return InsertPage(GetPageCount(), id, page, text, bmp_name, inactive_bmp_name, bSelect);
|
||||
return InsertPage(GetPageCount(), page, text, bSelect, imageId);
|
||||
}
|
||||
|
||||
// Page management
|
||||
@@ -154,12 +164,38 @@ public:
|
||||
const wxString & text,
|
||||
bool bSelect = false,
|
||||
int imageId = NO_IMAGE) override
|
||||
{
|
||||
wxString page_name;
|
||||
std::string bmp_name;
|
||||
const bool is_fixed_page = get_fixed_page_info(imageId, page_name, bmp_name);
|
||||
const int stored_image_id = is_fixed_page ? NO_IMAGE : imageId;
|
||||
|
||||
if (!wxBookCtrlBase::InsertPage(n, page, text, bSelect, stored_image_id))
|
||||
return false;
|
||||
|
||||
m_pageNames.insert(m_pageNames.begin() + n, page_name);
|
||||
m_pageImageIds.insert(m_pageImageIds.begin() + n, stored_image_id);
|
||||
GetBtnsListCtrl()->InsertPage(n, text, bSelect, bmp_name, stored_image_id);
|
||||
|
||||
if (!DoSetSelectionAfterInsertion(n, bSelect))
|
||||
page->Hide();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertPage(size_t n,
|
||||
const wxString& id,
|
||||
wxWindow* page,
|
||||
const wxString& text,
|
||||
int imageId,
|
||||
bool bSelect = false)
|
||||
{
|
||||
if (!wxBookCtrlBase::InsertPage(n, page, text, bSelect, imageId))
|
||||
return false;
|
||||
|
||||
m_pageNames.insert(m_pageNames.begin() + n, wxString());
|
||||
GetBtnsListCtrl()->InsertPage(n, text, bSelect);
|
||||
m_pageNames.insert(m_pageNames.begin() + n, id);
|
||||
m_pageImageIds.insert(m_pageImageIds.begin() + n, imageId);
|
||||
GetBtnsListCtrl()->InsertPage(n, text, bSelect, "", imageId);
|
||||
|
||||
if (!DoSetSelectionAfterInsertion(n, bSelect))
|
||||
page->Hide();
|
||||
@@ -172,14 +208,14 @@ public:
|
||||
wxWindow * page,
|
||||
const wxString & text,
|
||||
const std::string& bmp_name = "",
|
||||
const std::string& inactive_bmp_name = "",
|
||||
bool bSelect = false)
|
||||
{
|
||||
if (!wxBookCtrlBase::InsertPage(n, page, text, bSelect))
|
||||
return false;
|
||||
|
||||
m_pageNames.insert(m_pageNames.begin() + n, id);
|
||||
GetBtnsListCtrl()->InsertPage(n, text, bSelect, bmp_name, inactive_bmp_name);
|
||||
m_pageImageIds.insert(m_pageImageIds.begin() + n, NO_IMAGE);
|
||||
GetBtnsListCtrl()->InsertPage(n, text, bSelect, bmp_name);
|
||||
|
||||
// wxBookCtrlBase::InsertPage() only inserts into the page list and sizes the
|
||||
// new page to the current page's rect — it never touches visibility. A freshly
|
||||
@@ -222,8 +258,7 @@ public:
|
||||
return DoSetSelection(n);
|
||||
}
|
||||
|
||||
// Neither labels nor images are supported but we still store the labels
|
||||
// just in case the user code attaches some importance to them.
|
||||
// Labels are stored by the custom button list; page images use the wx image-list IDs below.
|
||||
virtual bool SetPageText(size_t n, const wxString & strText) override
|
||||
{
|
||||
wxCHECK_MSG(n < GetPageCount(), false, wxS("Invalid page"));
|
||||
@@ -239,14 +274,27 @@ public:
|
||||
return GetBtnsListCtrl()->GetPageText(n);
|
||||
}
|
||||
|
||||
virtual bool SetPageImage(size_t WXUNUSED(n), int WXUNUSED(imageId)) override
|
||||
virtual bool SetPageImage(size_t n, int imageId) override
|
||||
{
|
||||
return false;
|
||||
if (n >= m_pageImageIds.size())
|
||||
return false;
|
||||
|
||||
if (!GetBtnsListCtrl()->SetPageImage(n, imageId))
|
||||
return false;
|
||||
|
||||
m_pageImageIds[n] = imageId;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual int GetPageImage(size_t WXUNUSED(n)) const override
|
||||
virtual int GetPageImage(size_t n) const override
|
||||
{
|
||||
return NO_IMAGE;
|
||||
return n < m_pageImageIds.size() ? m_pageImageIds[n] : NO_IMAGE;
|
||||
}
|
||||
|
||||
void SetImageList(wxImageList* imageList)
|
||||
{
|
||||
m_imageList = imageList;
|
||||
GetBtnsListCtrl()->SetImageList(imageList);
|
||||
}
|
||||
|
||||
bool SetPageImage(size_t n, const std::string& bmp_name)
|
||||
@@ -271,6 +319,7 @@ public:
|
||||
virtual bool DeleteAllPages() override
|
||||
{
|
||||
m_pageNames.clear();
|
||||
m_pageImageIds.clear();
|
||||
return wxBookCtrlBase::DeleteAllPages();
|
||||
}
|
||||
|
||||
@@ -431,6 +480,7 @@ protected:
|
||||
if (win)
|
||||
{
|
||||
m_pageNames.erase(m_pageNames.begin() + page);
|
||||
m_pageImageIds.erase(m_pageImageIds.begin() + page);
|
||||
GetBtnsListCtrl()->RemovePage(page);
|
||||
DoSetSelectionAfterRemoval(page);
|
||||
}
|
||||
@@ -454,9 +504,47 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
static bool get_fixed_page_info(int imageId, wxString& page_name, std::string& bmp_name)
|
||||
{
|
||||
switch (imageId) {
|
||||
case PAGE_HOME:
|
||||
page_name = wxS("home");
|
||||
bmp_name = "tab_home_active";
|
||||
return true;
|
||||
case PAGE_PREPARE:
|
||||
page_name = wxS("prepare");
|
||||
bmp_name = "tab_3d_active";
|
||||
return true;
|
||||
case PAGE_PREVIEW:
|
||||
page_name = wxS("preview");
|
||||
bmp_name = "tab_preview_active";
|
||||
return true;
|
||||
case PAGE_MONITOR:
|
||||
page_name = wxS("monitor");
|
||||
bmp_name = "tab_monitor_active";
|
||||
return true;
|
||||
case PAGE_MULTI_DEVICE:
|
||||
page_name = wxS("multi_device");
|
||||
bmp_name = "tab_multi_active";
|
||||
return true;
|
||||
case PAGE_PROJECT:
|
||||
page_name = wxS("project");
|
||||
bmp_name = "tab_auxiliary_active";
|
||||
return true;
|
||||
case PAGE_CALIBRATION:
|
||||
page_name = wxS("calibration");
|
||||
bmp_name = "tab_calibration_active";
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Init();
|
||||
|
||||
std::vector<wxString> m_pageNames; // index-parallel to wxBookCtrlBase::m_pages
|
||||
std::vector<int> m_pageImageIds; // index-parallel to wxBookCtrlBase::m_pages
|
||||
wxImageList* m_imageList{nullptr};
|
||||
|
||||
wxShowEffect m_showEffect,
|
||||
m_hideEffect;
|
||||
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
// by this control) and show it immediately.
|
||||
bool ShowNewPage(wxWindow * page)
|
||||
{
|
||||
return AddPage(page, wxString(), ""/*true *//* select it */);
|
||||
return AddPage(page, wxString());
|
||||
}
|
||||
|
||||
// Set effect to use for showing/hiding pages.
|
||||
@@ -139,14 +139,13 @@ public:
|
||||
|
||||
// Implement base class pure virtual methods.
|
||||
|
||||
// adds a new page to the control
|
||||
bool AddPage(wxWindow* page,
|
||||
const wxString& text,
|
||||
const std::string& bmp_name,
|
||||
bool bSelect = false)
|
||||
bool bSelect = false,
|
||||
int imageId = NO_IMAGE) override
|
||||
{
|
||||
DoInvalidateBestSize();
|
||||
return InsertNewPage(GetPageCount(), page, text, bmp_name, bSelect);
|
||||
return InsertPage(GetPageCount(), page, text, bSelect, imageId);
|
||||
}
|
||||
|
||||
//// Page management
|
||||
@@ -167,23 +166,6 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertNewPage(size_t n,
|
||||
wxWindow * page,
|
||||
const wxString & text,
|
||||
const std::string& bmp_name = "",
|
||||
bool bSelect = false)
|
||||
{
|
||||
if (!wxBookCtrlBase::InsertPage(n, page, text, bSelect))
|
||||
return false;
|
||||
|
||||
GetBtnsListCtrl()->InsertPage(n, text, bSelect, bmp_name);
|
||||
|
||||
if (bSelect)
|
||||
SetSelection(n);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RemovePage(size_t n)
|
||||
{
|
||||
if (!wxBookCtrlBase::RemovePage(n))
|
||||
|
||||
@@ -95,14 +95,11 @@ void Button::SetIcon(const wxString& icon)
|
||||
}
|
||||
}
|
||||
|
||||
void Button::SetInactiveIcon(const wxString &icon)
|
||||
void Button::SetIcon(const wxBitmap& icon)
|
||||
{
|
||||
if (!icon.IsEmpty()) {
|
||||
// BBS set button icon default size to 20
|
||||
this->inactive_icon = ScalableBitmap(this, icon.ToStdString(), this->active_icon.px_cnt());
|
||||
} else {
|
||||
this->inactive_icon = ScalableBitmap();
|
||||
}
|
||||
this->active_icon = ScalableBitmap();
|
||||
this->active_icon.bmp() = icon;
|
||||
messureSize();
|
||||
Refresh();
|
||||
}
|
||||
|
||||
@@ -260,9 +257,6 @@ void Button::Rescale()
|
||||
if (this->active_icon.bmp().IsOk())
|
||||
this->active_icon.msw_rescale();
|
||||
|
||||
if (this->inactive_icon.bmp().IsOk())
|
||||
this->inactive_icon.msw_rescale();
|
||||
|
||||
messureSize();
|
||||
|
||||
if(m_has_style)
|
||||
@@ -293,11 +287,7 @@ void Button::render(wxDC& dc)
|
||||
wxSize szIcon;
|
||||
wxSize textSize = this->textSize.GetSize();
|
||||
|
||||
ScalableBitmap icon;
|
||||
if (m_selected || ((states & (int)StateColor::State::Hovered) != 0))
|
||||
icon = active_icon;
|
||||
else
|
||||
icon = inactive_icon;
|
||||
ScalableBitmap icon = active_icon;
|
||||
wxSize padding = this->paddingSize;
|
||||
int spacing = 5;
|
||||
// Wrap text
|
||||
|
||||
@@ -34,12 +34,10 @@ class Button : public StaticBox
|
||||
wxSize minSize; // set by outer
|
||||
wxSize paddingSize;
|
||||
ScalableBitmap active_icon;
|
||||
ScalableBitmap inactive_icon;
|
||||
|
||||
StateColor text_color;
|
||||
|
||||
bool pressedDown = false;
|
||||
bool m_selected = true;
|
||||
bool canFocus = true;
|
||||
bool isCenter = true;
|
||||
bool vertical = false;
|
||||
@@ -61,8 +59,7 @@ public:
|
||||
bool SetFont(const wxFont& font) override;
|
||||
|
||||
void SetIcon(const wxString& icon);
|
||||
|
||||
void SetInactiveIcon(const wxString& icon);
|
||||
void SetIcon(const wxBitmap& icon);
|
||||
|
||||
void SetMinSize(const wxSize& size) override;
|
||||
void SetMaxSize(const wxSize& size) override;
|
||||
@@ -75,8 +72,6 @@ public:
|
||||
|
||||
void SetTextColorNormal(wxColor const &color);
|
||||
|
||||
void SetSelected(bool selected = true) { m_selected = selected; }
|
||||
|
||||
bool Enable(bool enable = true) override;
|
||||
void EnableTooltipEvenDisabled();// The tip will be shown even if the button is disabled
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <boost/log/trivial.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <wx/bookctrl.h>
|
||||
#include <wx/sizer.h>
|
||||
|
||||
#include <utility>
|
||||
@@ -204,6 +206,11 @@ void PluginPages::initialize(Notebook* parent)
|
||||
if (m_parent == nullptr)
|
||||
return;
|
||||
|
||||
// Keep image-list indices stable for the lifetime of this notebook. Removing an image
|
||||
// would shift every later index, so deregistration only removes the page.
|
||||
m_image_list = std::make_unique<wxImageList>(20, 20, true, 0);
|
||||
m_parent->SetImageList(m_image_list.get());
|
||||
|
||||
for (const auto& capability : PluginManager::instance().get_plugin_capabilities("", PluginCapabilityType::Pages)) {
|
||||
if (capability)
|
||||
on_cap_register(capability->identity());
|
||||
@@ -214,6 +221,9 @@ void PluginPages::shutdown()
|
||||
{
|
||||
while (!m_pages.empty())
|
||||
remove_page(m_pages.begin()->first);
|
||||
if (m_parent != nullptr)
|
||||
m_parent->SetImageList(nullptr);
|
||||
m_image_list.reset();
|
||||
m_parent = nullptr;
|
||||
}
|
||||
|
||||
@@ -235,6 +245,15 @@ void PluginPages::on_cap_register(const PluginCapabilityId& id)
|
||||
if (!capability)
|
||||
return;
|
||||
|
||||
std::string icon;
|
||||
try {
|
||||
icon = capability->get_icon();
|
||||
} catch (const std::exception& error) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Failed to get icon for plugin " << id.plugin_key << ": " << error.what();
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Failed to get icon for plugin " << id.plugin_key;
|
||||
}
|
||||
|
||||
auto* page = new PluginPage(m_parent, std::move(capability));
|
||||
if (!page->is_valid()) {
|
||||
page->Destroy();
|
||||
@@ -242,8 +261,29 @@ void PluginPages::on_cap_register(const PluginCapabilityId& id)
|
||||
}
|
||||
|
||||
const wxString title = wxString::FromUTF8(id.name);
|
||||
const wxString page_id = wxString::FromUTF8("plugin." + id.plugin_key + "." + id.name);
|
||||
if (!m_parent->AddPage(page_id, page, title, "tab_auxiliary_active", "tab_auxiliary_active", false)) {
|
||||
|
||||
int image_id = wxBookCtrlBase::NO_IMAGE;
|
||||
if (!icon.empty() && m_image_list) {
|
||||
try {
|
||||
boost::filesystem::path icon_path(icon);
|
||||
const std::string extension = icon_path.extension().string();
|
||||
if (extension == ".svg" || extension == ".png")
|
||||
icon_path.replace_extension();
|
||||
|
||||
const wxBitmap bitmap = create_scaled_bitmap(icon_path.string(), m_parent, 20);
|
||||
if (bitmap.IsOk())
|
||||
image_id = m_image_list->Add(bitmap);
|
||||
} catch (const std::exception& error) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Failed to load icon for plugin " << id.plugin_key << ": " << error.what();
|
||||
} catch (...) {
|
||||
BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " Failed to load icon for plugin " << id.plugin_key;
|
||||
}
|
||||
}
|
||||
|
||||
page->set_icon_image_id(image_id);
|
||||
if (!m_parent->AddPage(page, title, false, image_id)) {
|
||||
if (image_id != wxBookCtrlBase::NO_IMAGE && m_image_list && image_id == m_image_list->GetImageCount() - 1)
|
||||
m_image_list->Remove(image_id);
|
||||
page->Destroy();
|
||||
return;
|
||||
}
|
||||
@@ -285,12 +325,39 @@ void PluginPages::remove_page(const PluginCapabilityId& id)
|
||||
return;
|
||||
|
||||
PluginPage* page = it->second;
|
||||
const int removed_image_id = page->get_icon_image_id();
|
||||
page->detach_capability();
|
||||
if (m_parent != nullptr) {
|
||||
const int index = m_parent->FindPage(page);
|
||||
if (index != wxNOT_FOUND)
|
||||
m_parent->RemovePage(static_cast<size_t>(index));
|
||||
}
|
||||
|
||||
if (m_image_list && removed_image_id != wxBookCtrlBase::NO_IMAGE &&
|
||||
removed_image_id >= 0 && removed_image_id < m_image_list->GetImageCount()) {
|
||||
m_image_list->Remove(removed_image_id);
|
||||
|
||||
// wxImageList IDs are positional. Removing one shifts all later images down by
|
||||
// one, so update both the page state and the notebook button for those pages.
|
||||
for (const auto& [other_id, other_page] : m_pages) {
|
||||
if (other_id == id)
|
||||
continue;
|
||||
|
||||
const int other_image_id = other_page->get_icon_image_id();
|
||||
if (other_image_id <= removed_image_id)
|
||||
continue;
|
||||
|
||||
const int updated_image_id = other_image_id - 1;
|
||||
other_page->set_icon_image_id(updated_image_id);
|
||||
|
||||
if (m_parent != nullptr) {
|
||||
const int other_index = m_parent->FindPage(other_page);
|
||||
if (other_index != wxNOT_FOUND)
|
||||
m_parent->SetPageImage(static_cast<size_t>(other_index), updated_image_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
page->Destroy();
|
||||
m_pages.erase(it);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <wx/bookctrl.h>
|
||||
#include <wx/imaglist.h>
|
||||
#include <wx/panel.h>
|
||||
#include <wx/webview.h>
|
||||
|
||||
@@ -29,16 +31,20 @@ public:
|
||||
void on_new_window(wxWebViewEvent& event);
|
||||
void on_script_message(wxWebViewEvent& event);
|
||||
void push_message(const std::string& message);
|
||||
void set_icon_image_id(int id) { m_icon_image_id = id; }
|
||||
int get_icon_image_id() const { return m_icon_image_id; }
|
||||
|
||||
private:
|
||||
void load_plugin_content();
|
||||
wxString bootstrap_url() const;
|
||||
wxString web_base_url() const;
|
||||
|
||||
wxWebView* m_browser{nullptr};
|
||||
std::shared_ptr<PagesPluginCapability> m_cap;
|
||||
std::shared_ptr<std::atomic<PluginPage*>> m_lifetime;
|
||||
bool m_content_loaded{false};
|
||||
wxWebView* m_browser{nullptr};
|
||||
std::shared_ptr<PagesPluginCapability> m_cap;
|
||||
std::shared_ptr<std::atomic<PluginPage*>> m_lifetime;
|
||||
bool m_content_loaded{false};
|
||||
|
||||
int m_icon_image_id = wxBookCtrlBase::NO_IMAGE;
|
||||
};
|
||||
|
||||
class PluginPages
|
||||
@@ -47,7 +53,7 @@ public:
|
||||
PluginPages() = default;
|
||||
~PluginPages();
|
||||
|
||||
PluginPages(const PluginPages&) = delete;
|
||||
PluginPages(const PluginPages&) = delete;
|
||||
PluginPages& operator=(const PluginPages&) = delete;
|
||||
|
||||
void initialize(Notebook* parent);
|
||||
@@ -63,7 +69,9 @@ private:
|
||||
void remove_page(const PluginCapabilityId& id);
|
||||
|
||||
std::map<PluginCapabilityId, PluginPage*> m_pages;
|
||||
Notebook* m_parent{nullptr};
|
||||
Notebook* m_parent{nullptr};
|
||||
|
||||
std::unique_ptr<wxImageList> m_image_list;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
@@ -23,6 +23,7 @@ void PagesPluginCapability::RegisterBindings(pybind11::module_& module)
|
||||
.def(py::init<>())
|
||||
.def("get_type", &PagesPluginCapability::get_type)
|
||||
.def("get_ui", &PagesPluginCapability::get_ui)
|
||||
.def("get_icon", &PagesPluginCapability::get_icon)
|
||||
.def("on_message", &PagesPluginCapability::on_message)
|
||||
.def(
|
||||
"post_message",
|
||||
|
||||
@@ -18,6 +18,7 @@ public:
|
||||
|
||||
virtual std::string get_ui() = 0;
|
||||
virtual void on_message(std::string message) { (void) message; }
|
||||
virtual std::string get_icon() { return {}; }
|
||||
|
||||
void post_message(std::string message);
|
||||
void set_message_sender(std::function<void(const std::string&)> sender);
|
||||
|
||||
@@ -13,6 +13,17 @@ class PyPagesPluginCapabilityTrampoline : public PyPluginCommonTrampoline<PagesP
|
||||
public:
|
||||
using PyPluginCommonTrampoline<PagesPluginCapability>::PyPluginCommonTrampoline;
|
||||
|
||||
std::string get_icon() override
|
||||
{
|
||||
ORCA_PY_OVERRIDE_AUDITED(
|
||||
::Slic3r::PluginAuditManager::AuditMode::Loading,
|
||||
[] {},
|
||||
PYBIND11_OVERRIDE,
|
||||
std::string,
|
||||
PagesPluginCapability,
|
||||
get_icon);
|
||||
}
|
||||
|
||||
std::string get_ui() override
|
||||
{
|
||||
ORCA_PY_OVERRIDE_AUDITED(
|
||||
|
||||
Reference in New Issue
Block a user