BambuStudio/src/slic3r/GUI/Preferences.cpp

994 lines
42 KiB
C++

#include "Preferences.hpp"
#include "OptionsGroup.hpp"
#include "GUI_App.hpp"
#include "MainFrame.hpp"
#include "Plater.hpp"
#include "MsgDialog.hpp"
#include "I18N.hpp"
#include "libslic3r/AppConfig.hpp"
#include <wx/notebook.h>
#include "Notebook.hpp"
#include "OG_CustomCtrl.hpp"
#include "wx/graphics.h"
#include "Widgets/CheckBox.hpp"
#include "Widgets/ComboBox.hpp"
#include "Widgets/RadioBox.hpp"
#include "Widgets/TextInput.hpp"
#include <wx/listimpl.cpp>
#include <map>
namespace Slic3r { namespace GUI {
WX_DEFINE_LIST(RadioSelectorList);
wxDEFINE_EVENT(EVT_PREFERENCES_SELECT_TAB, wxCommandEvent);
// @class: PreferencesDialog
// @ret: items
// @birth: created by onion
wxBoxSizer *PreferencesDialog::create_item_title(wxString title, wxWindow *parent, wxString tooltip)
{
wxBoxSizer *m_sizer_title = new wxBoxSizer(wxHORIZONTAL);
auto m_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxDefaultSize, 0);
m_title->SetForegroundColour(DESIGN_GRAY800_COLOR);
m_title->SetFont(::Label::Head_13);
m_title->Wrap(-1);
//m_title->SetToolTip(tooltip);
auto m_line = new wxPanel(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, 1), wxTAB_TRAVERSAL);
m_line->SetBackgroundColour(DESIGN_GRAY400_COLOR);
m_sizer_title->Add(m_title, 0, wxALIGN_CENTER | wxALL, 3);
m_sizer_title->Add(0, 0, 0, wxLEFT, 9);
//m_sizer_title->Add(m_line, 0, wxEXPAND, 0);
wxBoxSizer *sizer_line = new wxBoxSizer(wxVERTICAL);
sizer_line->Add( m_line, 0, wxEXPAND, 0 );
m_sizer_title->Add( sizer_line, 1, wxALIGN_CENTER, 0 );
//m_sizer_title->Add( 0, 0, 0, wxEXPAND|wxLEFT, 80 );
return m_sizer_title;
}
wxBoxSizer *PreferencesDialog::create_item_combobox(wxString title, wxWindow *parent, wxString tooltip, std::string param, std::vector<wxString> vlist)
{
wxBoxSizer *m_sizer_combox = new wxBoxSizer(wxHORIZONTAL);
m_sizer_combox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
auto combo_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, DESIGN_TITLE_SIZE, 0);
combo_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
combo_title->SetFont(::Label::Body_13);
combo_title->SetToolTip(tooltip);
combo_title->Wrap(-1);
m_sizer_combox->Add(combo_title, 0, wxALIGN_CENTER | wxALL, 3);
auto combobox = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, DESIGN_LARGE_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
combobox->SetFont(::Label::Body_13);
combobox->GetDropDown().SetFont(::Label::Body_13);
std::vector<wxString>::iterator iter;
for (iter = vlist.begin(); iter != vlist.end(); iter++) { combobox->Append(*iter); }
auto use_inch = app_config->get(param);
if (!use_inch.empty()) { combobox->SetSelection(atoi(use_inch.c_str())); }
m_sizer_combox->Add(combobox, 0, wxALIGN_CENTER, 0);
//// save config
combobox->GetDropDown().Bind(wxEVT_COMBOBOX, [this, param](wxCommandEvent &e) {
app_config->set(param, std::to_string(e.GetSelection()));
app_config->save();
e.Skip();
});
return m_sizer_combox;
}
wxBoxSizer *PreferencesDialog::create_item_language_combobox(
wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param, std::vector<const wxLanguageInfo *> vlist)
{
wxBoxSizer *m_sizer_combox = new wxBoxSizer(wxHORIZONTAL);
m_sizer_combox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
auto combo_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, DESIGN_TITLE_SIZE, 0);
combo_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
combo_title->SetFont(::Label::Body_13);
combo_title->SetToolTip(tooltip);
combo_title->Wrap(-1);
m_sizer_combox->Add(combo_title, 0, wxALIGN_CENTER | wxALL, 3);
auto combobox = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, DESIGN_LARGE_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
combobox->SetFont(::Label::Body_13);
combobox->GetDropDown().SetFont(::Label::Body_13);
std::vector<wxString>::iterator iter;
for (size_t i = 0; i < vlist.size(); ++i) {
auto language_name = vlist[i]->Description;
if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_CHINESE_SIMPLIFIED)) {
//language_name = _L(vlist[i]->Description);
//language_name = _L("Chinese (Simplified)");
language_name = wxString::FromUTF8("\xe4\xb8\xad\xe6\x96\x87\x28\xe7\xae\x80\xe4\xbd\x93\x29");
}
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_SPANISH)) {
language_name = wxString::FromUTF8("\x45\x73\x70\x61\xc3\xb1\x6f\x6c");
}
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_GERMAN)) {
language_name = wxString::FromUTF8("Deutsch");
}
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_SWEDISH)) {
language_name = wxString::FromUTF8("\x53\x76\x65\x6e\x73\x6b\x61"); //Svenska
}
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_DUTCH)) {
language_name = wxString::FromUTF8("Nederlands");
}
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_FRENCH)) {
language_name = wxString::FromUTF8("\x46\x72\x61\x6E\xC3\xA7\x61\x69\x73");
}
else if (vlist[i] == wxLocale::GetLanguageInfo(wxLANGUAGE_HUNGARIAN)) {
language_name = wxString::FromUTF8("Magyar");
}
if (app_config->get(param) == vlist[i]->CanonicalName) {
m_current_language_selected = i;
}
combobox->Append(language_name);
}
combobox->SetSelection(m_current_language_selected);
m_sizer_combox->Add(combobox, 0, wxALIGN_CENTER, 0);
combobox->Bind(wxEVT_LEFT_DOWN, [this, combobox](wxMouseEvent &e) {
m_current_language_selected = combobox->GetSelection();
e.Skip();
});
combobox->Bind(wxEVT_COMBOBOX, [this, param, vlist, combobox](wxCommandEvent &e) {
if (combobox->GetSelection() == m_current_language_selected)
return;
if (e.GetString().mb_str() != app_config->get(param)) {
{
// the dialog needs to be destroyed before the call to switch_language()
// or sometimes the application crashes into wxDialogBase() destructor
// so we put it into an inner scope
MessageDialog msg_wingow(nullptr, _L("Switching the language requires application restart.\n") + "\n" + _L("Do you want to continue?"),
L("Language selection"), wxICON_QUESTION | wxOK | wxCANCEL);
if (msg_wingow.ShowModal() == wxID_CANCEL) {
combobox->SetSelection(m_current_language_selected);
return;
}
}
auto check = [this](bool yes_or_no) {
// if (yes_or_no)
// return true;
int act_btns = UnsavedChangesDialog::ActionButtons::SAVE;
return wxGetApp().check_and_keep_current_preset_changes(_L("Switching application language"),
_L("Switching application language while some presets are modified."), act_btns);
};
m_current_language_selected = combobox->GetSelection();
if (m_current_language_selected >= 0 && m_current_language_selected < vlist.size()) {
app_config->set(param, vlist[m_current_language_selected]->CanonicalName.ToUTF8().data());
app_config->save();
wxGetApp().load_language(vlist[m_current_language_selected]->CanonicalName, false);
Close();
// Reparent(nullptr);
GetParent()->RemoveChild(this);
wxGetApp().recreate_GUI(_L("Changing application language"));
}
}
e.Skip();
});
return m_sizer_combox;
}
wxBoxSizer *PreferencesDialog::create_item_region_combobox(wxString title, wxWindow *parent, wxString tooltip, std::vector<wxString> vlist)
{
std::vector<wxString> local_regions = {"Asia-Pacific", "China", "Europe", "North America", "Others"};
wxBoxSizer *m_sizer_combox = new wxBoxSizer(wxHORIZONTAL);
m_sizer_combox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
auto combo_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, DESIGN_TITLE_SIZE, 0);
combo_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
combo_title->SetFont(::Label::Body_13);
combo_title->SetToolTip(tooltip);
combo_title->Wrap(-1);
m_sizer_combox->Add(combo_title, 0, wxALIGN_CENTER | wxALL, 3);
auto combobox = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, DESIGN_LARGE_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
combobox->SetFont(::Label::Body_13);
combobox->GetDropDown().SetFont(::Label::Body_13);
m_sizer_combox->Add(combobox, 0, wxALIGN_CENTER, 0);
std::vector<wxString>::iterator iter;
for (iter = vlist.begin(); iter != vlist.end(); iter++) { combobox->Append(*iter); }
AppConfig * config = GUI::wxGetApp().app_config;
int current_region = 0;
if (!config->get("region").empty()) {
std::string country_code = config->get("region");
for (auto i = 0; i < vlist.size(); i++) {
if (local_regions[i].ToStdString() == country_code) {
combobox->SetSelection(i);
current_region = i;
}
}
}
combobox->GetDropDown().Bind(wxEVT_COMBOBOX, [this, combobox, current_region, local_regions](wxCommandEvent &e) {
auto region_index = e.GetSelection();
auto region = local_regions[region_index];
auto area = "";
if (region == "CHN" || region == "China")
area = "CN";
else if (region == "USA")
area = "US";
else if (region == "Asia-Pacific")
area = "Others";
else if (region == "Europe")
area = "US";
else if (region == "North America")
area = "US";
else
area = "Others";
NetworkAgent* agent = wxGetApp().getAgent();
AppConfig* config = GUI::wxGetApp().app_config;
if (agent) {
MessageDialog msg_wingow(this, _L("Changing the region will log out your account.\n") + "\n" + _L("Do you want to continue?"), L("Region selection"),
wxICON_QUESTION | wxOK | wxCANCEL);
if (msg_wingow.ShowModal() == wxID_CANCEL) {
combobox->SetSelection(current_region);
return;
} else {
wxGetApp().request_user_logout();
if (agent) {
agent->set_country_code(area);
}
config->set("region", region.ToStdString());
EndModal(wxID_CANCEL);
}
} else {
config->set("region", region.ToStdString());
}
e.Skip();
});
return m_sizer_combox;
}
wxBoxSizer *PreferencesDialog::create_item_loglevel_combobox(wxString title, wxWindow *parent, wxString tooltip, std::vector<wxString> vlist)
{
wxBoxSizer *m_sizer_combox = new wxBoxSizer(wxHORIZONTAL);
m_sizer_combox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
auto combo_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, DESIGN_TITLE_SIZE, 0);
combo_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
combo_title->SetFont(::Label::Body_13);
combo_title->SetToolTip(tooltip);
combo_title->Wrap(-1);
m_sizer_combox->Add(combo_title, 0, wxALIGN_CENTER | wxALL, 3);
auto combobox = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, DESIGN_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
combobox->SetFont(::Label::Body_13);
combobox->GetDropDown().SetFont(::Label::Body_13);
std::vector<wxString>::iterator iter;
for (iter = vlist.begin(); iter != vlist.end(); iter++) { combobox->Append(*iter); }
m_sizer_combox->Add(combobox, 0, wxALIGN_CENTER, 0);
auto severity_level = app_config->get("severity_level");
if (!severity_level.empty()) { combobox->SetValue(severity_level); }
m_sizer_combox->Add(combobox, 0, wxALIGN_CENTER, 0);
//// save config
combobox->GetDropDown().Bind(wxEVT_COMBOBOX, [this](wxCommandEvent &e) {
auto level = Slic3r::get_string_logging_level(e.GetSelection());
Slic3r::set_logging_level(Slic3r::level_string_to_boost(level));
app_config->set("severity_level",level);
app_config->save();
e.Skip();
});
return m_sizer_combox;
}
wxBoxSizer *PreferencesDialog::create_item_multiple_combobox(
wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param, std::vector<wxString> vlista, std::vector<wxString> vlistb)
{
std::vector<wxString> params;
Split(app_config->get(param), "/", params);
std::vector<wxString>::iterator iter;
wxBoxSizer *m_sizer_tcombox= new wxBoxSizer(wxHORIZONTAL);
m_sizer_tcombox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
auto combo_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, DESIGN_TITLE_SIZE, 0);
combo_title->SetToolTip(tooltip);
combo_title->Wrap(-1);
combo_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
combo_title->SetFont(::Label::Body_13);
m_sizer_tcombox->Add(combo_title, 0, wxALIGN_CENTER | wxALL, 3);
auto combobox_left = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, DESIGN_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
combobox_left->SetFont(::Label::Body_13);
combobox_left->GetDropDown().SetFont(::Label::Body_13);
for (iter = vlista.begin(); iter != vlista.end(); iter++) { combobox_left->Append(*iter); }
combobox_left->SetValue(std::string(params[0].mb_str()));
m_sizer_tcombox->Add(combobox_left, 0, wxALIGN_CENTER, 0);
auto combo_title_add = new wxStaticText(parent, wxID_ANY, wxT("+"), wxDefaultPosition, wxDefaultSize, 0);
combo_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
combo_title->SetFont(::Label::Body_13);
combo_title_add->Wrap(-1);
m_sizer_tcombox->Add(combo_title_add, 0, wxALIGN_CENTER | wxALL, 3);
auto combobox_right = new ::ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, DESIGN_COMBOBOX_SIZE, 0, nullptr, wxCB_READONLY);
combobox_right->SetFont(::Label::Body_13);
combobox_right->GetDropDown().SetFont(::Label::Body_13);
for (iter = vlistb.begin(); iter != vlistb.end(); iter++) { combobox_right->Append(*iter); }
combobox_right->SetValue(std::string(params[1].mb_str()));
m_sizer_tcombox->Add(combobox_right, 0, wxALIGN_CENTER, 0);
// save config
combobox_left->GetDropDown().Bind(wxEVT_COMBOBOX, [this, param, combobox_right](wxCommandEvent &e) {
auto config = e.GetString() + wxString("/") + combobox_right->GetValue();
app_config->set(param, std::string(config.mb_str()));
app_config->save();
e.Skip();
});
combobox_right->GetDropDown().Bind(wxEVT_COMBOBOX, [this, param, combobox_left](wxCommandEvent &e) {
auto config = combobox_left->GetValue() + wxString("/") + e.GetString();
app_config->set(param, std::string(config.mb_str()));
app_config->save();
e.Skip();
});
return m_sizer_tcombox;
}
wxBoxSizer *PreferencesDialog::create_item_backup_input(wxString title, wxWindow *parent, wxString tooltip, std::string param)
{
wxBoxSizer *m_sizer_input = new wxBoxSizer(wxHORIZONTAL);
auto input_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, DESIGN_TITLE_SIZE, 0);
input_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
input_title->SetFont(::Label::Body_13);
input_title->SetToolTip(tooltip);
input_title->Wrap(-1);
auto input = new ::TextInput(parent, wxEmptyString, wxEmptyString, wxEmptyString, wxDefaultPosition, DESIGN_INPUT_SIZE, wxTE_PROCESS_ENTER);
input->GetTextCtrl()->SetFont(::Label::Body_13);
input->GetTextCtrl()->SetValue(app_config->get(param));
auto second_title = new wxStaticText(parent, wxID_ANY, _L("Second"), wxDefaultPosition, DESIGN_TITLE_SIZE, 0);
second_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
second_title->SetFont(::Label::Body_13);
second_title->SetToolTip(tooltip);
second_title->Wrap(-1);
m_sizer_input->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
m_sizer_input->Add(input_title, 0, wxALIGN_CENTER | wxALL, 3);
m_sizer_input->Add(input, 0, wxALIGN_CENTER, 0);
m_sizer_input->Add(0, 0, 0, wxEXPAND | wxLEFT, 3);
m_sizer_input->Add(second_title, 0, wxALIGN_CENTER| wxALL, 3);
input->GetTextCtrl()->Bind(wxEVT_COMMAND_TEXT_UPDATED, [this, param, input](wxCommandEvent &e) {
m_backup_interval_time = input->GetTextCtrl()->GetValue();
e.Skip();
});
input->GetTextCtrl()->Bind(wxEVT_TEXT_ENTER, [this, param, input](wxCommandEvent &e) {
m_backup_interval_time = input->GetTextCtrl()->GetValue();
app_config->set("backup_interval", std::string(m_backup_interval_time.mb_str()));
app_config->save();
e.Skip();
});
input->GetTextCtrl()->Bind(wxEVT_KILL_FOCUS, [this, param, input](wxFocusEvent &e) {
m_backup_interval_time = input->GetTextCtrl()->GetValue();
app_config->set("backup_interval", std::string(m_backup_interval_time.mb_str()));
app_config->save();
e.Skip();
});
if (app_config->get("backup_switch") == "true") {
input->Enable(true);
} else {
input->Enable(false);
}
if (param == "backup_interval") { m_backup_interval_textinput = input; }
return m_sizer_input;
}
wxBoxSizer *PreferencesDialog::create_item_switch(wxString title, wxWindow *parent, wxString tooltip ,std::string param)
{
wxBoxSizer *m_sizer_switch = new wxBoxSizer(wxHORIZONTAL);
auto switch_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, DESIGN_TITLE_SIZE, 0);
switch_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
switch_title->SetFont(::Label::Body_13);
switch_title->SetToolTip(tooltip);
switch_title->Wrap(-1);
auto switchbox = new ::SwitchButton(parent, wxID_ANY);
/*auto index = app_config->get(param);
if (!index.empty()) { combobox->SetSelection(atoi(index.c_str())); }*/
m_sizer_switch->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
m_sizer_switch->Add(switch_title, 0, wxALIGN_CENTER | wxALL, 3);
m_sizer_switch->Add( 0, 0, 1, wxEXPAND, 0 );
m_sizer_switch->Add(switchbox, 0, wxALIGN_CENTER, 0);
m_sizer_switch->Add( 0, 0, 0, wxEXPAND|wxLEFT, 40 );
//// save config
switchbox->Bind(wxEVT_TOGGLEBUTTON, [this, param](wxCommandEvent &e) {
/* app_config->set(param, std::to_string(e.GetSelection()));
app_config->save();*/
e.Skip();
});
return m_sizer_switch;
}
wxBoxSizer *PreferencesDialog::create_item_checkbox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, std::string param)
{
wxBoxSizer *m_sizer_checkbox = new wxBoxSizer(wxHORIZONTAL);
m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 23);
auto checkbox = new ::CheckBox(parent);
checkbox->SetValue((app_config->get(param) == "true") ? true : false);
m_sizer_checkbox->Add(checkbox, 0, wxALIGN_CENTER, 0);
m_sizer_checkbox->Add(0, 0, 0, wxEXPAND | wxLEFT, 8);
auto checkbox_title = new wxStaticText(parent, wxID_ANY, title, wxDefaultPosition, wxSize(-1, -1), 0);
checkbox_title->SetForegroundColour(DESIGN_GRAY900_COLOR);
checkbox_title->SetFont(::Label::Body_13);
checkbox_title->Wrap(-1);
m_sizer_checkbox->Add(checkbox_title, 0, wxALIGN_CENTER | wxALL, 3);
//// save config
checkbox->Bind(wxEVT_TOGGLEBUTTON, [this, checkbox, param](wxCommandEvent &e) {
app_config->set_bool(param, checkbox->GetValue());
app_config->save();
// backup
if (param == "backup_switch") {
bool pbool = app_config->get("backup_switch") == "true" ? true : false;
if (m_backup_interval_textinput != nullptr) { m_backup_interval_textinput->Enable(pbool); }
}
if (param == "sync_user_preset") {
bool sync = app_config->get("sync_user_preset") == "true" ? true : false;
if (sync) {
wxGetApp().start_sync_user_preset(true);
} else {
wxGetApp().stop_sync_user_preset();
}
}
#ifdef __WXMSW__
if (param == "associate_3mf") {
bool pbool = app_config->get("associate_3mf") == "true" ? true : false;
if (pbool) {
wxGetApp().associate_files(L"3mf");
} else {
wxGetApp().disassociate_files(L"3mf");
}
}
if (param == "associate_stl") {
bool pbool = app_config->get("associate_stl") == "true" ? true : false;
if (pbool) {
wxGetApp().associate_files(L"stl");
} else {
wxGetApp().disassociate_files(L"stl");
}
}
if (param == "associate_step") {
bool pbool = app_config->get("associate_step") == "true" ? true : false;
if (pbool) {
wxGetApp().associate_files(L"step");
} else {
wxGetApp().disassociate_files(L"step");
}
}
#endif // __WXMSW__
e.Skip();
});
//// for debug mode
if (param == "developer_mode") { m_developer_mode_ckeckbox = checkbox; }
if (param == "dump_video") { m_dump_video_ckeckbox = checkbox; }
checkbox->SetToolTip(tooltip);
return m_sizer_checkbox;
}
wxWindow *PreferencesDialog ::create_item_radiobox(wxString title, wxWindow *parent, wxString tooltip, int padding_left, int groupid, std::string param)
{
wxWindow *item = new wxWindow(parent, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(28)));
item->SetBackgroundColour(*wxWHITE);
RadioBox *radiobox = new RadioBox(item);
radiobox->SetPosition(wxPoint(padding_left, (item->GetSize().GetHeight() - radiobox->GetSize().GetHeight()) / 2));
radiobox->Bind(wxEVT_LEFT_DOWN, &PreferencesDialog::OnSelectRadio, this);
RadioSelector *rs = new RadioSelector;
rs->m_groupid = groupid;
rs->m_param_name = param;
rs->m_radiobox = radiobox;
rs->m_selected = false;
m_radio_group.Append(rs);
wxStaticText *text = new wxStaticText(item, wxID_ANY, title, wxDefaultPosition, wxDefaultSize);
text->SetPosition(wxPoint(padding_left + radiobox->GetSize().GetWidth() + 10, (item->GetSize().GetHeight() - text->GetSize().GetHeight()) / 2));
radiobox->SetToolTip(tooltip);
text->SetToolTip(tooltip);
return item;
}
PreferencesDialog::PreferencesDialog(wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos, const wxSize &size, long style)
: DPIDialog(parent, id, _L("Preferences"), pos, size, style)
{
SetBackgroundColour(*wxWHITE);
create();
}
void PreferencesDialog::create()
{
app_config = get_app_config();
m_backup_interval_time = app_config->get("backup_interval");
// set icon for dialog
std::string icon_path = (boost::format("%1%/images/BambuStudioTitle.ico") % resources_dir()).str();
SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO));
SetSizeHints(wxDefaultSize, wxDefaultSize);
auto main_sizer = new wxBoxSizer(wxVERTICAL);
m_scrolledWindow = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxVSCROLL);
m_scrolledWindow->SetScrollRate(5, 5);
m_sizer_body = new wxBoxSizer(wxVERTICAL);
auto m_top_line = new wxPanel(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxSize(DESIGN_RESOUTION_PREFERENCES.x, 1), wxTAB_TRAVERSAL);
m_top_line->SetBackgroundColour(DESIGN_GRAY400_COLOR);
m_sizer_body->Add(m_top_line, 0, wxEXPAND, 0);
auto general_page = create_general_page();
#if !BBL_RELEASE_TO_PUBLIC
auto debug_page = create_debug_page();
#endif
/* create_gui_page();
create_sync_page();
create_shortcuts_page();*/
m_sizer_body->Add(0, 0, 0, wxTOP, FromDIP(28));
m_sizer_body->Add(general_page, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(38));
#if !BBL_RELEASE_TO_PUBLIC
m_sizer_body->Add(debug_page, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(38));
#endif
m_sizer_body->Add(0, 0, 0, wxBOTTOM, FromDIP(28));
m_scrolledWindow->SetSizerAndFit(m_sizer_body);
main_sizer->Add(m_scrolledWindow, 1, wxEXPAND);
SetSizer(main_sizer);
Layout();
Fit();
int screen_height = wxGetDisplaySize().GetY();
if (this->GetSize().GetY() > screen_height)
this->SetSize(this->GetSize().GetX() + FromDIP(40), screen_height * 4 / 5);
CenterOnParent();
wxPoint start_pos = this->GetPosition();
if (start_pos.y < 0) { this->SetPosition(wxPoint(start_pos.x, 0)); }
//select first
auto event = wxCommandEvent(EVT_PREFERENCES_SELECT_TAB);
event.SetInt(0);
event.SetEventObject(this);
wxPostEvent(this, event);
}
PreferencesDialog::~PreferencesDialog()
{
m_radio_group.DeleteContents(true);
m_hash_selector.clear();
}
void PreferencesDialog::on_dpi_changed(const wxRect &suggested_rect) { this->Refresh(); }
void PreferencesDialog::Split(const std::string &src, const std::string &separator, std::vector<wxString> &dest)
{
std::string str = src;
std::string substring;
std::string::size_type start = 0, index;
dest.clear();
index = str.find_first_of(separator, start);
do {
if (index != std::string::npos) {
substring = str.substr(start, index - start);
dest.push_back(substring);
start = index + separator.size();
index = str.find(separator, start);
if (start == std::string::npos) break;
}
} while (index != std::string::npos);
substring = str.substr(start);
dest.push_back(substring);
}
wxWindow* PreferencesDialog::create_general_page()
{
auto page = new wxWindow(m_scrolledWindow, wxID_ANY);
page->SetBackgroundColour(*wxWHITE);
wxBoxSizer *sizer_page = new wxBoxSizer(wxVERTICAL);
auto title_general_settings = create_item_title(_L("General Settings"), page, _L("General Settings"));
// bbs supported languages
wxLanguage supported_languages[]{
wxLANGUAGE_ENGLISH,
wxLANGUAGE_CHINESE_SIMPLIFIED,
wxLANGUAGE_GERMAN,
wxLANGUAGE_FRENCH,
wxLANGUAGE_SPANISH,
wxLANGUAGE_SWEDISH,
wxLANGUAGE_DUTCH,
wxLANGUAGE_HUNGARIAN };
auto translations = wxTranslations::Get()->GetAvailableTranslations(SLIC3R_APP_KEY);
std::vector<const wxLanguageInfo *> language_infos;
language_infos.emplace_back(wxLocale::GetLanguageInfo(wxLANGUAGE_ENGLISH));
for (size_t i = 0; i < translations.GetCount(); ++i) {
const wxLanguageInfo *langinfo = wxLocale::FindLanguageInfo(translations[i]);
if (langinfo == nullptr) continue;
int language_num = sizeof(supported_languages) / sizeof(supported_languages[0]);
for (auto si = 0; si < language_num; si++) {
if (langinfo == wxLocale::GetLanguageInfo(supported_languages[si])) {
language_infos.emplace_back(langinfo);
}
}
//if (langinfo != nullptr) language_infos.emplace_back(langinfo);
}
sort_remove_duplicates(language_infos);
std::sort(language_infos.begin(), language_infos.end(), [](const wxLanguageInfo *l, const wxLanguageInfo *r) { return l->Description < r->Description; });
auto item_language = create_item_language_combobox(_L("Language"), page, _L("Language"), 50, "language", language_infos);
std::vector<wxString> Regions = {_L("Asia-Pacific"), _L("China"), _L("Europe"), _L("North America"), _L("Others")};
auto item_region= create_item_region_combobox(_L("Login Region"), page, _L("Login Region"), Regions);
std::vector<wxString> Units = {_L("Metric"), _L("Imperial")};
auto item_currency = create_item_combobox(_L("Units"), page, _L("Units"), "use_inches", Units);
auto title_sync_settings = create_item_title(_L("User sync"), page, _L("User sync"));
auto item_user_sync = create_item_checkbox(_L("Auto sync user presets(Printer/Filament/Process)"), page, _L("User Sync"), 50, "sync_user_preset");
auto title_associate_file = create_item_title(_L("Associate files to BambuStudio"), page, _L("Associate files to BambuStudio"));
// associate file
auto item_associate_3mf = create_item_checkbox(_L("Associate .3mf files to BambuStudio"), page,
_L("If enabled, sets BambuStudio as default application to open .3mf files"), 50, "associate_3mf");
auto item_associate_stl = create_item_checkbox(_L("Associate .stl files to BambuStudio"), page,
_L("If enabled, sets BambuStudio as default application to open .stl files"), 50, "associate_stl");
auto item_associate_step = create_item_checkbox(_L("Associate .step/.stp files to BambuStudio"), page,
_L("If enabled, sets BambuStudio as default application to open .step files"), 50, "associate_step");
auto title_backup = create_item_title(_L("Backup"), page, _L("Backup"));
//auto item_backup = create_item_switch(_L("Backup switch"), page, _L("Backup switch"), "units");
auto item_backup = create_item_checkbox(_L("Auto-Backup"), page,_L("Auto-Backup"), 50, "backup_switch");
auto item_backup_interval = create_item_backup_input(_L("Backup interval"), page, _L("Backup interval"), "backup_interval");
sizer_page->Add(title_general_settings, 0, wxEXPAND, 0);
sizer_page->Add(item_language, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_region, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_currency, 0, wxTOP, FromDIP(3));
sizer_page->Add(title_sync_settings, 0, wxTOP | wxEXPAND, FromDIP(20));
sizer_page->Add(item_user_sync, 0, wxTOP, FromDIP(3));
sizer_page->Add(title_associate_file, 0, wxTOP| wxEXPAND, FromDIP(20));
sizer_page->Add(item_associate_3mf, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_associate_stl, 0, wxTOP, FromDIP(3));
sizer_page->Add(item_associate_step, 0, wxTOP, FromDIP(3));
sizer_page->Add(title_backup, 0, wxTOP| wxEXPAND, FromDIP(20));
sizer_page->Add(item_backup, 0, wxTOP,FromDIP(3));
sizer_page->Add(item_backup_interval, 0, wxTOP,FromDIP(3));
//sizer_page->Add(0, 0, 0, wxTOP, 26);
page->SetSizer(sizer_page);
page->Layout();
sizer_page->Fit(page);
return page;
}
void PreferencesDialog::create_gui_page()
{
auto page = new wxWindow(this, wxID_ANY);
wxBoxSizer *sizer_page = new wxBoxSizer(wxVERTICAL);
auto title_index_and_tip = create_item_title(_L("Home page and daily tips"), page, _L("Home page and daily tips"));
auto item_home_page = create_item_checkbox(_L("Show home page on startup"), page, _L("Show home page on startup"), 50, "show_home_page");
//auto item_daily_tip = create_item_checkbox(_L("Show daily tip on startup"), page, _L("Show daily tip on startup"), 50, "show_daily_tips");
sizer_page->Add(title_index_and_tip, 0, wxTOP, 26);
sizer_page->Add(item_home_page, 0, wxTOP, 6);
//sizer_page->Add(item_daily_tip, 0, wxTOP, 6);
page->SetSizer(sizer_page);
page->Layout();
sizer_page->Fit(page);
}
void PreferencesDialog::create_sync_page()
{
auto page = new wxWindow(this, wxID_ANY);
wxBoxSizer *sizer_page = new wxBoxSizer(wxVERTICAL);
auto title_sync_settingy = create_item_title(_L("Sync settings"), page, _L("Sync settings"));
auto item_user_sync = create_item_checkbox(_L("User sync"), page, _L("User sync"), 50, "user_sync_switch");
auto item_preset_sync = create_item_checkbox(_L("Preset sync"), page, _L("Preset sync"), 50, "preset_sync_switch");
auto item_preferences_sync = create_item_checkbox(_L("Preferences sync"), page, _L("Preferences sync"), 50, "preferences_sync_switch");
sizer_page->Add(title_sync_settingy, 0, wxTOP, 26);
sizer_page->Add(item_user_sync, 0, wxTOP, 6);
sizer_page->Add(item_preset_sync, 0, wxTOP, 6);
sizer_page->Add(item_preferences_sync, 0, wxTOP, 6);
page->SetSizer(sizer_page);
page->Layout();
sizer_page->Fit(page);
}
void PreferencesDialog::create_shortcuts_page()
{
auto page = new wxWindow(this, wxID_ANY);
wxBoxSizer *sizer_page = new wxBoxSizer(wxVERTICAL);
auto title_view_control = create_item_title(_L("View control settings"), page, _L("View control settings"));
std::vector<wxString> keyboard_supported;
Split(app_config->get("keyboard_supported"), "/", keyboard_supported);
std::vector<wxString> mouse_supported;
Split(app_config->get("mouse_supported"), "/", mouse_supported);
auto item_rotate_view = create_item_multiple_combobox(_L("Rotate of view"), page, _L("Rotate of view"), 10, "rotate_view", keyboard_supported,
mouse_supported);
auto item_move_view = create_item_multiple_combobox(_L("Move of view"), page, _L("Move of view"), 10, "move_view", keyboard_supported, mouse_supported);
auto item_zoom_view = create_item_multiple_combobox(_L("Zoom of view"), page, _L("Zoom of view"), 10, "rotate_view", keyboard_supported, mouse_supported);
auto title_other = create_item_title(_L("Other"), page, _L("Other"));
auto item_other = create_item_checkbox(_L("Mouse wheel reverses when zooming"), page, _L("Mouse wheel reverses when zooming"), 50, "mouse_wheel");
sizer_page->Add(title_view_control, 0, wxTOP, 26);
sizer_page->Add(item_rotate_view, 0, wxTOP, 8);
sizer_page->Add(item_move_view, 0, wxTOP, 8);
sizer_page->Add(item_zoom_view, 0, wxTOP, 8);
// sizer_page->Add(item_precise_control, 0, wxTOP, 0);
sizer_page->Add(title_other, 0, wxTOP, 20);
sizer_page->Add(item_other, 0, wxTOP, 5);
page->SetSizer(sizer_page);
page->Layout();
sizer_page->Fit(page);
}
wxBoxSizer* PreferencesDialog::create_debug_page()
{
//wxBoxSizer *sizer_page = new wxBoxSizer(wxVERTICAL);
m_developer_mode_def = app_config->get("developer_mode");
m_dump_video_def = app_config->get("dump_video");
m_backup_interval_def = app_config->get("backup_interval");
m_iot_environment_def = app_config->get("iot_environment");
wxBoxSizer *bSizer = new wxBoxSizer(wxVERTICAL);
auto title_develop_mode = create_item_title(_L("Develop mode"), m_scrolledWindow, _L("Develop mode"));
auto item_develop_mode = create_item_checkbox(_L("Develop mode"), m_scrolledWindow, _L("Develop mode"), 50, "developer_mode");
auto item_dump_video = create_item_checkbox(_L("Dump video"), m_scrolledWindow, _L("Dump video"), 50, "dump_video");
auto title_log_level = create_item_title(_L("Log Level"), m_scrolledWindow, _L("Log Level"));
auto log_level_list = std::vector<wxString>{_L("fatal"), _L("error"), _L("warning"), _L("info"), _L("debug"), _L("trace")};
auto loglevel_combox = create_item_loglevel_combobox(_L("Log Level"), m_scrolledWindow, _L("Log Level"), log_level_list);
auto title_host = create_item_title(_L("Host Setting"), m_scrolledWindow, _L("Host Setting"));
auto radio1 = create_item_radiobox(_L("DEV host: api-dev.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "dev_host");
auto radio2 = create_item_radiobox(_L("QA host: api-qa.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "qa_host");
auto radio3 = create_item_radiobox(_L("PRE host: api-pre.bambu-lab.com/v1"), m_scrolledWindow, wxEmptyString, 50, 1, "pre_host");
auto radio4 = create_item_radiobox(_L("Product host"), m_scrolledWindow, wxEmptyString, 50, 1, "product_host");
if (m_iot_environment_def == ENV_DEV_HOST) {
on_select_radio("dev_host");
} else if (m_iot_environment_def == ENV_QAT_HOST) {
on_select_radio("qa_host");
} else if (m_iot_environment_def == ENV_PRE_HOST) {
on_select_radio("pre_host");
} else if (m_iot_environment_def == ENV_PRODUCT_HOST) {
on_select_radio("product_host");
}
wxButton *debug_button = new wxButton(m_scrolledWindow, wxID_ANY, _L("debug save button"), wxDefaultPosition, wxDefaultSize, 0);
debug_button->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) {
// success message box
MessageDialog dialog(this, _L("save debug settings"), _L("DEBUG settings have saved successfully!"), wxNO_DEFAULT | wxYES_NO | wxICON_INFORMATION);
switch (dialog.ShowModal()) {
case wxID_NO: {
if (m_developer_mode_def != app_config->get("developer_mode")) {
app_config->set_bool("developer_mode", m_developer_mode_def == "true" ? true : false);
m_developer_mode_ckeckbox->SetValue(m_developer_mode_def == "true" ? true : false);
}
if (m_dump_video_def != app_config->get("dump_video")) {
app_config->set_bool("dump_video", m_dump_video_def == "true" ? true : false);
m_dump_video_ckeckbox->SetValue(m_dump_video_def == "true" ? true : false);
}
if (m_backup_interval_def != m_backup_interval_time) { m_backup_interval_textinput->GetTextCtrl()->SetValue(m_backup_interval_def); }
if (m_iot_environment_def == ENV_DEV_HOST) {
on_select_radio("dev_host");
} else if (m_iot_environment_def == ENV_QAT_HOST) {
on_select_radio("qa_host");
} else if (m_iot_environment_def == ENV_PRE_HOST) {
on_select_radio("pre_host");
} else if (m_iot_environment_def == ENV_PRODUCT_HOST) {
on_select_radio("product_host");
}
break;
}
case wxID_YES: {
// bbs domain changed
auto param = get_select_radio(1);
std::map<wxString, wxString> iot_environment_map;
iot_environment_map["dev_host"] = ENV_DEV_HOST;
iot_environment_map["qa_host"] = ENV_QAT_HOST;
iot_environment_map["pre_host"] = ENV_PRE_HOST;
iot_environment_map["product_host"] = ENV_PRODUCT_HOST;
if (iot_environment_map[param] != m_iot_environment_def) {
NetworkAgent* agent = wxGetApp().getAgent();
if (param == "dev_host") {
app_config->set("iot_environment", ENV_DEV_HOST);
}
else if (param == "qa_host") {
app_config->set("iot_environment", ENV_QAT_HOST);
}
else if (param == "pre_host") {
app_config->set("iot_environment", ENV_PRE_HOST);
}
else if (param == "product_host") {
app_config->set("iot_environment", ENV_PRODUCT_HOST);
}
AppConfig* config = GUI::wxGetApp().app_config;
std::string country_code = config->get_country_code();
if (agent) {
wxGetApp().request_user_logout();
agent->set_country_code(country_code);
}
wxMessageBox(_L("Switch cloud environment, Please login again!"));
}
// bbs backup
//app_config->set("backup_interval", std::string(m_backup_interval_time.mb_str()));
app_config->save();
Slic3r::set_backup_interval(boost::lexical_cast<long>(app_config->get("backup_interval")));
// bbs developer mode
auto developer_mode = app_config->get("developer_mode");
if (developer_mode == "true") {
Slic3r::GUI::wxGetApp().save_mode(comDevelop);
Slic3r::GUI::wxGetApp().mainframe->show_log_window();
} else {
Slic3r::GUI::wxGetApp().save_mode(comAdvanced);
}
this->Close();
break;
}
}
});
bSizer->Add(title_develop_mode, 0, wxTOP | wxEXPAND, FromDIP(20));
bSizer->Add(item_develop_mode, 0, wxTOP,FromDIP(3));
bSizer->Add(item_dump_video, 0, wxTOP, FromDIP(3));
bSizer->Add(title_log_level, 0, wxTOP| wxEXPAND, FromDIP(20));
bSizer->Add(loglevel_combox, 0, wxTOP, FromDIP(3));
bSizer->Add(title_host, 0, wxTOP| wxEXPAND, FromDIP(20));
bSizer->Add(radio1, 0, wxEXPAND | wxTOP, FromDIP(3));
bSizer->Add(radio2, 0, wxEXPAND | wxTOP, FromDIP(3));
bSizer->Add(radio3, 0, wxEXPAND | wxTOP, FromDIP(3));
bSizer->Add(radio4, 0, wxEXPAND | wxTOP, FromDIP(3));
bSizer->Add(debug_button, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(15));
return bSizer;
}
void PreferencesDialog::on_select_radio(std::string param)
{
RadioSelectorList::Node *node = m_radio_group.GetFirst();
auto groupid = 0;
while (node) {
RadioSelector *rs = node->GetData();
if (rs->m_param_name == param) groupid = rs->m_groupid;
node = node->GetNext();
}
node = m_radio_group.GetFirst();
while (node) {
RadioSelector *rs = node->GetData();
if (rs->m_groupid == groupid && rs->m_param_name == param) rs->m_radiobox->SetValue(true);
if (rs->m_groupid == groupid && rs->m_param_name != param) rs->m_radiobox->SetValue(false);
node = node->GetNext();
}
}
wxString PreferencesDialog::get_select_radio(int groupid)
{
RadioSelectorList::Node *node = m_radio_group.GetFirst();
while (node) {
RadioSelector *rs = node->GetData();
if (rs->m_groupid == groupid && rs->m_radiobox->GetValue()) { return rs->m_param_name; }
node = node->GetNext();
}
return wxEmptyString;
}
void PreferencesDialog::OnSelectRadio(wxMouseEvent &event)
{
RadioSelectorList::Node *node = m_radio_group.GetFirst();
auto groupid = 0;
while (node) {
RadioSelector *rs = node->GetData();
if (rs->m_radiobox->GetId() == event.GetId()) groupid = rs->m_groupid;
node = node->GetNext();
}
node = m_radio_group.GetFirst();
while (node) {
RadioSelector *rs = node->GetData();
if (rs->m_groupid == groupid && rs->m_radiobox->GetId() == event.GetId()) rs->m_radiobox->SetValue(true);
if (rs->m_groupid == groupid && rs->m_radiobox->GetId() != event.GetId()) rs->m_radiobox->SetValue(false);
node = node->GetNext();
}
}
}} // namespace Slic3r::GUI