mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-11 11:07:40 +00:00
Plugin system UI Fixes / Improvements (#15568)
this one is wxWidgets related ones. will send web dialogs related one later # Slicing-Pipeline management • Matched UI components and colors • All row clickable for editing to make it easier to click • Add button also uses full row to make it easier to click • Simplified code before <img width="411" height="211" alt="Screenshot-20260907131847" src="https://github.com/user-attachments/assets/c6f12f40-0592-4723-ae2c-f6f179f8b819" /> after <img width="420" height="238" alt="Screenshot-20260907131905" src="https://github.com/user-attachments/assets/8bb63c76-00d8-44eb-9c03-0bfde4915c3e" /> <img width="470" height="327" alt="orca-slicer_F5Lszk6Mc3" src="https://github.com/user-attachments/assets/90023ede-f5de-4b77-8409-39c800ab9618" /> # Plugin choice dialog • Matched UI components and colors before <img width="313" height="189" alt="Screenshot-20260907132149" src="https://github.com/user-attachments/assets/fc0ab0b1-f03a-407e-93f6-adecc2bcbb07" /> after <img width="405" height="213" alt="Screenshot-20260907132203" src="https://github.com/user-attachments/assets/4f73d7c3-6af8-4ba8-bfea-a2758288f999" /> # No plugin message before <img width="370" height="165" alt="Screenshot-20260908111523" src="https://github.com/user-attachments/assets/fdf13dcd-ae18-4511-9936-42ea1c2fdacd" /> after <img width="399" height="183" alt="Screenshot-20260908111338" src="https://github.com/user-attachments/assets/875f5cdb-eecc-43e9-ac5d-a9d8c3708e05" /> # Progress dialog this one also effects other progress dialogs as well i was not able to recolor progress bar on previous version of wxWidgets. before <img width="373" height="164" alt="Screenshot-20260910163859" src="https://github.com/user-attachments/assets/c6f408e7-da45-413e-9bd2-f987a7d20685" /> after <img width="393" height="144" alt="Screenshot-20260910165844" src="https://github.com/user-attachments/assets/a150294d-677a-42b9-98e2-c1b571b1d4ed" /> <!-- > A guide for users on how to download the artifacts from this PR. --> [How to Download Pull Requests Artifacts for Testing](https://www.orcaslicer.com/wiki/how_to_download_pr_artifacts)
This commit is contained in:
@@ -1,8 +1,4 @@
|
||||
<svg width="25" height="25" xmlns="http://www.w3.org/2000/svg" fill="none">
|
||||
|
||||
<g>
|
||||
<title>Layer 1</title>
|
||||
<path id="svg_1" stroke-linecap="round" stroke-width="2" stroke="#262E30" d="m1,12.5l23,0"/>
|
||||
<path id="svg_2" stroke-linecap="round" stroke-width="2" stroke="#262E30" d="m12.5,24l0,-23"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<line x1="0.5" y1="7.5" x2="14.5" y2="7.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/>
|
||||
<line x1="7.5" y1="0.5" x2="7.5" y2="14.5" style="fill:none;stroke:#949494;stroke-linecap:round;stroke-linejoin:round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 312 B After Width: | Height: | Size: 332 B |
@@ -2154,6 +2154,7 @@ void PrinterAgentChoice::msw_rescale()
|
||||
void PluginField::BUILD()
|
||||
{
|
||||
auto* panel = new wxPanel(m_parent, wxID_ANY);
|
||||
panel->SetBackgroundColour(*wxWHITE);
|
||||
wxGetApp().UpdateDarkUI(panel);
|
||||
window = panel;
|
||||
|
||||
@@ -2196,9 +2197,8 @@ void PluginField::rebuild_ui()
|
||||
m_rows.clear();
|
||||
m_standalone_add_btn = nullptr;
|
||||
|
||||
if (m_values.empty()) {
|
||||
add_empty_state_row();
|
||||
} else {
|
||||
add_empty_state_row();
|
||||
if (!m_values.empty()) {
|
||||
for (size_t i = 0; i < m_values.size(); ++i)
|
||||
add_plugin_row(display_name_for_value(m_values[i]), i == m_values.size() - 1);
|
||||
}
|
||||
@@ -2215,94 +2215,43 @@ void PluginField::rebuild_ui()
|
||||
|
||||
void PluginField::add_empty_state_row()
|
||||
{
|
||||
const auto button_size = wxSize(def_width_thinner() * m_em_unit, -1);
|
||||
auto row_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
wxTextCtrl* display = new wxTextCtrl(window, wxID_ANY, _L("No plugin selected"),
|
||||
wxDefaultPosition, wxSize(def_width_wider() * m_em_unit, wxDefaultCoord),
|
||||
wxTE_READONLY);
|
||||
display->SetEditable(false);
|
||||
wxGetApp().UpdateDarkUI(display);
|
||||
display->SetToolTip(_L("No plugin selected"));
|
||||
|
||||
auto add_btn = new ScalableButton(window, wxID_ANY, "param_add", wxEmptyString,
|
||||
button_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true, 16);
|
||||
wxGetApp().UpdateDarkUI(add_btn);
|
||||
add_btn->SetToolTip(_L("Add plugin"));
|
||||
auto add_btn = new Button(window, _L("Add plugin"), "param_add", 0, 16);
|
||||
add_btn->SetStyle(ButtonStyle::Regular, ButtonType::Parameter);
|
||||
|
||||
add_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { on_add_clicked(); });
|
||||
|
||||
row_sizer->Add(display, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4);
|
||||
row_sizer->Add(add_btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||
m_main_sizer->Add(row_sizer, 0, wxEXPAND);
|
||||
|
||||
PluginRow row;
|
||||
row.display = display;
|
||||
row.add_btn = add_btn;
|
||||
row.sizer = row_sizer;
|
||||
m_rows.push_back(row);
|
||||
m_main_sizer->Add(add_btn, 0, wxEXPAND | wxBOTTOM, window->FromDIP(SidebarProps::ContentMarginV()));
|
||||
|
||||
m_standalone_add_btn = add_btn;
|
||||
}
|
||||
|
||||
void PluginField::add_plugin_row(const wxString& value, bool is_last)
|
||||
{
|
||||
const auto button_size = wxSize(def_width_thinner() * m_em_unit, -1);
|
||||
auto row_sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
|
||||
ScalableButton* select_btn = new ScalableButton(window, wxID_ANY, "search", wxEmptyString,
|
||||
button_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true, 16);
|
||||
wxGetApp().UpdateDarkUI(select_btn);
|
||||
select_btn->SetToolTip(_L("Select plugin"));
|
||||
|
||||
wxTextCtrl* display = new wxTextCtrl(window, wxID_ANY, value,
|
||||
wxDefaultPosition, wxSize(def_width_wider() * m_em_unit, wxDefaultCoord),
|
||||
wxTE_READONLY);
|
||||
display->SetEditable(false);
|
||||
wxGetApp().UpdateDarkUI(display);
|
||||
ComboBox* display = new ComboBox(window, wxID_ANY, value, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY | CB_NO_DROP_ICON);
|
||||
display->SetIcon("edit");
|
||||
display->SetToolTip(get_tooltip_text(value));
|
||||
|
||||
ScalableButton* remove_btn = nullptr;
|
||||
if (!m_opt.readonly) {
|
||||
remove_btn = new ScalableButton(window, wxID_ANY, "cross", wxEmptyString,
|
||||
button_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true, 16);
|
||||
wxGetApp().UpdateDarkUI(remove_btn);
|
||||
remove_btn->SetToolTip(_L("Remove plugin"));
|
||||
}
|
||||
ScalableButton* remove_btn = new ScalableButton(window, wxID_ANY, "cross", wxEmptyString,
|
||||
wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true, 16);
|
||||
remove_btn->SetToolTip(_L("Remove plugin"));
|
||||
|
||||
ScalableButton* add_btn = nullptr;
|
||||
if (is_last && !m_opt.readonly) {
|
||||
add_btn = new ScalableButton(window, wxID_ANY, "param_add", wxEmptyString,
|
||||
button_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true, 16);
|
||||
wxGetApp().UpdateDarkUI(add_btn);
|
||||
add_btn->SetToolTip(_L("Add plugin"));
|
||||
add_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent&) { on_add_clicked(); });
|
||||
}
|
||||
if (m_opt.readonly)
|
||||
remove_btn->Disable();
|
||||
|
||||
const size_t row_index = m_rows.size();
|
||||
select_btn->Bind(wxEVT_BUTTON, [this, row_index](wxCommandEvent&) { on_select_clicked(row_index); });
|
||||
if (remove_btn)
|
||||
remove_btn->Bind(wxEVT_BUTTON, [this, row_index](wxCommandEvent&) { on_remove_clicked(row_index); });
|
||||
display->Bind(wxEVT_LEFT_DOWN, [this, row_index](wxMouseEvent& ) { on_select_clicked(row_index); });
|
||||
remove_btn->Bind(wxEVT_BUTTON, [this, row_index](wxCommandEvent&) { on_remove_clicked(row_index); });
|
||||
|
||||
row_sizer->Add(select_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4);
|
||||
row_sizer->Add(display, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4);
|
||||
if (remove_btn)
|
||||
row_sizer->Add(remove_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4);
|
||||
if (add_btn)
|
||||
row_sizer->Add(add_btn, 0, wxALIGN_CENTER_VERTICAL);
|
||||
else if (!m_opt.readonly) {
|
||||
// Reserve space equal to the add button so all rows align.
|
||||
row_sizer->Add(button_size.GetWidth(), button_size.GetHeight(), 0, wxALIGN_CENTER_VERTICAL);
|
||||
}
|
||||
row_sizer->Add(display , 1, wxALIGN_CENTER_VERTICAL);
|
||||
row_sizer->Add(remove_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, window->FromDIP(SidebarProps::ElementSpacing()));
|
||||
|
||||
const int bottom_gap = is_last ? 0 : 4;
|
||||
m_main_sizer->Add(row_sizer, 0, wxEXPAND | (bottom_gap > 0 ? wxBOTTOM : 0), bottom_gap);
|
||||
m_main_sizer->Add(row_sizer, 0, wxEXPAND | wxBOTTOM, window->FromDIP(is_last ? SidebarProps::ContentMarginV() : 4));
|
||||
|
||||
PluginRow row;
|
||||
row.select_btn = select_btn;
|
||||
row.display = display;
|
||||
row.remove_btn = remove_btn;
|
||||
row.add_btn = add_btn;
|
||||
row.sizer = row_sizer;
|
||||
m_rows.push_back(row);
|
||||
}
|
||||
@@ -2354,9 +2303,9 @@ void PluginField::on_add_clicked()
|
||||
m_values.push_back(selected);
|
||||
m_value = m_values;
|
||||
|
||||
rebuild_ui();
|
||||
|
||||
on_change_field();
|
||||
// Defer: don't destroy the clicked button from inside its own handler.
|
||||
if(window)
|
||||
window->CallAfter([this]() {rebuild_ui(); on_change_field();});
|
||||
}
|
||||
|
||||
void PluginField::on_remove_clicked(size_t index)
|
||||
@@ -2367,8 +2316,9 @@ void PluginField::on_remove_clicked(size_t index)
|
||||
m_values.erase(m_values.begin() + index);
|
||||
m_value = m_values;
|
||||
|
||||
rebuild_ui();
|
||||
on_change_field();
|
||||
// Defer: don't destroy the clicked button from inside its own handler.
|
||||
if(window)
|
||||
window->CallAfter([this]() {rebuild_ui(); on_change_field();});
|
||||
}
|
||||
|
||||
wxString PluginField::get_row_value(size_t index) const
|
||||
@@ -2382,7 +2332,7 @@ void PluginField::set_row_value(size_t index, const wxString& value)
|
||||
{
|
||||
if (index >= m_rows.size() || !m_rows[index].display)
|
||||
return;
|
||||
m_rows[index].display->ChangeValue(value);
|
||||
m_rows[index].display->SetValue(value);
|
||||
m_rows[index].display->SetToolTip(get_tooltip_text(value));
|
||||
}
|
||||
|
||||
@@ -2425,14 +2375,10 @@ boost::any& PluginField::get_value()
|
||||
void PluginField::enable()
|
||||
{
|
||||
for (auto& row : m_rows) {
|
||||
if (row.select_btn)
|
||||
row.select_btn->Enable();
|
||||
if (row.display)
|
||||
row.display->Enable();
|
||||
if (row.remove_btn)
|
||||
row.remove_btn->Enable();
|
||||
if (row.add_btn)
|
||||
row.add_btn->Enable();
|
||||
}
|
||||
if (m_standalone_add_btn)
|
||||
m_standalone_add_btn->Enable();
|
||||
@@ -2441,14 +2387,10 @@ void PluginField::enable()
|
||||
void PluginField::disable()
|
||||
{
|
||||
for (auto& row : m_rows) {
|
||||
if (row.select_btn)
|
||||
row.select_btn->Disable();
|
||||
if (row.display)
|
||||
row.display->Disable();
|
||||
if (row.remove_btn)
|
||||
row.remove_btn->Disable();
|
||||
if (row.add_btn)
|
||||
row.add_btn->Disable();
|
||||
}
|
||||
if (m_standalone_add_btn)
|
||||
m_standalone_add_btn->Disable();
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "wxExtensions.hpp"
|
||||
#include "Widgets/SpinInput.hpp"
|
||||
#include "Widgets/TextInput.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
|
||||
#ifdef __WXMSW__
|
||||
#define wxMSW true
|
||||
@@ -532,10 +533,8 @@ public:
|
||||
|
||||
private:
|
||||
struct PluginRow {
|
||||
ScalableButton* select_btn { nullptr };
|
||||
wxTextCtrl* display { nullptr };
|
||||
ComboBox* display { nullptr };
|
||||
ScalableButton* remove_btn { nullptr };
|
||||
ScalableButton* add_btn { nullptr };
|
||||
wxBoxSizer* sizer { nullptr };
|
||||
};
|
||||
|
||||
@@ -553,7 +552,7 @@ private:
|
||||
wxBoxSizer* m_main_sizer { nullptr };
|
||||
std::vector<PluginRow> m_rows;
|
||||
std::vector<std::string> m_values;
|
||||
ScalableButton* m_standalone_add_btn { nullptr };
|
||||
Button* m_standalone_add_btn { nullptr };
|
||||
std::function<std::string()> m_selector;
|
||||
};
|
||||
|
||||
|
||||
@@ -698,10 +698,15 @@ std::string OptionsGroup::pick_plugin(const ConfigOptionDef& opt)
|
||||
Slic3r::PluginManager& manager = Slic3r::PluginManager::instance();
|
||||
const Slic3r::PluginCapabilityType plugin_type = Slic3r::plugin_capability_type_from_string(opt.plugin_type);
|
||||
if (plugin_type == Slic3r::PluginCapabilityType::Unknown) {
|
||||
const std::string message = opt.plugin_type.empty()
|
||||
? "This setting does not specify a plugin capability type."
|
||||
: "This setting specifies an unrecognized plugin capability type: '" + opt.plugin_type + "'.";
|
||||
wxMessageBox(from_u8(message), _L("Plugin Selection"), wxOK | wxICON_WARNING, m_parent);
|
||||
MessageDialog dlg(m_parent,
|
||||
opt.plugin_type.empty() ? _L("This setting does not specify a plugin capability type.")
|
||||
: _L("This setting specifies an unrecognized plugin capability type: ") + "'" + opt.plugin_type + "'.",
|
||||
_L("Plugin Selection"),
|
||||
wxOK | wxICON_WARNING
|
||||
);
|
||||
dlg.CenterOnParent();
|
||||
dlg.ShowModal();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -714,7 +719,13 @@ std::string OptionsGroup::pick_plugin(const ConfigOptionDef& opt)
|
||||
});
|
||||
|
||||
if (caps.empty()) {
|
||||
wxMessageBox(_L("No plugins capabilities available for this type.\nEnable or install some to use."), _L("Plugin Selection"), wxOK | wxICON_INFORMATION, m_parent);
|
||||
MessageDialog dlg(m_parent,
|
||||
_L("No plugins capabilities available for this type.\nEnable or install some to use."),
|
||||
_L("Plugin Selection"),
|
||||
wxOK | wxICON_INFORMATION
|
||||
);
|
||||
dlg.CenterOnParent();
|
||||
dlg.ShowModal();
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@@ -9,12 +9,16 @@
|
||||
#include "GUI.hpp"
|
||||
#include "I18N.hpp"
|
||||
|
||||
#include "GUI_App.hpp"
|
||||
|
||||
#include "Widgets/DialogButtons.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
PluginPickerDialog::PluginPickerDialog(wxWindow* parent,
|
||||
const wxString& plugin_type_label,
|
||||
const std::vector<Slic3r::PluginDescriptor>& plugins)
|
||||
: wxDialog(parent, wxID_ANY, wxString::Format(_L("Select %s Plugin"), plugin_type_label))
|
||||
: DPIDialog(parent, wxID_ANY, wxString::Format(_L("Select %s Plugin"), plugin_type_label))
|
||||
, m_plugins(plugins)
|
||||
{
|
||||
build_ui(plugin_type_label);
|
||||
@@ -24,7 +28,7 @@ PluginPickerDialog::PluginPickerDialog(wxWindow* parent,
|
||||
PluginPickerDialog::PluginPickerDialog(wxWindow* parent,
|
||||
const wxString& plugin_type_label,
|
||||
std::vector<CapabilityEntry> capabilities)
|
||||
: wxDialog(parent, wxID_ANY, wxString::Format(_L("Select %s Plugin"), plugin_type_label))
|
||||
: DPIDialog(parent, wxID_ANY, wxString::Format(_L("Select %s Plugin"), plugin_type_label))
|
||||
, m_capabilities(std::move(capabilities))
|
||||
{
|
||||
build_capability_ui(plugin_type_label);
|
||||
@@ -33,12 +37,18 @@ PluginPickerDialog::PluginPickerDialog(wxWindow* parent,
|
||||
|
||||
void PluginPickerDialog::build_ui(const wxString& plugin_type_label)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
const bool has_plugins = !m_plugins.empty();
|
||||
|
||||
auto* top_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
auto* info_text = new wxStaticText(this, wxID_ANY,
|
||||
wxString::Format(_L("Choose a %s plugin from the list below."), plugin_type_label));
|
||||
top_sizer->Add(info_text, 0, wxALL | wxEXPAND, 10);
|
||||
info_text->SetFont(Label::Body_14);
|
||||
info_text->SetForegroundColour(wxColour("#363636"));
|
||||
top_sizer->Add(info_text, 0, wxALL | wxEXPAND, FromDIP(10));
|
||||
|
||||
top_sizer->AddSpacer(FromDIP(5));
|
||||
|
||||
wxArrayString choices;
|
||||
choices.reserve(m_plugins.size());
|
||||
@@ -49,84 +59,103 @@ void PluginPickerDialog::build_ui(const wxString& plugin_type_label)
|
||||
choices.Add(label);
|
||||
}
|
||||
|
||||
m_choice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
|
||||
m_choice = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
|
||||
for (const wxString &opt : choices) { m_choice->Append(opt); }
|
||||
|
||||
if (has_plugins) {
|
||||
m_choice->SetSelection(0);
|
||||
m_choice->Bind(wxEVT_CHOICE, [this](wxCommandEvent& evt) {
|
||||
m_choice->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
|
||||
update_description(evt.GetSelection());
|
||||
});
|
||||
} else {
|
||||
m_choice->Enable(false);
|
||||
}
|
||||
|
||||
top_sizer->Add(m_choice, 0, wxLEFT | wxRIGHT | wxEXPAND, 10);
|
||||
top_sizer->Add(m_choice, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(10));
|
||||
|
||||
m_description = new wxStaticText(this, wxID_ANY, wxEmptyString);
|
||||
m_description->SetFont(Label::Body_14);
|
||||
m_description->SetForegroundColour(wxColour("#363636"));
|
||||
m_description->Wrap(400);
|
||||
top_sizer->Add(m_description, 0, wxALL | wxEXPAND, 10);
|
||||
top_sizer->Add(m_description, 0, wxALL | wxEXPAND, FromDIP(10));
|
||||
|
||||
if (has_plugins)
|
||||
update_description(0);
|
||||
else
|
||||
m_description->SetLabel(_L("No plugins found for this type."));
|
||||
|
||||
auto* button_sizer = new wxStdDialogButtonSizer();
|
||||
auto* ok_button = new wxButton(this, wxID_OK);
|
||||
ok_button->Enable(has_plugins);
|
||||
button_sizer->AddButton(ok_button);
|
||||
button_sizer->AddButton(new wxButton(this, wxID_CANCEL));
|
||||
button_sizer->Realize();
|
||||
auto dlg_btns = new DialogButtons(this, {"OK", "Cancel"});
|
||||
|
||||
top_sizer->Add(button_sizer, 0, wxALL | wxALIGN_RIGHT, 10);
|
||||
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { EndModal(wxID_OK); });
|
||||
dlg_btns->GetOK()->Enable(has_plugins);
|
||||
|
||||
dlg_btns->GetCANCEL()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { EndModal(wxID_CANCEL); });
|
||||
|
||||
top_sizer->Add(dlg_btns, 0, wxEXPAND);
|
||||
|
||||
SetSizerAndFit(top_sizer);
|
||||
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
void PluginPickerDialog::build_capability_ui(const wxString& plugin_type_label)
|
||||
{
|
||||
SetBackgroundColour(*wxWHITE);
|
||||
|
||||
const bool has_capabilities = !m_capabilities.empty();
|
||||
|
||||
auto* top_sizer = new wxBoxSizer(wxVERTICAL);
|
||||
auto* info_text = new wxStaticText(this, wxID_ANY,
|
||||
wxString::Format(_L("Choose a %s plugin from the list below."), plugin_type_label));
|
||||
top_sizer->Add(info_text, 0, wxALL | wxEXPAND, 10);
|
||||
info_text->SetFont(Label::Body_14);
|
||||
info_text->SetForegroundColour(wxColour("#363636"));
|
||||
|
||||
top_sizer->Add(info_text, 0, wxALL | wxEXPAND, FromDIP(10));
|
||||
|
||||
top_sizer->AddSpacer(FromDIP(5));
|
||||
|
||||
wxArrayString choices;
|
||||
choices.reserve(m_capabilities.size());
|
||||
for (const auto& cap : m_capabilities)
|
||||
choices.Add(cap.label);
|
||||
|
||||
m_choice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, choices);
|
||||
m_choice = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
|
||||
for (const wxString &opt : choices) { m_choice->Append(opt); }
|
||||
|
||||
if (has_capabilities) {
|
||||
m_choice->SetSelection(0);
|
||||
m_choice->Bind(wxEVT_CHOICE, [this](wxCommandEvent& evt) {
|
||||
m_choice->Bind(wxEVT_COMBOBOX, [this](wxCommandEvent& evt) {
|
||||
update_capability_description(evt.GetSelection());
|
||||
});
|
||||
} else {
|
||||
m_choice->Enable(false);
|
||||
}
|
||||
|
||||
top_sizer->Add(m_choice, 0, wxLEFT | wxRIGHT | wxEXPAND, 10);
|
||||
top_sizer->Add(m_choice, 0, wxLEFT | wxRIGHT | wxEXPAND, FromDIP(10));
|
||||
|
||||
m_description = new wxStaticText(this, wxID_ANY, wxEmptyString);
|
||||
m_description->SetFont(Label::Body_14);
|
||||
m_description->SetForegroundColour(wxColour("#363636"));
|
||||
m_description->Wrap(400);
|
||||
top_sizer->Add(m_description, 0, wxALL | wxEXPAND, 10);
|
||||
top_sizer->Add(m_description, 0, wxALL | wxEXPAND, FromDIP(10));
|
||||
|
||||
if (has_capabilities)
|
||||
update_capability_description(0);
|
||||
else
|
||||
m_description->SetLabel(_L("No plugins found for this type."));
|
||||
|
||||
auto* button_sizer = new wxStdDialogButtonSizer();
|
||||
auto* ok_button = new wxButton(this, wxID_OK);
|
||||
ok_button->Enable(has_capabilities);
|
||||
button_sizer->AddButton(ok_button);
|
||||
button_sizer->AddButton(new wxButton(this, wxID_CANCEL));
|
||||
button_sizer->Realize();
|
||||
auto dlg_btns = new DialogButtons(this, {"OK", "Cancel"});
|
||||
|
||||
top_sizer->Add(button_sizer, 0, wxALL | wxALIGN_RIGHT, 10);
|
||||
dlg_btns->GetOK()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { EndModal(wxID_OK); });
|
||||
dlg_btns->GetOK()->Enable(has_capabilities);
|
||||
|
||||
dlg_btns->GetCANCEL()->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) { EndModal(wxID_CANCEL); });
|
||||
|
||||
top_sizer->Add(dlg_btns, 0, wxEXPAND);
|
||||
|
||||
SetSizerAndFit(top_sizer);
|
||||
|
||||
wxGetApp().UpdateDlgDarkUI(this);
|
||||
}
|
||||
|
||||
PluginPickerDialog::CapabilityEntry PluginPickerDialog::selected_capability() const
|
||||
@@ -185,4 +214,6 @@ void PluginPickerDialog::update_description(int selection)
|
||||
Layout();
|
||||
}
|
||||
|
||||
void PluginPickerDialog::on_dpi_changed(const wxRect &suggested_rect) {}
|
||||
|
||||
}} // namespace Slic3r::GUI
|
||||
|
||||
@@ -11,9 +11,12 @@
|
||||
|
||||
#include "slic3r/plugin/PluginManager.hpp"
|
||||
|
||||
#include "GUI_Utils.hpp"
|
||||
#include "Widgets/ComboBox.hpp"
|
||||
|
||||
namespace Slic3r { namespace GUI {
|
||||
|
||||
class PluginPickerDialog : public wxDialog
|
||||
class PluginPickerDialog : public DPIDialog
|
||||
{
|
||||
public:
|
||||
// Entry for capability-level selection (plugin_type non-empty path).
|
||||
@@ -40,13 +43,15 @@ public:
|
||||
// Returns the {plugin_key, name} of the selected capability (capability path).
|
||||
CapabilityEntry selected_capability() const;
|
||||
|
||||
void on_dpi_changed(const wxRect &suggested_rect) override;
|
||||
|
||||
private:
|
||||
void build_ui(const wxString& plugin_type_label);
|
||||
void build_capability_ui(const wxString& plugin_type_label);
|
||||
void update_description(int selection);
|
||||
void update_capability_description(int selection);
|
||||
|
||||
wxChoice* m_choice { nullptr };
|
||||
ComboBox* m_choice { nullptr };
|
||||
wxStaticText* m_description { nullptr };
|
||||
std::vector<Slic3r::PluginDescriptor> m_plugins;
|
||||
std::vector<CapabilityEntry> m_capabilities;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define slic3r_PluginsDialog_hpp_
|
||||
|
||||
#include "Widgets/WebViewHostDialog.hpp"
|
||||
#include "Widgets/ProgressDialog.hpp"
|
||||
#include "PluginSource.hpp"
|
||||
#include "PluginStatus.hpp"
|
||||
#include "PluginSort.hpp"
|
||||
@@ -107,12 +108,12 @@ private:
|
||||
const wxString& title,
|
||||
const wxString& message,
|
||||
int maximum = 100,
|
||||
int style = wxPD_APP_MODAL | wxPD_AUTO_HIDE,
|
||||
int style = wxPD_APP_MODAL | wxPD_AUTO_HIDE, // | wxPD_CAN_ABORT for cancel button
|
||||
bool finish_after_dialog_destroyed = false)
|
||||
{
|
||||
const auto alive = m_alive;
|
||||
wxProgressDialog* progress = new wxProgressDialog(title, message, maximum, this, style);
|
||||
wxTimer* timer = new wxTimer();
|
||||
ProgressDialog* progress = new ProgressDialog(title, message, maximum, this, style);
|
||||
wxTimer* timer = new wxTimer();
|
||||
|
||||
timer->Bind(wxEVT_TIMER, [alive, progress, message](wxTimerEvent&) {
|
||||
if (alive->load(std::memory_order_acquire) && progress)
|
||||
|
||||
@@ -178,7 +178,7 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int
|
||||
wxBoxSizer *sizer_1line = new wxBoxSizer(wxHORIZONTAL);
|
||||
m_msg = new wxStaticText(m_panel_1line, wxID_ANY, wxEmptyString, wxDefaultPosition, PROGRESSDIALOG_SIMPLEBOOK_SIZE, 0);
|
||||
m_msg->Wrap(-1);
|
||||
m_msg->SetFont(::Label::Body_13);
|
||||
m_msg->SetFont(::Label::Body_14);
|
||||
m_msg->SetForegroundColour(PROGRESSDIALOG_GREY_700);
|
||||
sizer_1line->Add(m_msg, 0, wxALIGN_CENTER, 0);
|
||||
m_panel_1line->SetSizer(sizer_1line);
|
||||
@@ -188,7 +188,7 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int
|
||||
wxBoxSizer *sizer_2line = new wxBoxSizer(wxVERTICAL);
|
||||
m_msg_2line = new wxStaticText(m_panel_2line, wxID_ANY, wxEmptyString, wxDefaultPosition, PROGRESSDIALOG_SIMPLEBOOK_SIZE, 0);
|
||||
m_msg_2line->Wrap(PROGRESSDIALOG_SIMPLEBOOK_SIZE.x);
|
||||
m_msg_2line->SetFont(::Label::Body_13);
|
||||
m_msg_2line->SetFont(::Label::Body_14);
|
||||
m_msg_2line->SetForegroundColour(PROGRESSDIALOG_GREY_700);
|
||||
m_msg_2line->SetMaxSize(wxSize(PROGRESSDIALOG_SIMPLEBOOK_SIZE.x, -1));
|
||||
sizer_2line->Add(m_msg_2line, 1, wxALL, 0);
|
||||
@@ -204,7 +204,7 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int
|
||||
|
||||
m_msg = new wxStaticText(m_msg_scrolledWindow, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(PROGRESSDIALOG_SIMPLEBOOK_SIZE.x, -1), 0);
|
||||
m_msg->Wrap(PROGRESSDIALOG_SIMPLEBOOK_SIZE.x);
|
||||
m_msg->SetFont(::Label::Body_13);
|
||||
m_msg->SetFont(::Label::Body_14);
|
||||
m_msg->SetForegroundColour(PROGRESSDIALOG_GREY_700);
|
||||
|
||||
m_msg_sizer->Add(m_msg, 0, wxEXPAND | wxALL, 0);
|
||||
@@ -228,6 +228,9 @@ bool ProgressDialog::Create(const wxString &title, const wxString &message, int
|
||||
if (!HasPDFlag(wxPD_NO_PROGRESS)) {
|
||||
m_gauge = new wxGauge(this, wxID_ANY, maximum, wxDefaultPosition, PROGRESSDIALOG_GAUGE_SIZE, gauge_style);
|
||||
m_gauge->SetValue(0);
|
||||
m_gauge->SetForegroundColour(wxColour("#009688"));
|
||||
m_gauge->SetBackgroundColour(wxColour("#D9D9D9"));
|
||||
wxGetApp().UpdateDarkUI(m_gauge);
|
||||
m_sizer_main->Add(m_gauge, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(28));
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ class WXDLLIMPEXP_FWD_CORE wxWindowDisabler;
|
||||
#define PROGRESSDIALOG_GAUGE_SIZE wxSize(FromDIP(320), FromDIP(6))
|
||||
#define PROGRESSDIALOG_CANCEL_BUTTON_SIZE wxSize(FromDIP(60), FromDIP(24))
|
||||
#define PROGRESSDIALOG_DEF_BK wxColour(255,255,255)
|
||||
#define PROGRESSDIALOG_GREY_700 wxColour(107,107,107)
|
||||
#define PROGRESSDIALOG_GREY_700 wxColour(54,54,54) // #363636 label color
|
||||
|
||||
#define wxPD_NO_PROGRESS 0x0100
|
||||
|
||||
|
||||
Reference in New Issue
Block a user