From 083c626770fcfb5a050328641c020ac0bff09919 Mon Sep 17 00:00:00 2001 From: Enrico Turri <enricoturri@seznam.cz> Date: Mon, 17 Dec 2018 10:55:14 +0100 Subject: [PATCH] Added background texture to toolbars --- resources/icons/toolbar_background.png | Bin 0 -> 1544 bytes resources/icons/view_toolbar.png | Bin 18226 -> 21977 bytes src/libslic3r/Technologies.hpp | 2 + src/slic3r/GUI/GLCanvas3D.cpp | 92 +++- src/slic3r/GUI/GLCanvas3D.hpp | 8 + src/slic3r/GUI/GLToolbar.cpp | 683 +++++++++++++++++++++++-- src/slic3r/GUI/GLToolbar.hpp | 159 +++++- src/slic3r/GUI/GUI_Preview.cpp | 8 + src/slic3r/GUI/GUI_Preview.hpp | 14 + src/slic3r/GUI/Plater.cpp | 59 +++ 10 files changed, 976 insertions(+), 49 deletions(-) create mode 100644 resources/icons/toolbar_background.png diff --git a/resources/icons/toolbar_background.png b/resources/icons/toolbar_background.png new file mode 100644 index 0000000000000000000000000000000000000000..2b5ea013be7a6b804fb8390bec7d386e39e42d16 GIT binary patch literal 1544 zcma)5c{~(&6#vaIGt4kn>!`tC9b1l^Q(<DvjANWRmQX?rW91rhgwN2dh+T3`Cc^fS z9Jwlr>SI$%a^FMlM&#PE&cROm-~Q9?=Y78Kect!I&wKBW?@K*nXCaEjAOQfP6ic!r zKQg{T2+sGd#@-zOK*wU8&qg?UM=6AchfrxjehLvWp?(T}(KIRm(VS(LNBx+BNb;nc z8H=IJ^fI{FVH4H!VG}_w=%94lXo<zA<b%9dVjr_9Gdmfpt?{j9ZckBx$GC@2S7(yA zNp_#-BOB&gD^_hj?f<b-jS$H$&i!&?WBG#D@EAaiCEz)QgZHx=dJ@(YkJ72;{=21` z%5fapWb@P4xuK1Pdj_0_g;D$@f~3tR+K+@uAIdQ7auZa~REFVd4A&k;ug8r3v=q5C zJ{XUj7`$@5P;2aXMoFk~@U<<8JC}Zpmur?R*_G_Q#Jz@49hNBaIcaWvah)EeLME#< zJuA<+Uxk$wV>%Airub|f-D$8gr;PZ(>fmgIRb)=8c&BM1MiMjN>QU~KnrI~B&V5@S zL`l~hhN-+GUbU^)M@VT%4hT}84-tQ!c*?EJ(WWa!>zW1~+H)RPpDoI<4oJ^$A{(Et zd(jll)z8yu@5Fcl;>Fj_u5qqmQ8BZtEl8n7B>e?E&BQL1w2<dfe+tDLK+Jc$Uah(W zVG7aJrASbyan@0@&uu~El#9@!q+GqeeE@O%U>?l))l#tFB|SJ@$NhO#96RhGU|LBC zur*+{#4~dlzc6Lh)G!4V<~UpSBXX)@V0!Ni{?7GOm{S@xPs4+fMeLKvF3ky7%YQH> z)GzzsNkMp5saGF#A*mOJEtQRXBaS{j<85L1*+H$ZEV%;bQd!P*$DE`^?|B4q-2<QG z+R2p<kcP3%e+|&J1fHDmWtJ$RWoUB_#{+LID&b;(*u>#D1FChkyd`r{>H{%h_UlwT zszO^LVO$lWtZz>>b`Zk1+ft47Jdu89lnO&Jwmu4n4eQWNBk$kDw|COEG=q8S;laP} zO3#gx8{6Z#8%gf!pJdFWinpb@ZpI!tH8R!XH0{id>XUC=34u)zLrNNZJU(i!OU0u0 zOo##|*frPwJ;9gpH&{H_qdC6X;Xc+DWN`4+il3Eb^BLh#OE)?I=$Bss$yG<o@JU1j z#nuclBZ3x|HCp7rmiZ4-O(B~)^FM*38RG6B%lLC1Yk808y#<)Qkbd6_kii)C+O!%q zQ}6r73kFFgHZ1)TcrStIl|+|*8-U0MD=`UoMYUXc-Tk|q^nT|=sUE>ag6KWq7lBsy z5`M=xrVTf5;f;v;S|n6MB4%a~^9j8}I!O@i?MV<wkPa{!uGAOY2@?wo2Sth4&{^3U z4s;92!>>~p3bo!tHnC%<5|Qz?N%;)nDfHINII>JQXrmitg}A)C*;Uaaju)`sMtQF? zYv$9DHPXX7HK6JCn##0l^<TFD#&c1nRBo7O59Iu_3hc0ige$Hz8f1{s8093%a7kgo zt=8+cYvU`*^aop4a3xtzsGy>Gb=zEqSe&EF#?quU<OoBA09O#mguDU1Ko@)~W%(>; z-IZfp(MPEM)1Pw|$guR5fiA0`^dD0or=b69#kUXmS2bb-xcsK*RtYo;N%eV<n+Df> zJE7W<=yo>TYe_Z>hi(x%Ym_!umFNJtI?z%-!FOMFfx!HY0@DO}-~|;ar06Dxbxw{8 zFA1Rhoubno4}qM^6VWhFhKIj%fLKcn2?Fr1ifredEhicB&00C=xR2r^hfNiw4|ey{ zN~4VNklTs&gwfISdpZZ+2U;eqz1a?2G3sIA?BMO?&F!fe`^$657y=?-`rx~BO}MdJ z_^Uj}Ri)8XnVL2sHsSP&q8e7Ui~4FKY(IUO^epTgZ@W%rOH?eyDK?*_-NqL)pqSZ_ ItNBv=8$V5yi2wiq literal 0 HcmV?d00001 diff --git a/resources/icons/view_toolbar.png b/resources/icons/view_toolbar.png index 26202a2a4236d2ca6f08d56b9d49db6267512f0f..dd1f5aca49d65d43bcbda9028c341ecc0998fde1 100644 GIT binary patch literal 21977 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 literal 18226 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 GGywpU_whdf diff --git a/src/libslic3r/Technologies.hpp b/src/libslic3r/Technologies.hpp index e0c35d55c..d604896ad 100644 --- a/src/libslic3r/Technologies.hpp +++ b/src/libslic3r/Technologies.hpp @@ -38,6 +38,8 @@ #define ENABLE_CONSTRAINED_CAMERA_TARGET (1 && ENABLE_1_42_0) // Use wxDataViewRender instead of wxDataViewCustomRenderer #define ENABLE_NONCUSTOM_DATA_VIEW_RENDERING (0 && ENABLE_1_42_0) +// Adds background texture to toolbars +#define ENABLE_TOOLBAR_BACKGROUND_TEXTURE (1 && ENABLE_1_42_0) #endif // _technologies_h_ diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 352ea2f49..8b1d636e5 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -3434,7 +3434,11 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas) : m_canvas(canvas) , m_context(nullptr) , m_in_render(false) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + , m_toolbar(GLToolbar::Normal) +#else , m_toolbar(*this) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #if ENABLE_REMOVE_TABS_FROM_PLATER , m_view_toolbar(nullptr) #endif // ENABLE_REMOVE_TABS_FROM_PLATER @@ -4675,7 +4679,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) int layer_editing_object_idx = is_layers_editing_enabled() ? selected_object_idx : -1; m_layers_editing.last_object_id = layer_editing_object_idx; bool gizmos_overlay_contains_mouse = m_gizmos.overlay_contains_mouse(*this, m_mouse.position); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + int toolbar_contains_mouse = m_toolbar.contains_mouse(m_mouse.position, *this); +#else int toolbar_contains_mouse = m_toolbar.contains_mouse(m_mouse.position); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #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 @@ -4699,7 +4707,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else if (evt.LeftDClick() && (toolbar_contains_mouse != -1)) { m_toolbar_action_running = true; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_toolbar.do_action((unsigned int)toolbar_contains_mouse, *this); +#else m_toolbar.do_action((unsigned int)toolbar_contains_mouse); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } else if (evt.LeftDClick() && (m_gizmos.get_current_type() != Gizmos::Undefined)) { @@ -4778,7 +4790,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) else if (toolbar_contains_mouse != -1) { m_toolbar_action_running = true; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_toolbar.do_action((unsigned int)toolbar_contains_mouse, *this); +#else m_toolbar.do_action((unsigned int)toolbar_contains_mouse); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE m_mouse.left_down = false; } else @@ -5061,7 +5077,11 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt) // updates toolbar overlay if (tooltip.empty()) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + tooltip = m_toolbar.update_hover_state(m_mouse.position, *this); +#else tooltip = m_toolbar.update_hover_state(m_mouse.position); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE // updates view toolbar overlay if (tooltip.empty() && (m_view_toolbar != nullptr)) @@ -5429,7 +5449,24 @@ bool GLCanvas3D::_init_toolbar() if (!m_toolbar.is_enabled()) return true; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + ItemsIconsTexture::Metadata icons_data; + icons_data.filename = "toolbar.png"; + icons_data.icon_size = 36; + icons_data.icon_border_size = 1; + icons_data.icon_gap_size = 1; + + BackgroundTexture::Metadata background_data; + background_data.filename = "toolbar_background.png"; + background_data.left = 16; + background_data.top = 16; + background_data.right = 16; + background_data.bottom = 16; + + if (!m_toolbar.init(icons_data, background_data)) +#else if (!m_toolbar.init("toolbar.png", 36, 1, 1)) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { // unable to init the toolbar texture, disable it m_toolbar.set_enabled(false); @@ -5438,6 +5475,10 @@ bool GLCanvas3D::_init_toolbar() // m_toolbar.set_layout_type(GLToolbar::Layout::Vertical); m_toolbar.set_layout_type(GLToolbar::Layout::Horizontal); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_toolbar.set_layout_orientation(GLToolbar::Layout::Top); + m_toolbar.set_border(5.0f); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE m_toolbar.set_separator_size(5); m_toolbar.set_gap_size(2); @@ -5524,9 +5565,6 @@ bool GLCanvas3D::_init_toolbar() if (!m_toolbar.add_item(item)) return false; - if (!m_toolbar.add_separator()) - return false; - enable_toolbar_item("add", true); return true; @@ -6063,7 +6101,11 @@ void GLCanvas3D::_render_toolbar() const #if !ENABLE_REMOVE_TABS_FROM_PLATER _resize_toolbar(); #endif // !ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_toolbar.render(*this); +#else m_toolbar.render(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } #if ENABLE_REMOVE_TABS_FROM_PLATER @@ -7721,25 +7763,54 @@ void GLCanvas3D::_resize_toolbar() const float zoom = get_camera_zoom(); float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + GLToolbar::Layout::EOrientation orientation = m_toolbar.get_layout_orientation(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + switch (m_toolbar.get_layout_type()) { default: case GLToolbar::Layout::Horizontal: { // centers the toolbar on the top edge of the 3d scene - unsigned int toolbar_width = m_toolbar.get_width(); - float top = (0.5f * (float)cnv_size.get_height() - 2.0f) * inv_zoom; - float left = -0.5f * (float)toolbar_width * inv_zoom; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float top, left; + if (orientation == GLToolbar::Layout::Top) + { + top = 0.5f * (float)cnv_size.get_height() * inv_zoom; + left = -0.5f * m_toolbar.get_width() * inv_zoom; + } + else + { + top = (-0.5f * (float)cnv_size.get_height() + m_view_toolbar->get_height()) * inv_zoom; + left = -0.5f * m_toolbar.get_width() * inv_zoom; + } +#else + float top = 0.5f * (float)cnv_size.get_height() * inv_zoom; + float left = -0.5f * m_toolbar.get_width() * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE m_toolbar.set_position(top, left); break; } case GLToolbar::Layout::Vertical: { // centers the toolbar on the right edge of the 3d scene - unsigned int toolbar_width = m_toolbar.get_width(); - unsigned int toolbar_height = m_toolbar.get_height(); - float top = 0.5f * (float)toolbar_height * inv_zoom; - float left = (0.5f * (float)cnv_size.get_width() - toolbar_width - 2.0f) * inv_zoom; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float top, left; + if (orientation == GLToolbar::Layout::Left) + { + top = 0.5f * m_toolbar.get_height() * inv_zoom; + left = (-0.5f * (float)cnv_size.get_width()) * inv_zoom; + } + else + { + top = 0.5f * m_toolbar.get_height() * inv_zoom; + left = (0.5f * (float)cnv_size.get_width() - m_toolbar.get_width()) * inv_zoom; + } +#else + float top = 0.5f * m_toolbar.get_height() * inv_zoom; + float left = (0.5f * (float)cnv_size.get_width() - m_toolbar.get_width()) * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE m_toolbar.set_position(top, left); break; } @@ -7748,6 +7819,7 @@ void GLCanvas3D::_resize_toolbar() const #if ENABLE_REMOVE_TABS_FROM_PLATER if (m_view_toolbar != nullptr) { + // places the toolbar on the bottom-left corner of the 3d scene 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); diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index 12a83eebd..ebc2929d9 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -769,7 +769,11 @@ private: mutable Gizmos m_gizmos; mutable GLToolbar m_toolbar; #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + GLToolbar* m_view_toolbar; +#else GLRadioToolbar* m_view_toolbar; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER ClippingPlane m_clipping_planes[2]; bool m_use_clipping_planes; @@ -824,7 +828,11 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas; } #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void set_view_toolbar(GLToolbar* toolbar) { m_view_toolbar = toolbar; } +#else void set_view_toolbar(GLRadioToolbar* toolbar) { m_view_toolbar = toolbar; } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER bool init(bool useVBOs, bool use_legacy_opengl); diff --git a/src/slic3r/GUI/GLToolbar.cpp b/src/slic3r/GUI/GLToolbar.cpp index 92b3e96af..a7f623b8d 100644 --- a/src/slic3r/GUI/GLToolbar.cpp +++ b/src/slic3r/GUI/GLToolbar.cpp @@ -75,6 +75,13 @@ bool GLToolbarItem::is_enabled() const return m_state != Disabled; } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +bool GLToolbarItem::is_disabled() const +{ + return m_state == Disabled; +} +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + bool GLToolbarItem::is_hovered() const { return (m_state == Hover) || (m_state == HoverPressed); @@ -124,24 +131,63 @@ GLTexture::Quad_UVs GLToolbarItem::get_uvs(unsigned int texture_size, unsigned i return uvs; } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +ItemsIconsTexture::Metadata::Metadata() + : filename("") + , icon_size(0) + , icon_border_size(0) + , icon_gap_size(0) +{ +} +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + +#if !ENABLE_TOOLBAR_BACKGROUND_TEXTURE ItemsIconsTexture::ItemsIconsTexture() : items_icon_size(0) , items_icon_border_size(0) , items_icon_gap_size(0) { } +#endif // !ENABLE_TOOLBAR_BACKGROUND_TEXTURE + +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +BackgroundTexture::Metadata::Metadata() + : filename("") + , left(0) + , right(0) + , top(0) + , bottom(0) +{ +} +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE GLToolbar::Layout::Layout() : type(Horizontal) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + , orientation(Center) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE , top(0.0f) , left(0.0f) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + , border(0.0f) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE , separator_size(0.0f) , gap_size(0.0f) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + , width(0.0f) + , height(0.0f) + , dirty(true) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +GLToolbar::GLToolbar(GLToolbar::EType type) + : m_type(type) +#else GLToolbar::GLToolbar(GLCanvas3D& parent) : m_parent(parent) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE , m_enabled(false) { } @@ -154,6 +200,26 @@ GLToolbar::~GLToolbar() } } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +bool GLToolbar::init(const ItemsIconsTexture::Metadata& icons_texture, const BackgroundTexture::Metadata& background_texture) +{ + 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.metadata = icons_texture; + + if (!background_texture.filename.empty()) + res = m_background_texture.texture.load_from_file(path + background_texture.filename, false); + + if (res) + m_background_texture.metadata = background_texture; + + return res; +} +#else bool GLToolbar::init(const std::string& icons_texture_filename, unsigned int items_icon_size, unsigned int items_icon_border_size, unsigned int items_icon_gap_size) { std::string path = resources_dir() + "/icons/"; @@ -167,31 +233,61 @@ bool GLToolbar::init(const std::string& icons_texture_filename, unsigned int ite return res; } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE -GLToolbar::Layout::Type GLToolbar::get_layout_type() const +GLToolbar::Layout::EType GLToolbar::get_layout_type() const { return m_layout.type; } -void GLToolbar::set_layout_type(GLToolbar::Layout::Type type) +void GLToolbar::set_layout_type(GLToolbar::Layout::EType type) { m_layout.type = type; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_layout.dirty = true; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +GLToolbar::Layout::EOrientation GLToolbar::get_layout_orientation() const +{ + return m_layout.orientation; +} + +void GLToolbar::set_layout_orientation(GLToolbar::Layout::EOrientation orientation) +{ + m_layout.orientation = orientation; +} +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void GLToolbar::set_position(float top, float left) { m_layout.top = top; m_layout.left = left; } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::set_border(float border) +{ + m_layout.border = border; + m_layout.dirty = true; +} +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void GLToolbar::set_separator_size(float size) { m_layout.separator_size = size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_layout.dirty = true; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } void GLToolbar::set_gap_size(float size) { m_layout.gap_size = size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_layout.dirty = true; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } bool GLToolbar::is_enabled() const @@ -211,6 +307,9 @@ bool GLToolbar::add_item(const GLToolbarItem::Data& data) return false; m_items.push_back(item); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_layout.dirty = true; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE return true; } @@ -222,11 +321,20 @@ bool GLToolbar::add_separator() return false; m_items.push_back(item); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + m_layout.dirty = true; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE return true; } float GLToolbar::get_width() const { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + if (m_layout.dirty) + calc_layout(); + + return m_layout.width; +#else switch (m_layout.type) { default: @@ -239,10 +347,17 @@ float GLToolbar::get_width() const return get_width_vertical(); } } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } float GLToolbar::get_height() const { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + if (m_layout.dirty) + calc_layout(); + + return m_layout.height; +#else switch (m_layout.type) { default: @@ -255,6 +370,7 @@ float GLToolbar::get_height() const return get_height_vertical(); } } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } void GLToolbar::enable_item(const std::string& name) @@ -281,6 +397,23 @@ void GLToolbar::disable_item(const std::string& name) } } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::select_item(const std::string& name) +{ + if (is_item_disabled(name)) + return; + + for (GLToolbarItem* item : m_items) + { + if (!item->is_disabled()) + { + bool hover = item->is_hovered(); + item->set_state((item->get_name() == name) ? (hover ? GLToolbarItem::HoverPressed : GLToolbarItem::Pressed) : (hover ? GLToolbarItem::Hover : GLToolbarItem::Normal)); + } + } +} +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + bool GLToolbar::is_item_pressed(const std::string& name) const { for (GLToolbarItem* item : m_items) @@ -292,10 +425,31 @@ bool GLToolbar::is_item_pressed(const std::string& name) const return false; } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +bool GLToolbar::is_item_disabled(const std::string& name) const +{ + for (GLToolbarItem* item : m_items) + { + if (item->get_name() == name) + return item->is_disabled(); + } + + return false; +} +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent) +#else std::string GLToolbar::update_hover_state(const Vec2d& mouse_pos) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE +#else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent) #else void GLToolbar::update_hover_state(const Vec2d& mouse_pos) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER { #if ENABLE_REMOVE_TABS_FROM_PLATER @@ -310,24 +464,30 @@ void GLToolbar::update_hover_state(const Vec2d& mouse_pos) { default: #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + case Layout::Horizontal: { return update_hover_state_horizontal(mouse_pos, parent); } + case Layout::Vertical: { return update_hover_state_vertical(mouse_pos, parent); } +#else case Layout::Horizontal: { return update_hover_state_horizontal(mouse_pos); } case Layout::Vertical: { return update_hover_state_vertical(mouse_pos); } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #else - case Layout::Horizontal: - { - update_hover_state_horizontal(mouse_pos); - break; - } - case Layout::Vertical: - { - update_hover_state_vertical(mouse_pos); - break; - } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + case Layout::Horizontal: { update_hover_state_horizontal(mouse_pos, parent); break; } + case Layout::Vertical: { update_hover_state_vertical(mouse_pos, parent); break; } +#else + case Layout::Horizontal: { update_hover_state_horizontal(mouse_pos); break; } + case Layout::Vertical: { update_hover_state_vertical(mouse_pos); break; } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER } } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +int GLToolbar::contains_mouse(const Vec2d& mouse_pos, const GLCanvas3D& parent) const +#else int GLToolbar::contains_mouse(const Vec2d& mouse_pos) const +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { if (!m_enabled) return -1; @@ -335,18 +495,21 @@ int GLToolbar::contains_mouse(const Vec2d& mouse_pos) const switch (m_layout.type) { default: - case Layout::Horizontal: - { - return contains_mouse_horizontal(mouse_pos); - } - case Layout::Vertical: - { - return contains_mouse_vertical(mouse_pos); - } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + case Layout::Horizontal: { return contains_mouse_horizontal(mouse_pos, parent); } + case Layout::Vertical: { return contains_mouse_vertical(mouse_pos, parent); } +#else + case Layout::Horizontal: { return contains_mouse_horizontal(mouse_pos); } + case Layout::Vertical: { return contains_mouse_vertical(mouse_pos); } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::do_action(unsigned int item_id, GLCanvas3D& parent) +#else void GLToolbar::do_action(unsigned int item_id) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { if (item_id < (unsigned int)m_items.size()) { @@ -361,26 +524,51 @@ void GLToolbar::do_action(unsigned int item_id) else if (state == GLToolbarItem::HoverPressed) item->set_state(GLToolbarItem::Hover); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.render(); + item->do_action(parent.get_wxglcanvas()); +#else m_parent.render(); item->do_action(m_parent.get_wxglcanvas()); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } else { - item->set_state(GLToolbarItem::HoverPressed); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + if (m_type == Radio) + select_item(item->get_name()); + else +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + item->set_state(GLToolbarItem::HoverPressed); + +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.render(); + item->do_action(parent.get_wxglcanvas()); + if ((m_type == Normal) && (item->get_state() != GLToolbarItem::Disabled)) +#else m_parent.render(); item->do_action(m_parent.get_wxglcanvas()); if (item->get_state() != GLToolbarItem::Disabled) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { // the item may get disabled during the action, if not, set it back to hover state item->set_state(GLToolbarItem::Hover); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.render(); +#else m_parent.render(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } } } } } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::render(const GLCanvas3D& parent) const +#else void GLToolbar::render() const +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { if (!m_enabled || m_items.empty()) return; @@ -393,21 +581,42 @@ void GLToolbar::render() const switch (m_layout.type) { default: - case Layout::Horizontal: - { - render_horizontal(); - break; - } - case Layout::Vertical: - { - render_vertical(); - break; - } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + case Layout::Horizontal: { render_horizontal(parent); break; } + case Layout::Vertical: { render_vertical(parent); break; } +#else + case Layout::Horizontal: { render_horizontal(); break; } + case Layout::Vertical: { render_vertical(); break; } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } ::glPopMatrix(); } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::calc_layout() const +{ + switch (m_layout.type) + { + default: + case Layout::Horizontal: + { + m_layout.width = get_width_horizontal(); + m_layout.height = get_height_horizontal(); + break; + } + case Layout::Vertical: + { + m_layout.width = get_width_vertical(); + m_layout.height = get_height_vertical(); + break; + } + } + + m_layout.dirty = false; +} +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float GLToolbar::get_width_horizontal() const { return get_main_size(); @@ -415,12 +624,20 @@ float GLToolbar::get_width_horizontal() const float GLToolbar::get_width_vertical() const { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + return 2.0f * m_layout.border + m_icons_texture.metadata.icon_size; +#else return m_icons_texture.items_icon_size; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } float GLToolbar::get_height_horizontal() const { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + return 2.0f * m_layout.border + m_icons_texture.metadata.icon_size; +#else return m_icons_texture.items_icon_size; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } float GLToolbar::get_height_vertical() const @@ -430,13 +647,21 @@ float GLToolbar::get_height_vertical() const float GLToolbar::get_main_size() const { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float size = 2.0f * m_layout.border; +#else float size = 0.0f; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE for (unsigned int i = 0; i < (unsigned int)m_items.size(); ++i) { if (m_items[i]->is_separator()) size += m_layout.separator_size; else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + size += (float)m_icons_texture.metadata.icon_size; +#else size += (float)m_icons_texture.items_icon_size; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } if (m_items.size() > 1) @@ -446,26 +671,54 @@ float GLToolbar::get_main_size() const } #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent) +#else std::string GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE +#else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent) #else void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float zoom = parent.get_camera_zoom(); +#else float zoom = m_parent.get_camera_zoom(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + Size cnv_size = parent.get_canvas_size(); +#else Size cnv_size = m_parent.get_canvas_size(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE 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); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * inv_zoom; +#else float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float scaled_separator_size = m_layout.separator_size * inv_zoom; float scaled_gap_size = m_layout.gap_size * inv_zoom; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_border = m_layout.border * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float separator_stride = scaled_separator_size + scaled_gap_size; float icon_stride = scaled_icons_size + scaled_gap_size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float left = m_layout.left + scaled_border; + float top = m_layout.top - scaled_border; +#else float left = m_layout.left; float top = m_layout.top; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE std::string tooltip = ""; @@ -486,7 +739,14 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos) case GLToolbarItem::Normal: { if (inside) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + { +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE item->set_state(GLToolbarItem::Hover); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.set_as_dirty(); + } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE break; } @@ -495,15 +755,29 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos) if (inside) tooltip = item->get_tooltip(); else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + { +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE item->set_state(GLToolbarItem::Normal); - +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.set_as_dirty(); + } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + break; } case GLToolbarItem::Pressed: { if (inside) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + { +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE item->set_state(GLToolbarItem::HoverPressed); - +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.set_as_dirty(); + } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + break; } case GLToolbarItem::HoverPressed: @@ -511,8 +785,15 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos) if (inside) tooltip = item->get_tooltip(); else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + { +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE item->set_state(GLToolbarItem::Pressed); - +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.set_as_dirty(); + } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + break; } default: @@ -535,26 +816,54 @@ void GLToolbar::update_hover_state_horizontal(const Vec2d& mouse_pos) } #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent) +#else std::string GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE +#else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent) #else void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float zoom = parent.get_camera_zoom(); +#else float zoom = m_parent.get_camera_zoom(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + Size cnv_size = parent.get_canvas_size(); +#else Size cnv_size = m_parent.get_canvas_size(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE 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); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * inv_zoom; +#else float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float scaled_separator_size = m_layout.separator_size * inv_zoom; float scaled_gap_size = m_layout.gap_size * inv_zoom; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_border = m_layout.border * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float separator_stride = scaled_separator_size + scaled_gap_size; float icon_stride = scaled_icons_size + scaled_gap_size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float left = m_layout.left + scaled_border; + float top = m_layout.top - scaled_border; +#else float left = m_layout.left; float top = m_layout.top; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE std::string tooltip = ""; @@ -575,7 +884,14 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos) case GLToolbarItem::Normal: { if (inside) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + { +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE item->set_state(GLToolbarItem::Hover); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.set_as_dirty(); + } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE break; } @@ -584,14 +900,28 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos) if (inside) tooltip = item->get_tooltip(); else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + { +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE item->set_state(GLToolbarItem::Normal); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.set_as_dirty(); + } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE break; } case GLToolbarItem::Pressed: { if (inside) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + { +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE item->set_state(GLToolbarItem::HoverPressed); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.set_as_dirty(); + } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE break; } @@ -600,7 +930,14 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos) if (inside) tooltip = item->get_tooltip(); else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + { +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE item->set_state(GLToolbarItem::Pressed); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + parent.set_as_dirty(); + } +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE break; } @@ -622,23 +959,47 @@ void GLToolbar::update_hover_state_vertical(const Vec2d& mouse_pos) #endif // ENABLE_REMOVE_TABS_FROM_PLATER } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const +#else int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos) const +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float zoom = parent.get_camera_zoom(); +#else float zoom = m_parent.get_camera_zoom(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + Size cnv_size = parent.get_canvas_size(); +#else Size cnv_size = m_parent.get_canvas_size(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE 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); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * inv_zoom; +#else float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float scaled_separator_size = m_layout.separator_size * inv_zoom; float scaled_gap_size = m_layout.gap_size * inv_zoom; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_border = m_layout.border * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float separator_stride = scaled_separator_size + scaled_gap_size; float icon_stride = scaled_icons_size + scaled_gap_size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float left = m_layout.left + scaled_border; + float top = m_layout.top - scaled_border; +#else float left = m_layout.left; float top = m_layout.top; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE int id = -1; @@ -663,23 +1024,47 @@ int GLToolbar::contains_mouse_horizontal(const Vec2d& mouse_pos) const return -1; } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const +#else int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos) const +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float zoom = parent.get_camera_zoom(); +#else float zoom = m_parent.get_camera_zoom(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + Size cnv_size = parent.get_canvas_size(); +#else Size cnv_size = m_parent.get_canvas_size(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE 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); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * inv_zoom; +#else float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float scaled_separator_size = m_layout.separator_size * inv_zoom; float scaled_gap_size = m_layout.gap_size * inv_zoom; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_border = m_layout.border * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float separator_stride = scaled_separator_size + scaled_gap_size; float icon_stride = scaled_icons_size + scaled_gap_size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float left = m_layout.left + scaled_border; + float top = m_layout.top - scaled_border; +#else float left = m_layout.left; float top = m_layout.top; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE int id = -1; @@ -704,7 +1089,11 @@ int GLToolbar::contains_mouse_vertical(const Vec2d& mouse_pos) const return -1; } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::render_horizontal(const GLCanvas3D& parent) const +#else void GLToolbar::render_horizontal() const +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { unsigned int tex_id = m_icons_texture.texture.get_id(); int tex_size = m_icons_texture.texture.get_width(); @@ -712,18 +1101,124 @@ void GLToolbar::render_horizontal() const if ((tex_id == 0) || (tex_size <= 0)) return; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float zoom = parent.get_camera_zoom(); +#else float zoom = m_parent.get_camera_zoom(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * inv_zoom; +#else float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float scaled_separator_size = m_layout.separator_size * inv_zoom; float scaled_gap_size = m_layout.gap_size * inv_zoom; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_border = m_layout.border * inv_zoom; + float scaled_width = get_width() * inv_zoom; + float scaled_height = get_height() * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float separator_stride = scaled_separator_size + scaled_gap_size; float icon_stride = scaled_icons_size + scaled_gap_size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE float left = m_layout.left; float top = m_layout.top; + float right = left + scaled_width; + float bottom = top - scaled_height; + + // renders background + unsigned int bg_tex_id = m_background_texture.texture.get_id(); + float bg_tex_width = (float)m_background_texture.texture.get_width(); + float bg_tex_height = (float)m_background_texture.texture.get_height(); + if ((bg_tex_id != 0) && (bg_tex_width > 0) && (bg_tex_height > 0)) + { + float inv_bg_tex_width = (bg_tex_width != 0.0f) ? 1.0f / bg_tex_width : 0.0f; + float inv_bg_tex_height = (bg_tex_height != 0.0f) ? 1.0f / bg_tex_height : 0.0f; + + float bg_uv_left = 0.0f; + float bg_uv_right = 1.0f; + float bg_uv_top = 1.0f; + float bg_uv_bottom = 0.0f; + + float bg_left = left; + float bg_right = right; + float bg_top = top; + float bg_bottom = bottom; + float bg_width = right - left; + float bg_height = top - bottom; + float bg_min_size = std::min(bg_width, bg_height); + + float bg_uv_i_left = (float)m_background_texture.metadata.left * inv_bg_tex_width; + float bg_uv_i_right = 1.0f - (float)m_background_texture.metadata.right * inv_bg_tex_width; + float bg_uv_i_top = 1.0f - (float)m_background_texture.metadata.top * inv_bg_tex_height; + float bg_uv_i_bottom = (float)m_background_texture.metadata.bottom * inv_bg_tex_height; + + float bg_i_left = bg_left + scaled_border; + float bg_i_right = bg_right - scaled_border; + float bg_i_top = bg_top - scaled_border; + float bg_i_bottom = bg_bottom + scaled_border; + + switch (m_layout.orientation) + { + case Layout::Top: + { + bg_uv_top = bg_uv_i_top; + bg_i_top = bg_top; + break; + } + case Layout::Bottom: + { + bg_uv_bottom = bg_uv_i_bottom; + bg_i_bottom = bg_bottom; + break; + } + case Layout::Center: + { + break; + } + }; + + if ((m_layout.border > 0) && (bg_uv_top != bg_uv_i_top)) + { + if (bg_uv_left != bg_uv_i_left) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_top, bg_top, { { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_top }, { bg_uv_i_left, bg_uv_top } }); + + if (bg_uv_right != bg_uv_i_right) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } }); + } + + if ((m_layout.border > 0) && (bg_uv_left != bg_uv_i_left)) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } }); + + if ((m_layout.border > 0) && (bg_uv_right != bg_uv_i_right)) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } }); + + if ((m_layout.border > 0) && (bg_uv_bottom != bg_uv_i_bottom)) + { + if (bg_uv_left != bg_uv_i_left) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_bottom, bg_i_bottom, { { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_right, bg_uv_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom } }); + + if (bg_uv_right != bg_uv_i_right) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_bottom, bg_i_bottom, { { bg_uv_i_right, bg_uv_bottom }, { bg_uv_right, bg_uv_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom } }); + } + } + + left += scaled_border; + top -= scaled_border; +#else + float left = m_layout.left; + float top = m_layout.top; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE // renders icons for (const GLToolbarItem* item : m_items) @@ -732,13 +1227,21 @@ void GLToolbar::render_horizontal() const left += separator_stride; else { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.metadata.icon_border_size, m_icons_texture.metadata.icon_size, m_icons_texture.metadata.icon_gap_size); +#else 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); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE left += icon_stride; } } } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void GLToolbar::render_vertical(const GLCanvas3D& parent) const +#else void GLToolbar::render_vertical() const +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { unsigned int tex_id = m_icons_texture.texture.get_id(); int tex_size = m_icons_texture.texture.get_width(); @@ -746,18 +1249,124 @@ void GLToolbar::render_vertical() const if ((tex_id == 0) || (tex_size <= 0)) return; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float zoom = parent.get_camera_zoom(); +#else float zoom = m_parent.get_camera_zoom(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float inv_zoom = (zoom != 0.0f) ? 1.0f / zoom : 0.0f; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_icons_size = (float)m_icons_texture.metadata.icon_size * inv_zoom; +#else float scaled_icons_size = (float)m_icons_texture.items_icon_size * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float scaled_separator_size = m_layout.separator_size * inv_zoom; float scaled_gap_size = m_layout.gap_size * inv_zoom; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float scaled_border = m_layout.border * inv_zoom; + float scaled_width = get_width() * inv_zoom; + float scaled_height = get_height() * inv_zoom; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float separator_stride = scaled_separator_size + scaled_gap_size; float icon_stride = scaled_icons_size + scaled_gap_size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE float left = m_layout.left; float top = m_layout.top; + float right = left + scaled_width; + float bottom = top - scaled_height; + + // renders background + unsigned int bg_tex_id = m_background_texture.texture.get_id(); + float bg_tex_width = (float)m_background_texture.texture.get_width(); + float bg_tex_height = (float)m_background_texture.texture.get_height(); + if ((bg_tex_id != 0) && (bg_tex_width > 0) && (bg_tex_height > 0)) + { + float inv_bg_tex_width = (bg_tex_width != 0.0f) ? 1.0f / bg_tex_width : 0.0f; + float inv_bg_tex_height = (bg_tex_height != 0.0f) ? 1.0f / bg_tex_height : 0.0f; + + float bg_uv_left = 0.0f; + float bg_uv_right = 1.0f; + float bg_uv_top = 1.0f; + float bg_uv_bottom = 0.0f; + + float bg_left = left; + float bg_right = right; + float bg_top = top; + float bg_bottom = bottom; + float bg_width = right - left; + float bg_height = top - bottom; + float bg_min_size = std::min(bg_width, bg_height); + + float bg_uv_i_left = (float)m_background_texture.metadata.left * inv_bg_tex_width; + float bg_uv_i_right = 1.0f - (float)m_background_texture.metadata.right * inv_bg_tex_width; + float bg_uv_i_top = 1.0f - (float)m_background_texture.metadata.top * inv_bg_tex_height; + float bg_uv_i_bottom = (float)m_background_texture.metadata.bottom * inv_bg_tex_height; + + float bg_i_left = bg_left + scaled_border; + float bg_i_right = bg_right - scaled_border; + float bg_i_top = bg_top - scaled_border; + float bg_i_bottom = bg_bottom + scaled_border; + + switch (m_layout.orientation) + { + case Layout::Left: + { + bg_uv_left = bg_uv_i_left; + bg_i_left = bg_left; + break; + } + case Layout::Right: + { + bg_uv_right = bg_uv_i_right; + bg_i_right = bg_right; + break; + } + case Layout::Center: + { + break; + } + }; + + if ((m_layout.border > 0) && (bg_uv_top != bg_uv_i_top)) + { + if (bg_uv_left != bg_uv_i_left) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_top, bg_top, { { bg_uv_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_left, bg_uv_top }, { bg_uv_left, bg_uv_top } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_top, bg_top, { { bg_uv_i_left, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_top }, { bg_uv_i_left, bg_uv_top } }); + + if (bg_uv_right != bg_uv_i_right) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_top, bg_top, { { bg_uv_i_right, bg_uv_i_top }, { bg_uv_right, bg_uv_i_top }, { bg_uv_right, bg_uv_top }, { bg_uv_i_right, bg_uv_top } }); + } + + if ((m_layout.border > 0) && (bg_uv_left != bg_uv_i_left)) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_i_bottom, bg_i_top, { { bg_uv_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_top }, { bg_uv_left, bg_uv_i_top } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_i_bottom, bg_i_top, { { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_top }, { bg_uv_i_left, bg_uv_i_top } }); + + if ((m_layout.border > 0) && (bg_uv_right != bg_uv_i_right)) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_i_bottom, bg_i_top, { { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_right, bg_uv_i_top }, { bg_uv_i_right, bg_uv_i_top } }); + + if ((m_layout.border > 0) && (bg_uv_bottom != bg_uv_i_bottom)) + { + if (bg_uv_left != bg_uv_i_left) + GLTexture::render_sub_texture(bg_tex_id, bg_left, bg_i_left, bg_bottom, bg_i_bottom, { { bg_uv_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_left, bg_uv_i_bottom }, { bg_uv_left, bg_uv_i_bottom } }); + + GLTexture::render_sub_texture(bg_tex_id, bg_i_left, bg_i_right, bg_bottom, bg_i_bottom, { { bg_uv_i_left, bg_uv_bottom }, { bg_uv_i_right, bg_uv_bottom }, { bg_uv_i_right, bg_uv_i_bottom }, { bg_uv_i_left, bg_uv_i_bottom } }); + + if (bg_uv_right != bg_uv_i_right) + GLTexture::render_sub_texture(bg_tex_id, bg_i_right, bg_right, bg_bottom, bg_i_bottom, { { bg_uv_i_right, bg_uv_bottom }, { bg_uv_right, bg_uv_bottom }, { bg_uv_right, bg_uv_i_bottom }, { bg_uv_i_right, bg_uv_i_bottom } }); + } + } + + left += scaled_border; + top -= scaled_border; +#else + float left = m_layout.left; + float top = m_layout.top; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE // renders icons for (const GLToolbarItem* item : m_items) @@ -766,12 +1375,17 @@ void GLToolbar::render_vertical() const top -= separator_stride; else { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + item->render(tex_id, left, left + scaled_icons_size, top - scaled_icons_size, top, (unsigned int)tex_size, m_icons_texture.metadata.icon_border_size, m_icons_texture.metadata.icon_size, m_icons_texture.metadata.icon_gap_size); +#else 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); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE top -= icon_stride; } } } +#if !ENABLE_TOOLBAR_BACKGROUND_TEXTURE GLRadioToolbarItem::Data::Data() : name("") , tooltip("") @@ -1075,6 +1689,7 @@ void GLRadioToolbar::render(const GLCanvas3D& parent) const ::glPopMatrix(); } +#endif // !ENABLE_TOOLBAR_BACKGROUND_TEXTURE } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GLToolbar.hpp b/src/slic3r/GUI/GLToolbar.hpp index 7eab518f7..4e15edd17 100644 --- a/src/slic3r/GUI/GLToolbar.hpp +++ b/src/slic3r/GUI/GLToolbar.hpp @@ -77,6 +77,9 @@ public: void do_action(wxEvtHandler *target); bool is_enabled() const; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + bool is_disabled() const; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE bool is_hovered() const; bool is_pressed() const; @@ -94,7 +97,25 @@ private: // from left to right struct ItemsIconsTexture { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + struct Metadata + { + // path of the file containing the icons' texture + std::string filename; + // size of the square icons, in pixels + unsigned int icon_size; + // size of the border, in pixels + unsigned int icon_border_size; + // distance between two adjacent icons (to avoid filtering artifacts), in pixels + unsigned int icon_gap_size; + + Metadata(); + }; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE GLTexture texture; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + Metadata metadata; +#else // size of the square icons, in pixels unsigned int items_icon_size; // distance from the border, in pixels @@ -103,49 +124,129 @@ struct ItemsIconsTexture unsigned int items_icon_gap_size; ItemsIconsTexture(); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE }; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +struct BackgroundTexture +{ + struct Metadata + { + // path of the file containing the background texture + std::string filename; + // size of the left edge, in pixels + unsigned int left; + // size of the right edge, in pixels + unsigned int right; + // size of the top edge, in pixels + unsigned int top; + // size of the bottom edge, in pixels + unsigned int bottom; + + Metadata(); + }; + + GLTexture texture; + Metadata metadata; +}; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + class GLToolbar { public: +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + enum EType : unsigned char + { + Normal, + Radio, + Num_Types + }; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + struct Layout { - enum Type : unsigned char + enum EType : unsigned char { Horizontal, Vertical, Num_Types }; - Type type; + enum EOrientation : unsigned int + { + Top, + Bottom, + Left, + Right, + Center, + Num_Locations + }; + + EType type; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + EOrientation orientation; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float top; float left; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float border; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float separator_size; float gap_size; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + float width; + float height; + bool dirty; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + Layout(); }; private: typedef std::vector<GLToolbarItem*> ItemsList; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + EType m_type; +#else GLCanvas3D& m_parent; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE bool m_enabled; ItemsIconsTexture m_icons_texture; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + BackgroundTexture m_background_texture; + mutable Layout m_layout; +#else Layout m_layout; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE ItemsList m_items; public: +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + explicit GLToolbar(EType type); +#else explicit GLToolbar(GLCanvas3D& parent); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE ~GLToolbar(); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + bool init(const ItemsIconsTexture::Metadata& icons_texture, const BackgroundTexture::Metadata& background_texture); +#else 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); - - Layout::Type get_layout_type() const; - void set_layout_type(Layout::Type type); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE + + Layout::EType get_layout_type() const; + void set_layout_type(Layout::EType type); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + Layout::EOrientation get_layout_orientation() const; + void set_layout_orientation(Layout::EOrientation orientation); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE void set_position(float top, float left); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void set_border(float border); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE void set_separator_size(float size); void set_gap_size(float size); @@ -160,42 +261,89 @@ public: void enable_item(const std::string& name); void disable_item(const std::string& name); +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void select_item(const std::string& name); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE bool is_item_pressed(const std::string& name) const; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + bool is_item_disabled(const std::string& name) const; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + std::string update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent); +#else std::string update_hover_state(const Vec2d& mouse_pos); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE +#else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void update_hover_state(const Vec2d& mouse_pos, GLCanvas3D& parent); #else void update_hover_state(const Vec2d& mouse_pos); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + // 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; + + void do_action(unsigned int item_id, GLCanvas3D& parent); +#else // returns the id of the item under the given mouse position or -1 if none int contains_mouse(const Vec2d& mouse_pos) const; void do_action(unsigned int item_id); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void render(const GLCanvas3D& parent) const; +#else void render() const; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE private: +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void calc_layout() const; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE float get_width_horizontal() const; float get_width_vertical() const; float get_height_horizontal() const; float get_height_vertical() const; float get_main_size() const; #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + std::string update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent); + std::string update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent); +#else std::string update_hover_state_horizontal(const Vec2d& mouse_pos); std::string update_hover_state_vertical(const Vec2d& mouse_pos); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE +#else +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void update_hover_state_horizontal(const Vec2d& mouse_pos, GLCanvas3D& parent); + void update_hover_state_vertical(const Vec2d& mouse_pos, GLCanvas3D& parent); #else void update_hover_state_horizontal(const Vec2d& mouse_pos); void update_hover_state_vertical(const Vec2d& mouse_pos); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + int contains_mouse_horizontal(const Vec2d& mouse_pos, const GLCanvas3D& parent) const; + int contains_mouse_vertical(const Vec2d& mouse_pos, const GLCanvas3D& parent) const; + + void render_horizontal(const GLCanvas3D& parent) const; + void render_vertical(const GLCanvas3D& parent) const; +#else int contains_mouse_horizontal(const Vec2d& mouse_pos) const; int contains_mouse_vertical(const Vec2d& mouse_pos) const; void render_horizontal() const; void render_vertical() const; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE }; +#if !ENABLE_TOOLBAR_BACKGROUND_TEXTURE class GLRadioToolbarItem { public: @@ -274,6 +422,7 @@ public: void render(const GLCanvas3D& parent) const; }; +#endif // !ENABLE_TOOLBAR_BACKGROUND_TEXTURE } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/GUI_Preview.cpp b/src/slic3r/GUI/GUI_Preview.cpp index 724815076..4e14aefe8 100644 --- a/src/slic3r/GUI/GUI_Preview.cpp +++ b/src/slic3r/GUI/GUI_Preview.cpp @@ -92,7 +92,11 @@ bool View3D::init(wxWindow* parent, Model* model, DynamicPrintConfig* config, Ba return true; } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void View3D::set_view_toolbar(GLToolbar* toolbar) +#else void View3D::set_view_toolbar(GLRadioToolbar* toolbar) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { if (m_canvas != nullptr) m_canvas->set_view_toolbar(toolbar); @@ -365,7 +369,11 @@ Preview::~Preview() } #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +void Preview::set_view_toolbar(GLToolbar* toolbar) +#else void Preview::set_view_toolbar(GLRadioToolbar* toolbar) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { if (m_canvas != nullptr) m_canvas->set_view_toolbar(toolbar); diff --git a/src/slic3r/GUI/GUI_Preview.hpp b/src/slic3r/GUI/GUI_Preview.hpp index 2aebdccd5..23e6a682f 100644 --- a/src/slic3r/GUI/GUI_Preview.hpp +++ b/src/slic3r/GUI/GUI_Preview.hpp @@ -28,9 +28,15 @@ class Model; namespace GUI { class GLCanvas3D; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE +#if ENABLE_REMOVE_TABS_FROM_PLATER +class GLToolbar; +#endif // ENABLE_REMOVE_TABS_FROM_PLATER +#else #if ENABLE_REMOVE_TABS_FROM_PLATER class GLRadioToolbar; #endif // ENABLE_REMOVE_TABS_FROM_PLATER +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #if ENABLE_REMOVE_TABS_FROM_PLATER class View3D : public wxPanel @@ -53,7 +59,11 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } GLCanvas3D* get_canvas3d() { return m_canvas; } +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void set_view_toolbar(GLToolbar* toolbar); +#else void set_view_toolbar(GLRadioToolbar* toolbar); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE void set_as_dirty(); void set_bed_shape(const Pointfs& shape); @@ -122,7 +132,11 @@ public: wxGLCanvas* get_wxglcanvas() { return m_canvas_widget; } #if ENABLE_REMOVE_TABS_FROM_PLATER +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + void set_view_toolbar(GLToolbar* toolbar); +#else void set_view_toolbar(GLRadioToolbar* toolbar); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #endif // ENABLE_REMOVE_TABS_FROM_PLATER void set_number_extruders(unsigned int number_extruders); diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 381a9e864..8db804c12 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -913,7 +913,11 @@ struct Plater::priv Sidebar *sidebar; #if ENABLE_REMOVE_TABS_FROM_PLATER View3D* view3D; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + GLToolbar view_toolbar; +#else GLRadioToolbar view_toolbar; +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE #else #if !ENABLE_IMGUI wxPanel *panel3d; @@ -1068,6 +1072,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) #endif // !ENABLE_REMOVE_TABS_FROM_PLATER , delayed_scene_refresh(false) , project_filename(wxEmptyString) +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + , view_toolbar(GLToolbar::Radio) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE { arranging.store(false); rotoptimizing.store(false); @@ -1286,7 +1293,9 @@ void Plater::priv::select_view_3D(const std::string& name) else if (name == "Preview") set_current_panel(preview); +#if !ENABLE_TOOLBAR_BACKGROUND_TEXTURE view_toolbar.set_selection(name); +#endif // !ENABLE_TOOLBAR_BACKGROUND_TEXTURE } #else void Plater::priv::select_view(const std::string& direction) @@ -2646,9 +2655,58 @@ bool Plater::priv::complit_init_part_menu() #if ENABLE_REMOVE_TABS_FROM_PLATER void Plater::priv::init_view_toolbar() { +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + ItemsIconsTexture::Metadata icons_data; + icons_data.filename = "view_toolbar.png"; + icons_data.icon_size = 64; + icons_data.icon_border_size = 0; + icons_data.icon_gap_size = 0; + + BackgroundTexture::Metadata background_data; + background_data.filename = "toolbar_background.png"; + background_data.left = 16; + background_data.top = 16; + background_data.right = 16; + background_data.bottom = 16; + + if (!view_toolbar.init(icons_data, background_data)) +#else if (!view_toolbar.init("view_toolbar.png", 64, 0, 0)) +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE return; +#if ENABLE_TOOLBAR_BACKGROUND_TEXTURE + view_toolbar.set_layout_orientation(GLToolbar::Layout::Bottom); + view_toolbar.set_border(5.0f); + view_toolbar.set_gap_size(1.0f); + + GLToolbarItem::Data item; + + item.name = "3D"; + item.tooltip = GUI::L_str("3D editor view"); + item.sprite_id = 0; + item.action_event = EVT_GLVIEWTOOLBAR_3D; + item.is_toggable = false; + 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; + item.is_toggable = false; + if (!view_toolbar.add_item(item)) + return; + + view_toolbar.enable_item("3D"); + view_toolbar.enable_item("Preview"); + + view_toolbar.select_item("3D"); + view_toolbar.set_enabled(true); + + view3D->set_view_toolbar(&view_toolbar); + preview->set_view_toolbar(&view_toolbar); +#else GLRadioToolbarItem::Data item; item.name = "3D"; @@ -2669,6 +2727,7 @@ void Plater::priv::init_view_toolbar() preview->set_view_toolbar(&view_toolbar); view_toolbar.set_selection("3D"); +#endif // ENABLE_TOOLBAR_BACKGROUND_TEXTURE } #endif // ENABLE_REMOVE_TABS_FROM_PLATER