Removal of tabs from plater -> added buttons to scene to switch between views

This commit is contained in:
Enrico Turri 2018-12-06 10:38:19 +01:00
parent cc14676ca5
commit c908a4674a
8 changed files with 595 additions and 18 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -26,7 +26,11 @@
#include <wx/dcmemory.h>
#include <wx/image.h>
#include <wx/settings.h>
#if ENABLE_REMOVE_TABS_FROM_PLATER
#include <wx/tipwin.h>
#else
#include <wx/tooltip.h>
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
#include <wx/debug.h>
// Print now includes tbb, and tbb includes Windows. This breaks compilation of wxWidgets if included before wx.
@ -3360,6 +3364,9 @@ void GLCanvas3D::LegendTexture::render(const GLCanvas3D& canvas) const
}
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
wxDEFINE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
wxDEFINE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_OBJECT_SELECT, SimpleEvent);
wxDEFINE_EVENT(EVT_GLCANVAS_VIEWPORT_CHANGED, SimpleEvent);
@ -3379,6 +3386,9 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas)
, m_context(nullptr)
, m_in_render(false)
, m_toolbar(*this)
#if ENABLE_REMOVE_TABS_FROM_PLATER
, m_view_toolbar(nullptr)
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
, m_use_clipping_planes(false)
, m_config(nullptr)
, m_process(nullptr)
@ -3522,6 +3532,10 @@ bool GLCanvas3D::init(bool useVBOs, bool use_legacy_opengl)
if (!_init_toolbar())
return false;
#if ENABLE_REMOVE_TABS_FROM_PLATER
post_event(SimpleEvent(EVT_GLCANVAS_INIT));
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
m_initialized = true;
return true;
@ -3845,7 +3859,9 @@ void GLCanvas3D::render()
float theta = m_camera.get_theta();
bool is_custom_bed = m_bed.is_custom();
#if !ENABLE_REMOVE_TABS_FROM_PLATER
set_tooltip("");
#endif // !ENABLE_REMOVE_TABS_FROM_PLATER
#if ENABLE_IMGUI
wxGetApp().imgui()->new_frame();
@ -3889,7 +3905,13 @@ void GLCanvas3D::render()
_render_gizmos_overlay();
_render_warning_texture();
_render_legend_texture();
#if ENABLE_REMOVE_TABS_FROM_PLATER
_resize_toolbars();
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
_render_toolbar();
#if ENABLE_REMOVE_TABS_FROM_PLATER
_render_view_toolbar();
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
_render_layer_editing_overlay();
#if ENABLE_IMGUI
@ -4575,6 +4597,9 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
m_layers_editing.last_object_id = layer_editing_object_idx;
bool gizmos_overlay_contains_mouse = m_gizmos.overlay_contains_mouse(*this, m_mouse.position);
int toolbar_contains_mouse = m_toolbar.contains_mouse(m_mouse.position);
#if ENABLE_REMOVE_TABS_FROM_PLATER
int view_toolbar_contains_mouse = (m_view_toolbar != nullptr) ? m_view_toolbar->contains_mouse(m_mouse.position, *this) : -1;
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
if (evt.Entering())
{
@ -4660,6 +4685,13 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
if (m_gizmos.get_current_type() == Gizmos::SlaSupports)
m_gizmos.delete_current_grabber();
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
else if (view_toolbar_contains_mouse != -1)
{
if (m_view_toolbar != nullptr)
m_view_toolbar->do_action((unsigned int)view_toolbar_contains_mouse, *this);
}
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
else if (toolbar_contains_mouse != -1)
{
m_toolbar_action_running = true;
@ -4936,7 +4968,31 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
}
else if (evt.Moving())
{
m_mouse.position = Vec2d((double)pos(0), (double)pos(1));
m_mouse.position = pos.cast<double>();
#if ENABLE_REMOVE_TABS_FROM_PLATER
std::string tooltip = "";
// updates gizmos overlay
if (!m_selection.is_empty())
tooltip = m_gizmos.update_hover_state(*this, m_mouse.position, m_selection);
else
m_gizmos.reset_all_states();
// updates toolbar overlay
if (tooltip.empty())
tooltip = m_toolbar.update_hover_state(m_mouse.position);
// updates view toolbar overlay
if (tooltip.empty() && (m_view_toolbar != nullptr))
{
tooltip = m_view_toolbar->update_hover_state(m_mouse.position, *this);
if (!tooltip.empty())
m_dirty = true;
}
set_tooltip(tooltip);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
// Only refresh if picking is enabled, in that case the objects may get highlighted if the mouse cursor hovers over.
if (m_picking_enabled)
m_dirty = true;
@ -5660,6 +5716,7 @@ void GLCanvas3D::_picking_pass() const
_update_volumes_hover_state();
#if !ENABLE_REMOVE_TABS_FROM_PLATER
// updates gizmos overlay
if (!m_selection.is_empty())
{
@ -5671,6 +5728,7 @@ void GLCanvas3D::_picking_pass() const
m_gizmos.reset_all_states();
m_toolbar.update_hover_state(pos);
#endif // !ENABLE_REMOVE_TABS_FROM_PLATER
}
}
@ -5899,10 +5957,20 @@ void GLCanvas3D::_render_gizmos_overlay() const
void GLCanvas3D::_render_toolbar() const
{
#if !ENABLE_REMOVE_TABS_FROM_PLATER
_resize_toolbar();
#endif // !ENABLE_REMOVE_TABS_FROM_PLATER
m_toolbar.render();
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
void GLCanvas3D::_render_view_toolbar() const
{
if (m_view_toolbar != nullptr)
m_view_toolbar->render(*this);
}
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
#if ENABLE_SHOW_CAMERA_TARGET
void GLCanvas3D::_render_camera_target() const
{
@ -7495,7 +7563,11 @@ bool GLCanvas3D::_is_any_volume_outside() const
return false;
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
void GLCanvas3D::_resize_toolbars() const
#else
void GLCanvas3D::_resize_toolbar() const
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
{
Size cnv_size = get_canvas_size();
float zoom = get_camera_zoom();
@ -7524,6 +7596,15 @@ void GLCanvas3D::_resize_toolbar() const
break;
}
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
if (m_view_toolbar != nullptr)
{
float top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar->get_height()) * inv_zoom;
float left = -0.5f * (float)cnv_size.get_width() * inv_zoom;
m_view_toolbar->set_position(top, left);
}
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
}
const Print* GLCanvas3D::fff_print() const

View file

@ -94,6 +94,9 @@ template <size_t N> using Vec2dsEvent = ArrayEvent<Vec2d, N>;
using Vec3dEvent = Event<Vec3d>;
template <size_t N> using Vec3dsEvent = ArrayEvent<Vec3d, N>;
#if ENABLE_REMOVE_TABS_FROM_PLATER
wxDECLARE_EVENT(EVT_GLCANVAS_INIT, SimpleEvent);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
wxDECLARE_EVENT(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_VIEWPORT_CHANGED, SimpleEvent);
wxDECLARE_EVENT(EVT_GLCANVAS_RIGHT_CLICK, Vec2dEvent);
@ -737,6 +740,9 @@ private:
Mouse m_mouse;
mutable Gizmos m_gizmos;
mutable GLToolbar m_toolbar;
#if ENABLE_REMOVE_TABS_FROM_PLATER
GLRadioToolbar* m_view_toolbar;
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
ClippingPlane m_clipping_planes[2];
bool m_use_clipping_planes;
mutable SlaCap m_sla_caps[2];
@ -787,6 +793,10 @@ public:
wxGLCanvas* get_wxglcanvas() { return m_canvas; }
#if ENABLE_REMOVE_TABS_FROM_PLATER
void set_view_toolbar(GLRadioToolbar* toolbar) { m_view_toolbar = toolbar; }
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
bool init(bool useVBOs, bool use_legacy_opengl);
void post_event(wxEvent &&event);
@ -958,6 +968,9 @@ private:
void _render_current_gizmo() const;
void _render_gizmos_overlay() const;
void _render_toolbar() const;
#if ENABLE_REMOVE_TABS_FROM_PLATER
void _render_view_toolbar() const;
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
#if ENABLE_SHOW_CAMERA_TARGET
void _render_camera_target() const;
#endif // ENABLE_SHOW_CAMERA_TARGET
@ -1021,7 +1034,11 @@ private:
bool _is_any_volume_outside() const;
#if ENABLE_REMOVE_TABS_FROM_PLATER
void _resize_toolbars() const;
#else
void _resize_toolbar() const;
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
static std::vector<float> _parse_colors(const std::vector<std::string>& colors);

View file

@ -26,6 +26,8 @@ wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_SPLIT_VOLUMES, SimpleEvent);
wxDEFINE_EVENT(EVT_GLTOOLBAR_LAYERSEDITING, SimpleEvent);
wxDEFINE_EVENT(EVT_GLVIEWTOOLBAR_3D, SimpleEvent);
wxDEFINE_EVENT(EVT_GLVIEWTOOLBAR_PREVIEW, SimpleEvent);
GLToolbarItem::Data::Data()
: name("")
@ -121,7 +123,7 @@ GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int texture_size, unsigned i
return uvs;
}
GLToolbar::ItemsIconsTexture::ItemsIconsTexture()
ItemsIconsTexture::ItemsIconsTexture()
: items_icon_size(0)
, items_icon_border_size(0)
, items_icon_gap_size(0)
@ -289,14 +291,27 @@ bool GLToolbar::is_item_pressed(const std::string& name) const
return false;
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos)
#else
void GLToolbar::update_hover_state(const Vec2d& mouse_pos)
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
{
#if ENABLE_REMOVE_TABS_FROM_PLATER
if (!m_enabled)
return "";
#else
if (!m_enabled)
return;
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
switch (m_layout.type)
{
default:
#if ENABLE_REMOVE_TABS_FROM_PLATER
case Layout::Horizontal: { return update_hover_state_horizontal(mouse_pos); }
case Layout::Vertical: { return update_hover_state_vertical(mouse_pos); }
#else
case Layout::Horizontal:
{
update_hover_state_horizontal(mouse_pos);
@ -307,6 +322,7 @@ void GLToolbar::update_hover_state(const Vec2d& mouse_pos)
update_hover_state_vertical(mouse_pos);
break;
}
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
}
}
@ -428,7 +444,11 @@ float GLToolbar::get_main_size() const
return size;
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos)
#else
void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos)
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
{
float zoom = m_parent.get_camera_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
@ -505,11 +525,19 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos)
}
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
return tooltip;
#else
if (!tooltip.empty())
m_parent.set_tooltip(tooltip);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos)
#else
void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos)
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
{
float zoom = m_parent.get_camera_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
@ -586,7 +614,11 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos)
}
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
return tooltip;
#else
m_parent.set_tooltip(tooltip);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
}
int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos) const
@ -739,5 +771,297 @@ void GLToolbar::render_vertical() const
}
}
GLRadioToolbarItem::Data::Data()
: name("")
, tooltip("")
, sprite_id(-1)
{
}
GLRadioToolbarItem::GLRadioToolbarItem(const GLRadioToolbarItem::Data& data)
: m_state(Normal)
, m_data(data)
{
}
GLRadioToolbarItem::EState GLRadioToolbarItem::get_state() const
{
return m_state;
}
void GLRadioToolbarItem::set_state(GLRadioToolbarItem::EState state)
{
m_state = state;
}
const std::string& GLRadioToolbarItem::get_name() const
{
return m_data.name;
}
const std::string& GLRadioToolbarItem::get_tooltip() const
{
return m_data.tooltip;
}
bool GLRadioToolbarItem::is_hovered() const
{
return (m_state == Hover) || (m_state == HoverPressed);
}
bool GLRadioToolbarItem::is_pressed() const
{
return (m_state == Pressed) || (m_state == HoverPressed);
}
void GLRadioToolbarItem::do_action(wxEvtHandler *target)
{
wxPostEvent(target, SimpleEvent(m_data.action_event));
}
void GLRadioToolbarItem::render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
{
GLTexture::render_sub_texture(tex_id, left, right, bottom, top, get_uvs(texture_size, border_size, icon_size, gap_size));
}
GLTexture::Quad_UVs GLRadioToolbarItem::get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const
{
GLTexture::Quad_UVs uvs;
float inv_texture_size = (texture_size != 0) ? 1.0f / (float)texture_size : 0.0f;
float scaled_icon_size = (float)icon_size * inv_texture_size;
float scaled_border_size = (float)border_size * inv_texture_size;
float scaled_gap_size = (float)gap_size * inv_texture_size;
float stride = scaled_icon_size + scaled_gap_size;
float left = scaled_border_size + (float)m_state * stride;
float right = left + scaled_icon_size;
float top = scaled_border_size + (float)m_data.sprite_id * stride;
float bottom = top + scaled_icon_size;
uvs.left_top = { left, top };
uvs.left_bottom = { left, bottom };
uvs.right_bottom = { right, bottom };
uvs.right_top = { right, top };
return uvs;
}
GLRadioToolbar::GLRadioToolbar()
: m_top(0.0f)
, m_left(0.0f)
{
}
GLRadioToolbar::~GLRadioToolbar()
{
for (GLRadioToolbarItem* item : m_items)
{
delete item;
}
}
bool GLRadioToolbar::init(const std::string& icons_texture_filename, unsigned int items_icon_size, unsigned int items_icon_border_size, unsigned int items_icon_gap_size)
{
if (m_icons_texture.texture.get_id() != 0)
return true;
std::string path = resources_dir() + "/icons/";
bool res = !icons_texture_filename.empty() && m_icons_texture.texture.load_from_file(path + icons_texture_filename, false);
if (res)
{
m_icons_texture.items_icon_size = items_icon_size;
m_icons_texture.items_icon_border_size = items_icon_border_size;
m_icons_texture.items_icon_gap_size = items_icon_gap_size;
}
return res;
}
bool GLRadioToolbar::add_item(const GLRadioToolbarItem::Data& data)
{
GLRadioToolbarItem* item = new GLRadioToolbarItem(data);
if (item == nullptr)
return false;
m_items.push_back(item);
return true;
}
float GLRadioToolbar::get_height() const
{
return m_icons_texture.items_icon_size;
}
void GLRadioToolbar::set_position(float top, float left)
{
m_top = top;
m_left = left;
}
void GLRadioToolbar::set_selection(const std::string& name)
{
for (GLRadioToolbarItem* item : m_items)
{
item->set_state((item->get_name() == name) ? GLRadioToolbarItem::Pressed : GLRadioToolbarItem::Normal);
}
}
int GLRadioToolbar::contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent) const
{
float zoom = parent.get_camera_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
Size cnv_size = parent.get_canvas_size();
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
float left = m_left;
float top = m_top;
int id = -1;
for (GLRadioToolbarItem* item : m_items)
{
++id;
float right = left + scaled_icons_size;
float bottom = top - scaled_icons_size;
if ((left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top))
return id;
left += scaled_icons_size;
}
return -1;
}
std::string GLRadioToolbar::update_hover_state(const Vec2d& mouse_pos, const GLCanvas3D& parent)
{
float zoom = parent.get_camera_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
Size cnv_size = parent.get_canvas_size();
Vec2d scaled_mouse_pos((mouse_pos(0) - 0.5 * (double)cnv_size.get_width()) * inv_zoom, (0.5 * (double)cnv_size.get_height() - mouse_pos(1)) * inv_zoom);
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
float left = m_left;
float top = m_top;
std::string tooltip = "";
for (GLRadioToolbarItem* item : m_items)
{
float right = left + scaled_icons_size;
float bottom = top - scaled_icons_size;
GLRadioToolbarItem::EState state = item->get_state();
bool inside = (left <= (float)scaled_mouse_pos(0)) && ((float)scaled_mouse_pos(0) <= right) && (bottom <= (float)scaled_mouse_pos(1)) && ((float)scaled_mouse_pos(1) <= top);
switch (state)
{
case GLRadioToolbarItem::Normal:
{
if (inside)
item->set_state(GLRadioToolbarItem::Hover);
break;
}
case GLRadioToolbarItem::Hover:
{
if (inside)
tooltip = item->get_tooltip();
else
item->set_state(GLRadioToolbarItem::Normal);
break;
}
case GLRadioToolbarItem::Pressed:
{
if (inside)
item->set_state(GLRadioToolbarItem::HoverPressed);
break;
}
case GLRadioToolbarItem::HoverPressed:
{
if (inside)
tooltip = item->get_tooltip();
else
item->set_state(GLRadioToolbarItem::Pressed);
break;
}
default:
{
break;
}
}
left += scaled_icons_size;
}
return tooltip;
}
void GLRadioToolbar::do_action(unsigned int item_id, GLCanvas3D& parent)
{
for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i)
{
if (i != item_id)
m_items[i]->set_state(GLRadioToolbarItem::Normal);
}
if (item_id < (unsigned int)m_items.size())
{
GLRadioToolbarItem* item = m_items[item_id];
if ((item != nullptr) && item->is_hovered() && !item->is_pressed())
{
item->set_state(GLRadioToolbarItem::HoverPressed);
item->do_action(parent.get_wxglcanvas());
}
}
parent.set_as_dirty();
}
void GLRadioToolbar::render(const GLCanvas3D& parent) const
{
if (m_items.empty())
return;
::glDisable(GL_DEPTH_TEST);
::glPushMatrix();
::glLoadIdentity();
unsigned int tex_id = m_icons_texture.texture.get_id();
int tex_size = m_icons_texture.texture.get_width();
if ((tex_id == 0) || (tex_size <= 0))
return;
float zoom = parent.get_camera_zoom();
float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f;
float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom;
float left = m_left;
float top = m_top;
// renders icons
for (const GLRadioToolbarItem* item : m_items)
{
item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.items_icon_border_size, m_icons_texture.items_icon_size, m_icons_texture.items_icon_gap_size);
left += scaled_icons_size;
}
::glPopMatrix();
}
} // namespace GUI
} // namespace Slic3r

View file

@ -26,6 +26,9 @@ wxDECLARE_EVENT(EVT_GLTOOLBAR_SPLIT_OBJECTS, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_SPLIT_VOLUMES, SimpleEvent);
wxDECLARE_EVENT(EVT_GLTOOLBAR_LAYERSEDITING, SimpleEvent);
wxDECLARE_EVENT(EVT_GLVIEWTOOLBAR_3D, SimpleEvent);
wxDECLARE_EVENT(EVT_GLVIEWTOOLBAR_PREVIEW, SimpleEvent);
class GLToolbarItem
{
public:
@ -86,25 +89,25 @@ private:
GLTexture::Quad_UVs get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const;
};
// items icon textures are assumed to be square and all with the same size in pixels, no internal check is done
// icons are layed-out into the texture starting from the top-left corner in the same order as enum GLToolbarItem::EState
// from left to right
struct ItemsIconsTexture
{
GLTexture texture;
// size of the square icons, in pixels
unsigned int items_icon_size;
// distance from the border, in pixels
unsigned int items_icon_border_size;
// distance between two adjacent icons (to avoid filtering artifacts), in pixels
unsigned int items_icon_gap_size;
ItemsIconsTexture();
};
class GLToolbar
{
public:
// items icon textures are assumed to be square and all with the same size in pixels, no internal check is done
// icons are layed-out into the texture starting from the top-left corner in the same order as enum GLToolbarItem::EState
// from left to right
struct ItemsIconsTexture
{
GLTexture texture;
// size of the square icons, in pixels
unsigned int items_icon_size;
// distance from the border, in pixels
unsigned int items_icon_border_size;
// distance between two adjacent icons (to avoid filtering artifacts), in pixels
unsigned int items_icon_gap_size;
ItemsIconsTexture();
};
struct Layout
{
enum Type : unsigned char
@ -160,7 +163,11 @@ public:
bool is_item_pressed(const std::string& name) const;
#if ENABLE_REMOVE_TABS_FROM_PLATER
std::string update_hover_state(const Vec2d& mouse_pos);
#else
void update_hover_state(const Vec2d& mouse_pos);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
// returns the id of the item under the given mouse position or -1 if none
int contains_mouse(const Vec2d& mouse_pos) const;
@ -175,8 +182,13 @@ private:
float get_height_horizontal() const;
float get_height_vertical() const;
float get_main_size() const;
#if ENABLE_REMOVE_TABS_FROM_PLATER
std::string update_hover_state_horizontal(const Vec2d& mouse_pos);
std::string update_hover_state_vertical(const Vec2d& mouse_pos);
#else
void update_hover_state_horizontal(const Vec2d& mouse_pos);
void update_hover_state_vertical(const Vec2d& mouse_pos);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
int contains_mouse_horizontal(const Vec2d& mouse_pos) const;
int contains_mouse_vertical(const Vec2d& mouse_pos) const;
@ -184,6 +196,85 @@ private:
void render_vertical() const;
};
class GLRadioToolbarItem
{
public:
struct Data
{
std::string name;
std::string tooltip;
unsigned int sprite_id;
wxEventType action_event;
Data();
};
enum EState : unsigned char
{
Normal,
Pressed,
Hover,
HoverPressed,
Num_States
};
private:
EState m_state;
Data m_data;
public:
GLRadioToolbarItem(const Data& data);
EState get_state() const;
void set_state(EState state);
const std::string& get_name() const;
const std::string& get_tooltip() const;
bool is_hovered() const;
bool is_pressed() const;
void do_action(wxEvtHandler *target);
void render(unsigned int tex_id, float left, float right, float bottom, float top, unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const;
private:
GLTexture::Quad_UVs get_uvs(unsigned int texture_size, unsigned int border_size, unsigned int icon_size, unsigned int gap_size) const;
};
class GLRadioToolbar
{
typedef std::vector<GLRadioToolbarItem*> ItemsList;
ItemsIconsTexture m_icons_texture;
ItemsList m_items;
float m_top;
float m_left;
public:
GLRadioToolbar();
~GLRadioToolbar();
bool init(const std::string& icons_texture_filename, unsigned int items_icon_size, unsigned int items_icon_border_size, unsigned int items_icon_gap_size);
bool add_item(const GLRadioToolbarItem::Data& data);
float get_height() const;
void set_position(float top, float left);
void set_selection(const std::string& name);
// returns the id of the item under the given mouse position or -1 if none
int contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent) const;
std::string update_hover_state(const Vec2d& mouse_pos, const GLCanvas3D& parent);
void do_action(unsigned int item_id, GLCanvas3D& parent);
void render(const GLCanvas3D& parent) const;
};
} // namespace GUI
} // namespace Slic3r

View file

@ -92,6 +92,12 @@ bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, Ba
return true;
}
void View3D::set_view_toolbar(GLRadioToolbar* toolbar)
{
if (m_canvas != nullptr)
m_canvas->set_view_toolbar(toolbar);
}
void View3D::set_as_dirty()
{
if (m_canvas != nullptr)
@ -358,6 +364,14 @@ Preview::~Preview()
}
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
void Preview::set_view_toolbar(GLRadioToolbar* toolbar)
{
if (m_canvas != nullptr)
m_canvas->set_view_toolbar(toolbar);
}
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
void Preview::set_number_extruders(unsigned int number_extruders)
{
if (m_number_extruders != number_extruders)

View file

@ -28,6 +28,9 @@ class Model;
namespace GUI {
class GLCanvas3D;
#if ENABLE_REMOVE_TABS_FROM_PLATER
class GLRadioToolbar;
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
#if ENABLE_REMOVE_TABS_FROM_PLATER
class View3D : public wxPanel
@ -50,6 +53,8 @@ public:
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
GLCanvas3D* get_canvas3d() { return m_canvas; }
void set_view_toolbar(GLRadioToolbar* toolbar);
void set_as_dirty();
void set_bed_shape(const Pointfs& shape);
@ -116,6 +121,10 @@ public:
wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; }
#if ENABLE_REMOVE_TABS_FROM_PLATER
void set_view_toolbar(GLRadioToolbar* toolbar);
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
void set_number_extruders(unsigned int number_extruders);
void reset_gcode_preview_data();
void set_canvas_as_dirty();

View file

@ -931,6 +931,7 @@ struct Plater::priv
Sidebar *sidebar;
#if ENABLE_REMOVE_TABS_FROM_PLATER
View3D* view3D;
GLRadioToolbar view_toolbar;
#else
#if !ENABLE_IMGUI
wxPanel *panel3d;
@ -1031,6 +1032,9 @@ struct Plater::priv
private:
bool init_object_menu();
#if ENABLE_REMOVE_TABS_FROM_PLATER
void init_view_toolbar();
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
bool can_delete_object() const;
bool can_increase_instances() const;
@ -1201,6 +1205,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_OBJECTS, &priv::on_action_split_objects, this);
view3D_canvas->Bind(EVT_GLTOOLBAR_SPLIT_VOLUMES, &priv::on_action_split_volumes, this);
view3D_canvas->Bind(EVT_GLTOOLBAR_LAYERSEDITING, &priv::on_action_layersediting, this);
view3D_canvas->Bind(EVT_GLCANVAS_INIT, [this](SimpleEvent&) { init_view_toolbar(); });
#else
// 3DScene events:
canvas3Dwidget->Bind(EVT_GLCANVAS_SCHEDULE_BACKGROUND_PROCESS, [this](SimpleEvent&) { this->schedule_background_process(); });
@ -1230,9 +1235,16 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
// Preview events:
preview->get_wxglcanvas()->Bind(EVT_GLCANVAS_VIEWPORT_CHANGED, &priv::on_viewport_changed, this);
#if ENABLE_REMOVE_TABS_FROM_PLATER
view3D_canvas->Bind(EVT_GLCANVAS_INIT, [this](SimpleEvent&) { init_view_toolbar(); });
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
q->Bind(EVT_SLICING_COMPLETED, &priv::on_slicing_completed, this);
q->Bind(EVT_PROCESS_COMPLETED, &priv::on_process_completed, this);
#if ENABLE_REMOVE_TABS_FROM_PLATER
q->Bind(EVT_GLVIEWTOOLBAR_3D, [q](SimpleEvent&) { q->select_view_3D("3D"); });
q->Bind(EVT_GLVIEWTOOLBAR_PREVIEW, [q](SimpleEvent&) { q->select_view_3D("Preview"); });
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
// Drop target:
q->SetDropTarget(new PlaterDropTarget(q)); // if my understanding is right, wxWindow takes the owenership
@ -2462,6 +2474,35 @@ bool Plater::priv::init_object_menu()
return true;
}
#if ENABLE_REMOVE_TABS_FROM_PLATER
void Plater::priv::init_view_toolbar()
{
if (!view_toolbar.init("view_toolbar.png", 36, 1, 1))
return;
GLRadioToolbarItem::Data item;
item.name = "3d";
item.tooltip = GUI::L_str("3D editor view");
item.sprite_id = 0;
item.action_event = EVT_GLVIEWTOOLBAR_3D;
if (!view_toolbar.add_item(item))
return;
item.name = "preview";
item.tooltip = GUI::L_str("Preview");
item.sprite_id = 1;
item.action_event = EVT_GLVIEWTOOLBAR_PREVIEW;
if (!view_toolbar.add_item(item))
return;
view3D->set_view_toolbar(&view_toolbar);
preview->set_view_toolbar(&view_toolbar);
view_toolbar.set_selection("3d");
}
#endif // ENABLE_REMOVE_TABS_FROM_PLATER
bool Plater::priv::can_delete_object() const
{
int obj_idx = get_selected_object_idx();