feat: support tab icons

This commit is contained in:
Ian Chua
2026-07-29 19:37:17 +08:00
parent e00906a833
commit 3145f28bb7
15 changed files with 260 additions and 104 deletions

View File

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

View File

@@ -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);
}

View File

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

View File

@@ -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()) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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);
}

View File

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

View File

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

View File

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

View File

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