mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-14 04:27:36 +00:00
feat: add max visible pages to app config under Preferences -> General -> Plugins
This commit is contained in:
@@ -280,6 +280,20 @@ void AppConfig::set_defaults()
|
|||||||
set(SETTING_OPENGL_FPS_CAP, std::to_string(fps_cap));
|
set(SETTING_OPENGL_FPS_CAP, std::to_string(fps_cap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (get(SETTING_PLUGIN_PAGES_VISIBLE_COUNT).empty())
|
||||||
|
set(SETTING_PLUGIN_PAGES_VISIBLE_COUNT, std::to_string(PLUGIN_PAGES_VISIBLE_COUNT_DEFAULT));
|
||||||
|
else {
|
||||||
|
int visible_count = PLUGIN_PAGES_VISIBLE_COUNT_DEFAULT;
|
||||||
|
try {
|
||||||
|
visible_count = std::stoi(get(SETTING_PLUGIN_PAGES_VISIBLE_COUNT));
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
visible_count = PLUGIN_PAGES_VISIBLE_COUNT_DEFAULT;
|
||||||
|
}
|
||||||
|
visible_count = std::max(PLUGIN_PAGES_VISIBLE_COUNT_MIN, std::min(visible_count, PLUGIN_PAGES_VISIBLE_COUNT_MAX));
|
||||||
|
set(SETTING_PLUGIN_PAGES_VISIBLE_COUNT, std::to_string(visible_count));
|
||||||
|
}
|
||||||
|
|
||||||
if (get(SETTING_OPENGL_SHOW_FPS_OVERLAY).empty())
|
if (get(SETTING_OPENGL_SHOW_FPS_OVERLAY).empty())
|
||||||
set_bool(SETTING_OPENGL_SHOW_FPS_OVERLAY, false);
|
set_bool(SETTING_OPENGL_SHOW_FPS_OVERLAY, false);
|
||||||
|
|
||||||
@@ -1630,6 +1644,28 @@ void AppConfig::set_network_plugin_version(const std::string& version)
|
|||||||
set(SETTING_NETWORK_PLUGIN_VERSION, version);
|
set(SETTING_NETWORK_PLUGIN_VERSION, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AppConfig::get_plugin_pages_visible_count() const
|
||||||
|
{
|
||||||
|
std::string value = get(SETTING_PLUGIN_PAGES_VISIBLE_COUNT);
|
||||||
|
if (value.empty())
|
||||||
|
return PLUGIN_PAGES_VISIBLE_COUNT_DEFAULT;
|
||||||
|
|
||||||
|
int visible_count = PLUGIN_PAGES_VISIBLE_COUNT_DEFAULT;
|
||||||
|
try {
|
||||||
|
visible_count = std::stoi(value);
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
return PLUGIN_PAGES_VISIBLE_COUNT_DEFAULT;
|
||||||
|
}
|
||||||
|
return std::max(PLUGIN_PAGES_VISIBLE_COUNT_MIN, std::min(visible_count, PLUGIN_PAGES_VISIBLE_COUNT_MAX));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppConfig::set_plugin_pages_visible_count(int count)
|
||||||
|
{
|
||||||
|
count = std::max(PLUGIN_PAGES_VISIBLE_COUNT_MIN, std::min(count, PLUGIN_PAGES_VISIBLE_COUNT_MAX));
|
||||||
|
set(SETTING_PLUGIN_PAGES_VISIBLE_COUNT, std::to_string(count));
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> AppConfig::get_skipped_network_versions() const
|
std::vector<std::string> AppConfig::get_skipped_network_versions() const
|
||||||
{
|
{
|
||||||
std::vector<std::string> result;
|
std::vector<std::string> result;
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ using namespace nlohmann;
|
|||||||
#define SETTING_OPENGL_PHONG_SSAO "opengl_phong_ssao"
|
#define SETTING_OPENGL_PHONG_SSAO "opengl_phong_ssao"
|
||||||
#define SETTING_OPENGL_PHONG_SMOOTH_NORMALS "opengl_phong_smooth_normals"
|
#define SETTING_OPENGL_PHONG_SMOOTH_NORMALS "opengl_phong_smooth_normals"
|
||||||
|
|
||||||
|
#define SETTING_PLUGIN_PAGES_VISIBLE_COUNT "plugin_pages_visible_count"
|
||||||
|
#define PLUGIN_PAGES_VISIBLE_COUNT_MIN 1
|
||||||
|
#define PLUGIN_PAGES_VISIBLE_COUNT_DEFAULT 5
|
||||||
|
#define PLUGIN_PAGES_VISIBLE_COUNT_MAX 10
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
#define BAMBU_NETWORK_AGENT_VERSION_LEGACY "01.10.01.09"
|
#define BAMBU_NETWORK_AGENT_VERSION_LEGACY "01.10.01.09"
|
||||||
#else
|
#else
|
||||||
@@ -374,6 +379,11 @@ public:
|
|||||||
std::string get_network_plugin_version() const;
|
std::string get_network_plugin_version() const;
|
||||||
void set_network_plugin_version(const std::string& version);
|
void set_network_plugin_version(const std::string& version);
|
||||||
|
|
||||||
|
// Number of plugin pages shown as fixed tabs before the rest are collapsed into a
|
||||||
|
// dropdown on the last tab.
|
||||||
|
int get_plugin_pages_visible_count() const;
|
||||||
|
void set_plugin_pages_visible_count(int count);
|
||||||
|
|
||||||
std::vector<std::string> get_skipped_network_versions() const;
|
std::vector<std::string> get_skipped_network_versions() const;
|
||||||
void add_skipped_network_version(const std::string& version);
|
void add_skipped_network_version(const std::string& version);
|
||||||
bool is_network_version_skipped(const std::string& version) const;
|
bool is_network_version_skipped(const std::string& version) const;
|
||||||
|
|||||||
@@ -1748,11 +1748,26 @@ void PreferencesDialog::create_items()
|
|||||||
g_sizer->Add(item_pop_up_filament_map_dialog);
|
g_sizer->Add(item_pop_up_filament_map_dialog);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//// GENERAL > Plugins
|
||||||
|
g_sizer->Add(create_item_title(_L("Plugins")), 1, wxEXPAND);
|
||||||
|
|
||||||
|
auto item_plugin_pages_visible_count = create_item_spinctrl(
|
||||||
|
_L("Visible plugin pages"),
|
||||||
|
"",
|
||||||
|
_L("pages"),
|
||||||
|
_L("Number of plugin pages shown as fixed tabs before the remaining pages collapse into a dropdown on the last tab."),
|
||||||
|
SETTING_PLUGIN_PAGES_VISIBLE_COUNT,
|
||||||
|
PLUGIN_PAGES_VISIBLE_COUNT_MIN,
|
||||||
|
PLUGIN_PAGES_VISIBLE_COUNT_MAX,
|
||||||
|
[](int value) { wxGetApp().mainframe->plugin_pages().set_visible_page_count(value); }
|
||||||
|
);
|
||||||
|
g_sizer->Add(item_plugin_pages_visible_count);
|
||||||
|
|
||||||
g_sizer->AddSpacer(FromDIP(10));
|
g_sizer->AddSpacer(FromDIP(10));
|
||||||
sizer_page->Add(g_sizer, 0, wxEXPAND);
|
sizer_page->Add(g_sizer, 0, wxEXPAND);
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
//// CONTROL TAB
|
//// CONTROL TAB
|
||||||
/////////////////////////////////////
|
/////////////////////////////////////
|
||||||
m_pref_tabs->AppendItem(_L("Control"));
|
m_pref_tabs->AppendItem(_L("Control"));
|
||||||
f_sizers.push_back(new wxFlexGridSizer(1, 1, v_gap, 0));
|
f_sizers.push_back(new wxFlexGridSizer(1, 1, v_gap, 0));
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "PluginPages.hpp"
|
#include "PluginPages.hpp"
|
||||||
|
|
||||||
|
#include "libslic3r/AppConfig.hpp"
|
||||||
#include "slic3r/GUI/GUI.hpp"
|
#include "slic3r/GUI/GUI.hpp"
|
||||||
#include "slic3r/GUI/Notebook.hpp"
|
#include "slic3r/GUI/Notebook.hpp"
|
||||||
#include "slic3r/GUI/GUI_App.hpp"
|
#include "slic3r/GUI/GUI_App.hpp"
|
||||||
@@ -10,12 +11,15 @@
|
|||||||
|
|
||||||
#include <libslic3r/Utils.hpp>
|
#include <libslic3r/Utils.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
#include <boost/log/trivial.hpp>
|
#include <boost/log/trivial.hpp>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <wx/bookctrl.h>
|
#include <wx/bookctrl.h>
|
||||||
|
#include <wx/choice.h>
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
@@ -194,9 +198,119 @@ void PluginPage::push_message(const std::string& message)
|
|||||||
WebView::RunScript(m_browser, script);
|
WebView::RunScript(m_browser, script);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PluginPagesOverflowPanel : public wxPanel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit PluginPagesOverflowPanel(Notebook* parent)
|
||||||
|
: wxPanel(parent, wxID_ANY)
|
||||||
|
, m_notebook(parent)
|
||||||
|
{
|
||||||
|
auto* sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
|
||||||
|
m_choice = new wxChoice(this, wxID_ANY);
|
||||||
|
m_choice->Bind(wxEVT_CHOICE, &PluginPagesOverflowPanel::on_choice, this);
|
||||||
|
sizer->Add(m_choice, wxSizerFlags().Expand().Border(wxALL, FromDIP(4)));
|
||||||
|
|
||||||
|
m_content_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
|
sizer->Add(m_content_sizer, wxSizerFlags().Expand().Proportion(1));
|
||||||
|
|
||||||
|
SetSizer(sizer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_entry(const PluginCapabilityId& id, PluginPage* page, const wxString& title)
|
||||||
|
{
|
||||||
|
page->Reparent(this);
|
||||||
|
page->Hide();
|
||||||
|
m_entries.push_back({id, page, title});
|
||||||
|
m_choice->Append(title);
|
||||||
|
if (m_entries.size() == 1)
|
||||||
|
select_index(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void select_entry(const PluginCapabilityId& id)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < m_entries.size(); ++i) {
|
||||||
|
if (m_entries[i].id == id) {
|
||||||
|
select_index(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
if (m_shown_index != wxNOT_FOUND)
|
||||||
|
m_entries[static_cast<size_t>(m_shown_index)].page->Hide();
|
||||||
|
m_content_sizer->Clear(false);
|
||||||
|
|
||||||
|
for (const Entry& entry : m_entries)
|
||||||
|
entry.page->Reparent(m_notebook);
|
||||||
|
|
||||||
|
m_entries.clear();
|
||||||
|
m_choice->Clear();
|
||||||
|
m_shown_index = wxNOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxString current_title() const { return m_shown_index == wxNOT_FOUND ? wxString() : m_entries[static_cast<size_t>(m_shown_index)].title; }
|
||||||
|
int current_image_id() const
|
||||||
|
{
|
||||||
|
return m_shown_index == wxNOT_FOUND ? wxBookCtrlBase::NO_IMAGE : m_entries[static_cast<size_t>(m_shown_index)].page->get_icon_image_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Entry
|
||||||
|
{
|
||||||
|
PluginCapabilityId id;
|
||||||
|
PluginPage* page;
|
||||||
|
wxString title;
|
||||||
|
};
|
||||||
|
|
||||||
|
void on_choice(wxCommandEvent&)
|
||||||
|
{
|
||||||
|
const int selection = m_choice->GetSelection();
|
||||||
|
if (selection != wxNOT_FOUND)
|
||||||
|
select_index(static_cast<size_t>(selection));
|
||||||
|
}
|
||||||
|
|
||||||
|
void select_index(size_t index)
|
||||||
|
{
|
||||||
|
if (index >= m_entries.size())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_shown_index != wxNOT_FOUND)
|
||||||
|
m_entries[static_cast<size_t>(m_shown_index)].page->Hide();
|
||||||
|
|
||||||
|
m_content_sizer->Clear(false);
|
||||||
|
m_content_sizer->Add(m_entries[index].page, wxSizerFlags().Expand().Proportion(1));
|
||||||
|
m_entries[index].page->Show();
|
||||||
|
Layout();
|
||||||
|
|
||||||
|
m_shown_index = static_cast<int>(index);
|
||||||
|
m_choice->SetSelection(static_cast<int>(index));
|
||||||
|
|
||||||
|
const int tab_index = m_notebook->FindPage(this);
|
||||||
|
if (tab_index != wxNOT_FOUND) {
|
||||||
|
m_notebook->SetPageText(static_cast<size_t>(tab_index), m_entries[index].title);
|
||||||
|
m_notebook->SetPageImage(static_cast<size_t>(tab_index), m_entries[index].page->get_icon_image_id());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Notebook* m_notebook{nullptr};
|
||||||
|
wxChoice* m_choice{nullptr};
|
||||||
|
wxBoxSizer* m_content_sizer{nullptr};
|
||||||
|
std::vector<Entry> m_entries;
|
||||||
|
int m_shown_index{wxNOT_FOUND};
|
||||||
|
};
|
||||||
|
|
||||||
PluginPages::~PluginPages()
|
PluginPages::~PluginPages()
|
||||||
{
|
{
|
||||||
shutdown();
|
shutdown();
|
||||||
|
// try {
|
||||||
|
// } catch (const std::exception& error) {
|
||||||
|
// BOOST_LOG_TRIVIAL(error) << "PluginPages::~PluginPages: shutdown() threw: " << error.what();
|
||||||
|
// } catch (...) {
|
||||||
|
// BOOST_LOG_TRIVIAL(error) << "PluginPages::~PluginPages: shutdown() threw a non-standard exception";
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginPages::initialize(Notebook* parent)
|
void PluginPages::initialize(Notebook* parent)
|
||||||
@@ -206,15 +320,17 @@ void PluginPages::initialize(Notebook* parent)
|
|||||||
if (m_parent == nullptr)
|
if (m_parent == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Keep image-list indices stable for the lifetime of this notebook. Removing an image
|
m_visible_page_count = GUI::wxGetApp().app_config->get_plugin_pages_visible_count();
|
||||||
// would shift every later index, so deregistration only removes the page.
|
m_notebook_base_index = static_cast<size_t>(m_parent->GetPageCount());
|
||||||
|
|
||||||
m_image_list = std::make_unique<wxImageList>(20, 20, true, 0);
|
m_image_list = std::make_unique<wxImageList>(20, 20, true, 0);
|
||||||
m_parent->SetImageList(m_image_list.get());
|
m_parent->SetImageList(m_image_list.get());
|
||||||
|
|
||||||
for (const auto& capability : PluginManager::instance().get_plugin_capabilities("", PluginCapabilityType::Pages)) {
|
for (const auto& capability : PluginManager::instance().get_plugin_capabilities("", PluginCapabilityType::Pages)) {
|
||||||
if (capability)
|
if (capability)
|
||||||
on_cap_register(capability->identity());
|
create_page(capability->identity());
|
||||||
}
|
}
|
||||||
|
relayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginPages::shutdown()
|
void PluginPages::shutdown()
|
||||||
@@ -225,6 +341,17 @@ void PluginPages::shutdown()
|
|||||||
m_parent->SetImageList(nullptr);
|
m_parent->SetImageList(nullptr);
|
||||||
m_image_list.reset();
|
m_image_list.reset();
|
||||||
m_parent = nullptr;
|
m_parent = nullptr;
|
||||||
|
m_notebook_base_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginPages::set_visible_page_count(int count)
|
||||||
|
{
|
||||||
|
const int clamped = std::max(PLUGIN_PAGES_VISIBLE_COUNT_MIN, std::min(count, PLUGIN_PAGES_VISIBLE_COUNT_MAX));
|
||||||
|
if (clamped == m_visible_page_count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_visible_page_count = clamped;
|
||||||
|
relayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<PagesPluginCapability> PluginPages::get_pages_cap(const PluginCapabilityId& id, bool is_enabled) const
|
std::shared_ptr<PagesPluginCapability> PluginPages::get_pages_cap(const PluginCapabilityId& id, bool is_enabled) const
|
||||||
@@ -236,14 +363,14 @@ std::shared_ptr<PagesPluginCapability> PluginPages::get_pages_cap(const PluginCa
|
|||||||
return std::dynamic_pointer_cast<PagesPluginCapability>(capability);
|
return std::dynamic_pointer_cast<PagesPluginCapability>(capability);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginPages::on_cap_register(const PluginCapabilityId& id)
|
bool PluginPages::create_page(const PluginCapabilityId& id)
|
||||||
{
|
{
|
||||||
if (m_parent == nullptr || m_pages.find(id) != m_pages.end())
|
if (m_pages.find(id) != m_pages.end())
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
auto capability = get_pages_cap(id, true);
|
auto capability = get_pages_cap(id, true);
|
||||||
if (!capability)
|
if (!capability)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
std::string icon;
|
std::string icon;
|
||||||
try {
|
try {
|
||||||
@@ -257,11 +384,9 @@ void PluginPages::on_cap_register(const PluginCapabilityId& id)
|
|||||||
auto* page = new PluginPage(m_parent, std::move(capability));
|
auto* page = new PluginPage(m_parent, std::move(capability));
|
||||||
if (!page->is_valid()) {
|
if (!page->is_valid()) {
|
||||||
page->Destroy();
|
page->Destroy();
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const wxString title = wxString::FromUTF8(id.name);
|
|
||||||
|
|
||||||
int image_id = wxBookCtrlBase::NO_IMAGE;
|
int image_id = wxBookCtrlBase::NO_IMAGE;
|
||||||
if (!icon.empty() && m_image_list) {
|
if (!icon.empty() && m_image_list) {
|
||||||
try {
|
try {
|
||||||
@@ -281,14 +406,18 @@ void PluginPages::on_cap_register(const PluginCapabilityId& id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
page->set_icon_image_id(image_id);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pages.emplace(id, page);
|
m_pages.emplace(id, page);
|
||||||
|
m_order.push_back(id);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginPages::on_cap_register(const PluginCapabilityId& id)
|
||||||
|
{
|
||||||
|
if (m_parent == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (create_page(id))
|
||||||
|
relayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginPages::on_cap_deregister(const PluginCapabilityId& id)
|
void PluginPages::on_cap_deregister(const PluginCapabilityId& id)
|
||||||
@@ -327,39 +456,87 @@ void PluginPages::remove_page(const PluginCapabilityId& id)
|
|||||||
PluginPage* page = it->second;
|
PluginPage* page = it->second;
|
||||||
const int removed_image_id = page->get_icon_image_id();
|
const int removed_image_id = page->get_icon_image_id();
|
||||||
page->detach_capability();
|
page->detach_capability();
|
||||||
if (m_parent != nullptr) {
|
|
||||||
const int index = m_parent->FindPage(page);
|
m_pages.erase(it);
|
||||||
if (index != wxNOT_FOUND)
|
m_order.erase(std::remove(m_order.begin(), m_order.end(), id), m_order.end());
|
||||||
m_parent->RemovePage(static_cast<size_t>(index));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_image_list && removed_image_id != wxBookCtrlBase::NO_IMAGE &&
|
if (m_image_list && removed_image_id != wxBookCtrlBase::NO_IMAGE &&
|
||||||
removed_image_id >= 0 && removed_image_id < m_image_list->GetImageCount()) {
|
removed_image_id >= 0 && removed_image_id < m_image_list->GetImageCount()) {
|
||||||
m_image_list->Remove(removed_image_id);
|
m_image_list->Remove(removed_image_id);
|
||||||
|
|
||||||
// wxImageList IDs are positional. Removing one shifts all later images down by
|
// wxImageList IDs are positional. Removing one shifts all later images down by one.
|
||||||
// one, so update both the page state and the notebook button for those pages.
|
for (auto& [other_id, other_page] : m_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();
|
const int other_image_id = other_page->get_icon_image_id();
|
||||||
if (other_image_id <= removed_image_id)
|
if (other_image_id > removed_image_id)
|
||||||
continue;
|
other_page->set_icon_image_id(other_image_id - 1);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
relayout();
|
||||||
page->Destroy();
|
page->Destroy();
|
||||||
m_pages.erase(it);
|
}
|
||||||
|
|
||||||
|
wxString PluginPages::page_tab_id(const PluginCapabilityId& id)
|
||||||
|
{
|
||||||
|
return wxString::FromUTF8("plugin." + id.plugin_key + "." + id.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PluginPages::relayout()
|
||||||
|
{
|
||||||
|
if (m_parent == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_order.erase(std::remove_if(m_order.begin(), m_order.end(),
|
||||||
|
[this](const PluginCapabilityId& id) {
|
||||||
|
const bool orphaned = m_pages.find(id) == m_pages.end();
|
||||||
|
if (orphaned)
|
||||||
|
BOOST_LOG_TRIVIAL(error) << "PluginPages::relayout: '" << id.name << "' was in m_order but not m_pages, dropping";
|
||||||
|
return orphaned;
|
||||||
|
}),
|
||||||
|
m_order.end());
|
||||||
|
|
||||||
|
wxString id_to_reselect = m_parent->GetSelectedPageName();
|
||||||
|
|
||||||
|
while (m_parent->GetPageCount() > m_notebook_base_index)
|
||||||
|
m_parent->RemovePage(m_parent->GetPageCount() - 1);
|
||||||
|
if (m_overflow_panel != nullptr)
|
||||||
|
m_overflow_panel->clear();
|
||||||
|
|
||||||
|
const int visible_slots = std::max(1, m_visible_page_count);
|
||||||
|
const bool need_overflow = static_cast<int>(m_order.size()) > visible_slots;
|
||||||
|
const size_t individual_count = need_overflow ? static_cast<size_t>(visible_slots - 1) : m_order.size();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < individual_count; ++i) {
|
||||||
|
const PluginCapabilityId& id = m_order[i];
|
||||||
|
PluginPage* page = m_pages.at(id);
|
||||||
|
m_parent->InsertPage(m_parent->GetPageCount(), page_tab_id(id), page, wxString::FromUTF8(id.name), page->get_icon_image_id());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_overflow) {
|
||||||
|
if (m_overflow_panel == nullptr)
|
||||||
|
m_overflow_panel = new PluginPagesOverflowPanel(m_parent);
|
||||||
|
|
||||||
|
bool reselecting_overflow_entry = false;
|
||||||
|
for (size_t i = individual_count; i < m_order.size(); ++i) {
|
||||||
|
const PluginCapabilityId& id = m_order[i];
|
||||||
|
m_overflow_panel->add_entry(id, m_pages.at(id), wxString::FromUTF8(id.name));
|
||||||
|
if (page_tab_id(id) == id_to_reselect) {
|
||||||
|
m_overflow_panel->select_entry(id);
|
||||||
|
reselecting_overflow_entry = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (reselecting_overflow_entry)
|
||||||
|
id_to_reselect = "plugin.__overflow__";
|
||||||
|
|
||||||
|
m_parent->InsertPage(m_parent->GetPageCount(), "plugin.__overflow__", m_overflow_panel,
|
||||||
|
m_overflow_panel->current_title(), m_overflow_panel->current_image_id());
|
||||||
|
} else if (m_overflow_panel != nullptr) {
|
||||||
|
m_overflow_panel->Destroy();
|
||||||
|
m_overflow_panel = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!id_to_reselect.empty())
|
||||||
|
m_parent->SelectPageByName(id_to_reselect);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <wx/bookctrl.h>
|
#include <wx/bookctrl.h>
|
||||||
#include <wx/imaglist.h>
|
#include <wx/imaglist.h>
|
||||||
@@ -47,6 +48,8 @@ private:
|
|||||||
int m_icon_image_id = wxBookCtrlBase::NO_IMAGE;
|
int m_icon_image_id = wxBookCtrlBase::NO_IMAGE;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class PluginPagesOverflowPanel;
|
||||||
|
|
||||||
class PluginPages
|
class PluginPages
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -64,14 +67,26 @@ public:
|
|||||||
void on_plugin_register(const std::string& plugin_key);
|
void on_plugin_register(const std::string& plugin_key);
|
||||||
void on_plugin_deregister(const std::string& plugin_key);
|
void on_plugin_deregister(const std::string& plugin_key);
|
||||||
|
|
||||||
|
int get_visible_page_count() const { return m_visible_page_count; }
|
||||||
|
void set_visible_page_count(int count);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<PagesPluginCapability> get_pages_cap(const PluginCapabilityId& id, bool is_enabled) const;
|
std::shared_ptr<PagesPluginCapability> get_pages_cap(const PluginCapabilityId& id, bool is_enabled) const;
|
||||||
|
bool create_page(const PluginCapabilityId& id);
|
||||||
void remove_page(const PluginCapabilityId& id);
|
void remove_page(const PluginCapabilityId& id);
|
||||||
|
|
||||||
|
void relayout();
|
||||||
|
static wxString page_tab_id(const PluginCapabilityId& id);
|
||||||
|
|
||||||
std::map<PluginCapabilityId, PluginPage*> m_pages;
|
std::map<PluginCapabilityId, PluginPage*> m_pages;
|
||||||
|
std::vector<PluginCapabilityId> m_order;
|
||||||
Notebook* m_parent{nullptr};
|
Notebook* m_parent{nullptr};
|
||||||
|
size_t m_notebook_base_index{0};
|
||||||
|
|
||||||
std::unique_ptr<wxImageList> m_image_list;
|
std::unique_ptr<wxImageList> m_image_list;
|
||||||
|
int m_visible_page_count{0};
|
||||||
|
|
||||||
|
PluginPagesOverflowPanel* m_overflow_panel{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|||||||
Reference in New Issue
Block a user