Emulation of kill focus event on object manipulator fields when changing selection into objects list [WIN+LINUX]
This commit is contained in:
parent
5fa5d495bb
commit
8076b39c4b
@ -66,9 +66,12 @@ ObjectList::ObjectList(wxWindow* parent) :
|
|||||||
|
|
||||||
// describe control behavior
|
// describe control behavior
|
||||||
Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxEvent& event) {
|
Bind(wxEVT_DATAVIEW_SELECTION_CHANGED, [this](wxEvent& event) {
|
||||||
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
#ifndef __APPLE__
|
||||||
std::cout << "SELECTION_CHANGED" << std::endl;
|
// On Windows and Linux, forces a kill focus emulation on the object manipulator fields because this event handler is called
|
||||||
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
// before the kill focus event handler on the object manipulator when changing selection in the list, invalidating the object
|
||||||
|
// manipulator cache with the following call to selection_changed()
|
||||||
|
wxGetApp().obj_manipul()->emulate_kill_focus();
|
||||||
|
#endif // __APPLE__
|
||||||
selection_changed();
|
selection_changed();
|
||||||
#ifndef __WXMSW__
|
#ifndef __WXMSW__
|
||||||
set_tooltip_for_item(get_mouse_position_in_control());
|
set_tooltip_for_item(get_mouse_position_in_control());
|
||||||
|
@ -17,85 +17,23 @@ namespace GUI
|
|||||||
|
|
||||||
ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
ObjectManipulation::ObjectManipulation(wxWindow* parent) :
|
||||||
OG_Settings(parent, true)
|
OG_Settings(parent, true)
|
||||||
|
#ifndef __APPLE__
|
||||||
|
, m_focused_option("")
|
||||||
|
#endif // __APPLE__
|
||||||
{
|
{
|
||||||
m_og->set_name(_(L("Object Manipulation")));
|
m_og->set_name(_(L("Object Manipulation")));
|
||||||
m_og->label_width = 125;
|
m_og->label_width = 125;
|
||||||
m_og->set_grid_vgap(5);
|
m_og->set_grid_vgap(5);
|
||||||
|
|
||||||
m_og->m_on_change = [this](const std::string& opt_key, const boost::any& value) {
|
m_og->m_on_change = std::bind(&ObjectManipulation::on_change, this, std::placeholders::_1, std::placeholders::_2);
|
||||||
// needed to hide the visual hints in 3D scene
|
m_og->m_fill_empty_value = std::bind(&ObjectManipulation::on_fill_empty_value, this, std::placeholders::_1);
|
||||||
wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, false);
|
|
||||||
|
|
||||||
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
||||||
std::cout << "KILL_FOCUS" << std::endl;
|
|
||||||
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
||||||
|
|
||||||
if (!m_cache.is_valid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::vector<std::string> axes{ "_x", "_y", "_z" };
|
|
||||||
|
|
||||||
std::string param;
|
|
||||||
std::copy(opt_key.begin(), opt_key.end() - 2, std::back_inserter(param));
|
|
||||||
|
|
||||||
size_t i = 0;
|
|
||||||
Vec3d new_value;
|
|
||||||
for (auto axis : axes)
|
|
||||||
new_value(i++) = boost::any_cast<double>(m_og->get_value(param+axis));
|
|
||||||
|
|
||||||
if (param == "position")
|
|
||||||
change_position_value(new_value);
|
|
||||||
else if (param == "rotation")
|
|
||||||
change_rotation_value(new_value);
|
|
||||||
else if (param == "scale")
|
|
||||||
change_scale_value(new_value);
|
|
||||||
else if (param == "size")
|
|
||||||
change_size_value(new_value);
|
|
||||||
};
|
|
||||||
|
|
||||||
m_og->m_fill_empty_value = [this](const std::string& opt_key)
|
|
||||||
{
|
|
||||||
// needed to hide the visual hints in 3D scene
|
|
||||||
wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, false);
|
|
||||||
|
|
||||||
if (!m_cache.is_valid())
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::string param;
|
|
||||||
std::copy(opt_key.begin(), opt_key.end() - 2, std::back_inserter(param));
|
|
||||||
|
|
||||||
double value = 0.0;
|
|
||||||
|
|
||||||
if (param == "position") {
|
|
||||||
int axis = opt_key.back() == 'x' ? 0 :
|
|
||||||
opt_key.back() == 'y' ? 1 : 2;
|
|
||||||
|
|
||||||
value = m_cache.position(axis);
|
|
||||||
}
|
|
||||||
else if (param == "rotation") {
|
|
||||||
int axis = opt_key.back() == 'x' ? 0 :
|
|
||||||
opt_key.back() == 'y' ? 1 : 2;
|
|
||||||
|
|
||||||
value = m_cache.rotation(axis);
|
|
||||||
}
|
|
||||||
else if (param == "scale") {
|
|
||||||
int axis = opt_key.back() == 'x' ? 0 :
|
|
||||||
opt_key.back() == 'y' ? 1 : 2;
|
|
||||||
|
|
||||||
value = m_cache.scale(axis);
|
|
||||||
}
|
|
||||||
else if (param == "size") {
|
|
||||||
int axis = opt_key.back() == 'x' ? 0 :
|
|
||||||
opt_key.back() == 'y' ? 1 : 2;
|
|
||||||
|
|
||||||
value = m_cache.size(axis);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_og->set_value(opt_key, double_to_string(value));
|
|
||||||
};
|
|
||||||
|
|
||||||
m_og->m_set_focus = [this](const std::string& opt_key)
|
m_og->m_set_focus = [this](const std::string& opt_key)
|
||||||
{
|
{
|
||||||
|
#ifndef __APPLE__
|
||||||
|
m_focused_option = opt_key;
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
// needed to show the visual hints in 3D scene
|
// needed to show the visual hints in 3D scene
|
||||||
wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, true);
|
wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, true);
|
||||||
};
|
};
|
||||||
@ -383,6 +321,23 @@ void ObjectManipulation::update_if_dirty()
|
|||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
void ObjectManipulation::emulate_kill_focus()
|
||||||
|
{
|
||||||
|
if (m_focused_option.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// we need to use a copy because the value of m_focused_option is modified inside on_change() and on_fill_empty_value()
|
||||||
|
std::string option = m_focused_option;
|
||||||
|
|
||||||
|
// see TextCtrl::propagate_value()
|
||||||
|
if (static_cast<wxTextCtrl*>(m_og->get_fieldc(option, 0)->getWindow())->GetValue().empty())
|
||||||
|
on_fill_empty_value(option);
|
||||||
|
else
|
||||||
|
on_change(option, 0);
|
||||||
|
}
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
void ObjectManipulation::reset_settings_value()
|
void ObjectManipulation::reset_settings_value()
|
||||||
{
|
{
|
||||||
m_new_position = Vec3d::Zero();
|
m_new_position = Vec3d::Zero();
|
||||||
@ -504,5 +459,80 @@ void ObjectManipulation::change_size_value(const Vec3d& size)
|
|||||||
m_cache.size = size;
|
m_cache.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectManipulation::on_change(const t_config_option_key& opt_key, const boost::any& value)
|
||||||
|
{
|
||||||
|
// needed to hide the visual hints in 3D scene
|
||||||
|
wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, false);
|
||||||
|
#ifndef __APPLE__
|
||||||
|
m_focused_option = "";
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
if (!m_cache.is_valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<std::string> axes{ "_x", "_y", "_z" };
|
||||||
|
|
||||||
|
std::string param;
|
||||||
|
std::copy(opt_key.begin(), opt_key.end() - 2, std::back_inserter(param));
|
||||||
|
|
||||||
|
size_t i = 0;
|
||||||
|
Vec3d new_value;
|
||||||
|
for (auto axis : axes)
|
||||||
|
new_value(i++) = boost::any_cast<double>(m_og->get_value(param + axis));
|
||||||
|
|
||||||
|
if (param == "position")
|
||||||
|
change_position_value(new_value);
|
||||||
|
else if (param == "rotation")
|
||||||
|
change_rotation_value(new_value);
|
||||||
|
else if (param == "scale")
|
||||||
|
change_scale_value(new_value);
|
||||||
|
else if (param == "size")
|
||||||
|
change_size_value(new_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectManipulation::on_fill_empty_value(const std::string& opt_key)
|
||||||
|
{
|
||||||
|
// needed to hide the visual hints in 3D scene
|
||||||
|
wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event(opt_key, false);
|
||||||
|
#ifndef __APPLE__
|
||||||
|
m_focused_option = "";
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
|
if (!m_cache.is_valid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string param;
|
||||||
|
std::copy(opt_key.begin(), opt_key.end() - 2, std::back_inserter(param));
|
||||||
|
|
||||||
|
double value = 0.0;
|
||||||
|
|
||||||
|
if (param == "position") {
|
||||||
|
int axis = opt_key.back() == 'x' ? 0 :
|
||||||
|
opt_key.back() == 'y' ? 1 : 2;
|
||||||
|
|
||||||
|
value = m_cache.position(axis);
|
||||||
|
}
|
||||||
|
else if (param == "rotation") {
|
||||||
|
int axis = opt_key.back() == 'x' ? 0 :
|
||||||
|
opt_key.back() == 'y' ? 1 : 2;
|
||||||
|
|
||||||
|
value = m_cache.rotation(axis);
|
||||||
|
}
|
||||||
|
else if (param == "scale") {
|
||||||
|
int axis = opt_key.back() == 'x' ? 0 :
|
||||||
|
opt_key.back() == 'y' ? 1 : 2;
|
||||||
|
|
||||||
|
value = m_cache.scale(axis);
|
||||||
|
}
|
||||||
|
else if (param == "size") {
|
||||||
|
int axis = opt_key.back() == 'x' ? 0 :
|
||||||
|
opt_key.back() == 'y' ? 1 : 2;
|
||||||
|
|
||||||
|
value = m_cache.size(axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_og->set_value(opt_key, double_to_string(value));
|
||||||
|
}
|
||||||
|
|
||||||
} //namespace GUI
|
} //namespace GUI
|
||||||
} //namespace Slic3r
|
} //namespace Slic3r
|
@ -77,6 +77,11 @@ class ObjectManipulation : public OG_Settings
|
|||||||
bool m_uniform_scale {true};
|
bool m_uniform_scale {true};
|
||||||
PrusaLockButton* m_lock_bnt{ nullptr };
|
PrusaLockButton* m_lock_bnt{ nullptr };
|
||||||
|
|
||||||
|
#ifndef __APPLE__
|
||||||
|
// Currently focused option name (empty if none)
|
||||||
|
std::string m_focused_option;
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ObjectManipulation(wxWindow* parent);
|
ObjectManipulation(wxWindow* parent);
|
||||||
~ObjectManipulation() {}
|
~ObjectManipulation() {}
|
||||||
@ -94,6 +99,12 @@ public:
|
|||||||
bool get_uniform_scaling() const { return m_uniform_scale; }
|
bool get_uniform_scaling() const { return m_uniform_scale; }
|
||||||
|
|
||||||
void reset_cache() { m_cache.reset(); }
|
void reset_cache() { m_cache.reset(); }
|
||||||
|
#ifndef __APPLE__
|
||||||
|
// On Windows and Linux, emulates a kill focus event on the currently focused option (if any)
|
||||||
|
// Used only in ObjectList wxEVT_DATAVIEW_SELECTION_CHANGED handler which is called before the regular kill focus event
|
||||||
|
// bound to this class when changing selection in the objects list
|
||||||
|
void emulate_kill_focus();
|
||||||
|
#endif // __APPLE__
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reset_settings_value();
|
void reset_settings_value();
|
||||||
@ -108,6 +119,9 @@ private:
|
|||||||
void change_rotation_value(const Vec3d& rotation);
|
void change_rotation_value(const Vec3d& rotation);
|
||||||
void change_scale_value(const Vec3d& scale);
|
void change_scale_value(const Vec3d& scale);
|
||||||
void change_size_value(const Vec3d& size);
|
void change_size_value(const Vec3d& size);
|
||||||
|
|
||||||
|
void on_change(const t_config_option_key& opt_key, const boost::any& value);
|
||||||
|
void on_fill_empty_value(const std::string& opt_key);
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
Loading…
Reference in New Issue
Block a user