Merge remote-tracking branch 'origin/profile_changes_reset'

This commit is contained in:
bubnikv 2018-04-13 18:31:19 +02:00
commit eb58e29245
19 changed files with 747 additions and 238 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 B

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 B

After

Width:  |  Height:  |  Size: 419 B

View File

@ -6,7 +6,7 @@ namespace GUI {
class Bed_2D : public wxPanel
{
bool m_user_drawn_background = false;
bool m_user_drawn_background = true;
bool m_painted = false;
bool m_interactive = false;
@ -26,7 +26,9 @@ public:
{
Create(parent, wxID_ANY, wxDefaultPosition, wxSize(250, -1), wxTAB_TRAVERSAL);
// m_user_drawn_background = $^O ne 'darwin';
m_user_drawn_background = true;
#ifdef __APPLE__
m_user_drawn_background = false;
#endif /*__APPLE__*/
Bind(wxEVT_PAINT, ([this](wxPaintEvent e) { repaint(); }));
// EVT_ERASE_BACKGROUND($self, sub{}) if $self->{user_drawn_background};
// Bind(EVT_MOUSE_EVENTS, ([this](wxMouseEvent event){/*mouse_event()*/; }));

View File

@ -1,5 +1,14 @@
#include "BitmapCache.hpp"
#if ! defined(WIN32) && ! defined(__APPLE__)
#define BROKEN_ALPHA
#endif
#ifdef BROKEN_ALPHA
#include <wx/mstream.h>
#include <wx/rawbmp.h>
#endif /* BROKEN_ALPHA */
namespace Slic3r { namespace GUI {
void BitmapCache::clear()
@ -8,19 +17,31 @@ void BitmapCache::clear()
delete bitmap.second;
}
static wxBitmap wxImage_to_wxBitmap_with_alpha(wxImage &&image)
{
#ifdef BROKEN_ALPHA
wxMemoryOutputStream stream;
image.SaveFile(stream, wxBITMAP_TYPE_PNG);
wxStreamBuffer *buf = stream.GetOutputStreamBuffer();
return wxBitmap::NewFromPNGData(buf->GetBufferStart(), buf->GetBufferSize());
#else
return wxBitmap(std::move(image));
#endif
}
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_t height)
{
wxBitmap *bitmap = nullptr;
auto it = m_map.find(bitmap_key);
if (it == m_map.end()) {
bitmap = new wxBitmap(width, height);
m_map[bitmap_key] = bitmap;
} else {
bitmap = it->second;
if (bitmap->GetWidth() != width || bitmap->GetHeight() != height)
bitmap->Create(width, height);
}
#if defined(__APPLE__) || defined(_MSC_VER)
wxBitmap *bitmap = nullptr;
auto it = m_map.find(bitmap_key);
if (it == m_map.end()) {
bitmap = new wxBitmap(width, height);
m_map[bitmap_key] = bitmap;
} else {
bitmap = it->second;
if (bitmap->GetWidth() != width || bitmap->GetHeight() != height)
bitmap->Create(width, height);
}
#ifndef BROKEN_ALPHA
bitmap->UseAlpha();
#endif
return bitmap;
@ -28,77 +49,108 @@ wxBitmap* BitmapCache::insert(const std::string &bitmap_key, size_t width, size_
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp)
{
wxBitmap *bitmap = this->insert(bitmap_key, bmp.GetWidth(), bmp.GetHeight());
wxMemoryDC memDC;
memDC.SelectObject(*bitmap);
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
memDC.Clear();
memDC.DrawBitmap(bmp, 0, 0, true);
memDC.SelectObject(wxNullBitmap);
return bitmap;
wxBitmap *bitmap = nullptr;
auto it = m_map.find(bitmap_key);
if (it == m_map.end()) {
bitmap = new wxBitmap(bmp);
m_map[bitmap_key] = bitmap;
} else {
bitmap = it->second;
*bitmap = bmp;
}
return bitmap;
}
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp, const wxBitmap &bmp2)
{
wxBitmap *bitmap = this->insert(bitmap_key, bmp.GetWidth() + bmp2.GetWidth(), std::max(bmp.GetHeight(), bmp2.GetHeight()));
wxMemoryDC memDC;
memDC.SelectObject(*bitmap);
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
memDC.Clear();
if (bmp.GetWidth() > 0)
memDC.DrawBitmap(bmp, 0, 0, true);
if (bmp2.GetWidth() > 0)
memDC.DrawBitmap(bmp2, bmp.GetWidth(), 0, true);
memDC.SelectObject(wxNullBitmap);
return bitmap;
// Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
const wxBitmap bmps[2] = { bmp, bmp2 };
return this->insert(bitmap_key, bmps, bmps + 2);
}
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3)
{
wxBitmap *bitmap = this->insert(bitmap_key, bmp.GetWidth() + bmp2.GetWidth() + bmp3.GetWidth(), std::max(std::max(bmp.GetHeight(), bmp2.GetHeight()), bmp3.GetHeight()));
wxMemoryDC memDC;
memDC.SelectObject(*bitmap);
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
memDC.Clear();
if (bmp.GetWidth() > 0)
memDC.DrawBitmap(bmp, 0, 0, true);
if (bmp2.GetWidth() > 0)
memDC.DrawBitmap(bmp2, bmp.GetWidth(), 0, true);
if (bmp3.GetWidth() > 0)
memDC.DrawBitmap(bmp3, bmp.GetWidth() + bmp2.GetWidth(), 0, true);
memDC.SelectObject(wxNullBitmap);
return bitmap;
// Copying the wxBitmaps is cheap as the bitmap's content is reference counted.
const wxBitmap bmps[3] = { bmp, bmp2, bmp3 };
return this->insert(bitmap_key, bmps, bmps + 3);
}
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, std::vector<wxBitmap> &bmps)
wxBitmap* BitmapCache::insert(const std::string &bitmap_key, const wxBitmap *begin, const wxBitmap *end)
{
size_t width = 0;
size_t height = 0;
for (wxBitmap &bmp : bmps) {
width += bmp.GetWidth();
height = std::max<size_t>(height, bmp.GetHeight());
}
wxBitmap *bitmap = this->insert(bitmap_key, width, height);
size_t width = 0;
size_t height = 0;
for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
width += bmp->GetWidth();
height = std::max<size_t>(height, bmp->GetHeight());
}
#ifdef BROKEN_ALPHA
wxImage image(width, height);
image.InitAlpha();
// Fill in with a white color.
memset(image.GetData(), 0x0ff, width * height * 3);
// Fill in with full transparency.
memset(image.GetAlpha(), 0, width * height);
size_t x = 0;
for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
if (bmp->GetWidth() > 0) {
if (bmp->GetDepth() == 32) {
wxAlphaPixelData data(*const_cast<wxBitmap*>(bmp));
data.UseAlpha();
if (data) {
for (int r = 0; r < bmp->GetHeight(); ++ r) {
wxAlphaPixelData::Iterator src(data);
src.Offset(data, 0, r);
unsigned char *dst_pixels = image.GetData() + (x + r * width) * 3;
unsigned char *dst_alpha = image.GetAlpha() + x + r * width;
for (int c = 0; c < bmp->GetWidth(); ++ c, ++ src) {
*dst_pixels ++ = src.Red();
*dst_pixels ++ = src.Green();
*dst_pixels ++ = src.Blue();
*dst_alpha ++ = src.Alpha();
}
}
}
} else if (bmp->GetDepth() == 24) {
wxNativePixelData data(*const_cast<wxBitmap*>(bmp));
if (data) {
for (int r = 0; r < bmp->GetHeight(); ++ r) {
wxNativePixelData::Iterator src(data);
src.Offset(data, 0, r);
unsigned char *dst_pixels = image.GetData() + (x + r * width) * 3;
unsigned char *dst_alpha = image.GetAlpha() + x + r * width;
for (int c = 0; c < bmp->GetWidth(); ++ c, ++ src) {
*dst_pixels ++ = src.Red();
*dst_pixels ++ = src.Green();
*dst_pixels ++ = src.Blue();
*dst_alpha ++ = wxALPHA_OPAQUE;
}
}
}
}
}
x += bmp->GetWidth();
}
return this->insert(bitmap_key, wxImage_to_wxBitmap_with_alpha(std::move(image)));
#else
wxBitmap *bitmap = this->insert(bitmap_key, width, height);
wxMemoryDC memDC;
memDC.SelectObject(*bitmap);
memDC.SetBackground(*wxTRANSPARENT_BRUSH);
memDC.Clear();
size_t x = 0;
for (wxBitmap &bmp : bmps) {
if (bmp.GetWidth() > 0)
memDC.DrawBitmap(bmp, x, 0, true);
x += bmp.GetWidth();
}
for (const wxBitmap *bmp = begin; bmp != end; ++ bmp) {
if (bmp->GetWidth() > 0)
memDC.DrawBitmap(*bmp, x, 0, true);
x += bmp->GetWidth();
}
memDC.SelectObject(wxNullBitmap);
return bitmap;
return bitmap;
#endif
}
wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency)
@ -113,7 +165,7 @@ wxBitmap BitmapCache::mksolid(size_t width, size_t height, unsigned char r, unsi
*imgdata ++ = b;
*imgalpha ++ = transparency;
}
return wxBitmap(std::move(image));
return wxImage_to_wxBitmap_with_alpha(std::move(image));
}
} // namespace GUI

View File

@ -27,7 +27,8 @@ public:
wxBitmap* insert(const std::string &name, const wxBitmap &bmp);
wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2);
wxBitmap* insert(const std::string &name, const wxBitmap &bmp, const wxBitmap &bmp2, const wxBitmap &bmp3);
wxBitmap* insert(const std::string &name, std::vector<wxBitmap> &bmps);
wxBitmap* insert(const std::string &name, const std::vector<wxBitmap> &bmps) { return this->insert(name, &bmps.front(), &bmps.front() + bmps.size()); }
wxBitmap* insert(const std::string &name, const wxBitmap *begin, const wxBitmap *end);
static wxBitmap mksolid(size_t width, size_t height, unsigned char r, unsigned char g, unsigned char b, unsigned char transparency);
static wxBitmap mksolid(size_t width, size_t height, const unsigned char rgb[3]) { return mksolid(width, height, rgb[0], rgb[1], rgb[2], wxALPHA_OPAQUE); }

View File

@ -75,13 +75,13 @@ namespace Slic3r { namespace GUI {
return tooltip_text;
}
bool Field::is_matched(std::string string, std::string pattern)
bool Field::is_matched(const std::string& string, const std::string& pattern)
{
std::regex regex_pattern(pattern, std::regex_constants::icase); // use ::icase to make the matching case insensitive like /i in perl
return std::regex_match(string, regex_pattern);
}
boost::any Field::get_value_by_opt_type(wxString str)
boost::any Field::get_value_by_opt_type(wxString& str)
{
boost::any ret_val;
switch (m_opt.type){
@ -173,8 +173,7 @@ namespace Slic3r { namespace GUI {
temp->Bind(wxEVT_KILL_FOCUS, ([this, temp](wxEvent& e)
{
// on_kill_focus(e);
e.Skip();
e.Skip();// on_kill_focus(e);
temp->GetToolTip()->Enable(true);
}), temp->GetId());
@ -378,7 +377,7 @@ void Choice::set_selection()
}
}
void Choice::set_value(const std::string value, bool change_event) //! Redundant?
void Choice::set_value(const std::string& value, bool change_event) //! Redundant?
{
m_disable_change_event = !change_event;
@ -397,7 +396,7 @@ void Choice::set_value(const std::string value, bool change_event) //! Redundan
m_disable_change_event = false;
}
void Choice::set_value(boost::any value, bool change_event)
void Choice::set_value(const boost::any& value, bool change_event)
{
m_disable_change_event = !change_event;
@ -436,7 +435,7 @@ void Choice::set_value(boost::any value, bool change_event)
}
//! it's needed for _update_serial_ports()
void Choice::set_values(const std::vector<std::string> values)
void Choice::set_values(const std::vector<std::string>& values)
{
if (values.empty())
return;
@ -555,7 +554,7 @@ void PointCtrl::BUILD()
y_textctrl->SetToolTip(get_tooltip_text(X+", "+Y));
}
void PointCtrl::set_value(const Pointf value, bool change_event)
void PointCtrl::set_value(const Pointf& value, bool change_event)
{
m_disable_change_event = !change_event;
@ -567,10 +566,10 @@ void PointCtrl::set_value(const Pointf value, bool change_event)
m_disable_change_event = false;
}
void PointCtrl::set_value(boost::any value, bool change_event)
void PointCtrl::set_value(const boost::any& value, bool change_event)
{
Pointf pt;
Pointf *ptf = boost::any_cast<Pointf>(&value);
const Pointf *ptf = boost::any_cast<Pointf>(&value);
if (!ptf)
{
ConfigOptionPoints* pts = boost::any_cast<ConfigOptionPoints*>(value);
@ -578,21 +577,6 @@ void PointCtrl::set_value(boost::any value, bool change_event)
}
else
pt = *ptf;
// try
// {
// pt = boost::any_cast<ConfigOptionPoints*>(value)->values.at(0);
// }
// catch (const std::exception &e)
// {
// try{
// pt = boost::any_cast<Pointf>(value);
// }
// catch (const std::exception &e)
// {
// std::cerr << "Error! Can't cast PointCtrl value" << m_opt_id << "\n";
// return;
// }
// }
set_value(pt, change_event);
}

View File

@ -31,8 +31,8 @@ namespace Slic3r { namespace GUI {
class Field;
using t_field = std::unique_ptr<Field>;
using t_kill_focus = std::function<void()>;
using t_change = std::function<void(t_config_option_key, boost::any)>;
using t_back_to_init = std::function<void(std::string)>;
using t_change = std::function<void(t_config_option_key, const boost::any&)>;
using t_back_to_init = std::function<void(const std::string&)>;
wxString double_to_string(double const value);
@ -81,7 +81,7 @@ public:
/// Sets a value for this control.
/// subclasses should overload with a specific version
/// Postcondition: Method does not fire the on_change event.
virtual void set_value(boost::any value, bool change_event) = 0;
virtual void set_value(const boost::any& value, bool change_event) = 0;
/// Gets a boost::any representing this control.
/// subclasses should overload with a specific version
@ -100,7 +100,7 @@ public:
virtual wxString get_tooltip_text(const wxString& default_string);
// set icon to "UndoToSystemValue" button according to an inheritance of preset
void set_nonsys_btn_icon(const std::string& icon);
void set_nonsys_btn_icon(const std::string& icon);
Field(const ConfigOptionDef& opt, const t_config_option_key& id) : m_opt(opt), m_opt_id(id) {};
Field(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : m_parent(parent), m_opt(opt), m_opt_id(id) {};
@ -109,8 +109,8 @@ public:
virtual wxSizer* getSizer() { return nullptr; }
virtual wxWindow* getWindow() { return nullptr; }
bool is_matched(std::string string, std::string pattern);
boost::any get_value_by_opt_type(wxString str);
bool is_matched(const std::string& string, const std::string& pattern);
boost::any get_value_by_opt_type(wxString& str);
/// Factory method for generating new derived classes.
template<class T>
@ -137,16 +137,17 @@ class TextCtrl : public Field {
public:
TextCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
TextCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~TextCtrl() {}
void BUILD();
wxWindow* window {nullptr};
virtual void set_value(std::string value, bool change_event = false) {
virtual void set_value(const std::string& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxTextCtrl*>(window)->SetValue(wxString(value));
m_disable_change_event = false;
}
virtual void set_value(boost::any value, bool change_event = false) {
virtual void set_value(const boost::any& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxTextCtrl*>(window)->SetValue(boost::any_cast<wxString>(value));
m_disable_change_event = false;
@ -164,6 +165,7 @@ class CheckBox : public Field {
public:
CheckBox(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
CheckBox(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~CheckBox() {}
wxWindow* window{ nullptr };
void BUILD() override;
@ -173,7 +175,7 @@ public:
dynamic_cast<wxCheckBox*>(window)->SetValue(value);
m_disable_change_event = false;
}
void set_value(boost::any value, bool change_event = false) {
void set_value(const boost::any& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxCheckBox*>(window)->SetValue(boost::any_cast<bool>(value));
m_disable_change_event = false;
@ -190,21 +192,22 @@ class SpinCtrl : public Field {
public:
SpinCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id), tmp_value(-9999) {}
SpinCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id), tmp_value(-9999) {}
~SpinCtrl() {}
int tmp_value;
wxWindow* window{ nullptr };
void BUILD() override;
void set_value(const std::string value, bool change_event = false) {
void set_value(const std::string& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxSpinCtrl*>(window)->SetValue(value);
m_disable_change_event = false;
}
void set_value(boost::any value, bool change_event = false) {
void set_value(const boost::any& value, bool change_event = false) {
m_disable_change_event = !change_event;
tmp_value = boost::any_cast<int>(value);
dynamic_cast<wxSpinCtrl*>(window)->SetValue(tmp_value/*boost::any_cast<int>(value)*/);
dynamic_cast<wxSpinCtrl*>(window)->SetValue(tmp_value);
m_disable_change_event = false;
}
boost::any get_value() override {
@ -221,14 +224,15 @@ class Choice : public Field {
public:
Choice(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
Choice(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~Choice() {}
wxWindow* window{ nullptr };
void BUILD() override;
void set_selection();
void set_value(const std::string value, bool change_event = false);
void set_value(boost::any value, bool change_event = false);
void set_values(const std::vector<std::string> values);
void set_value(const std::string& value, bool change_event = false);
void set_value(const boost::any& value, bool change_event = false);
void set_values(const std::vector<std::string> &values);
boost::any get_value() override;
void enable() override { dynamic_cast<wxComboBox*>(window)->Enable(); };
@ -241,16 +245,17 @@ class ColourPicker : public Field {
public:
ColourPicker(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
ColourPicker(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~ColourPicker() {}
wxWindow* window{ nullptr };
void BUILD() override;
void set_value(const std::string value, bool change_event = false) {
void set_value(const std::string& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxColourPickerCtrl*>(window)->SetColour(value);
m_disable_change_event = false;
}
void set_value(boost::any value, bool change_event = false) {
void set_value(const boost::any& value, bool change_event = false) {
m_disable_change_event = !change_event;
dynamic_cast<wxColourPickerCtrl*>(window)->SetColour(boost::any_cast<wxString>(value));
m_disable_change_event = false;
@ -268,23 +273,24 @@ class PointCtrl : public Field {
public:
PointCtrl(const ConfigOptionDef& opt, const t_config_option_key& id) : Field(opt, id) {}
PointCtrl(wxWindow* parent, const ConfigOptionDef& opt, const t_config_option_key& id) : Field(parent, opt, id) {}
~PointCtrl() {}
wxSizer* sizer{ nullptr };
wxTextCtrl* x_textctrl;
wxTextCtrl* y_textctrl;
wxTextCtrl* x_textctrl{ nullptr };
wxTextCtrl* y_textctrl{ nullptr };
void BUILD() override;
void set_value(const Pointf value, bool change_event = false);
void set_value(boost::any value, bool change_event = false);
void set_value(const Pointf& value, bool change_event = false);
void set_value(const boost::any& value, bool change_event = false);
boost::any get_value() override;
void enable() override {
x_textctrl->Enable();
y_textctrl->Enable(); };
y_textctrl->Enable(); }
void disable() override{
x_textctrl->Disable();
y_textctrl->Disable(); };
y_textctrl->Disable(); }
wxSizer* getSizer() override { return sizer; }
};

View File

@ -405,7 +405,7 @@ TabIface* get_preset_tab_iface(char *name)
}
// opt_index = 0, by the reason of zero-index in ConfigOptionVector by default (in case only one element)
void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, boost::any value, int opt_index /*= 0*/)
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/)
{
try{
switch (config.def()->get(opt_key)->type){
@ -441,11 +441,18 @@ void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, b
config.set_key_value(opt_key, new ConfigOptionString(boost::any_cast<std::string>(value)));
break;
case coStrings:{
if (opt_key.compare("compatible_printers") == 0 ||
config.def()->get(opt_key)->gui_flags.compare("serialized") == 0){
config.option<ConfigOptionStrings>(opt_key)->values.resize(0);
std::vector<std::string> values = boost::any_cast<std::vector<std::string>>(value);
if (values.size() == 1 && values[0] == "")
if (opt_key.compare("compatible_printers") == 0) {
config.option<ConfigOptionStrings>(opt_key)->values =
boost::any_cast<std::vector<std::string>>(value);
}
else if (config.def()->get(opt_key)->gui_flags.compare("serialized") == 0){
std::string str = boost::any_cast<std::string>(value);
if (str.back() == ';') str.pop_back();
// Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values.
// Currently used for the post_process config value only.
std::vector<std::string> values;
boost::split(values, str, boost::is_any_of(";"));
if (values.size() == 1 && values[0] == "")
break;
config.option<ConfigOptionStrings>(opt_key)->values = values;
}
@ -512,17 +519,17 @@ void add_created_tab(Tab* panel)
g_wxTabPanel->AddPage(panel, panel->title());
}
void show_error(wxWindow* parent, wxString message){
void show_error(wxWindow* parent, const wxString& message){
auto msg_wingow = new wxMessageDialog(parent, message, _(L("Error")), wxOK | wxICON_ERROR);
msg_wingow->ShowModal();
}
void show_info(wxWindow* parent, wxString message, wxString title){
void show_info(wxWindow* parent, const wxString& message, const wxString& title){
auto msg_wingow = new wxMessageDialog(parent, message, title.empty() ? _(L("Notice")) : title, wxOK | wxICON_INFORMATION);
msg_wingow->ShowModal();
}
void warning_catcher(wxWindow* parent, wxString message){
void warning_catcher(wxWindow* parent, const wxString& message){
if (message == _(L("GLUquadricObjPtr | Attempt to free unreferenced scalar")) )
return;
auto msg = new wxMessageDialog(parent, message, _(L("Warning")), wxOK | wxICON_WARNING);

View File

@ -97,11 +97,11 @@ TabIface* get_preset_tab_iface(char *name);
// add it at the end of the tab panel.
void add_created_tab(Tab* panel);
// Change option value in config
void change_opt_value(DynamicPrintConfig& config, t_config_option_key opt_key, boost::any value, int opt_index = 0);
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index = 0);
void show_error(wxWindow* parent, wxString message);
void show_info(wxWindow* parent, wxString message, wxString title);
void warning_catcher(wxWindow* parent, wxString message);
void show_error(wxWindow* parent, const wxString& message);
void show_info(wxWindow* parent, const wxString& message, const wxString& title);
void warning_catcher(wxWindow* parent, const wxString& message);
// load language saved at application config
bool load_language();

View File

@ -97,7 +97,7 @@ const t_field& OptionsGroup::build_field(const t_config_option_key& id, const Co
return field;
}
void OptionsGroup::append_line(const Line& line) {
void OptionsGroup::append_line(const Line& line, wxStaticText** colored_Label/* = nullptr*/) {
//! if (line.sizer != nullptr || (line.widget != nullptr && line.full_width > 0)){
if ( (line.sizer != nullptr || line.widget != nullptr) && line.full_width){
if (line.sizer != nullptr) {
@ -149,7 +149,8 @@ void OptionsGroup::append_line(const Line& line) {
// If there's a widget, build it and add the result to the sizer.
if (line.widget != nullptr) {
auto wgt = line.widget(parent());
grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, wxOSX ? 0 : 1);
grid_sizer->Add(wgt, 0, wxEXPAND | wxBOTTOM | wxTOP, wxOSX ? 0 : 5);
if (colored_Label != nullptr) *colored_Label = label;
return;
}
@ -227,12 +228,12 @@ Line OptionsGroup::create_single_option_line(const Option& option) const {
return retval;
}
void OptionsGroup::on_change_OG(t_config_option_key id, /*config_value*/boost::any value) {
void OptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost::any& value) {
if (m_on_change != nullptr)
m_on_change(id, value);
m_on_change(opt_id, value);
}
Option ConfigOptionsGroup::get_option(const std::string opt_key, int opt_index /*= -1*/)
Option ConfigOptionsGroup::get_option(const std::string& opt_key, int opt_index /*= -1*/)
{
if (!m_config->has(opt_key)) {
std::cerr << "No " << opt_key << " in ConfigOptionsGroup config.";
@ -245,7 +246,7 @@ Option ConfigOptionsGroup::get_option(const std::string opt_key, int opt_index /
return Option(*m_config->def()->get(opt_key), opt_id);
}
void ConfigOptionsGroup::on_change_OG(t_config_option_key opt_id, boost::any value)
void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const boost::any& value)
{
if (!m_opt_map.empty())
{
@ -268,16 +269,7 @@ void ConfigOptionsGroup::on_change_OG(t_config_option_key opt_id, boost::any val
if (opt_index != -1){
// die "Can't set serialized option indexed value" ;
}
// # Split a string to multiple strings by a semi - colon.This is the old way of storing multi - string values.
// # Currently used for the post_process config value only.
// my @values = split / ; / , $field_value;
// $self->config->set($opt_key, \@values);
std::string str = boost::any_cast<std::string>(value);
if (str.back() == ';')
str.pop_back();
std::vector<std::string> values;
boost::split(values, str, boost::is_any_of(";"));
change_opt_value(*m_config, opt_key, values);
change_opt_value(*m_config, opt_key, value);
}
else {
if (opt_index == -1) {
@ -297,14 +289,14 @@ void ConfigOptionsGroup::on_change_OG(t_config_option_key opt_id, boost::any val
OptionsGroup::on_change_OG(opt_id, value); //!? Why doing this
}
void ConfigOptionsGroup::back_to_initial_value(const std::string opt_key)
void ConfigOptionsGroup::back_to_initial_value(const std::string& opt_key)
{
if (m_get_initial_config == nullptr)
return;
back_to_config_value(m_get_initial_config(), opt_key);
}
void ConfigOptionsGroup::back_to_sys_value(const std::string opt_key)
void ConfigOptionsGroup::back_to_sys_value(const std::string& opt_key)
{
if (m_get_sys_config == nullptr)
return;
@ -313,7 +305,7 @@ void ConfigOptionsGroup::back_to_sys_value(const std::string opt_key)
back_to_config_value(m_get_sys_config(), opt_key);
}
void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, const std::string opt_key)
void ConfigOptionsGroup::back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key)
{
boost::any value;
if (opt_key == "extruders_count"){
@ -348,7 +340,7 @@ void ConfigOptionsGroup::reload_config(){
}
boost::any ConfigOptionsGroup::config_value(std::string opt_key, int opt_index, bool deserialize){
boost::any ConfigOptionsGroup::config_value(const std::string& opt_key, int opt_index, bool deserialize){
if (deserialize) {
// Want to edit a vector value(currently only multi - strings) in a single edit box.
@ -365,7 +357,7 @@ boost::any ConfigOptionsGroup::config_value(std::string opt_key, int opt_index,
}
}
boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config, std::string opt_key, int opt_index /*= -1*/)
boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index /*= -1*/)
{
size_t idx = opt_index == -1 ? 0 : opt_index;
@ -405,6 +397,10 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
ret = static_cast<wxString>(config.opt_string(opt_key));
break;
case coStrings:
if (opt_key.compare("compatible_printers") == 0){
ret = config.option<ConfigOptionStrings>(opt_key)->values;
break;
}
if (config.option<ConfigOptionStrings>(opt_key)->values.empty())
ret = text_value;
else if (opt->gui_flags.compare("serialized") == 0){
@ -457,7 +453,7 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
return ret;
}
Field* ConfigOptionsGroup::get_fieldc(t_config_option_key opt_key, int opt_index){
Field* ConfigOptionsGroup::get_fieldc(const t_config_option_key& opt_key, int opt_index){
Field* field = get_field(opt_key);
if (field != nullptr)
return field;
@ -471,7 +467,7 @@ Field* ConfigOptionsGroup::get_fieldc(t_config_option_key opt_key, int opt_index
return opt_id.empty() ? nullptr : get_field(opt_id);
}
void ogStaticText::SetText(wxString value)
void ogStaticText::SetText(const wxString& value)
{
SetLabel(value);
Wrap(400);

View File

@ -93,21 +93,21 @@ public:
/// but defining it as const means a lot of const_casts to deal with wx functions.
inline wxWindow* parent() const { return m_parent; }
void append_line(const Line& line);
void append_line(const Line& line, wxStaticText** colored_Label = nullptr);
Line create_single_option_line(const Option& option) const;
void append_single_option_line(const Option& option) { append_line(create_single_option_line(option)); }
// return a non-owning pointer reference
inline Field* get_field(t_config_option_key id) const{
inline Field* get_field(const t_config_option_key& id) const{
if (m_fields.find(id) == m_fields.end()) return nullptr;
return m_fields.at(id).get();
}
bool set_value(t_config_option_key id, boost::any value, bool change_event = false) {
bool set_value(const t_config_option_key& id, const boost::any& value, bool change_event = false) {
if (m_fields.find(id) == m_fields.end()) return false;
m_fields.at(id)->set_value(value, change_event);
return true;
}
boost::any get_value(t_config_option_key id) {
boost::any get_value(const t_config_option_key& id) {
boost::any out;
if (m_fields.find(id) == m_fields.end()) ;
else
@ -118,7 +118,7 @@ public:
inline void enable() { for (auto& field : m_fields) field.second->enable(); }
inline void disable() { for (auto& field : m_fields) field.second->disable(); }
OptionsGroup(wxWindow* _parent, wxString title, bool is_tab_opt=false) :
OptionsGroup(wxWindow* _parent, const wxString& title, bool is_tab_opt=false) :
m_parent(_parent), title(title), m_is_tab_opt(is_tab_opt), staticbox(title!="") {
sizer = (staticbox ? new wxStaticBoxSizer(new wxStaticBox(_parent, wxID_ANY, title), wxVERTICAL) : new wxBoxSizer(wxVERTICAL));
auto num_columns = 1U;
@ -152,14 +152,14 @@ protected:
const t_field& build_field(const Option& opt, wxStaticText* label = nullptr);
virtual void on_kill_focus (){};
virtual void on_change_OG(t_config_option_key opt_id, boost::any value);
virtual void back_to_initial_value(const std::string opt_key){};
virtual void back_to_sys_value(const std::string opt_key){};
virtual void on_change_OG(const t_config_option_key& opt_id, const boost::any& value);
virtual void back_to_initial_value(const std::string& opt_key){}
virtual void back_to_sys_value(const std::string& opt_key){}
};
class ConfigOptionsGroup: public OptionsGroup {
public:
ConfigOptionsGroup(wxWindow* parent, wxString title, DynamicPrintConfig* _config = nullptr, bool is_tab_opt = false) :
ConfigOptionsGroup(wxWindow* parent, const wxString& title, DynamicPrintConfig* _config = nullptr, bool is_tab_opt = false) :
OptionsGroup(parent, title, is_tab_opt), m_config(_config) {}
/// reference to libslic3r config, non-owning pointer (?).
@ -167,8 +167,8 @@ public:
bool m_full_labels {0};
t_opt_map m_opt_map;
Option get_option(const std::string opt_key, int opt_index = -1);
Line create_single_option_line(const std::string title, int idx = -1) /*const*/{
Option get_option(const std::string& opt_key, int opt_index = -1);
Line create_single_option_line(const std::string& title, int idx = -1) /*const*/{
Option option = get_option(title, idx);
return OptionsGroup::create_single_option_line(option);
}
@ -181,16 +181,16 @@ public:
append_single_option_line(option);
}
void on_change_OG(t_config_option_key opt_id, boost::any value) override;
void back_to_initial_value(const std::string opt_key) override;
void back_to_sys_value(const std::string opt_key) override;
void back_to_config_value(const DynamicPrintConfig& config, const std::string opt_key);
void on_change_OG(const t_config_option_key& opt_id, const boost::any& value) override;
void back_to_initial_value(const std::string& opt_key) override;
void back_to_sys_value(const std::string& opt_key) override;
void back_to_config_value(const DynamicPrintConfig& config, const std::string& opt_key);
void on_kill_focus() override{ reload_config();}
void reload_config();
boost::any config_value(std::string opt_key, int opt_index, bool deserialize);
boost::any config_value(const std::string& opt_key, int opt_index, bool deserialize);
// return option value from config
boost::any get_config_value(const DynamicPrintConfig& config, std::string opt_key, int opt_index = -1);
Field* get_fieldc(t_config_option_key opt_key, int opt_index);
boost::any get_config_value(const DynamicPrintConfig& config, const std::string& opt_key, int opt_index = -1);
Field* get_fieldc(const t_config_option_key& opt_key, int opt_index);
};
// Static text shown among the options.
@ -200,7 +200,7 @@ public:
ogStaticText(wxWindow* parent, const char *text) : wxStaticText(parent, wxID_ANY, text, wxDefaultPosition, wxDefaultSize){}
~ogStaticText(){}
void SetText(wxString value);
void SetText(const wxString& value);
};
}}

View File

@ -416,6 +416,20 @@ const Preset* PresetCollection::get_selected_preset_parent() const
return (preset == nullptr || preset->is_default || preset->is_external) ? nullptr : preset;
}
const Preset* PresetCollection::get_preset_parent(const Preset& child) const
{
auto *inherits = dynamic_cast<const ConfigOptionString*>(child.config.option("inherits"));
if (inherits == nullptr || inherits->value.empty())
// return this->get_selected_preset().is_system ? &this->get_selected_preset() : nullptr;
return nullptr;
const Preset* preset = this->find_preset(inherits->value, false);
return (preset == nullptr/* || preset->is_default */|| preset->is_external) ? nullptr : preset;
}
const std::string& PresetCollection::get_suffix_modified() {
return g_suffix_modified;
}
// Return a preset by its name. If the preset is active, a temporary copy is returned.
// If a preset is not found by its name, null is returned.
Preset* PresetCollection::find_preset(const std::string &name, bool first_visible_if_not_found)
@ -497,16 +511,44 @@ void PresetCollection::update_platter_ui(wxBitmapComboBox *ui)
// Otherwise fill in the list from scratch.
ui->Freeze();
ui->Clear();
std::map<wxString, bool> nonsys_presets;
wxString selected = "";
for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++ i) {
const Preset &preset = this->m_presets[i];
if (! preset.is_visible || (! preset.is_compatible && i != m_idx_selected))
continue;
const wxBitmap *bmp = (i == 0 || preset.is_compatible) ? m_bitmap_main_frame : m_bitmap_incompatible;
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
if (i == m_idx_selected)
ui->SetSelection(ui->GetCount() - 1);
}
// ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
// (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
// if (i == m_idx_selected)
// ui->SetSelection(ui->GetCount() - 1);
if (preset.is_default || preset.is_system){
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
if (i == m_idx_selected)
ui->SetSelection(ui->GetCount() - 1);
}
else
{
nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), preset.is_compatible);
if (i == m_idx_selected)
selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str());
}
if (preset.is_default)
ui->Append("------------------------------------", wxNullBitmap);
}
if (!nonsys_presets.empty())
{
ui->Append("------------------------------------", wxNullBitmap);
for (std::map<wxString, bool>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
const wxBitmap *bmp = it->second ? m_bitmap_compatible : m_bitmap_incompatible;
ui->Append(it->first,
(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
if (it->first == selected)
ui->SetSelection(ui->GetCount() - 1);
}
}
ui->Thaw();
}
@ -516,16 +558,44 @@ void PresetCollection::update_tab_ui(wxBitmapComboBox *ui, bool show_incompatibl
return;
ui->Freeze();
ui->Clear();
std::map<wxString, bool> nonsys_presets;
wxString selected = "";
for (size_t i = this->m_presets.front().is_visible ? 0 : 1; i < this->m_presets.size(); ++ i) {
const Preset &preset = this->m_presets[i];
if (! preset.is_visible || (! show_incompatible && ! preset.is_compatible && i != m_idx_selected))
continue;
const wxBitmap *bmp = preset.is_compatible ? m_bitmap_compatible : m_bitmap_incompatible;
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
if (i == m_idx_selected)
ui->SetSelection(ui->GetCount() - 1);
// ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
// (bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
// if (i == m_idx_selected)
// ui->SetSelection(ui->GetCount() - 1);
if (preset.is_default || preset.is_system){
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()),
(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
if (i == m_idx_selected)
ui->SetSelection(ui->GetCount() - 1);
}
else
{
nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str()), preset.is_compatible);
if (i == m_idx_selected)
selected = wxString::FromUTF8((preset.name + (preset.is_dirty ? g_suffix_modified : "")).c_str());
}
if (preset.is_default)
ui->Append("------------------------------------", wxNullBitmap);
}
if (!nonsys_presets.empty())
{
ui->Append("------------------------------------", wxNullBitmap);
for (std::map<wxString, bool>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
const wxBitmap *bmp = it->second ? m_bitmap_compatible : m_bitmap_incompatible;
ui->Append(it->first,
(bmp == 0) ? (m_bitmap_main_frame ? *m_bitmap_main_frame : wxNullBitmap) : *bmp);
if (it->first == selected)
ui->SetSelection(ui->GetCount() - 1);
}
}
ui->Thaw();
}

View File

@ -209,9 +209,17 @@ public:
// The parent preset may be a system preset or a user preset, which will be
// reflected by the UI.
const Preset* get_selected_preset_parent() const;
// Return the selected preset including the user modifications.
// get parent preset for some child preset
const Preset* get_preset_parent(const Preset& child) const;
// Return the selected preset including the user modifications.
Preset& get_edited_preset() { return m_edited_preset; }
const Preset& get_edited_preset() const { return m_edited_preset; }
// used to update preset_choice from Tab
const std::deque<Preset>& get_presets() { return m_presets; }
int get_idx_selected() { return m_idx_selected; }
const std::string& get_suffix_modified();
// Return a preset possibly with modifications.
const Preset& default_preset() const { return m_presets.front(); }
// Return a preset by an index. If the preset is active, a temporary copy is returned.

View File

@ -261,8 +261,8 @@ bool PresetBundle::load_compatible_bitmaps()
{
const std::string path_bitmap_compatible = "flag-green-icon.png";
const std::string path_bitmap_incompatible = "flag-red-icon.png";
const std::string path_bitmap_lock = "lock.png";
const std::string path_bitmap_lock_open = "lock_open.png";
const std::string path_bitmap_lock = "sys_lock.png";//"lock.png";
const std::string path_bitmap_lock_open = "sys_unlock.png";//"lock_open.png";
bool loaded_compatible = m_bitmapCompatible ->LoadFile(
wxString::FromUTF8(Slic3r::var(path_bitmap_compatible).c_str()), wxBITMAP_TYPE_PNG);
bool loaded_incompatible = m_bitmapIncompatible->LoadFile(
@ -1025,6 +1025,8 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma
// and draw a red flag in front of the selected preset.
bool wide_icons = selected_preset != nullptr && ! selected_preset->is_compatible && m_bitmapIncompatible != nullptr;
assert(selected_preset != nullptr);
std::map<wxString, wxBitmap> nonsys_presets;
wxString selected_str = "";
for (int i = this->filaments().front().is_visible ? 0 : 1; i < int(this->filaments().size()); ++ i) {
const Preset &preset = this->filaments.preset(i);
bool selected = this->filament_presets[idx_extruder] == preset.name;
@ -1062,10 +1064,36 @@ void PresetBundle::update_platter_filament_ui(unsigned int idx_extruder, wxBitma
(preset.is_dirty ? *m_bitmapLockOpen : *m_bitmapLock) : m_bitmapCache->mkclear(16, 16));
bitmap = m_bitmapCache->insert(bitmap_key, bmps);
}
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), (bitmap == 0) ? wxNullBitmap : *bitmap);
if (selected)
ui->SetSelection(ui->GetCount() - 1);
// ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()), (bitmap == 0) ? wxNullBitmap : *bitmap);
// if (selected)
// ui->SetSelection(ui->GetCount() - 1);
if (preset.is_default || preset.is_system){
ui->Append(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
(bitmap == 0) ? wxNullBitmap : *bitmap);
if (selected)
ui->SetSelection(ui->GetCount() - 1);
}
else
{
nonsys_presets.emplace(wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str()),
(bitmap == 0) ? wxNullBitmap : *bitmap);
if (selected)
selected_str = wxString::FromUTF8((preset.name + (preset.is_dirty ? Preset::suffix_modified() : "")).c_str());
}
if (preset.is_default)
ui->Append("------------------------------------", wxNullBitmap);
}
if (!nonsys_presets.empty())
{
ui->Append("------------------------------------", wxNullBitmap);
for (std::map<wxString, wxBitmap>::iterator it = nonsys_presets.begin(); it != nonsys_presets.end(); ++it) {
ui->Append(it->first, it->second);
if (it->first == selected_str)
ui->SetSelection(ui->GetCount() - 1);
}
}
ui->Thaw();
}

View File

@ -22,6 +22,7 @@
#include <wx/filedlg.h>
#include <boost/algorithm/string/predicate.hpp>
#include "wxExtensions.hpp"
namespace Slic3r {
namespace GUI {
@ -39,7 +40,42 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
// preset chooser
m_presets_choice = new wxBitmapComboBox(panel, wxID_ANY, "", wxDefaultPosition, wxSize(270, -1), 0, 0,wxCB_READONLY);
/*
m_cc_presets_choice = new wxComboCtrl(panel, wxID_ANY, L(""), wxDefaultPosition, wxDefaultSize, wxCB_READONLY);
wxDataViewTreeCtrlComboPopup* popup = new wxDataViewTreeCtrlComboPopup;
if (popup != nullptr)
{
// FIXME If the following line is removed, the combo box popup list will not react to mouse clicks.
// On the other side, with this line the combo box popup cannot be closed by clicking on the combo button on Windows 10.
// m_cc_presets_choice->UseAltPopupWindow();
// m_cc_presets_choice->EnablePopupAnimation(false);
m_cc_presets_choice->SetPopupControl(popup);
popup->SetStringValue(from_u8("Text1"));
popup->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this, popup](wxCommandEvent& evt)
{
auto selected = popup->GetItemText(popup->GetSelection());
if (selected != _(L("System presets")) && selected != _(L("Default presets")))
{
m_cc_presets_choice->SetText(selected);
std::string selected_string = selected.ToUTF8().data();
#ifdef __APPLE__
#else
select_preset(selected_string);
#endif
}
});
// popup->Bind(wxEVT_KEY_DOWN, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); });
// popup->Bind(wxEVT_KEY_UP, [popup](wxKeyEvent& evt) { popup->OnKeyEvent(evt); });
auto icons = new wxImageList(16, 16, true, 1);
popup->SetImageList(icons);
icons->Add(*new wxIcon(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG));
icons->Add(*new wxIcon(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG));
}
*/
auto color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
//buttons
@ -84,11 +120,44 @@ void Tab::create_preset_tab(PresetBundle *preset_bundle)
m_hsizer->AddSpacer(64);
m_hsizer->Add(m_undo_to_sys_btn, 0, wxALIGN_CENTER_VERTICAL);
m_hsizer->Add(m_undo_btn, 0, wxALIGN_CENTER_VERTICAL);
// m_hsizer->AddSpacer(64);
// m_hsizer->Add(m_cc_presets_choice, 1, wxLEFT | wxRIGHT | wxTOP | wxALIGN_CENTER_VERTICAL, 3);
//Horizontal sizer to hold the tree and the selected page.
m_hsizer = new wxBoxSizer(wxHORIZONTAL);
sizer->Add(m_hsizer, 1, wxEXPAND, 0);
/*
//temporary left vertical sizer
m_left_sizer = new wxBoxSizer(wxVERTICAL);
m_hsizer->Add(m_left_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 3);
// tree
m_presetctrl = new wxDataViewTreeCtrl(panel, wxID_ANY, wxDefaultPosition, wxSize(200, -1), wxDV_NO_HEADER);
m_left_sizer->Add(m_presetctrl, 1, wxEXPAND);
m_preset_icons = new wxImageList(16, 16, true, 1);
m_presetctrl->SetImageList(m_preset_icons);
m_preset_icons->Add(*new wxIcon(from_u8(Slic3r::var("flag-green-icon.png")), wxBITMAP_TYPE_PNG));
m_preset_icons->Add(*new wxIcon(from_u8(Slic3r::var("flag-red-icon.png")), wxBITMAP_TYPE_PNG));
m_presetctrl->Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxCommandEvent& evt)
{
auto selected = m_presetctrl->GetItemText(m_presetctrl->GetSelection());
if (selected != _(L("System presets")) && selected != _(L("Default presets")))
{
std::string selected_string = selected.ToUTF8().data();
#ifdef __APPLE__
#else
select_preset(selected_string);
#endif
}
});
*/
//left vertical sizer
m_left_sizer = new wxBoxSizer(wxVERTICAL);
m_hsizer->Add(m_left_sizer, 0, wxEXPAND | wxLEFT | wxTOP | wxBOTTOM, 3);
@ -136,11 +205,10 @@ void Tab::load_initial_data()
{
m_config = &m_presets->get_edited_preset().config;
m_nonsys_btn_icon = m_presets->get_selected_preset_parent() == nullptr ?
"bullet_white.png" :
wxMSW ? "sys_unlock.png" : "lock_open.png";
"bullet_white.png" : "sys_unlock.png";
}
PageShp Tab::add_options_page(wxString title, std::string icon, bool is_extruder_pages/* = false*/)
PageShp Tab::add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages/* = false*/)
{
// Index of icon in an icon list $self->{icons}.
auto icon_idx = 0;
@ -260,13 +328,14 @@ void Tab::update_changed_ui()
m_dirty_options = dirty_options;
}
Freeze();
//update options "decoration"
for (const auto opt_key : m_full_options_list)
{
bool is_nonsys_value = false;
bool is_modified_value = true;
std::string sys_icon = wxMSW ? "sys_lock.png" : "lock.png";
std::string icon = wxMSW ? "action_undo.png" : "arrow_undo.png";
std::string sys_icon = "sys_lock.png";
std::string icon = "action_undo.png";
wxColour color = get_sys_label_clr();
if (find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end()) {
is_nonsys_value = true;
@ -281,6 +350,14 @@ void Tab::update_changed_ui()
is_modified_value = false;
icon = "bullet_white.png";
}
if (opt_key == "bed_shape" || opt_key == "compatible_printers") {
if (m_colored_Label != nullptr) {
m_colored_Label->SetForegroundColour(color);
m_colored_Label->Refresh(true);
}
continue;
}
Field* field = get_field(opt_key);
if (field == nullptr) continue;
field->m_is_nonsys_value = is_nonsys_value;
@ -292,6 +369,7 @@ void Tab::update_changed_ui()
field->m_Label->Refresh(true);
}
}
Thaw();
wxTheApp->CallAfter([this]() {
update_changed_tree_ui();
@ -353,13 +431,20 @@ void Tab::update_sys_ui_after_sel_preset()
m_sys_options.resize(0);
}
void Tab::get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page)
{
if (sys_page && find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end())
sys_page = false;
if (!modified_page && find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end())
modified_page = true;
}
void Tab::update_changed_tree_ui()
{
auto cur_item = m_treectrl->GetFirstVisibleItem();
auto selection = m_treectrl->GetItemText(m_treectrl->GetSelection());
while (cur_item){
auto title = m_treectrl->GetItemText(cur_item);
int i=0;
for (auto page : m_pages)
{
if (page->title() != title)
@ -369,23 +454,20 @@ void Tab::update_changed_tree_ui()
if (title == _("General")){
std::initializer_list<const char*> optional_keys{ "extruders_count", "bed_shape" };
for (auto &opt_key : optional_keys) {
if (sys_page && find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end())
sys_page = false;
if (!modified_page && find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end())
modified_page = true;
get_sys_and_mod_flags(opt_key, sys_page, modified_page);
}
}
if (title == _("Dependencies")){
get_sys_and_mod_flags("compatible_printers", sys_page, modified_page);
}
for (auto group : page->m_optgroups)
{
for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) {
const std::string& opt_key = it->first;
if (sys_page && find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end())
sys_page = false;
if (!modified_page && find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end())
modified_page = true;
}
if (!sys_page && modified_page)
break;
for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) {
const std::string& opt_key = it->first;
get_sys_and_mod_flags(opt_key, sys_page, modified_page);
}
}
if (sys_page)
m_treectrl->SetItemTextColour(cur_item, get_sys_label_clr());
@ -411,10 +493,8 @@ void Tab::update_changed_tree_ui()
void Tab::update_undo_buttons()
{
const std::string& undo_icon = !m_is_modified_values ? "bullet_white.png" :
wxMSW ? "action_undo.png" : "arrow_undo.png";
const std::string& undo_to_sys_icon = m_is_nonsys_values ? m_nonsys_btn_icon :
wxMSW ? "sys_lock.png" : "lock.png";
const std::string& undo_icon = !m_is_modified_values ? "bullet_white.png" : "action_undo.png";
const std::string& undo_to_sys_icon = m_is_nonsys_values ? m_nonsys_btn_icon : "sys_lock.png";
m_undo_btn->SetBitmap(wxBitmap(from_u8(var(undo_icon)), wxBITMAP_TYPE_PNG));
m_undo_to_sys_btn->SetBitmap(wxBitmap(from_u8(var(undo_to_sys_icon)), wxBITMAP_TYPE_PNG));
@ -436,6 +516,14 @@ void Tab::on_back_to_initial_value()
if (find(m_dirty_options.begin(), m_dirty_options.end(), "bed_shape") != m_dirty_options.end())
group->back_to_initial_value("bed_shape");
}
if (group->title == _("Profile dependencies")){
if (find(m_dirty_options.begin(), m_dirty_options.end(), "compatible_printers") != m_dirty_options.end())
group->back_to_initial_value("compatible_printers");
bool is_empty = m_config->option<ConfigOptionStrings>("compatible_printers")->values.empty();
m_compatible_printers_checkbox->SetValue(is_empty);
is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable();
}
for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) {
const std::string& opt_key = it->first;
if (find(m_dirty_options.begin(), m_dirty_options.end(), opt_key) != m_dirty_options.end())
@ -463,6 +551,14 @@ void Tab::on_back_to_sys_value()
if (find(m_sys_options.begin(), m_sys_options.end(), "bed_shape") == m_sys_options.end())
group->back_to_sys_value("bed_shape");
}
if (group->title == _("Profile dependencies")){
if (find(m_sys_options.begin(), m_sys_options.end(), "compatible_printers") == m_sys_options.end())
group->back_to_sys_value("compatible_printers");
bool is_empty = m_config->option<ConfigOptionStrings>("compatible_printers")->values.empty();
m_compatible_printers_checkbox->SetValue(is_empty);
is_empty ? m_compatible_printers_btn->Disable() : m_compatible_printers_btn->Enable();
}
for (t_opt_map::iterator it = group->m_opt_map.begin(); it != group->m_opt_map.end(); ++it) {
const std::string& opt_key = it->first;
if (find(m_sys_options.begin(), m_sys_options.end(), opt_key) == m_sys_options.end())
@ -480,16 +576,19 @@ void Tab::update_dirty(){
m_presets->update_dirty_ui(m_presets_choice);
on_presets_changed();
update_changed_ui();
// update_dirty_presets(m_cc_presets_choice);
}
void Tab::update_tab_ui()
{
m_presets->update_tab_ui(m_presets_choice, m_show_incompatible_presets);
// update_tab_presets(m_cc_presets_choice, m_show_incompatible_presets);
// update_presetsctrl(m_presetctrl, m_show_incompatible_presets);
}
// Load a provied DynamicConfig into the tab, modifying the active preset.
// This could be used for example by setting a Wipe Tower position by interactive manipulation in the 3D view.
void Tab::load_config(DynamicPrintConfig config)
void Tab::load_config(const DynamicPrintConfig& config)
{
bool modified = 0;
for(auto opt_key : m_config->diff(config)) {
@ -512,7 +611,7 @@ void Tab::reload_config(){
Thaw();
}
Field* Tab::get_field(t_config_option_key opt_key, int opt_index/* = -1*/) const
Field* Tab::get_field(const t_config_option_key& opt_key, int opt_index/* = -1*/) const
{
Field* field = nullptr;
for (auto page : m_pages){
@ -526,7 +625,7 @@ Field* Tab::get_field(t_config_option_key opt_key, int opt_index/* = -1*/) const
// Set a key/value pair on this page. Return true if the value has been modified.
// Currently used for distributing extruders_count over preset pages of Slic3r::GUI::Tab::Printer
// after a preset is loaded.
bool Tab::set_value(t_config_option_key opt_key, boost::any value){
bool Tab::set_value(const t_config_option_key& opt_key, const boost::any& value){
bool changed = false;
for(auto page: m_pages) {
if (page->set_value(opt_key, value))
@ -537,7 +636,7 @@ bool Tab::set_value(t_config_option_key opt_key, boost::any value){
// To be called by custom widgets, load a value into a config,
// update the preset selection boxes (the dirty flags)
void Tab::load_key_value(std::string opt_key, boost::any value)
void Tab::load_key_value(const std::string& opt_key, const boost::any& value)
{
change_opt_value(*m_config, opt_key, value);
// Mark the print & filament enabled if they are compatible with the currently selected preset.
@ -551,7 +650,7 @@ void Tab::load_key_value(std::string opt_key, boost::any value)
extern wxFrame *g_wxMainFrame;
void Tab::on_value_change(std::string opt_key, boost::any value)
void Tab::on_value_change(const std::string& opt_key, const boost::any& value)
{
if (m_event_value_change > 0) {
wxCommandEvent event(m_event_value_change);
@ -566,8 +665,8 @@ void Tab::on_value_change(std::string opt_key, boost::any value)
}
if (opt_key == "fill_density")
{
value = get_optgroup()->get_config_value(*m_config, opt_key);
get_optgroup()->set_value(opt_key, value);
boost::any val = get_optgroup()->get_config_value(*m_config, opt_key);
get_optgroup()->set_value(opt_key, val);
}
if (opt_key == "support_material" || opt_key == "support_material_buildplate_only")
{
@ -858,7 +957,7 @@ void TabPrint::build()
line.widget = [this](wxWindow* parent){
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
};
optgroup->append_line(line);
optgroup->append_line(line, &m_colored_Label);
option = optgroup->get_option("compatible_printers_condition");
option.opt.full_width = true;
@ -1233,7 +1332,7 @@ void TabFilament::build()
line.widget = [this](wxWindow* parent){
return compatible_printers_widget(parent, &m_compatible_printers_checkbox, &m_compatible_printers_btn);
};
optgroup->append_line(line);
optgroup->append_line(line, &m_colored_Label);
option = optgroup->get_option("compatible_printers_condition");
option.opt.full_width = true;
@ -1327,7 +1426,7 @@ void TabPrinter::build()
return sizer;
};
optgroup->append_line(line);
optgroup->append_line(line, &m_colored_Label);
optgroup->append_single_option_line("max_print_height");
optgroup->append_single_option_line("z_offset");
@ -1755,9 +1854,7 @@ void Tab::load_current_preset()
// Reload preset pages with the new configuration values.
reload_config();
const Preset* parent = m_presets->get_selected_preset_parent();
m_nonsys_btn_icon = parent == nullptr ?
"bullet_white.png" :
wxMSW ? "sys_unlock.png" : "lock_open.png";
m_nonsys_btn_icon = parent == nullptr ? "bullet_white.png" : "sys_unlock.png";
// use CallAfter because some field triggers schedule on_change calls using CallAfter,
// and we don't want them to be called after this update_dirty() as they would mark the
@ -1814,7 +1911,7 @@ void Tab::rebuild_page_tree()
// Called by the UI combo box when the user switches profiles.
// Select a preset by a name.If !defined(name), then the default preset is selected.
// If the current profile is modified, user is asked to save the changes.
void Tab::select_preset(std::string preset_name /*= ""*/)
void Tab::select_preset(const std::string& preset_name /*= ""*/)
{
std::string name = preset_name;
auto force = false;
@ -1881,7 +1978,7 @@ void Tab::select_preset(std::string preset_name /*= ""*/)
// If the current preset is dirty, the user is asked whether the changes may be discarded.
// if the current preset was not dirty, or the user agreed to discard the changes, 1 is returned.
bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr*/, std::string new_printer_name /*= ""*/)
bool Tab::may_discard_current_dirty_preset(PresetCollection* presets /*= nullptr*/, const std::string& new_printer_name /*= ""*/)
{
if (presets == nullptr) presets = m_presets;
// Display a dialog showing the dirty options in a human readable form.
@ -2089,6 +2186,7 @@ wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox
if ((*checkbox)->GetValue())
load_key_value("compatible_printers", std::vector<std::string> {});
get_field("compatible_printers_condition")->toggle((*checkbox)->GetValue());
update_changed_ui();
}) );
(*btn)->Bind(wxEVT_BUTTON, ([this, parent, checkbox, btn](wxCommandEvent e)
@ -2131,18 +2229,186 @@ wxSizer* Tab::compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox
}
// All printers have been made compatible with this preset.
load_key_value("compatible_printers", value);
update_changed_ui();
}
}));
return sizer;
}
void Tab::update_presetsctrl(wxDataViewTreeCtrl* ui, bool show_incompatible)
{
if (ui == nullptr)
return;
ui->Freeze();
ui->DeleteAllItems();
auto presets = m_presets->get_presets();
auto idx_selected = m_presets->get_idx_selected();
auto suffix_modified = m_presets->get_suffix_modified();
int icon_compatible = 0;
int icon_incompatible = 1;
int cnt_items = 0;
auto root_sys = ui->AppendContainer(wxDataViewItem(0), _(L("System presets")));
auto root_def = ui->AppendContainer(wxDataViewItem(0), _(L("Default presets")));
auto show_def = get_app_config()->get("no_defaults")[0] != '1';
for (size_t i = presets.front().is_visible ? 0 : 1; i < presets.size(); ++i) {
const Preset &preset = presets[i];
if (!preset.is_visible || (!show_incompatible && !preset.is_compatible && i != idx_selected))
continue;
auto preset_name = wxString::FromUTF8((preset.name + (preset.is_dirty ? suffix_modified : "")).c_str());
wxDataViewItem item;
if (preset.is_system)
item = ui->AppendItem(root_sys, preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
else if (show_def && preset.is_default)
item = ui->AppendItem(root_def, preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
else
{
auto parent = m_presets->get_preset_parent(preset);
if (parent == nullptr)
item = ui->AppendItem(root_def, preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
else
{
auto parent_name = parent->name;
wxDataViewTreeStoreContainerNode *node = ui->GetStore()->FindContainerNode(root_sys);
if (node)
{
wxDataViewTreeStoreNodeList::iterator iter;
for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); iter++)
{
wxDataViewTreeStoreNode* child = *iter;
auto child_item = child->GetItem();
auto item_text = ui->GetItemText(child_item);
if (item_text == parent_name)
{
auto added_child = ui->AppendItem(child->GetItem(), preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
if (!added_child){
ui->DeleteItem(child->GetItem());
auto new_parent = ui->AppendContainer(root_sys, parent_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
ui->AppendItem(new_parent, preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
}
break;
}
}
}
}
}
cnt_items++;
if (i == idx_selected){
ui->Select(item);
m_cc_presets_choice->SetText(preset_name);
}
}
if (ui->GetStore()->GetChildCount(root_def) == 0)
ui->DeleteItem(root_def);
ui->Thaw();
}
void Tab::update_tab_presets(wxComboCtrl* ui, bool show_incompatible)
{
if (ui == nullptr)
return;
ui->Freeze();
ui->Clear();
auto presets = m_presets->get_presets();
auto idx_selected = m_presets->get_idx_selected();
auto suffix_modified = m_presets->get_suffix_modified();
int icon_compatible = 0;
int icon_incompatible = 1;
int cnt_items = 0;
wxDataViewTreeCtrlComboPopup* popup = wxDynamicCast(m_cc_presets_choice->GetPopupControl(), wxDataViewTreeCtrlComboPopup);
if (popup != nullptr)
{
popup->DeleteAllItems();
auto root_sys = popup->AppendContainer(wxDataViewItem(0), _(L("System presets")));
auto root_def = popup->AppendContainer(wxDataViewItem(0), _(L("Default presets")));
auto show_def = get_app_config()->get("no_defaults")[0] != '1';
for (size_t i = presets.front().is_visible ? 0 : 1; i < presets.size(); ++i) {
const Preset &preset = presets[i];
if (!preset.is_visible || (!show_incompatible && !preset.is_compatible && i != idx_selected))
continue;
auto preset_name = wxString::FromUTF8((preset.name + (preset.is_dirty ? suffix_modified : "")).c_str());
wxDataViewItem item;
if (preset.is_system)
item = popup->AppendItem(root_sys, preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
else if (show_def && preset.is_default)
item = popup->AppendItem(root_def, preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
else
{
auto parent = m_presets->get_preset_parent(preset);
if (parent == nullptr)
item = popup->AppendItem(root_def, preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
else
{
auto parent_name = parent->name;
wxDataViewTreeStoreContainerNode *node = popup->GetStore()->FindContainerNode(root_sys);
if (node)
{
wxDataViewTreeStoreNodeList::iterator iter;
for (iter = node->GetChildren().begin(); iter != node->GetChildren().end(); iter++)
{
wxDataViewTreeStoreNode* child = *iter;
auto child_item = child->GetItem();
auto item_text = popup->GetItemText(child_item);
if (item_text == parent_name)
{
auto added_child = popup->AppendItem(child->GetItem(), preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
if (!added_child){
popup->DeleteItem(child->GetItem());
auto new_parent = popup->AppendContainer(root_sys, parent_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
popup->AppendItem(new_parent, preset_name,
preset.is_compatible ? icon_compatible : icon_incompatible);
}
break;
}
}
}
}
}
cnt_items++;
if (i == idx_selected){
popup->Select(item);
m_cc_presets_choice->SetText(preset_name);
}
}
if (popup->GetStore()->GetChildCount(root_def) == 0)
popup->DeleteItem(root_def);
}
ui->Thaw();
}
void Page::reload_config()
{
for (auto group : m_optgroups)
group->reload_config();
}
Field* Page::get_field(t_config_option_key opt_key, int opt_index/* = -1*/) const
Field* Page::get_field(const t_config_option_key& opt_key, int opt_index /*= -1*/) const
{
Field* field = nullptr;
for (auto opt : m_optgroups){
@ -2153,7 +2419,7 @@ Field* Page::get_field(t_config_option_key opt_key, int opt_index/* = -1*/) cons
return field;
}
bool Page::set_value(t_config_option_key opt_key, boost::any value){
bool Page::set_value(const t_config_option_key& opt_key, const boost::any& value){
bool changed = false;
for(auto optgroup: m_optgroups) {
if (optgroup->set_value(opt_key, value))
@ -2163,7 +2429,7 @@ bool Page::set_value(t_config_option_key opt_key, boost::any value){
}
// package Slic3r::GUI::Tab::Page;
ConfigOptionsGroupShp Page::new_optgroup(wxString title, int noncommon_label_width /*= -1*/)
ConfigOptionsGroupShp Page::new_optgroup(const wxString& title, int noncommon_label_width /*= -1*/)
{
//! config_ have to be "right"
ConfigOptionsGroupShp optgroup = std::make_shared<ConfigOptionsGroup>(this, title, m_config, true);
@ -2204,7 +2470,7 @@ ConfigOptionsGroupShp Page::new_optgroup(wxString title, int noncommon_label_wid
return optgroup;
}
void SavePresetWindow::build(wxString title, std::string default_name, std::vector<std::string> &values)
void SavePresetWindow::build(const wxString& title, const std::string& default_name, std::vector<std::string> &values)
{
auto text = new wxStaticText(this, wxID_ANY, _(L("Save ")) + title + _(L(" as:")),
wxDefaultPosition, wxDefaultSize);

View File

@ -21,6 +21,7 @@
#include <wx/treectrl.h>
#include <wx/imaglist.h>
#include <wx/statbox.h>
#include <wx/dataview.h>
#include <map>
#include <vector>
@ -67,9 +68,9 @@ public:
size_t iconID() const { return m_iconID; }
void set_config(DynamicPrintConfig* config_in) { m_config = config_in; }
void reload_config();
Field* get_field(t_config_option_key opt_key, int opt_index = -1) const;
bool set_value(t_config_option_key opt_key, boost::any value);
ConfigOptionsGroupShp new_optgroup(wxString title, int noncommon_label_width = -1);
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
bool set_value(const t_config_option_key& opt_key, const boost::any& value);
ConfigOptionsGroupShp new_optgroup(const wxString& title, int noncommon_label_width = -1);
};
// Slic3r::GUI::Tab;
@ -95,6 +96,9 @@ protected:
wxButton* m_compatible_printers_btn;
wxButton* m_undo_btn;
wxButton* m_undo_to_sys_btn;
wxComboCtrl* m_cc_presets_choice;
wxDataViewTreeCtrl* m_presetctrl;
wxImageList* m_preset_icons;
int m_icon_count;
std::map<std::string, size_t> m_icon_index; // Map from an icon file name to its index
@ -122,10 +126,11 @@ public:
DynamicPrintConfig* m_config;
std::string m_nonsys_btn_icon;
ogStaticText* m_parent_preset_description_line;
wxStaticText* m_colored_Label = nullptr;
public:
Tab() {}
Tab(wxNotebook* parent, wxString title, const char* name, bool no_controller) :
Tab(wxNotebook* parent, const wxString& title, const char* name, bool no_controller) :
m_parent(parent), m_title(title), m_name(name), m_no_controller(no_controller) {
Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBK_LEFT | wxTAB_TRAVERSAL);
get_tabs_list().push_back(this);
@ -143,11 +148,12 @@ public:
void create_preset_tab(PresetBundle *preset_bundle);
void load_current_preset();
void rebuild_page_tree();
void select_preset(std::string preset_name = "");
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, std::string new_printer_name = "");
void select_preset(const std::string& preset_name = "");
bool may_discard_current_dirty_preset(PresetCollection* presets = nullptr, const std::string& new_printer_name = "");
wxSizer* compatible_printers_widget(wxWindow* parent, wxCheckBox** checkbox, wxButton** btn);
void load_key_value(std::string opt_key, boost::any value);
void update_presetsctrl(wxDataViewTreeCtrl* ui, bool show_incompatible);
void load_key_value(const std::string& opt_key, const boost::any& value);
void reload_compatible_printers_widget();
void OnTreeSelChange(wxTreeEvent& event);
@ -161,13 +167,14 @@ public:
void update_changed_ui();
void update_full_options_list();
void update_sys_ui_after_sel_preset();
void get_sys_and_mod_flags(const std::string& opt_key, bool& sys_page, bool& modified_page);
void update_changed_tree_ui();
void update_undo_buttons();
void on_back_to_initial_value();
void on_back_to_sys_value();
PageShp add_options_page(wxString title, std::string icon, bool is_extruder_pages = false);
PageShp add_options_page(const wxString& title, const std::string& icon, bool is_extruder_pages = false);
virtual void OnActivate(){}
virtual void on_preset_loaded(){}
@ -176,10 +183,10 @@ public:
void load_initial_data();
void update_dirty();
void update_tab_ui();
void load_config(DynamicPrintConfig config);
void load_config(const DynamicPrintConfig& config);
virtual void reload_config();
Field* get_field(t_config_option_key opt_key, int opt_index = -1) const;
bool set_value(t_config_option_key opt_key, boost::any value);
Field* get_field(const t_config_option_key& opt_key, int opt_index = -1) const;
bool set_value(const t_config_option_key& opt_key, const boost::any& value);
wxSizer* description_line_widget(wxWindow* parent, ogStaticText** StaticText);
bool current_preset_is_dirty();
DynamicPrintConfig* get_config() { return m_config; }
@ -189,12 +196,13 @@ public:
}
std::vector<std::string> get_dependent_tabs() { return m_reload_dependent_tabs; }
void on_value_change(std::string opt_key, boost::any value);
void on_value_change(const std::string& opt_key, const boost::any& value);
protected:
void on_presets_changed();
void update_frequently_changed_parameters();
void update_wiping_button_visibility();
void update_tab_presets(wxComboCtrl* ui, bool show_incompatible);
};
//Slic3r::GUI::Tab::Print;
@ -265,7 +273,7 @@ public:
std::string m_chosen_name;
wxComboBox* m_combo;
void build(wxString title, std::string default_name, std::vector<std::string> &values);
void build(const wxString& title, const std::string& default_name, std::vector<std::string> &values);
void accept();
std::string get_name() { return m_chosen_name; }
};

View File

@ -109,3 +109,59 @@ void wxCheckListBoxComboPopup::OnListBoxSelection(wxCommandEvent& evt)
ProcessEvent(event);
}
}
// *** wxDataViewTreeCtrlComboPopup ***
const unsigned int wxDataViewTreeCtrlComboPopup::DefaultWidth = 270;
const unsigned int wxDataViewTreeCtrlComboPopup::DefaultHeight = 200;
const unsigned int wxDataViewTreeCtrlComboPopup::DefaultItemHeight = 22;
bool wxDataViewTreeCtrlComboPopup::Create(wxWindow* parent)
{
return wxDataViewTreeCtrl::Create(parent, wxID_ANY/*HIGHEST + 1*/, wxPoint(0, 0), wxDefaultSize/*wxSize(270, -1)*/, wxDV_NO_HEADER);
}
/*
wxSize wxDataViewTreeCtrlComboPopup::GetAdjustedSize(int minWidth, int prefHeight, int maxHeight)
{
// matches owner wxComboCtrl's width
// and sets height dinamically in dependence of contained items count
wxComboCtrl* cmb = GetComboCtrl();
if (cmb != nullptr)
{
wxSize size = GetComboCtrl()->GetSize();
if (m_cnt_open_items > 0)
size.SetHeight(m_cnt_open_items * DefaultItemHeight);
else
size.SetHeight(DefaultHeight);
return size;
}
else
return wxSize(DefaultWidth, DefaultHeight);
}
*/
void wxDataViewTreeCtrlComboPopup::OnKeyEvent(wxKeyEvent& evt)
{
// filters out all the keys which are not working properly
if (evt.GetKeyCode() == WXK_UP)
{
return;
}
else if (evt.GetKeyCode() == WXK_DOWN)
{
return;
}
else
{
evt.Skip();
return;
}
}
void wxDataViewTreeCtrlComboPopup::OnDataViewTreeCtrlSelection(wxCommandEvent& evt)
{
wxComboCtrl* cmb = GetComboCtrl();
auto selected = GetItemText(GetSelection());
cmb->SetText(selected);
}

View File

@ -3,6 +3,7 @@
#include <wx/checklst.h>
#include <wx/combo.h>
#include <wx/dataview.h>
class wxCheckListBoxComboPopup : public wxCheckListBox, public wxComboPopup
{
@ -25,4 +26,28 @@ public:
void OnListBoxSelection(wxCommandEvent& evt);
};
// *** wxDataViewTreeCtrlComboBox ***
class wxDataViewTreeCtrlComboPopup: public wxDataViewTreeCtrl, public wxComboPopup
{
static const unsigned int DefaultWidth;
static const unsigned int DefaultHeight;
static const unsigned int DefaultItemHeight;
wxString m_text;
int m_cnt_open_items{0};
public:
virtual bool Create(wxWindow* parent);
virtual wxWindow* GetControl() { return this; }
virtual void SetStringValue(const wxString& value) { m_text = value; }
virtual wxString GetStringValue() const { return m_text; }
// virtual wxSize GetAdjustedSize(int minWidth, int prefHeight, int maxHeight);
virtual void OnKeyEvent(wxKeyEvent& evt);
void OnDataViewTreeCtrlSelection(wxCommandEvent& evt);
void SetItemsCnt(int cnt) { m_cnt_open_items = cnt; }
};
#endif // slic3r_GUI_wxExtensions_hpp_