diff --git a/specter/include/Specter/Button.hpp b/specter/include/Specter/Button.hpp index 5aa4ffe3c..87508a0bb 100644 --- a/specter/include/Specter/Button.hpp +++ b/specter/include/Specter/Button.hpp @@ -1,4 +1,56 @@ #ifndef SPECTER_BUTTON_HPP #define SPECTER_BUTTON_HPP +#include "Specter/TextView.hpp" +#include "Specter/Button.hpp" + +namespace Specter +{ + +class Button : public View +{ + std::string m_textStr; + std::unique_ptr m_text; + SolidShaderVert m_verts[28]; + + ViewBlock m_bBlock; + boo::IGraphicsBufferD* m_bBlockBuf; + + boo::IGraphicsBufferD* m_bVertsBuf; + boo::IVertexFormat* m_bVtxFmt; /* OpenGL only */ + boo::IShaderDataBinding* m_bShaderBinding; + + int m_nomWidth, m_nomHeight; + bool m_pressed = false; + bool m_hovered = false; + + void setInactive(); + void setHover(); + void setPressed(); + void setDisabled(); +public: + class Resources + { + friend class ViewResources; + friend class Button; + + void init(boo::IGraphicsDataFactory* factory, const ThemeData& theme); + }; + + Button(ViewResources& res, View& parentView, const std::string& text); + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); + void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); + void mouseEnter(const boo::SWindowCoord&); + void mouseLeave(const boo::SWindowCoord&); + void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub); + void resetResources(ViewResources& res); + void draw(boo::IGraphicsCommandQueue* gfxQ); + + void setText(const std::string& text); + int nominalWidth() const {return m_nomWidth;} + int nominalHeight() const {return m_nomHeight;} +}; + +} + #endif // SPECTER_BUTTON_HPP diff --git a/specter/include/Specter/MultiLineTextView.hpp b/specter/include/Specter/MultiLineTextView.hpp index 69dab260f..760eaf9dc 100644 --- a/specter/include/Specter/MultiLineTextView.hpp +++ b/specter/include/Specter/MultiLineTextView.hpp @@ -24,7 +24,7 @@ public: void typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaultColor=Zeus::CColor::skWhite); - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub); void draw(boo::IGraphicsCommandQueue* gfxQ); }; diff --git a/specter/include/Specter/RootView.hpp b/specter/include/Specter/RootView.hpp index d665f155e..3646d5ab4 100644 --- a/specter/include/Specter/RootView.hpp +++ b/specter/include/Specter/RootView.hpp @@ -2,6 +2,7 @@ #define SPECTER_ROOTVIEW_HPP #include "View.hpp" +#include "ViewResources.hpp" #include "MultiLineTextView.hpp" #include "SplitView.hpp" #include "FontCache.hpp" @@ -10,7 +11,6 @@ namespace Specter { -class ViewResources; class RootView : public View { @@ -19,6 +19,7 @@ class RootView : public View boo::SWindowRect m_rootRect = {}; bool m_resizeRTDirty = false; bool m_destroyed = false; + ViewResources* m_viewRes; DeferredWindowEvents m_events; @@ -28,7 +29,7 @@ public: void destroyed(); bool isDestroyed() const {return m_destroyed;} - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub); void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods); void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods); void mouseMove(const boo::SWindowCoord& coord); @@ -53,6 +54,8 @@ public: const boo::SWindowRect& rootRect() const {return m_rootRect;} boo::IWindow* window() const {return m_window;} + const ViewResources& viewRes() const {return *m_viewRes;} + const ThemeData& themeData() const {return m_viewRes->m_theme;} private: std::unique_ptr m_splitView; diff --git a/specter/include/Specter/Space.hpp b/specter/include/Specter/Space.hpp index 4d8077b08..b377b1b44 100644 --- a/specter/include/Specter/Space.hpp +++ b/specter/include/Specter/Space.hpp @@ -11,14 +11,21 @@ class Space : public View { Toolbar::Position m_tbPos; std::unique_ptr m_toolbar; + bool m_toolbarMouseIn = false; + bool m_toolbarMouseDown = false; std::unique_ptr m_contentView; + bool m_contentMouseIn = false; + bool m_contentMouseDown = false; public: Space(ViewResources& res, View& parentView, Toolbar::Position toolbarPos); std::unique_ptr setContentView(std::unique_ptr&& view); + Toolbar& toolbar() {return *m_toolbar;} void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseMove(const boo::SWindowCoord&); - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void mouseEnter(const boo::SWindowCoord&); + void mouseLeave(const boo::SWindowCoord&); + void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub); void resetResources(ViewResources& res); void draw(boo::IGraphicsCommandQueue* gfxQ); }; diff --git a/specter/include/Specter/SplitView.hpp b/specter/include/Specter/SplitView.hpp index a4fcf7629..a13747cfe 100644 --- a/specter/include/Specter/SplitView.hpp +++ b/specter/include/Specter/SplitView.hpp @@ -34,14 +34,16 @@ private: updateSize(); } - std::unique_ptr m_views[2]; + struct Child + { + std::unique_ptr m_view; + bool m_mouseIn = false; + bool m_mouseDown = false; + }; + Child m_views[2]; ViewBlock m_splitBlock; boo::IGraphicsBufferD* m_splitBlockBuf; - struct SplitVert - { - Zeus::CVector3f m_pos; - Zeus::CVector2f m_uv; - } m_splitVerts[4]; + TexShaderVert m_splitVerts[4]; void setHorizontalVerts(int width) { @@ -76,7 +78,9 @@ public: void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseMove(const boo::SWindowCoord&); - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void mouseEnter(const boo::SWindowCoord&); + void mouseLeave(const boo::SWindowCoord&); + void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub); void resetResources(ViewResources& res); void draw(boo::IGraphicsCommandQueue* gfxQ); }; diff --git a/specter/include/Specter/TextView.hpp b/specter/include/Specter/TextView.hpp index ffb413b55..aac8c4afd 100644 --- a/specter/include/Specter/TextView.hpp +++ b/specter/include/Specter/TextView.hpp @@ -20,6 +20,7 @@ class TextView : public View boo::IShaderDataBinding* m_shaderBinding; const FontAtlas& m_fontAtlas; bool m_valid = false; + int m_width = 0; public: class Resources @@ -64,8 +65,12 @@ public: void colorGlyphsTypeOn(const Zeus::CColor& newColor, float startInterval=0.2, float fadeTime=0.5); void think(); + void resized(const boo::SWindowRect &rootView, const boo::SWindowRect& sub); void draw(boo::IGraphicsCommandQueue* gfxQ); + int nominalWidth() const {return m_width;} + int nominalHeight() const {return m_fontAtlas.FT_LineHeight() >> 6;} + private: std::vector m_glyphs; }; diff --git a/specter/include/Specter/Toolbar.hpp b/specter/include/Specter/Toolbar.hpp index 03eb2c52f..e479175b1 100644 --- a/specter/include/Specter/Toolbar.hpp +++ b/specter/include/Specter/Toolbar.hpp @@ -2,6 +2,7 @@ #define SPECTER_TOOLBAR_HPP #include "Specter/View.hpp" +#include namespace Specter { @@ -25,16 +26,20 @@ public: }; private: Position m_tbPos; + struct Child + { + std::unique_ptr m_view; + bool m_mouseIn = false; + bool m_mouseDown = false; + Child(std::unique_ptr&& v) : m_view(std::move(v)) {} + }; + std::vector m_children; - std::unique_ptr m_contentView; ViewBlock m_tbBlock; boo::IGraphicsBufferD* m_tbBlockBuf; - struct ToolbarVert - { - Zeus::CVector3f m_pos; - Zeus::CVector2f m_uv; - } m_tbVerts[10]; + TexShaderVert m_tbVerts[10]; int m_gauge = 25; + int m_padding = 10; void setHorizontalVerts(int width) { @@ -89,17 +94,21 @@ private: boo::IGraphicsBufferD* m_tbVertsBuf; boo::IVertexFormat* m_tbVtxFmt; /* OpenGL only */ boo::IShaderDataBinding* m_tbShaderBinding; - bool m_splitValid = false; public: Toolbar(ViewResources& res, View& parentView, Position toolbarPos); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseMove(const boo::SWindowCoord&); - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub); + void mouseEnter(const boo::SWindowCoord&); + void mouseLeave(const boo::SWindowCoord&coord); + void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub); void resetResources(ViewResources& res); void draw(boo::IGraphicsCommandQueue* gfxQ); int gauge() const {return m_gauge;} + + void clear() {m_children.clear();} + void push_back(std::unique_ptr&& v) {m_children.push_back(std::move(v));} }; } diff --git a/specter/include/Specter/View.hpp b/specter/include/Specter/View.hpp index 615a6f21d..7986cc4b1 100644 --- a/specter/include/Specter/View.hpp +++ b/specter/include/Specter/View.hpp @@ -20,16 +20,26 @@ class RootView; class View { +public: + struct SolidShaderVert + { + Zeus::CVector3f m_pos; + Zeus::CColor m_color = Zeus::CColor::skClear; + }; + struct TexShaderVert + { + Zeus::CVector3f m_pos; + Zeus::CVector2f m_uv; + }; +private: RootView& m_rootView; View& m_parentView; boo::SWindowRect m_subRect; boo::IGraphicsBufferD* m_bgVertBuf; - boo::IGraphicsBufferD* m_bgInstBuf; boo::IVertexFormat* m_bgVtxFmt = nullptr; /* OpenGL only */ boo::IShaderDataBinding* m_bgShaderBinding; - Zeus::CVector3f m_bgRect[4]; - Zeus::CColor m_bgColor; - std::unique_ptr m_gfxData; + SolidShaderVert m_bgRect[4]; + boo::IGraphicsDataToken m_gfxData; friend class RootView; void buildResources(ViewResources& res); @@ -91,22 +101,30 @@ public: View(const View& other) = delete; View& operator=(const View& other) = delete; - View& parent() {return m_parentView;} - RootView& root() {return m_rootView;} + View& parentView() {return m_parentView;} + RootView& rootView() {return m_rootView;} const boo::SWindowRect& subRect() const {return m_subRect;} + int width() const {return m_subRect.size[0];} + int height() const {return m_subRect.size[1];} void updateSize(); - void setBackground(Zeus::CColor color) + void setBackground(const Zeus::CColor& color) { - m_bgColor = color; - m_bgInstBuf->load(&m_bgColor, sizeof(Zeus::CColor)); + for (int i=0 ; i<4 ; ++i) + m_bgRect[i].m_color = color; + m_bgVertBuf->load(&m_bgRect, sizeof(SolidShaderVert) * 4); } + virtual int nominalWidth() const {return 0;} + virtual int nominalHeight() const {return 0;} + virtual void updateCVar(HECL::CVar* cvar) {} virtual void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {} virtual void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {} virtual void mouseMove(const boo::SWindowCoord&) {} - virtual void resized(const boo::SWindowRect &root, const boo::SWindowRect& sub); + virtual void mouseEnter(const boo::SWindowCoord&) {} + virtual void mouseLeave(const boo::SWindowCoord&) {} + virtual void resized(const boo::SWindowRect &rootView, const boo::SWindowRect& sub); virtual void resetResources(ViewResources& res) {} virtual void draw(boo::IGraphicsCommandQueue* gfxQ); }; diff --git a/specter/include/Specter/ViewResources.hpp b/specter/include/Specter/ViewResources.hpp index c82eaaf19..256150cb2 100644 --- a/specter/include/Specter/ViewResources.hpp +++ b/specter/include/Specter/ViewResources.hpp @@ -2,8 +2,9 @@ #define SPECTER_VIEWRESOURCES_HPP #include "TextView.hpp" -#include "RootView.hpp" +#include "SplitView.hpp" #include "Toolbar.hpp" +#include "Button.hpp" namespace Specter { @@ -12,10 +13,26 @@ class ThemeData Zeus::CColor m_vpBg = {0.2,0.2,0.2,1.0}; Zeus::CColor m_tbBg = {0.4,0.4,0.4,1.0}; Zeus::CColor m_uiText = Zeus::CColor::skWhite; + Zeus::CColor m_button1Inactive = {0.2823, 0.2823, 0.2823, 1.0}; + Zeus::CColor m_button2Inactive = {0.1725, 0.1725, 0.1725, 1.0}; + Zeus::CColor m_button1Hover = {0.3523, 0.3523, 0.3523, 1.0}; + Zeus::CColor m_button2Hover = {0.2425, 0.2425, 0.2425, 1.0}; + Zeus::CColor m_button1Press = {0.1725, 0.1725, 0.1725, 1.0}; + Zeus::CColor m_button2Press = {0.2823, 0.2823, 0.2823, 1.0}; + Zeus::CColor m_button1Disabled = {0.2823, 0.2823, 0.2823, 0.5}; + Zeus::CColor m_button2Disabled = {0.1725, 0.1725, 0.1725, 0.5}; public: virtual const Zeus::CColor& viewportBackground() const {return m_vpBg;} virtual const Zeus::CColor& toolbarBackground() const {return m_tbBg;} virtual const Zeus::CColor& uiText() const {return m_uiText;} + virtual const Zeus::CColor& button1Inactive() const {return m_button1Inactive;} + virtual const Zeus::CColor& button2Inactive() const {return m_button2Inactive;} + virtual const Zeus::CColor& button1Hover() const {return m_button1Hover;} + virtual const Zeus::CColor& button2Hover() const {return m_button2Hover;} + virtual const Zeus::CColor& button1Press() const {return m_button1Press;} + virtual const Zeus::CColor& button2Press() const {return m_button2Press;} + virtual const Zeus::CColor& button1Disabled() const {return m_button1Disabled;} + virtual const Zeus::CColor& button2Disabled() const {return m_button2Disabled;} }; class ViewResources @@ -27,6 +44,7 @@ class ViewResources m_textRes.init(factory, fcache); m_splitRes.init(factory, theme); m_toolbarRes.init(factory, theme); + m_buttonRes.init(factory, theme); } public: @@ -36,8 +54,9 @@ public: TextView::Resources m_textRes; SplitView::Resources m_splitRes; Toolbar::Resources m_toolbarRes; - std::unique_ptr m_fontData; - std::unique_ptr m_resData; + Button::Resources m_buttonRes; + boo::IGraphicsDataToken m_fontData; + boo::IGraphicsDataToken m_resData; Specter::FontTag m_mainFont; Specter::FontTag m_monoFont; diff --git a/specter/lib/Button.cpp b/specter/lib/Button.cpp index e69de29bb..9d8d6c996 100644 --- a/specter/lib/Button.cpp +++ b/specter/lib/Button.cpp @@ -0,0 +1,198 @@ +#include +#include "Specter/Button.hpp" +#include "Specter/ViewResources.hpp" +#include "Specter/RootView.hpp" + +namespace Specter +{ +static LogVisor::LogModule Log("Specter::Button"); + +void Button::Resources::init(boo::IGraphicsDataFactory* factory, const ThemeData& theme) +{ +} + +Button::Button(ViewResources& res, View& parentView, const std::string& text) +: View(res, parentView), m_textStr(text) +{ + m_bBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); + m_bVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), 28); + + if (!res.m_viewRes.m_texVtxFmt) + { + boo::VertexElementDescriptor vdescs[] = + { + {m_bVertsBuf, nullptr, boo::VertexSemantic::Position4}, + {m_bVertsBuf, nullptr, boo::VertexSemantic::UV4} + }; + m_bVtxFmt = res.m_factory->newVertexFormat(2, vdescs); + boo::IGraphicsBuffer* bufs[] = {m_bBlockBuf}; + m_bShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, + m_bVtxFmt, m_bVertsBuf, nullptr, + nullptr, 1, bufs, 0, nullptr); + } + else + { + boo::IGraphicsBuffer* bufs[] = {m_bBlockBuf}; + m_bShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader, + res.m_viewRes.m_texVtxFmt, + m_bVertsBuf, nullptr, + nullptr, 1, bufs, 0, nullptr); + } + + commitResources(res); + resetResources(res); +} + +void Button::setText(const std::string& text) +{ + m_textStr = text; + + m_text->typesetGlyphs(text, rootView().themeData().uiText()); + float pf = rootView().window()->getVirtualPixelFactor(); + float width = m_text->nominalWidth() + 10 * pf; + float height = 20 * pf; + m_verts[0].m_pos.assign(1, height+1, 0); + m_verts[1].m_pos.assign(1, 1, 0); + m_verts[2].m_pos.assign(width+1, height+1, 0); + m_verts[3].m_pos.assign(width+1, 1, 0); + m_verts[4].m_pos.assign(width+1, 1, 0); + + m_verts[5].m_pos.assign(1, height+1, 0); + m_verts[6].m_pos.assign(1, height+1, 0); + m_verts[7].m_pos.assign(0, height+1, 0); + m_verts[8].m_pos.assign(1, 1, 0); + m_verts[9].m_pos.assign(0, 1, 0); + m_verts[10].m_pos.assign(0, 1, 0); + + m_verts[11].m_pos.assign(width+2, height+1, 0); + m_verts[12].m_pos.assign(width+2, height+1, 0); + m_verts[13].m_pos.assign(width+1, height+1, 0); + m_verts[14].m_pos.assign(width+2, 1, 0); + m_verts[15].m_pos.assign(width+1, 1, 0); + m_verts[16].m_pos.assign(width+1, 1, 0); + + m_verts[17].m_pos.assign(1, height+2, 0); + m_verts[18].m_pos.assign(1, height+2, 0); + m_verts[19].m_pos.assign(1, height+1, 0); + m_verts[20].m_pos.assign(width+1, height+2, 0); + m_verts[21].m_pos.assign(width+1, height+1, 0); + m_verts[22].m_pos.assign(width+1, height+1, 0); + + m_verts[23].m_pos.assign(1, 1, 0); + m_verts[24].m_pos.assign(1, 1, 0); + m_verts[25].m_pos.assign(1, 0, 0); + m_verts[26].m_pos.assign(width+1, 1, 0); + m_verts[27].m_pos.assign(width+1, 0, 0); + + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); + m_nomWidth = width + 2; + m_nomHeight = height; +} + +void Button::setInactive() +{ + m_verts[0].m_color = rootView().themeData().button1Inactive(); + m_verts[1].m_color = rootView().themeData().button2Inactive(); + m_verts[2].m_color = rootView().themeData().button1Inactive(); + m_verts[3].m_color = rootView().themeData().button2Inactive(); + m_verts[4].m_color = rootView().themeData().button2Inactive(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); +} + +void Button::setHover() +{ + m_verts[0].m_color = rootView().themeData().button1Hover(); + m_verts[1].m_color = rootView().themeData().button2Hover(); + m_verts[2].m_color = rootView().themeData().button1Hover(); + m_verts[3].m_color = rootView().themeData().button2Hover(); + m_verts[4].m_color = rootView().themeData().button2Hover(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); +} + +void Button::setPressed() +{ + m_verts[0].m_color = rootView().themeData().button1Press(); + m_verts[1].m_color = rootView().themeData().button2Press(); + m_verts[2].m_color = rootView().themeData().button1Press(); + m_verts[3].m_color = rootView().themeData().button2Press(); + m_verts[4].m_color = rootView().themeData().button2Press(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); +} + +void Button::setDisabled() +{ + m_verts[0].m_color = rootView().themeData().button1Disabled(); + m_verts[1].m_color = rootView().themeData().button2Disabled(); + m_verts[2].m_color = rootView().themeData().button1Disabled(); + m_verts[3].m_color = rootView().themeData().button2Disabled(); + m_verts[4].m_color = rootView().themeData().button2Disabled(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); +} + +void Button::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) +{ + m_pressed = true; + setPressed(); +} + +void Button::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) +{ + m_pressed = false; + if (m_hovered) + setHover(); + else + setInactive(); +} + +void Button::mouseEnter(const boo::SWindowCoord& coord) +{ + m_hovered = true; + if (m_pressed) + setPressed(); + else + setHover(); +} + +void Button::mouseLeave(const boo::SWindowCoord& coord) +{ + m_hovered = false; + setInactive(); +} + +void Button::resetResources(ViewResources& res) +{ + m_text.reset(new TextView(res, *this, res.m_mainFont)); + setText(m_textStr); + m_verts[0].m_color = res.themeData().button1Inactive(); + m_verts[1].m_color = res.themeData().button2Inactive(); + m_verts[2].m_color = res.themeData().button1Inactive(); + m_verts[3].m_color = res.themeData().button2Inactive(); + m_verts[4].m_color = res.themeData().button2Inactive(); + for (int i=5 ; i<28 ; ++i) + m_verts[i].m_color = res.themeData().button2Inactive(); + m_bVertsBuf->load(m_verts, sizeof(SolidShaderVert) * 28); +} + +void Button::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) +{ + View::resized(root, sub); + boo::SWindowRect textRect = sub; + m_bBlock.setViewRect(root, sub); + m_bBlockBuf->load(&m_bBlock, sizeof(ViewBlock)); + float pf = rootView().window()->getVirtualPixelFactor(); + textRect.location[0] += 5 * pf; + textRect.location[1] = 11 * pf; + m_text->resized(root, textRect); +} + +void Button::draw(boo::IGraphicsCommandQueue* gfxQ) +{ + View::draw(gfxQ); + gfxQ->setShaderDataBinding(m_bShaderBinding); + gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); + gfxQ->draw(0, 28); + m_text->draw(gfxQ); +} + +} + diff --git a/specter/lib/RootView.cpp b/specter/lib/RootView.cpp index 30f402c49..eac1a913f 100644 --- a/specter/lib/RootView.cpp +++ b/specter/lib/RootView.cpp @@ -7,7 +7,7 @@ namespace Specter static LogVisor::LogModule Log("Specter::RootView"); RootView::RootView(ViewResources& res, boo::IWindow* window) -: View(res), m_window(window), m_events(*this) +: View(res), m_window(window), m_events(*this), m_viewRes(&res) { window->setCallback(&m_events); boo::SWindowRect rect = window->getWindowFrame(); @@ -15,6 +15,7 @@ RootView::RootView(ViewResources& res, boo::IWindow* window) commitResources(res); m_splitView.reset(new SplitView(res, *this, SplitView::Axis::Horizontal)); Space* space1 = new Space(res, *m_splitView, Toolbar::Position::Bottom); + space1->toolbar().push_back(std::make_unique