Modified toolbar to call RenderCallback only when the item is toggable and pressed

This commit is contained in:
Enrico Turri 2019-07-10 10:52:12 +02:00
parent f985f5190c
commit 46e295407b
3 changed files with 65 additions and 77 deletions

View file

@ -3473,9 +3473,9 @@ static bool string_getter(const bool is_undo, int idx, const char** out_text)
void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x) void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x)
{ {
if (m_canvas != nullptr && m_toolbar.get_imgui_visible(is_undo)) if (m_canvas != nullptr)
{ {
const wxString& stack_name = _(is_undo ? L("Undo") : L("Redo")); const wxString stack_name = _(is_undo ? L("Undo") : L("Redo"));
ImGuiWrapper* imgui = wxGetApp().imgui(); ImGuiWrapper* imgui = wxGetApp().imgui();
const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width(); const float x = pos_x * (float)get_camera().get_zoom() + 0.5f * (float)get_canvas_size().get_width();
@ -3483,16 +3483,17 @@ void GLCanvas3D::_render_undo_redo_stack(const bool is_undo, float pos_x)
imgui->set_next_window_bg_alpha(0.5f); imgui->set_next_window_bg_alpha(0.5f);
imgui->begin(wxString::Format(_(L("%s Stack")), stack_name), imgui->begin(wxString::Format(_(L("%s Stack")), stack_name),
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse); ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse);
int hovered = m_toolbar.get_imgui_hovered_pos(); int hovered = -1;
int selected = -1; int selected = -1;
const float em = static_cast<float>(wxGetApp().em_unit()); const float em = static_cast<float>(wxGetApp().em_unit());
if (imgui->undo_redo_list(ImVec2(12 * em, 20 * em), is_undo, &string_getter, hovered, selected)) if (imgui->undo_redo_list(ImVec2(12 * em, 20 * em), is_undo, &string_getter, hovered, selected))
m_toolbar.set_imgui_hovered_pos(hovered); {
if (selected >= 0) if (selected >= 0)
is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected); is_undo ? wxGetApp().plater()->undo_to(selected) : wxGetApp().plater()->redo_to(selected);
}
imgui->text(wxString::Format(_(L("%s %d Action")), stack_name, hovered + 1)); imgui->text(wxString::Format(_(L("%s %d Action")), stack_name, hovered + 1));
@ -3685,18 +3686,9 @@ bool GLCanvas3D::_init_toolbar()
#endif // ENABLE_SVG_ICONS #endif // ENABLE_SVG_ICONS
item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]"; item.tooltip = _utf8(L("Undo")) + " [" + GUI::shortkey_ctrl_prefix() + "Z]";
item.sprite_id = 11; item.sprite_id = 11;
item.is_toggable = false; item.action_callback = [this]() { if (m_canvas != nullptr) { wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_UNDO)); } };
item.action_callback = [this]() {
if (m_canvas != nullptr) {
wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_UNDO));
m_toolbar.activate_imgui(true);
}
};
item.visibility_callback = []()->bool { return true; }; item.visibility_callback = []()->bool { return true; };
item.enabled_state_callback = [this]()->bool { item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_undo(); };
if (!wxGetApp().plater()->can_undo()) { m_toolbar.hide_imgui(true); return false; }
return true;
};
item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(true, pos_x); }; item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(true, pos_x); };
if (!m_toolbar.add_item(item)) if (!m_toolbar.add_item(item))
return false; return false;
@ -3707,16 +3699,8 @@ bool GLCanvas3D::_init_toolbar()
#endif // ENABLE_SVG_ICONS #endif // ENABLE_SVG_ICONS
item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]"; item.tooltip = _utf8(L("Redo")) + " [" + GUI::shortkey_ctrl_prefix() + "Y]";
item.sprite_id = 12; item.sprite_id = 12;
item.action_callback = [this]() { item.action_callback = [this]() { if (m_canvas != nullptr) { wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_REDO)); } };
if (m_canvas != nullptr) { item.enabled_state_callback = [this]()->bool { return wxGetApp().plater()->can_redo(); };
wxPostEvent(m_canvas, SimpleEvent(EVT_GLCANVAS_REDO));
m_toolbar.activate_imgui(false);
}
};
item.enabled_state_callback = [this]()->bool {
if (!wxGetApp().plater()->can_redo()) { m_toolbar.hide_imgui(false); return false; }
return true;
};
item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(false, pos_x); }; item.render_callback = [this](float pos_x, float, float, float) { _render_undo_redo_stack(false, pos_x); };
if (!m_toolbar.add_item(item)) if (!m_toolbar.add_item(item))
return false; return false;

View file

@ -84,7 +84,8 @@ void GLToolbarItem::render(unsigned int tex_id, float left, float right, float b
{ {
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size)); GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(tex_width, tex_height, icon_size));
m_data.render_callback(left, right, bottom, top); if (is_toggable() && is_pressed())
m_data.render_callback(left, right, bottom, top);
} }
GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int tex_width, unsigned int tex_height, unsigned int icon_size) const
@ -164,6 +165,7 @@ GLToolbar::GLToolbar(GLToolbar::EType type)
, m_icons_texture_dirty(true) , m_icons_texture_dirty(true)
#endif // ENABLE_SVG_ICONS #endif // ENABLE_SVG_ICONS
, m_tooltip("") , m_tooltip("")
, m_pressed_toggable_id(-1)
{ {
} }
@ -345,7 +347,7 @@ void GLToolbar::select_item(const std::string& name)
bool GLToolbar::is_item_pressed(const std::string& name) const bool GLToolbar::is_item_pressed(const std::string& name) const
{ {
for (GLToolbarItem* item : m_items) for (const GLToolbarItem* item : m_items)
{ {
if (item->get_name() == name) if (item->get_name() == name)
return item->is_pressed(); return item->is_pressed();
@ -356,7 +358,7 @@ bool GLToolbar::is_item_pressed(const std::string& name) const
bool GLToolbar::is_item_disabled(const std::string& name) const bool GLToolbar::is_item_disabled(const std::string& name) const
{ {
for (GLToolbarItem* item : m_items) for (const GLToolbarItem* item : m_items)
{ {
if (item->get_name() == name) if (item->get_name() == name)
return item->is_disabled(); return item->is_disabled();
@ -367,7 +369,7 @@ bool GLToolbar::is_item_disabled(const std::string& name) const
bool GLToolbar::is_item_visible(const std::string& name) const bool GLToolbar::is_item_visible(const std::string& name) const
{ {
for (GLToolbarItem* item : m_items) for (const GLToolbarItem* item : m_items)
{ {
if (item->get_name() == name) if (item->get_name() == name)
return item->is_visible(); return item->is_visible();
@ -376,11 +378,25 @@ bool GLToolbar::is_item_visible(const std::string& name) const
return false; return false;
} }
bool GLToolbar::is_any_item_pressed() const
{
for (const GLToolbarItem* item : m_items)
{
if (item->is_pressed())
return true;
}
return false;
}
bool GLToolbar::update_items_state() bool GLToolbar::update_items_state()
{ {
bool ret = false; bool ret = false;
ret |= update_items_visibility(); ret |= update_items_visibility();
ret |= update_items_enabled_state(); ret |= update_items_enabled_state();
if (!is_any_item_pressed())
m_pressed_toggable_id = -1;
return ret; return ret;
} }
@ -558,36 +574,41 @@ float GLToolbar::get_main_size() const
void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent) void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent)
{ {
if (item_id < (unsigned int)m_items.size()) if ((m_pressed_toggable_id == -1) || (m_pressed_toggable_id == item_id))
{ {
GLToolbarItem* item = m_items[item_id]; if (item_id < (unsigned int)m_items.size())
if ((item != nullptr) && !item->is_separator() && item->is_hovered())
{ {
if (item->is_toggable()) GLToolbarItem* item = m_items[item_id];
if ((item != nullptr) && !item->is_separator() && item->is_hovered())
{ {
GLToolbarItem::EState state = item->get_state(); if (item->is_toggable())
if (state == GLToolbarItem::Hover)
item->set_state(GLToolbarItem::HoverPressed);
else if (state == GLToolbarItem::HoverPressed)
item->set_state(GLToolbarItem::Hover);
parent.render();
item->do_action();
}
else
{
if (m_type == Radio)
select_item(item->get_name());
else
item->set_state(GLToolbarItem::HoverPressed);
parent.render();
item->do_action();
if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled))
{ {
// the item may get disabled during the action, if not, set it back to hover state GLToolbarItem::EState state = item->get_state();
item->set_state(GLToolbarItem::Hover); if (state == GLToolbarItem::Hover)
item->set_state(GLToolbarItem::HoverPressed);
else if (state == GLToolbarItem::HoverPressed)
item->set_state(GLToolbarItem::Hover);
m_pressed_toggable_id = item->is_pressed() ? item_id : -1;
parent.render(); parent.render();
item->do_action();
}
else
{
if (m_type == Radio)
select_item(item->get_name());
else
item->set_state(GLToolbarItem::HoverPressed);
parent.render();
item->do_action();
if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled))
{
// the item may get disabled during the action, if not, set it back to hover state
item->set_state(GLToolbarItem::Hover);
parent.render();
}
} }
} }
} }

View file

@ -252,10 +252,7 @@ private:
MouseCapture m_mouse_capture; MouseCapture m_mouse_capture;
std::string m_tooltip; std::string m_tooltip;
bool m_undo_imgui_visible {false}; unsigned int m_pressed_toggable_id;
bool m_redo_imgui_visible {false};
int m_imgui_hovered_pos { -1 };
int m_imgui_selected_pos { -1 };
public: public:
#if ENABLE_SVG_ICONS #if ENABLE_SVG_ICONS
@ -302,6 +299,8 @@ public:
bool is_item_disabled(const std::string& name) const; bool is_item_disabled(const std::string& name) const;
bool is_item_visible(const std::string& name) const; bool is_item_visible(const std::string& name) const;
bool is_any_item_pressed() const;
const std::string& get_tooltip() const { return m_tooltip; } const std::string& get_tooltip() const { return m_tooltip; }
@ -312,22 +311,6 @@ public:
bool on_mouse(wxMouseEvent& evt, GLCanvas3D& parent); bool on_mouse(wxMouseEvent& evt, GLCanvas3D& parent);
// undo == true => "undo" imgui is activated
// undo == false => "redo" imgui is activated
bool get_imgui_visible(const bool undo) const { return undo ? m_undo_imgui_visible : m_redo_imgui_visible; }
void hide_imgui(const bool undo) { undo ? m_undo_imgui_visible = false : m_redo_imgui_visible = false; }
void activate_imgui(const bool undo) {
m_undo_imgui_visible = undo;
m_redo_imgui_visible = !undo;
m_imgui_hovered_pos = m_imgui_selected_pos = -1;
}
void set_imgui_hovered_pos(int pos = -1) { m_imgui_hovered_pos = pos; }
int get_imgui_hovered_pos() const { return m_imgui_hovered_pos; }
void set_imgui_selected_pos(int pos = -1) { m_imgui_selected_pos = pos; }
int get_imgui_selected_pos() const { return m_imgui_selected_pos; }
private: private:
void calc_layout() const; void calc_layout() const;
float get_width_horizontal() const; float get_width_horizontal() const;