mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-10-26 18:21:18 -06:00
Merge remote-tracking branch 'origin/master' into ys_printable_property
This commit is contained in:
commit
885da35544
45 changed files with 1533 additions and 619 deletions
|
|
@ -106,6 +106,9 @@ void CopyrightsDialog::fill_entries()
|
|||
"2001-2016 Expat maintainers" , "http://www.libexpat.org/" },
|
||||
{ "AVRDUDE" , "2018 Free Software Foundation, Inc." , "http://savannah.nongnu.org/projects/avrdude" },
|
||||
{ "Shinyprofiler" , "2007-2010 Aidin Abedi" , "http://code.google.com/p/shinyprofiler/" },
|
||||
{ "Real-Time DXT1/DXT5 C compression library"
|
||||
, "Based on original by fabian \"ryg\" giesen v1.04. "
|
||||
"Custom version, modified by Yann Collet" , "https://github.com/Cyan4973/RygsDXTc" },
|
||||
{ "Icons for STL and GCODE files."
|
||||
, "Akira Yasuda" , "http://3dp0.com/icons-for-stl-and-gcode/" }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -136,6 +136,8 @@ bool Field::is_matched(const std::string& string, const std::string& pattern)
|
|||
return std::regex_match(string, regex_pattern);
|
||||
}
|
||||
|
||||
static wxString na_value() { return _(L("N/A")); }
|
||||
|
||||
void Field::get_value_by_opt_type(wxString& str)
|
||||
{
|
||||
switch (m_opt.type) {
|
||||
|
|
@ -165,7 +167,9 @@ void Field::get_value_by_opt_type(wxString& str)
|
|||
val = 0.0;
|
||||
else
|
||||
{
|
||||
if (!str.ToCDouble(&val))
|
||||
if (m_opt.nullable && str == na_value())
|
||||
val = ConfigOptionFloatsNullable::nil_value();
|
||||
else if (!str.ToCDouble(&val))
|
||||
{
|
||||
show_error(m_parent, _(L("Invalid numeric input.")));
|
||||
set_value(double_to_string(val), true);
|
||||
|
|
@ -256,6 +260,7 @@ void TextCtrl::BUILD() {
|
|||
m_opt.default_value->getFloat() :
|
||||
m_opt.get_default_value<ConfigOptionPercents>()->get_at(m_opt_idx);
|
||||
text_value = double_to_string(val);
|
||||
m_last_meaningful_value = text_value;
|
||||
break;
|
||||
}
|
||||
case coString:
|
||||
|
|
@ -325,24 +330,7 @@ void TextCtrl::BUILD() {
|
|||
}
|
||||
propagate_value();
|
||||
}), temp->GetId());
|
||||
/*
|
||||
temp->Bind(wxEVT_TEXT, ([this](wxCommandEvent& evt)
|
||||
{
|
||||
#ifdef __WXGTK__
|
||||
if (bChangedValueEvent)
|
||||
#endif //__WXGTK__
|
||||
if(is_defined_input_value())
|
||||
on_change_field();
|
||||
}), temp->GetId());
|
||||
|
||||
#ifdef __WXGTK__
|
||||
// to correct value updating on GTK we should:
|
||||
// call on_change_field() on wxEVT_KEY_UP instead of wxEVT_TEXT
|
||||
// and prevent value updating on wxEVT_KEY_DOWN
|
||||
temp->Bind(wxEVT_KEY_DOWN, &TextCtrl::change_field_value, this);
|
||||
temp->Bind(wxEVT_KEY_UP, &TextCtrl::change_field_value, this);
|
||||
#endif //__WXGTK__
|
||||
*/
|
||||
// select all text using Ctrl+A
|
||||
temp->Bind(wxEVT_CHAR, ([temp](wxKeyEvent& event)
|
||||
{
|
||||
|
|
@ -355,14 +343,70 @@ void TextCtrl::BUILD() {
|
|||
window = dynamic_cast<wxWindow*>(temp);
|
||||
}
|
||||
|
||||
bool TextCtrl::value_was_changed()
|
||||
{
|
||||
if (m_value.empty())
|
||||
return true;
|
||||
|
||||
boost::any val = m_value;
|
||||
wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue();
|
||||
// update m_value!
|
||||
get_value_by_opt_type(ret_str);
|
||||
|
||||
switch (m_opt.type) {
|
||||
case coInt:
|
||||
return boost::any_cast<int>(m_value) != boost::any_cast<int>(val);
|
||||
case coPercent:
|
||||
case coPercents:
|
||||
case coFloats:
|
||||
case coFloat: {
|
||||
if (m_opt.nullable && std::isnan(boost::any_cast<double>(m_value)) &&
|
||||
std::isnan(boost::any_cast<double>(val)))
|
||||
return false;
|
||||
return boost::any_cast<double>(m_value) != boost::any_cast<double>(val);
|
||||
}
|
||||
case coString:
|
||||
case coStrings:
|
||||
case coFloatOrPercent:
|
||||
return boost::any_cast<std::string>(m_value) != boost::any_cast<std::string>(val);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void TextCtrl::propagate_value()
|
||||
{
|
||||
if (is_defined_input_value<wxTextCtrl>(window, m_opt.type))
|
||||
if (is_defined_input_value<wxTextCtrl>(window, m_opt.type) && value_was_changed())
|
||||
on_change_field();
|
||||
else
|
||||
on_kill_focus();
|
||||
}
|
||||
|
||||
void TextCtrl::set_value(const boost::any& value, bool change_event/* = false*/) {
|
||||
m_disable_change_event = !change_event;
|
||||
if (m_opt.nullable) {
|
||||
const bool m_is_na_val = boost::any_cast<wxString>(value) == na_value();
|
||||
if (!m_is_na_val)
|
||||
m_last_meaningful_value = value;
|
||||
dynamic_cast<wxTextCtrl*>(window)->SetValue(m_is_na_val ? na_value() : boost::any_cast<wxString>(value));
|
||||
}
|
||||
else
|
||||
dynamic_cast<wxTextCtrl*>(window)->SetValue(boost::any_cast<wxString>(value));
|
||||
m_disable_change_event = false;
|
||||
}
|
||||
|
||||
void TextCtrl::set_last_meaningful_value()
|
||||
{
|
||||
dynamic_cast<wxTextCtrl*>(window)->SetValue(boost::any_cast<wxString>(m_last_meaningful_value));
|
||||
propagate_value();
|
||||
}
|
||||
|
||||
void TextCtrl::set_na_value()
|
||||
{
|
||||
dynamic_cast<wxTextCtrl*>(window)->SetValue(na_value());
|
||||
propagate_value();
|
||||
}
|
||||
|
||||
boost::any& TextCtrl::get_value()
|
||||
{
|
||||
wxString ret_str = static_cast<wxTextCtrl*>(window)->GetValue();
|
||||
|
|
@ -409,6 +453,8 @@ void CheckBox::BUILD() {
|
|||
m_opt.get_default_value<ConfigOptionBools>()->get_at(m_opt_idx) :
|
||||
false;
|
||||
|
||||
m_last_meaningful_value = static_cast<unsigned char>(check_value);
|
||||
|
||||
// Set Label as a string of at least one space simbol to correct system scaling of a CheckBox
|
||||
auto temp = new wxCheckBox(m_parent, wxID_ANY, wxString(" "), wxDefaultPosition, size);
|
||||
temp->SetFont(Slic3r::GUI::wxGetApp().normal_font());
|
||||
|
|
@ -416,7 +462,10 @@ void CheckBox::BUILD() {
|
|||
temp->SetValue(check_value);
|
||||
if (m_opt.readonly) temp->Disable();
|
||||
|
||||
temp->Bind(wxEVT_CHECKBOX, ([this](wxCommandEvent e) { on_change_field(); }), temp->GetId());
|
||||
temp->Bind(wxEVT_CHECKBOX, ([this](wxCommandEvent e) {
|
||||
m_is_na_val = false;
|
||||
on_change_field();
|
||||
}), temp->GetId());
|
||||
|
||||
temp->SetToolTip(get_tooltip_text(check_value ? "true" : "false"));
|
||||
|
||||
|
|
@ -424,6 +473,38 @@ void CheckBox::BUILD() {
|
|||
window = dynamic_cast<wxWindow*>(temp);
|
||||
}
|
||||
|
||||
void CheckBox::set_value(const boost::any& value, bool change_event)
|
||||
{
|
||||
m_disable_change_event = !change_event;
|
||||
if (m_opt.nullable) {
|
||||
m_is_na_val = boost::any_cast<unsigned char>(value) == ConfigOptionBoolsNullable::nil_value();
|
||||
if (!m_is_na_val)
|
||||
m_last_meaningful_value = value;
|
||||
dynamic_cast<wxCheckBox*>(window)->SetValue(m_is_na_val ? false : boost::any_cast<unsigned char>(value) != 0);
|
||||
}
|
||||
else
|
||||
dynamic_cast<wxCheckBox*>(window)->SetValue(boost::any_cast<bool>(value));
|
||||
m_disable_change_event = false;
|
||||
}
|
||||
|
||||
void CheckBox::set_last_meaningful_value()
|
||||
{
|
||||
if (m_opt.nullable) {
|
||||
m_is_na_val = false;
|
||||
dynamic_cast<wxCheckBox*>(window)->SetValue(boost::any_cast<unsigned char>(m_last_meaningful_value) != 0);
|
||||
on_change_field();
|
||||
}
|
||||
}
|
||||
|
||||
void CheckBox::set_na_value()
|
||||
{
|
||||
if (m_opt.nullable) {
|
||||
m_is_na_val = true;
|
||||
dynamic_cast<wxCheckBox*>(window)->SetValue(false);
|
||||
on_change_field();
|
||||
}
|
||||
}
|
||||
|
||||
boost::any& CheckBox::get_value()
|
||||
{
|
||||
// boost::any m_value;
|
||||
|
|
@ -431,7 +512,7 @@ boost::any& CheckBox::get_value()
|
|||
if (m_opt.type == coBool)
|
||||
m_value = static_cast<bool>(value);
|
||||
else
|
||||
m_value = static_cast<unsigned char>(value);
|
||||
m_value = m_is_na_val ? ConfigOptionBoolsNullable::nil_value() : static_cast<unsigned char>(value);
|
||||
return m_value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -123,6 +123,8 @@ public:
|
|||
/// subclasses should overload with a specific version
|
||||
/// Postcondition: Method does not fire the on_change event.
|
||||
virtual void set_value(const boost::any& value, bool change_event) = 0;
|
||||
virtual void set_last_meaningful_value() {}
|
||||
virtual void set_na_value() {}
|
||||
|
||||
/// Gets a boost::any representing this control.
|
||||
/// subclasses should overload with a specific version
|
||||
|
|
@ -247,6 +249,8 @@ protected:
|
|||
|
||||
// current value
|
||||
boost::any m_value;
|
||||
// last maeningful value
|
||||
boost::any m_last_meaningful_value;
|
||||
|
||||
int m_em_unit;
|
||||
|
||||
|
|
@ -277,6 +281,7 @@ public:
|
|||
~TextCtrl() {}
|
||||
|
||||
void BUILD();
|
||||
bool value_was_changed();
|
||||
// Propagate value from field to the OptionGroupe and Config after kill_focus/ENTER
|
||||
void propagate_value();
|
||||
wxWindow* window {nullptr};
|
||||
|
|
@ -286,11 +291,9 @@ public:
|
|||
dynamic_cast<wxTextCtrl*>(window)->SetValue(wxString(value));
|
||||
m_disable_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;
|
||||
}
|
||||
virtual void set_value(const boost::any& value, bool change_event = false) override;
|
||||
virtual void set_last_meaningful_value() override;
|
||||
virtual void set_na_value() override;
|
||||
|
||||
boost::any& get_value() override;
|
||||
|
||||
|
|
@ -303,6 +306,7 @@ public:
|
|||
|
||||
class CheckBox : public Field {
|
||||
using Field::Field;
|
||||
bool m_is_na_val {false};
|
||||
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) {}
|
||||
|
|
@ -316,11 +320,9 @@ public:
|
|||
dynamic_cast<wxCheckBox*>(window)->SetValue(value);
|
||||
m_disable_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;
|
||||
}
|
||||
void set_value(const boost::any& value, bool change_event = false) override;
|
||||
void set_last_meaningful_value() override;
|
||||
void set_na_value() override;
|
||||
boost::any& get_value() override;
|
||||
|
||||
void msw_rescale() override;
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@ namespace GUI {
|
|||
|
||||
void GLTexture::Compressor::reset()
|
||||
{
|
||||
// force compression completion, if any
|
||||
m_abort_compressing = true;
|
||||
// wait for compression completion, if any
|
||||
while (m_is_compressing) {}
|
||||
if (m_is_compressing)
|
||||
{
|
||||
// force compression completion, if any
|
||||
m_abort_compressing = true;
|
||||
// wait for compression completion, if any
|
||||
while (m_is_compressing) {}
|
||||
}
|
||||
|
||||
m_levels.clear();
|
||||
}
|
||||
|
|
@ -42,8 +45,6 @@ void GLTexture::Compressor::add_level(unsigned int w, unsigned int h, const std:
|
|||
|
||||
void GLTexture::Compressor::start_compressing()
|
||||
{
|
||||
m_is_compressing = true;
|
||||
m_abort_compressing = false;
|
||||
std::thread t(&GLTexture::Compressor::compress, this);
|
||||
t.detach();
|
||||
}
|
||||
|
|
@ -97,6 +98,9 @@ void GLTexture::Compressor::compress()
|
|||
{
|
||||
// reference: https://github.com/Cyan4973/RygsDXTc
|
||||
|
||||
m_is_compressing = true;
|
||||
m_abort_compressing = false;
|
||||
|
||||
for (Level& level : m_levels)
|
||||
{
|
||||
if (m_abort_compressing)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace GUI {
|
|||
|
||||
public:
|
||||
explicit Compressor(GLTexture& texture) : m_texture(texture), m_is_compressing(false), m_abort_compressing(false) {}
|
||||
~Compressor() { reset(); }
|
||||
|
||||
void reset();
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,13 @@ void config_wizard(int reason)
|
|||
void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt_key, const boost::any& value, int opt_index /*= 0*/)
|
||||
{
|
||||
try{
|
||||
|
||||
if (config.def()->get(opt_key)->type == coBools && config.def()->get(opt_key)->nullable) {
|
||||
ConfigOptionBoolsNullable* vec_new = new ConfigOptionBoolsNullable{ boost::any_cast<unsigned char>(value) };
|
||||
config.option<ConfigOptionBoolsNullable>(opt_key)->set_at(vec_new, opt_index, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (config.def()->get(opt_key)->type) {
|
||||
case coFloatOrPercent:{
|
||||
std::string str = boost::any_cast<std::string>(value);
|
||||
|
|
|
|||
|
|
@ -2843,7 +2843,7 @@ void ObjectList::update_selections_on_canvas()
|
|||
else
|
||||
{
|
||||
mode = Selection::Instance;
|
||||
single_selection = false;
|
||||
single_selection &= (obj_idx != selection.get_object_idx());
|
||||
std::vector<unsigned int> idxs = selection.get_volume_idxs_from_object(obj_idx);
|
||||
volume_idxs.insert(volume_idxs.end(), idxs.begin(), idxs.end());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
wxSize btn_size(em_unit(parent) * mirror_btn_width, em_unit(parent) * mirror_btn_width);
|
||||
auto btn = new ScalableButton(parent, wxID_ANY, "mirroring_off", wxEmptyString, btn_size, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER | wxTRANSPARENT_WINDOW);
|
||||
btn->SetToolTip(wxString::Format(_(L("Toggle %c axis mirroring")), (int)label));
|
||||
btn->SetBitmapDisabled_(m_mirror_bitmap_hidden);
|
||||
|
||||
m_mirror_buttons[axis_idx].first = btn;
|
||||
m_mirror_buttons[axis_idx].second = mbShown;
|
||||
|
|
@ -286,6 +287,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
sizer->Add(btn, wxBU_EXACTFIT);
|
||||
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &e) {
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Reset scale")));
|
||||
change_scale_value(0, 100.);
|
||||
change_scale_value(1, 100.);
|
||||
change_scale_value(2, 100.);
|
||||
|
|
@ -323,7 +325,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
selection.synchronize_unselected_instances(Selection::SYNC_ROTATION_GENERAL);
|
||||
selection.synchronize_unselected_volumes();
|
||||
// Copy rotation values from GLVolumes into Model (ModelInstance / ModelVolume), trigger background processing.
|
||||
canvas->do_rotate(L("Set Rotation"));
|
||||
canvas->do_rotate(L("Reset Rotation"));
|
||||
|
||||
UpdateAndShow(true);
|
||||
});
|
||||
|
|
@ -350,6 +352,7 @@ ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
|||
const Geometry::Transformation& instance_trafo = volume->get_instance_transformation();
|
||||
Vec3d diff = m_cache.position - instance_trafo.get_matrix(true).inverse() * Vec3d(0., 0., get_volume_min_z(volume));
|
||||
|
||||
Plater::TakeSnapshot snapshot(wxGetApp().plater(), _(L("Drop to bed")));
|
||||
change_position_value(0, diff.x());
|
||||
change_position_value(1, diff.y());
|
||||
change_position_value(2, diff.z());
|
||||
|
|
@ -646,13 +649,13 @@ void ObjectManipulation::update_mirror_buttons_visibility()
|
|||
wxGetApp().CallAfter([this, new_states]{
|
||||
for (int i=0; i<3; ++i) {
|
||||
if (new_states[i] != m_mirror_buttons[i].second) {
|
||||
const wxBitmap* bmp;
|
||||
const ScalableBitmap* bmp;
|
||||
switch (new_states[i]) {
|
||||
case mbHidden : bmp = &m_mirror_bitmap_hidden.bmp(); m_mirror_buttons[i].first->Enable(false); break;
|
||||
case mbShown : bmp = &m_mirror_bitmap_off.bmp(); m_mirror_buttons[i].first->Enable(true); break;
|
||||
case mbActive : bmp = &m_mirror_bitmap_on.bmp(); m_mirror_buttons[i].first->Enable(true); break;
|
||||
case mbHidden : bmp = &m_mirror_bitmap_hidden; m_mirror_buttons[i].first->Enable(false); break;
|
||||
case mbShown : bmp = &m_mirror_bitmap_off; m_mirror_buttons[i].first->Enable(true); break;
|
||||
case mbActive : bmp = &m_mirror_bitmap_on; m_mirror_buttons[i].first->Enable(true); break;
|
||||
}
|
||||
m_mirror_buttons[i].first->SetBitmap(*bmp);
|
||||
m_mirror_buttons[i].first->SetBitmap_(*bmp);
|
||||
m_mirror_buttons[i].second = new_states[i];
|
||||
}
|
||||
}
|
||||
|
|
@ -925,6 +928,9 @@ void ObjectManipulation::msw_rescale()
|
|||
m_reset_rotation_button->msw_rescale();
|
||||
m_drop_to_bed_button->msw_rescale();
|
||||
|
||||
for (int id = 0; id < 3; ++id)
|
||||
m_mirror_buttons[id].first->msw_rescale();
|
||||
|
||||
get_og()->msw_rescale();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -900,6 +900,10 @@ RENDER_AGAIN:
|
|||
ImGui::SameLine(diameter_slider_left);
|
||||
ImGui::PushItemWidth(window_width - diameter_slider_left);
|
||||
|
||||
// Following is a nasty way to:
|
||||
// - save the initial value of the slider before one starts messing with it
|
||||
// - keep updating the head radius during sliding so it is continuosly refreshed in 3D scene
|
||||
// - take correct undo/redo snapshot after the user is done with moving the slider
|
||||
float initial_value = m_new_point_head_diameter;
|
||||
ImGui::SliderFloat("", &m_new_point_head_diameter, 0.1f, diameter_upper_cap, "%.1f");
|
||||
if (ImGui::IsItemClicked()) {
|
||||
|
|
@ -960,20 +964,35 @@ RENDER_AGAIN:
|
|||
float density = static_cast<const ConfigOptionInt*>(opts[0])->value;
|
||||
float minimal_point_distance = static_cast<const ConfigOptionFloat*>(opts[1])->value;
|
||||
|
||||
bool value_changed = ImGui::SliderFloat("", &minimal_point_distance, 0.f, 20.f, "%.f mm");
|
||||
if (value_changed)
|
||||
m_model_object->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = minimal_point_distance;
|
||||
ImGui::SliderFloat("", &minimal_point_distance, 0.f, 20.f, "%.f mm");
|
||||
bool slider_clicked = ImGui::IsItemClicked(); // someone clicked the slider
|
||||
bool slider_edited = ImGui::IsItemEdited(); // someone is dragging the slider
|
||||
bool slider_released = ImGui::IsItemDeactivatedAfterEdit(); // someone has just released the slider
|
||||
|
||||
m_imgui->text(m_desc.at("points_density"));
|
||||
ImGui::SameLine(settings_sliders_left);
|
||||
|
||||
if (ImGui::SliderFloat(" ", &density, 0.f, 200.f, "%.f %%")) {
|
||||
value_changed = true;
|
||||
ImGui::SliderFloat(" ", &density, 0.f, 200.f, "%.f %%");
|
||||
slider_clicked |= ImGui::IsItemClicked();
|
||||
slider_edited |= ImGui::IsItemEdited();
|
||||
slider_released |= ImGui::IsItemDeactivatedAfterEdit();
|
||||
|
||||
if (slider_clicked) { // stash the values of the settings so we know what to revert to after undo
|
||||
m_minimal_point_distance_stash = minimal_point_distance;
|
||||
m_density_stash = density;
|
||||
}
|
||||
if (slider_edited) {
|
||||
m_model_object->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = minimal_point_distance;
|
||||
m_model_object->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)density;
|
||||
}
|
||||
|
||||
if (value_changed) // Update side panel
|
||||
if (slider_released) {
|
||||
m_model_object->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = m_minimal_point_distance_stash;
|
||||
m_model_object->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)m_density_stash;
|
||||
wxGetApp().plater()->take_snapshot(_(L("Support parameter change")));
|
||||
m_model_object->config.opt<ConfigOptionFloat>("support_points_minimal_distance", true)->value = minimal_point_distance;
|
||||
m_model_object->config.opt<ConfigOptionInt>("support_points_density_relative", true)->value = (int)density;
|
||||
wxGetApp().obj_list()->update_and_show_object_settings_item();
|
||||
}
|
||||
|
||||
bool generate = m_imgui->button(m_desc.at("auto_generate"));
|
||||
|
||||
|
|
|
|||
|
|
@ -107,7 +107,8 @@ private:
|
|||
float m_new_point_head_diameter; // Size of a new point.
|
||||
CacheEntry m_point_before_drag; // undo/redo - so we know what state was edited
|
||||
float m_old_point_head_diameter = 0.; // the same
|
||||
float m_minimal_point_distance = 20.f;
|
||||
float m_minimal_point_distance_stash = 0.f; // and again
|
||||
float m_density_stash = 0.f; // and again
|
||||
mutable std::vector<CacheEntry> m_editing_cache; // a support point and whether it is currently selected
|
||||
std::vector<sla::SupportPoint> m_normal_cache; // to restore after discarding changes or undo/redo
|
||||
|
||||
|
|
|
|||
|
|
@ -108,11 +108,15 @@ public:
|
|||
ar(m_current);
|
||||
|
||||
GLGizmoBase* curr = get_current();
|
||||
if (curr != nullptr)
|
||||
{
|
||||
curr->set_state(GLGizmoBase::On);
|
||||
curr->load(ar);
|
||||
}
|
||||
for (GizmosMap::const_iterator it = m_gizmos.begin(); it != m_gizmos.end(); ++it) {
|
||||
GLGizmoBase* gizmo = it->second;
|
||||
if (gizmo != nullptr) {
|
||||
gizmo->set_hover_id(-1);
|
||||
gizmo->set_state((it->second == curr) ? GLGizmoBase::On : GLGizmoBase::Off);
|
||||
if (gizmo == curr)
|
||||
gizmo->load(ar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
|
|
|
|||
|
|
@ -411,6 +411,7 @@ void MainFrame::init_menubar()
|
|||
}, wxID_FILE1, wxID_FILE9);
|
||||
|
||||
std::vector<std::string> recent_projects = wxGetApp().app_config->get_recent_projects();
|
||||
std::reverse(recent_projects.begin(), recent_projects.end());
|
||||
for (const std::string& project : recent_projects)
|
||||
{
|
||||
m_recent_projects.AddFileToHistory(from_u8(project));
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ void OptionsGroup::append_line(const Line& line, wxStaticText** full_Label/* = n
|
|||
// so we need a horizontal sizer to arrange these things
|
||||
auto sizer = new wxBoxSizer(wxHORIZONTAL);
|
||||
grid_sizer->Add(sizer, 0, wxEXPAND | (staticbox ? wxALL : wxBOTTOM | wxTOP | wxLEFT), staticbox ? 0 : 1);
|
||||
sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT, 7);
|
||||
sizer->Add(m_near_label_widget_ptrs.back(), 0, wxRIGHT | wxALIGN_CENTER_VERTICAL, 7);
|
||||
sizer->Add(label, 0, (staticbox ? 0 : wxALIGN_RIGHT | wxRIGHT) | wxALIGN_CENTER_VERTICAL, 5);
|
||||
}
|
||||
}
|
||||
|
|
@ -372,30 +372,10 @@ void ConfigOptionsGroup::on_change_OG(const t_config_option_key& opt_id, const b
|
|||
|
||||
auto option = m_options.at(opt_id).opt;
|
||||
|
||||
// get value
|
||||
//! auto field_value = get_value(opt_id);
|
||||
if (option.gui_flags.compare("serialized")==0) {
|
||||
if (opt_index != -1) {
|
||||
// die "Can't set serialized option indexed value" ;
|
||||
}
|
||||
change_opt_value(*m_config, opt_key, value);
|
||||
}
|
||||
else {
|
||||
if (opt_index == -1) {
|
||||
// change_opt_value(*m_config, opt_key, field_value);
|
||||
//!? why field_value?? in this case changed value will be lose! No?
|
||||
change_opt_value(*m_config, opt_key, value);
|
||||
}
|
||||
else {
|
||||
change_opt_value(*m_config, opt_key, value, opt_index);
|
||||
// auto value = m_config->get($opt_key);
|
||||
// $value->[$opt_index] = $field_value;
|
||||
// $self->config->set($opt_key, $value);
|
||||
}
|
||||
}
|
||||
change_opt_value(*m_config, opt_key, value, opt_index == -1 ? 0 : opt_index);
|
||||
}
|
||||
|
||||
OptionsGroup::on_change_OG(opt_id, value); //!? Why doing this
|
||||
OptionsGroup::on_change_OG(opt_id, value);
|
||||
}
|
||||
|
||||
void ConfigOptionsGroup::back_to_initial_value(const std::string& opt_key)
|
||||
|
|
@ -578,6 +558,34 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
|||
boost::any ret;
|
||||
wxString text_value = wxString("");
|
||||
const ConfigOptionDef* opt = config.def()->get(opt_key);
|
||||
|
||||
if (opt->nullable)
|
||||
{
|
||||
switch (opt->type)
|
||||
{
|
||||
case coPercents:
|
||||
case coFloats: {
|
||||
if (config.option(opt_key)->is_nil())
|
||||
ret = _(L("N/A"));
|
||||
else {
|
||||
double val = opt->type == coFloats ?
|
||||
config.option<ConfigOptionFloatsNullable>(opt_key)->get_at(idx) :
|
||||
config.option<ConfigOptionPercentsNullable>(opt_key)->get_at(idx);
|
||||
ret = double_to_string(val); }
|
||||
}
|
||||
break;
|
||||
case coBools:
|
||||
ret = config.option<ConfigOptionBoolsNullable>(opt_key)->values[idx];
|
||||
break;
|
||||
case coInts:
|
||||
ret = config.option<ConfigOptionIntsNullable>(opt_key)->get_at(idx);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
switch (opt->type) {
|
||||
case coFloatOrPercent:{
|
||||
const auto &value = *config.option<ConfigOptionFloatOrPercent>(opt_key);
|
||||
|
|
|
|||
|
|
@ -252,6 +252,9 @@ public:
|
|||
Option option = get_option(title, idx);
|
||||
return OptionsGroup::create_single_option_line(option);
|
||||
}
|
||||
Line create_single_option_line(const Option& option) const {
|
||||
return OptionsGroup::create_single_option_line(option);
|
||||
}
|
||||
void append_single_option_line(const Option& option) {
|
||||
OptionsGroup::append_single_option_line(option);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4406,6 +4406,12 @@ void Plater::reslice()
|
|||
{
|
||||
// Stop arrange and (or) optimize rotation tasks.
|
||||
this->stop_jobs();
|
||||
|
||||
if (printer_technology() == ptSLA) {
|
||||
for (auto& object : model().objects)
|
||||
if (object->sla_points_status == sla::PointsStatus::NoPoints)
|
||||
object->sla_points_status = sla::PointsStatus::Generating;
|
||||
}
|
||||
|
||||
//FIXME Don't reslice if export of G-code or sending to OctoPrint is running.
|
||||
// bitmask of UpdateBackgroundProcessReturnState
|
||||
|
|
|
|||
|
|
@ -400,6 +400,10 @@ const std::vector<std::string>& Preset::filament_options()
|
|||
"temperature", "first_layer_temperature", "bed_temperature", "first_layer_bed_temperature", "fan_always_on", "cooling", "min_fan_speed",
|
||||
"max_fan_speed", "bridge_fan_speed", "disable_fan_first_layers", "fan_below_layer_time", "slowdown_below_layer_time", "min_print_speed",
|
||||
"start_filament_gcode", "end_filament_gcode",
|
||||
// Retract overrides
|
||||
"filament_retract_length", "filament_retract_lift", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_speed", "filament_deretract_speed", "filament_retract_restart_extra", "filament_retract_before_travel",
|
||||
"filament_retract_layer_change", "filament_wipe", "filament_retract_before_wipe",
|
||||
// Profile compatibility
|
||||
"compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits"
|
||||
};
|
||||
return s_opts;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ PresetBundle::PresetBundle() :
|
|||
this->filaments.default_preset().config.option<ConfigOptionStrings>("filament_settings_id", true)->values = { "" };
|
||||
this->filaments.default_preset().compatible_printers_condition();
|
||||
this->filaments.default_preset().inherits();
|
||||
// Set all the nullable values to nils.
|
||||
this->filaments.default_preset().config.null_nullables();
|
||||
|
||||
this->sla_materials.default_preset().config.optptr("sla_material_settings_id", true);
|
||||
this->sla_materials.default_preset().compatible_printers_condition();
|
||||
|
|
|
|||
|
|
@ -1497,6 +1497,105 @@ void TabPrint::OnActivate()
|
|||
Tab::OnActivate();
|
||||
}
|
||||
|
||||
void TabFilament::add_filament_overrides_page()
|
||||
{
|
||||
PageShp page = add_options_page(_(L("Filament Overrides")), "wrench");
|
||||
ConfigOptionsGroupShp optgroup = page->new_optgroup(_(L("Retraction")));
|
||||
|
||||
auto append_single_option_line = [optgroup, this](const std::string& opt_key, int opt_index)
|
||||
{
|
||||
Line line {"",""};
|
||||
if (opt_key == "filament_retract_lift_above" || opt_key == "filament_retract_lift_below") {
|
||||
Option opt = optgroup->get_option(opt_key);
|
||||
opt.opt.label = opt.opt.full_label;
|
||||
line = optgroup->create_single_option_line(opt);
|
||||
}
|
||||
else
|
||||
line = optgroup->create_single_option_line(optgroup->get_option(opt_key));
|
||||
|
||||
line.near_label_widget = [this, optgroup, opt_key, opt_index](wxWindow* parent) {
|
||||
wxCheckBox* check_box = new wxCheckBox(parent, wxID_ANY, "");
|
||||
|
||||
check_box->Bind(wxEVT_CHECKBOX, [this, optgroup, opt_key, opt_index](wxCommandEvent& evt) {
|
||||
const bool is_checked = evt.IsChecked();
|
||||
Field* field = optgroup->get_fieldc(opt_key, opt_index);
|
||||
if (field != nullptr) {
|
||||
field->toggle(is_checked);
|
||||
if (is_checked)
|
||||
field->set_last_meaningful_value();
|
||||
else
|
||||
field->set_na_value();
|
||||
}
|
||||
}, check_box->GetId());
|
||||
|
||||
m_overrides_options[opt_key] = check_box;
|
||||
return check_box;
|
||||
};
|
||||
|
||||
optgroup->append_line(line);
|
||||
};
|
||||
|
||||
const int extruder_idx = 0; // #ys_FIXME
|
||||
|
||||
for (const std::string opt_key : { "filament_retract_length",
|
||||
"filament_retract_lift",
|
||||
"filament_retract_lift_above",
|
||||
"filament_retract_lift_below",
|
||||
"filament_retract_speed",
|
||||
"filament_deretract_speed",
|
||||
"filament_retract_restart_extra",
|
||||
"filament_retract_before_travel",
|
||||
"filament_retract_layer_change",
|
||||
"filament_wipe",
|
||||
"filament_retract_before_wipe"
|
||||
})
|
||||
append_single_option_line(opt_key, extruder_idx);
|
||||
}
|
||||
|
||||
void TabFilament::update_filament_overrides_page()
|
||||
{
|
||||
const auto page_it = std::find_if(m_pages.begin(), m_pages.end(), [](const PageShp page) {return page->title() == _(L("Filament Overrides")); });
|
||||
if (page_it == m_pages.end())
|
||||
return;
|
||||
PageShp page = *page_it;
|
||||
|
||||
const auto og_it = std::find_if(page->m_optgroups.begin(), page->m_optgroups.end(), [](const ConfigOptionsGroupShp og) {return og->title == _(L("Retraction")); });
|
||||
if (og_it == page->m_optgroups.end())
|
||||
return;
|
||||
ConfigOptionsGroupShp optgroup = *og_it;
|
||||
|
||||
std::vector<std::string> opt_keys = { "filament_retract_length",
|
||||
"filament_retract_lift",
|
||||
"filament_retract_lift_above",
|
||||
"filament_retract_lift_below",
|
||||
"filament_retract_speed",
|
||||
"filament_deretract_speed",
|
||||
"filament_retract_restart_extra",
|
||||
"filament_retract_before_travel",
|
||||
"filament_retract_layer_change",
|
||||
"filament_wipe",
|
||||
"filament_retract_before_wipe"
|
||||
};
|
||||
|
||||
const int extruder_idx = 0; // #ys_FIXME
|
||||
|
||||
const bool have_retract_length = m_config->option("filament_retract_length")->is_nil() ||
|
||||
m_config->opt_float("filament_retract_length", extruder_idx) > 0;
|
||||
|
||||
for (const std::string& opt_key : opt_keys)
|
||||
{
|
||||
bool is_checked = opt_key=="filament_retract_length" ? true : have_retract_length;
|
||||
m_overrides_options[opt_key]->Enable(is_checked);
|
||||
|
||||
is_checked &= !m_config->option(opt_key)->is_nil();
|
||||
m_overrides_options[opt_key]->SetValue(is_checked);
|
||||
|
||||
Field* field = optgroup->get_fieldc(opt_key, extruder_idx);
|
||||
if (field != nullptr)
|
||||
field->toggle(is_checked);
|
||||
}
|
||||
}
|
||||
|
||||
void TabFilament::build()
|
||||
{
|
||||
m_presets = &m_preset_bundle->filaments;
|
||||
|
|
@ -1594,10 +1693,14 @@ void TabFilament::build()
|
|||
};
|
||||
optgroup->append_line(line);
|
||||
|
||||
|
||||
add_filament_overrides_page();
|
||||
|
||||
|
||||
const int gcode_field_height = 15; // 150
|
||||
const int notes_field_height = 25; // 250
|
||||
|
||||
page = add_options_page(_(L("Custom G-code")), "cog");
|
||||
page = add_options_page(_(L("Custom G-code")), "cog");
|
||||
optgroup = page->new_optgroup(_(L("Start G-code")), 0);
|
||||
Option option = optgroup->get_option("start_filament_gcode");
|
||||
option.opt.full_width = true;
|
||||
|
|
@ -1661,7 +1764,7 @@ void TabFilament::update()
|
|||
return; // ys_FIXME
|
||||
|
||||
m_update_cnt++;
|
||||
// Freeze();
|
||||
|
||||
wxString text = from_u8(PresetHints::cooling_description(m_presets->get_edited_preset()));
|
||||
m_cooling_description_line->SetText(text);
|
||||
text = from_u8(PresetHints::maximum_volumetric_flow_description(*m_preset_bundle));
|
||||
|
|
@ -1676,7 +1779,9 @@ void TabFilament::update()
|
|||
|
||||
for (auto el : { "min_fan_speed", "disable_fan_first_layers" })
|
||||
get_field(el)->toggle(fan_always_on);
|
||||
// Thaw();
|
||||
|
||||
update_filament_overrides_page();
|
||||
|
||||
m_update_cnt--;
|
||||
|
||||
if (m_update_cnt == 0)
|
||||
|
|
|
|||
|
|
@ -337,6 +337,11 @@ class TabFilament : public Tab
|
|||
{
|
||||
ogStaticText* m_volumetric_speed_description_line;
|
||||
ogStaticText* m_cooling_description_line;
|
||||
|
||||
void add_filament_overrides_page();
|
||||
void update_filament_overrides_page();
|
||||
|
||||
std::map<std::string, wxCheckBox*> m_overrides_options;
|
||||
public:
|
||||
TabFilament(wxNotebook* parent) :
|
||||
// Tab(parent, _(L("Filament Settings")), L("filament")) {}
|
||||
|
|
|
|||
|
|
@ -513,6 +513,15 @@ ObjectDataViewModelNode::ObjectDataViewModelNode(ObjectDataViewModelNode* parent
|
|||
init_container();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool ObjectDataViewModelNode::valid()
|
||||
{
|
||||
// Verify that the object was not deleted yet.
|
||||
assert(m_idx >= -1);
|
||||
return m_idx >= -1;
|
||||
}
|
||||
#endif /* NDEBUG */
|
||||
|
||||
void ObjectDataViewModelNode::set_action_icon()
|
||||
{
|
||||
m_action_icon_name = m_type & itObject ? "advanced_plus" :
|
||||
|
|
@ -1457,6 +1466,7 @@ wxDataViewItem ObjectDataViewModel::GetParent(const wxDataViewItem &item) const
|
|||
return wxDataViewItem(0);
|
||||
|
||||
ObjectDataViewModelNode *node = (ObjectDataViewModelNode*)item.GetID();
|
||||
assert(node != nullptr && node->valid());
|
||||
|
||||
// objects nodes has no parent too
|
||||
if (node->m_type == itObject)
|
||||
|
|
@ -2783,21 +2793,20 @@ LockButton::LockButton( wxWindow *parent,
|
|||
const wxSize& size /*= wxDefaultSize*/):
|
||||
wxButton(parent, id, wxEmptyString, pos, size, wxBU_EXACTFIT | wxNO_BORDER)
|
||||
{
|
||||
m_bmp_lock_on = ScalableBitmap(this, "one_layer_lock_on.png");
|
||||
m_bmp_lock_off = ScalableBitmap(this, "one_layer_lock_off.png");
|
||||
m_bmp_unlock_on = ScalableBitmap(this, "one_layer_unlock_on.png");
|
||||
m_bmp_unlock_off = ScalableBitmap(this, "one_layer_unlock_off.png");
|
||||
m_bmp_lock_closed = ScalableBitmap(this, "lock_closed");
|
||||
m_bmp_lock_closed_f = ScalableBitmap(this, "lock_closed_f");
|
||||
m_bmp_lock_open = ScalableBitmap(this, "lock_open");
|
||||
m_bmp_lock_open_f = ScalableBitmap(this, "lock_open_f");
|
||||
|
||||
#ifdef __WXMSW__
|
||||
SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
|
||||
#endif // __WXMSW__
|
||||
SetBitmap(m_bmp_unlock_on.bmp());
|
||||
SetBitmapDisabled(m_bmp_lock_on.bmp());
|
||||
SetBitmap(m_bmp_lock_open.bmp());
|
||||
SetBitmapDisabled(m_bmp_lock_open.bmp());
|
||||
SetBitmapHover(m_bmp_lock_closed_f.bmp());
|
||||
|
||||
//button events
|
||||
Bind(wxEVT_BUTTON, &LockButton::OnButton, this);
|
||||
Bind(wxEVT_ENTER_WINDOW, &LockButton::OnEnterBtn, this);
|
||||
Bind(wxEVT_LEAVE_WINDOW, &LockButton::OnLeaveBtn, this);
|
||||
Bind(wxEVT_BUTTON, &LockButton::OnButton, this);
|
||||
}
|
||||
|
||||
void LockButton::OnButton(wxCommandEvent& event)
|
||||
|
|
@ -2806,7 +2815,7 @@ void LockButton::OnButton(wxCommandEvent& event)
|
|||
return;
|
||||
|
||||
m_is_pushed = !m_is_pushed;
|
||||
enter_button(true);
|
||||
update_button_bitmaps();
|
||||
|
||||
event.Skip();
|
||||
}
|
||||
|
|
@ -2814,23 +2823,21 @@ void LockButton::OnButton(wxCommandEvent& event)
|
|||
void LockButton::SetLock(bool lock)
|
||||
{
|
||||
m_is_pushed = lock;
|
||||
enter_button(true);
|
||||
update_button_bitmaps();
|
||||
}
|
||||
|
||||
void LockButton::msw_rescale()
|
||||
{
|
||||
m_bmp_lock_on .msw_rescale();
|
||||
m_bmp_lock_off .msw_rescale();
|
||||
m_bmp_unlock_on .msw_rescale();
|
||||
m_bmp_unlock_off.msw_rescale();
|
||||
m_bmp_lock_closed.msw_rescale();
|
||||
m_bmp_lock_closed_f.msw_rescale();
|
||||
m_bmp_lock_open.msw_rescale();
|
||||
m_bmp_lock_open_f.msw_rescale();
|
||||
}
|
||||
|
||||
void LockButton::enter_button(const bool enter)
|
||||
void LockButton::update_button_bitmaps()
|
||||
{
|
||||
const wxBitmap& icon = m_is_pushed ?
|
||||
enter ? m_bmp_lock_off.bmp() : m_bmp_lock_on.bmp() :
|
||||
enter ? m_bmp_unlock_off.bmp() : m_bmp_unlock_on.bmp();
|
||||
SetBitmap(icon);
|
||||
SetBitmap(m_is_pushed ? m_bmp_lock_closed.bmp() : m_bmp_lock_open.bmp());
|
||||
SetBitmapHover(m_is_pushed ? m_bmp_lock_closed_f.bmp() : m_bmp_lock_open_f.bmp());
|
||||
|
||||
Refresh();
|
||||
Update();
|
||||
|
|
@ -2999,6 +3006,13 @@ ScalableButton::ScalableButton( wxWindow * parent,
|
|||
#endif // __WXMSW__
|
||||
|
||||
SetBitmap(create_scaled_bitmap(parent, icon_name));
|
||||
|
||||
if (size != wxDefaultSize)
|
||||
{
|
||||
const int em = em_unit(parent);
|
||||
m_width = size.x/em;
|
||||
m_height= size.y/em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3025,11 +3039,24 @@ void ScalableButton::SetBitmap_(const ScalableBitmap& bmp)
|
|||
m_current_icon_name = bmp.name();
|
||||
}
|
||||
|
||||
void ScalableButton::SetBitmapDisabled_(const ScalableBitmap& bmp)
|
||||
{
|
||||
SetBitmapDisabled(bmp.bmp());
|
||||
m_disabled_icon_name = bmp.name();
|
||||
}
|
||||
|
||||
void ScalableButton::msw_rescale()
|
||||
{
|
||||
const wxBitmap bmp = create_scaled_bitmap(m_parent, m_current_icon_name);
|
||||
SetBitmap(create_scaled_bitmap(m_parent, m_current_icon_name));
|
||||
if (!m_disabled_icon_name.empty())
|
||||
SetBitmapDisabled(create_scaled_bitmap(m_parent, m_disabled_icon_name));
|
||||
|
||||
SetBitmap(bmp);
|
||||
if (m_width > 0 || m_height>0)
|
||||
{
|
||||
const int em = em_unit(m_parent);
|
||||
wxSize size(m_width * em, m_height * em);
|
||||
SetMinSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ DECLARE_VARIANT_OBJECT(DataViewBitmapText)
|
|||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// ObjectDataViewModelNode: a node inside PrusaObjectDataViewModel
|
||||
// ObjectDataViewModelNode: a node inside ObjectDataViewModel
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
enum ItemType {
|
||||
|
|
@ -259,6 +259,10 @@ public:
|
|||
ObjectDataViewModelNode *child = m_children[i];
|
||||
delete child;
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
// Indicate that the object was deleted.
|
||||
m_idx = -2;
|
||||
#endif /* NDEBUG */
|
||||
}
|
||||
|
||||
void init_container();
|
||||
|
|
@ -269,6 +273,7 @@ public:
|
|||
|
||||
ObjectDataViewModelNode* GetParent()
|
||||
{
|
||||
assert(m_parent == nullptr || m_parent->valid());
|
||||
return m_parent;
|
||||
}
|
||||
MyObjectTreeModelNodePtrArray& GetChildren()
|
||||
|
|
@ -357,6 +362,11 @@ public:
|
|||
bool update_settings_digest(const std::vector<std::string>& categories);
|
||||
int volume_type() const { return int(m_volume_type); }
|
||||
void msw_rescale();
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool valid();
|
||||
#endif /* NDEBUG */
|
||||
|
||||
private:
|
||||
friend class ObjectDataViewModel;
|
||||
};
|
||||
|
|
@ -859,8 +869,6 @@ public:
|
|||
~LockButton() {}
|
||||
|
||||
void OnButton(wxCommandEvent& event);
|
||||
void OnEnterBtn(wxMouseEvent& event) { enter_button(true); event.Skip(); }
|
||||
void OnLeaveBtn(wxMouseEvent& event) { enter_button(false); event.Skip(); }
|
||||
|
||||
bool IsLocked() const { return m_is_pushed; }
|
||||
void SetLock(bool lock);
|
||||
|
|
@ -872,16 +880,16 @@ public:
|
|||
void msw_rescale();
|
||||
|
||||
protected:
|
||||
void enter_button(const bool enter);
|
||||
void update_button_bitmaps();
|
||||
|
||||
private:
|
||||
bool m_is_pushed = false;
|
||||
bool m_disabled = false;
|
||||
|
||||
ScalableBitmap m_bmp_lock_on;
|
||||
ScalableBitmap m_bmp_lock_off;
|
||||
ScalableBitmap m_bmp_unlock_on;
|
||||
ScalableBitmap m_bmp_unlock_off;
|
||||
ScalableBitmap m_bmp_lock_closed;
|
||||
ScalableBitmap m_bmp_lock_closed_f;
|
||||
ScalableBitmap m_bmp_lock_open;
|
||||
ScalableBitmap m_bmp_lock_open_f;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -912,12 +920,16 @@ public:
|
|||
~ScalableButton() {}
|
||||
|
||||
void SetBitmap_(const ScalableBitmap& bmp);
|
||||
void SetBitmapDisabled_(const ScalableBitmap &bmp);
|
||||
|
||||
void msw_rescale();
|
||||
|
||||
private:
|
||||
wxWindow* m_parent;
|
||||
std::string m_current_icon_name = "";
|
||||
std::string m_disabled_icon_name = "";
|
||||
int m_width {-1}; // should be multiplied to em_unit
|
||||
int m_height{-1}; // should be multiplied to em_unit
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue