Button widget and mouse events

This commit is contained in:
Jack Andersen 2015-12-04 14:42:46 -10:00
parent 382016d4d7
commit 857615ab00
17 changed files with 709 additions and 112 deletions

View File

@ -1,4 +1,56 @@
#ifndef SPECTER_BUTTON_HPP #ifndef SPECTER_BUTTON_HPP
#define 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<TextView> 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 #endif // SPECTER_BUTTON_HPP

View File

@ -24,7 +24,7 @@ public:
void typesetGlyphs(const std::wstring& str, void typesetGlyphs(const std::wstring& str,
const Zeus::CColor& defaultColor=Zeus::CColor::skWhite); 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); void draw(boo::IGraphicsCommandQueue* gfxQ);
}; };

View File

@ -2,6 +2,7 @@
#define SPECTER_ROOTVIEW_HPP #define SPECTER_ROOTVIEW_HPP
#include "View.hpp" #include "View.hpp"
#include "ViewResources.hpp"
#include "MultiLineTextView.hpp" #include "MultiLineTextView.hpp"
#include "SplitView.hpp" #include "SplitView.hpp"
#include "FontCache.hpp" #include "FontCache.hpp"
@ -10,7 +11,6 @@
namespace Specter namespace Specter
{ {
class ViewResources;
class RootView : public View class RootView : public View
{ {
@ -19,6 +19,7 @@ class RootView : public View
boo::SWindowRect m_rootRect = {}; boo::SWindowRect m_rootRect = {};
bool m_resizeRTDirty = false; bool m_resizeRTDirty = false;
bool m_destroyed = false; bool m_destroyed = false;
ViewResources* m_viewRes;
DeferredWindowEvents<RootView> m_events; DeferredWindowEvents<RootView> m_events;
@ -28,7 +29,7 @@ public:
void destroyed(); void destroyed();
bool isDestroyed() const {return m_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 mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods);
void mouseUp(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); void mouseMove(const boo::SWindowCoord& coord);
@ -53,6 +54,8 @@ public:
const boo::SWindowRect& rootRect() const {return m_rootRect;} const boo::SWindowRect& rootRect() const {return m_rootRect;}
boo::IWindow* window() const {return m_window;} boo::IWindow* window() const {return m_window;}
const ViewResources& viewRes() const {return *m_viewRes;}
const ThemeData& themeData() const {return m_viewRes->m_theme;}
private: private:
std::unique_ptr<SplitView> m_splitView; std::unique_ptr<SplitView> m_splitView;

View File

@ -11,14 +11,21 @@ class Space : public View
{ {
Toolbar::Position m_tbPos; Toolbar::Position m_tbPos;
std::unique_ptr<Toolbar> m_toolbar; std::unique_ptr<Toolbar> m_toolbar;
bool m_toolbarMouseIn = false;
bool m_toolbarMouseDown = false;
std::unique_ptr<View> m_contentView; std::unique_ptr<View> m_contentView;
bool m_contentMouseIn = false;
bool m_contentMouseDown = false;
public: public:
Space(ViewResources& res, View& parentView, Toolbar::Position toolbarPos); Space(ViewResources& res, View& parentView, Toolbar::Position toolbarPos);
std::unique_ptr<View> setContentView(std::unique_ptr<View>&& view); std::unique_ptr<View> setContentView(std::unique_ptr<View>&& view);
Toolbar& toolbar() {return *m_toolbar;}
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseMove(const boo::SWindowCoord&); 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 resetResources(ViewResources& res);
void draw(boo::IGraphicsCommandQueue* gfxQ); void draw(boo::IGraphicsCommandQueue* gfxQ);
}; };

View File

@ -34,14 +34,16 @@ private:
updateSize(); updateSize();
} }
std::unique_ptr<View> m_views[2]; struct Child
{
std::unique_ptr<View> m_view;
bool m_mouseIn = false;
bool m_mouseDown = false;
};
Child m_views[2];
ViewBlock m_splitBlock; ViewBlock m_splitBlock;
boo::IGraphicsBufferD* m_splitBlockBuf; boo::IGraphicsBufferD* m_splitBlockBuf;
struct SplitVert TexShaderVert m_splitVerts[4];
{
Zeus::CVector3f m_pos;
Zeus::CVector2f m_uv;
} m_splitVerts[4];
void setHorizontalVerts(int width) void setHorizontalVerts(int width)
{ {
@ -76,7 +78,9 @@ public:
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseMove(const boo::SWindowCoord&); 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 resetResources(ViewResources& res);
void draw(boo::IGraphicsCommandQueue* gfxQ); void draw(boo::IGraphicsCommandQueue* gfxQ);
}; };

View File

@ -20,6 +20,7 @@ class TextView : public View
boo::IShaderDataBinding* m_shaderBinding; boo::IShaderDataBinding* m_shaderBinding;
const FontAtlas& m_fontAtlas; const FontAtlas& m_fontAtlas;
bool m_valid = false; bool m_valid = false;
int m_width = 0;
public: public:
class Resources class Resources
@ -64,8 +65,12 @@ public:
void colorGlyphsTypeOn(const Zeus::CColor& newColor, float startInterval=0.2, float fadeTime=0.5); void colorGlyphsTypeOn(const Zeus::CColor& newColor, float startInterval=0.2, float fadeTime=0.5);
void think(); void think();
void resized(const boo::SWindowRect &rootView, const boo::SWindowRect& sub);
void draw(boo::IGraphicsCommandQueue* gfxQ); void draw(boo::IGraphicsCommandQueue* gfxQ);
int nominalWidth() const {return m_width;}
int nominalHeight() const {return m_fontAtlas.FT_LineHeight() >> 6;}
private: private:
std::vector<RenderGlyph> m_glyphs; std::vector<RenderGlyph> m_glyphs;
}; };

View File

@ -2,6 +2,7 @@
#define SPECTER_TOOLBAR_HPP #define SPECTER_TOOLBAR_HPP
#include "Specter/View.hpp" #include "Specter/View.hpp"
#include <bitset>
namespace Specter namespace Specter
{ {
@ -25,16 +26,20 @@ public:
}; };
private: private:
Position m_tbPos; Position m_tbPos;
struct Child
{
std::unique_ptr<View> m_view;
bool m_mouseIn = false;
bool m_mouseDown = false;
Child(std::unique_ptr<View>&& v) : m_view(std::move(v)) {}
};
std::vector<Child> m_children;
std::unique_ptr<View> m_contentView;
ViewBlock m_tbBlock; ViewBlock m_tbBlock;
boo::IGraphicsBufferD* m_tbBlockBuf; boo::IGraphicsBufferD* m_tbBlockBuf;
struct ToolbarVert TexShaderVert m_tbVerts[10];
{
Zeus::CVector3f m_pos;
Zeus::CVector2f m_uv;
} m_tbVerts[10];
int m_gauge = 25; int m_gauge = 25;
int m_padding = 10;
void setHorizontalVerts(int width) void setHorizontalVerts(int width)
{ {
@ -89,17 +94,21 @@ private:
boo::IGraphicsBufferD* m_tbVertsBuf; boo::IGraphicsBufferD* m_tbVertsBuf;
boo::IVertexFormat* m_tbVtxFmt; /* OpenGL only */ boo::IVertexFormat* m_tbVtxFmt; /* OpenGL only */
boo::IShaderDataBinding* m_tbShaderBinding; boo::IShaderDataBinding* m_tbShaderBinding;
bool m_splitValid = false;
public: public:
Toolbar(ViewResources& res, View& parentView, Position toolbarPos); Toolbar(ViewResources& res, View& parentView, Position toolbarPos);
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseMove(const boo::SWindowCoord&); 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 resetResources(ViewResources& res);
void draw(boo::IGraphicsCommandQueue* gfxQ); void draw(boo::IGraphicsCommandQueue* gfxQ);
int gauge() const {return m_gauge;} int gauge() const {return m_gauge;}
void clear() {m_children.clear();}
void push_back(std::unique_ptr<View>&& v) {m_children.push_back(std::move(v));}
}; };
} }

View File

@ -20,16 +20,26 @@ class RootView;
class View 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; RootView& m_rootView;
View& m_parentView; View& m_parentView;
boo::SWindowRect m_subRect; boo::SWindowRect m_subRect;
boo::IGraphicsBufferD* m_bgVertBuf; boo::IGraphicsBufferD* m_bgVertBuf;
boo::IGraphicsBufferD* m_bgInstBuf;
boo::IVertexFormat* m_bgVtxFmt = nullptr; /* OpenGL only */ boo::IVertexFormat* m_bgVtxFmt = nullptr; /* OpenGL only */
boo::IShaderDataBinding* m_bgShaderBinding; boo::IShaderDataBinding* m_bgShaderBinding;
Zeus::CVector3f m_bgRect[4]; SolidShaderVert m_bgRect[4];
Zeus::CColor m_bgColor; boo::IGraphicsDataToken m_gfxData;
std::unique_ptr<boo::IGraphicsData> m_gfxData;
friend class RootView; friend class RootView;
void buildResources(ViewResources& res); void buildResources(ViewResources& res);
@ -91,22 +101,30 @@ public:
View(const View& other) = delete; View(const View& other) = delete;
View& operator=(const View& other) = delete; View& operator=(const View& other) = delete;
View& parent() {return m_parentView;} View& parentView() {return m_parentView;}
RootView& root() {return m_rootView;} RootView& rootView() {return m_rootView;}
const boo::SWindowRect& subRect() const {return m_subRect;} 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 updateSize();
void setBackground(Zeus::CColor color) void setBackground(const Zeus::CColor& color)
{ {
m_bgColor = color; for (int i=0 ; i<4 ; ++i)
m_bgInstBuf->load(&m_bgColor, sizeof(Zeus::CColor)); 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 updateCVar(HECL::CVar* cvar) {}
virtual void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {} virtual void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {}
virtual void mouseUp(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 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 resetResources(ViewResources& res) {}
virtual void draw(boo::IGraphicsCommandQueue* gfxQ); virtual void draw(boo::IGraphicsCommandQueue* gfxQ);
}; };

View File

@ -2,8 +2,9 @@
#define SPECTER_VIEWRESOURCES_HPP #define SPECTER_VIEWRESOURCES_HPP
#include "TextView.hpp" #include "TextView.hpp"
#include "RootView.hpp" #include "SplitView.hpp"
#include "Toolbar.hpp" #include "Toolbar.hpp"
#include "Button.hpp"
namespace Specter namespace Specter
{ {
@ -12,10 +13,26 @@ class ThemeData
Zeus::CColor m_vpBg = {0.2,0.2,0.2,1.0}; 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_tbBg = {0.4,0.4,0.4,1.0};
Zeus::CColor m_uiText = Zeus::CColor::skWhite; 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: public:
virtual const Zeus::CColor& viewportBackground() const {return m_vpBg;} virtual const Zeus::CColor& viewportBackground() const {return m_vpBg;}
virtual const Zeus::CColor& toolbarBackground() const {return m_tbBg;} virtual const Zeus::CColor& toolbarBackground() const {return m_tbBg;}
virtual const Zeus::CColor& uiText() const {return m_uiText;} 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 class ViewResources
@ -27,6 +44,7 @@ class ViewResources
m_textRes.init(factory, fcache); m_textRes.init(factory, fcache);
m_splitRes.init(factory, theme); m_splitRes.init(factory, theme);
m_toolbarRes.init(factory, theme); m_toolbarRes.init(factory, theme);
m_buttonRes.init(factory, theme);
} }
public: public:
@ -36,8 +54,9 @@ public:
TextView::Resources m_textRes; TextView::Resources m_textRes;
SplitView::Resources m_splitRes; SplitView::Resources m_splitRes;
Toolbar::Resources m_toolbarRes; Toolbar::Resources m_toolbarRes;
std::unique_ptr<boo::IGraphicsData> m_fontData; Button::Resources m_buttonRes;
std::unique_ptr<boo::IGraphicsData> m_resData; boo::IGraphicsDataToken m_fontData;
boo::IGraphicsDataToken m_resData;
Specter::FontTag m_mainFont; Specter::FontTag m_mainFont;
Specter::FontTag m_monoFont; Specter::FontTag m_monoFont;

View File

@ -0,0 +1,198 @@
#include <LogVisor/LogVisor.hpp>
#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);
}
}

View File

@ -7,7 +7,7 @@ namespace Specter
static LogVisor::LogModule Log("Specter::RootView"); static LogVisor::LogModule Log("Specter::RootView");
RootView::RootView(ViewResources& res, boo::IWindow* window) 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); window->setCallback(&m_events);
boo::SWindowRect rect = window->getWindowFrame(); boo::SWindowRect rect = window->getWindowFrame();
@ -15,6 +15,7 @@ RootView::RootView(ViewResources& res, boo::IWindow* window)
commitResources(res); commitResources(res);
m_splitView.reset(new SplitView(res, *this, SplitView::Axis::Horizontal)); m_splitView.reset(new SplitView(res, *this, SplitView::Axis::Horizontal));
Space* space1 = new Space(res, *m_splitView, Toolbar::Position::Bottom); Space* space1 = new Space(res, *m_splitView, Toolbar::Position::Bottom);
space1->toolbar().push_back(std::make_unique<Button>(res, space1->toolbar(), "Hello Button"));
MultiLineTextView* textView1 = new MultiLineTextView(res, *this, res.m_heading18); MultiLineTextView* textView1 = new MultiLineTextView(res, *this, res.m_heading18);
space1->setContentView(std::unique_ptr<MultiLineTextView>(textView1)); space1->setContentView(std::unique_ptr<MultiLineTextView>(textView1));
Space* space2 = new Space(res, *m_splitView, Toolbar::Position::Bottom); Space* space2 = new Space(res, *m_splitView, Toolbar::Position::Bottom);
@ -64,10 +65,12 @@ void RootView::mouseMove(const boo::SWindowCoord& coord)
void RootView::mouseEnter(const boo::SWindowCoord& coord) void RootView::mouseEnter(const boo::SWindowCoord& coord)
{ {
m_splitView->mouseEnter(coord);
} }
void RootView::mouseLeave(const boo::SWindowCoord& coord) void RootView::mouseLeave(const boo::SWindowCoord& coord)
{ {
m_splitView->mouseLeave(coord);
} }
void RootView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) void RootView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll)
@ -114,6 +117,7 @@ void RootView::modKeyUp(boo::EModifierKey mod)
void RootView::resetResources(ViewResources& res) void RootView::resetResources(ViewResources& res)
{ {
m_viewRes = &res;
m_splitView->resetResources(res); m_splitView->resetResources(res);
} }

View File

@ -24,14 +24,94 @@ std::unique_ptr<View> Space::setContentView(std::unique_ptr<View>&& view)
void Space::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) void Space::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{ {
if (m_contentView && !m_contentMouseDown &&
m_contentView->subRect().coordInRect(coord))
{
m_contentView->mouseDown(coord, button, mod);
m_contentMouseDown = true;
}
if (m_toolbar && !m_toolbarMouseDown &&
m_toolbar->subRect().coordInRect(coord))
{
m_toolbar->mouseDown(coord, button, mod);
m_toolbarMouseDown = true;
}
} }
void Space::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) void Space::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{ {
if (m_contentView && m_contentMouseDown)
{
m_contentView->mouseUp(coord, button, mod);
m_contentMouseDown = false;
}
if (m_toolbar && m_toolbarMouseDown)
{
m_toolbar->mouseUp(coord, button, mod);
m_toolbarMouseDown = false;
}
} }
void Space::mouseMove(const boo::SWindowCoord& coord) void Space::mouseMove(const boo::SWindowCoord& coord)
{ {
if (m_contentView)
{
if (m_contentView->subRect().coordInRect(coord))
{
if (!m_contentMouseIn)
{
m_contentView->mouseEnter(coord);
m_contentMouseIn = true;
}
m_contentView->mouseMove(coord);
}
else
{
if (m_contentMouseIn)
{
m_contentView->mouseLeave(coord);
m_contentMouseIn = false;
}
}
}
if (m_toolbar)
{
if (m_toolbar->subRect().coordInRect(coord))
{
if (!m_toolbarMouseIn)
{
m_toolbar->mouseEnter(coord);
m_toolbarMouseIn = true;
}
m_toolbar->mouseMove(coord);
}
else
{
if (m_toolbarMouseIn)
{
m_toolbar->mouseLeave(coord);
m_toolbarMouseIn = false;
}
}
}
}
void Space::mouseEnter(const boo::SWindowCoord& coord)
{
}
void Space::mouseLeave(const boo::SWindowCoord& coord)
{
if (m_contentView && m_contentMouseIn)
{
m_contentView->mouseLeave(coord);
m_contentMouseIn = false;
}
if (m_toolbar && m_toolbarMouseIn)
{
m_toolbar->mouseLeave(coord);
m_toolbarMouseIn = false;
}
} }
void Space::resetResources(ViewResources& res) void Space::resetResources(ViewResources& res)

View File

@ -1,5 +1,6 @@
#include <LogVisor/LogVisor.hpp> #include <LogVisor/LogVisor.hpp>
#include "Specter/SplitView.hpp" #include "Specter/SplitView.hpp"
#include "Specter/RootView.hpp"
#include "Specter/ViewResources.hpp" #include "Specter/ViewResources.hpp"
namespace Specter namespace Specter
@ -21,7 +22,7 @@ SplitView::SplitView(ViewResources& system, View& parentView, Axis axis)
: View(system, parentView), m_axis(axis) : View(system, parentView), m_axis(axis)
{ {
m_splitBlockBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); m_splitBlockBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
m_splitVertsBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SplitVert), 4); m_splitVertsBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), 4);
if (!system.m_viewRes.m_texVtxFmt) if (!system.m_viewRes.m_texVtxFmt)
{ {
@ -34,17 +35,17 @@ SplitView::SplitView(ViewResources& system, View& parentView, Axis axis)
boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf}; boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf};
boo::ITexture* texs[] = {system.m_splitRes.m_shadingTex}; boo::ITexture* texs[] = {system.m_splitRes.m_shadingTex};
m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader, m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader,
m_splitVtxFmt, m_splitVertsBuf, nullptr, m_splitVtxFmt, m_splitVertsBuf, nullptr,
nullptr, 1, bufs, 1, texs); nullptr, 1, bufs, 1, texs);
} }
else else
{ {
boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf}; boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf};
boo::ITexture* texs[] = {system.m_splitRes.m_shadingTex}; boo::ITexture* texs[] = {system.m_splitRes.m_shadingTex};
m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader, m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader,
system.m_viewRes.m_texVtxFmt, system.m_viewRes.m_texVtxFmt,
m_splitVertsBuf, nullptr, m_splitVertsBuf, nullptr,
nullptr, 1, bufs, 1, texs); nullptr, 1, bufs, 1, texs);
} }
commitResources(system); commitResources(system);
@ -55,21 +56,61 @@ std::unique_ptr<View> SplitView::setContentView(int slot, std::unique_ptr<View>&
if (slot < 0 || slot > 1) if (slot < 0 || slot > 1)
Log.report(LogVisor::FatalError, "out-of-range slot to RootView::SplitView::setContentView"); Log.report(LogVisor::FatalError, "out-of-range slot to RootView::SplitView::setContentView");
std::unique_ptr<View> ret; std::unique_ptr<View> ret;
m_views[slot].swap(ret); m_views[slot].m_view.swap(ret);
m_views[slot] = std::move(view); m_views[slot].m_view = std::move(view);
m_views[slot].m_mouseDown = false;
m_views[slot].m_mouseIn = false;
updateSize(); updateSize();
return ret; return ret;
} }
void SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) void SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{ {
if (button == boo::EMouseButton::Primary) if (m_axis == Axis::Horizontal)
{ {
m_dragging = true; int slidePx = subRect().size[1] * m_slide;
if (m_axis == Axis::Horizontal) if (abs(int(coord.pixel[1]) - slidePx) < 4)
setSlide(coord.pixel[1] / float(subRect().size[1])); {
else if (m_axis == Axis::Vertical) if (button == boo::EMouseButton::Primary)
setSlide(coord.pixel[0] / float(subRect().size[0])); {
m_dragging = true;
setSlide(coord.pixel[1] / float(subRect().size[1]));
}
else if (button == boo::EMouseButton::Secondary)
{
// TODO: Split menu
}
return;
}
}
else if (m_axis == Axis::Vertical)
{
int slidePx = subRect().size[0] * m_slide;
if (abs(int(coord.pixel[0]) - slidePx) < 4)
{
if (button == boo::EMouseButton::Primary)
{
m_dragging = true;
setSlide(coord.pixel[0] / float(subRect().size[0]));
}
else if (button == boo::EMouseButton::Secondary)
{
// TODO: Split menu
}
return;
}
}
if (m_views[0].m_view && !m_views[0].m_mouseDown &&
m_views[0].m_view->subRect().coordInRect(coord))
{
m_views[0].m_view->mouseDown(coord, button, mod);
m_views[0].m_mouseDown = true;
}
if (m_views[1].m_view && !m_views[1].m_mouseDown &&
m_views[1].m_view->subRect().coordInRect(coord))
{
m_views[1].m_view->mouseDown(coord, button, mod);
m_views[1].m_mouseDown = true;
} }
} }
@ -77,6 +118,16 @@ void SplitView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button
{ {
if (button == boo::EMouseButton::Primary) if (button == boo::EMouseButton::Primary)
m_dragging = false; m_dragging = false;
if (m_views[0].m_view && m_views[0].m_mouseDown)
{
m_views[0].m_view->mouseUp(coord, button, mod);
m_views[0].m_mouseDown = false;
}
if (m_views[1].m_view && m_views[1].m_mouseDown)
{
m_views[1].m_view->mouseUp(coord, button, mod);
m_views[1].m_mouseDown = false;
}
} }
void SplitView::mouseMove(const boo::SWindowCoord& coord) void SplitView::mouseMove(const boo::SWindowCoord& coord)
@ -87,9 +138,9 @@ void SplitView::mouseMove(const boo::SWindowCoord& coord)
setSlide(coord.pixel[1] / float(subRect().size[1])); setSlide(coord.pixel[1] / float(subRect().size[1]));
int slidePx = subRect().size[1] * m_slide; int slidePx = subRect().size[1] * m_slide;
if (abs(int(coord.pixel[1]) - slidePx) < 4) if (abs(int(coord.pixel[1]) - slidePx) < 4)
root().window()->setCursor(boo::EMouseCursor::VerticalArrow); rootView().window()->setCursor(boo::EMouseCursor::VerticalArrow);
else else
root().window()->setCursor(boo::EMouseCursor::Pointer); rootView().window()->setCursor(boo::EMouseCursor::Pointer);
} }
else if (m_axis == Axis::Vertical) else if (m_axis == Axis::Vertical)
{ {
@ -97,18 +148,77 @@ void SplitView::mouseMove(const boo::SWindowCoord& coord)
setSlide(coord.pixel[0] / float(subRect().size[0])); setSlide(coord.pixel[0] / float(subRect().size[0]));
int slidePx = subRect().size[0] * m_slide; int slidePx = subRect().size[0] * m_slide;
if (abs(int(coord.pixel[0]) - slidePx) < 4) if (abs(int(coord.pixel[0]) - slidePx) < 4)
root().window()->setCursor(boo::EMouseCursor::HorizontalArrow); rootView().window()->setCursor(boo::EMouseCursor::HorizontalArrow);
else else
root().window()->setCursor(boo::EMouseCursor::Pointer); rootView().window()->setCursor(boo::EMouseCursor::Pointer);
}
if (m_views[0].m_view)
{
if (m_views[0].m_view->subRect().coordInRect(coord))
{
if (!m_views[0].m_mouseIn)
{
m_views[0].m_view->mouseEnter(coord);
m_views[0].m_mouseIn = true;
}
m_views[0].m_view->mouseMove(coord);
}
else
{
if (m_views[0].m_mouseIn)
{
m_views[0].m_view->mouseLeave(coord);
m_views[0].m_mouseIn = false;
}
}
}
if (m_views[1].m_view)
{
if (m_views[1].m_view->subRect().coordInRect(coord))
{
if (!m_views[1].m_mouseIn)
{
m_views[1].m_view->mouseEnter(coord);
m_views[1].m_mouseIn = true;
}
m_views[1].m_view->mouseMove(coord);
}
else
{
if (m_views[1].m_mouseIn)
{
m_views[1].m_view->mouseLeave(coord);
m_views[1].m_mouseIn = false;
}
}
}
}
void SplitView::mouseEnter(const boo::SWindowCoord& coord)
{
}
void SplitView::mouseLeave(const boo::SWindowCoord& coord)
{
if (m_views[0].m_view && m_views[0].m_mouseIn)
{
m_views[0].m_view->mouseLeave(coord);
m_views[0].m_mouseIn = false;
}
if (m_views[1].m_view && m_views[1].m_mouseIn)
{
m_views[1].m_view->mouseLeave(coord);
m_views[1].m_mouseIn = false;
} }
} }
void SplitView::resetResources(ViewResources& res) void SplitView::resetResources(ViewResources& res)
{ {
if (m_views[0]) if (m_views[0].m_view)
m_views[0]->resetResources(res); m_views[0].m_view->resetResources(res);
if (m_views[1]) if (m_views[1].m_view)
m_views[1]->resetResources(res); m_views[1].m_view->resetResources(res);
} }
void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
@ -118,12 +228,12 @@ void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& su
{ {
boo::SWindowRect ssub = sub; boo::SWindowRect ssub = sub;
ssub.size[1] *= m_slide; ssub.size[1] *= m_slide;
if (m_views[0]) if (m_views[0].m_view)
m_views[0]->resized(root, ssub); m_views[0].m_view->resized(root, ssub);
ssub.location[1] += ssub.size[1]; ssub.location[1] += ssub.size[1];
ssub.size[1] = sub.size[1] - ssub.size[1]; ssub.size[1] = sub.size[1] - ssub.size[1];
if (m_views[1]) if (m_views[1].m_view)
m_views[1]->resized(root, ssub); m_views[1].m_view->resized(root, ssub);
m_splitBlock.setViewRect(root, ssub); m_splitBlock.setViewRect(root, ssub);
setHorizontalVerts(ssub.size[0]); setHorizontalVerts(ssub.size[0]);
} }
@ -131,26 +241,26 @@ void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& su
{ {
boo::SWindowRect ssub = sub; boo::SWindowRect ssub = sub;
ssub.size[0] *= m_slide; ssub.size[0] *= m_slide;
if (m_views[0]) if (m_views[0].m_view)
m_views[0]->resized(root, ssub); m_views[0].m_view->resized(root, ssub);
ssub.location[0] += ssub.size[0]; ssub.location[0] += ssub.size[0];
ssub.size[0] = sub.size[0] - ssub.size[0]; ssub.size[0] = sub.size[0] - ssub.size[0];
if (m_views[1]) if (m_views[1].m_view)
m_views[1]->resized(root, ssub); m_views[1].m_view->resized(root, ssub);
m_splitBlock.setViewRect(root, ssub); m_splitBlock.setViewRect(root, ssub);
setVerticalVerts(ssub.size[1]); setVerticalVerts(ssub.size[1]);
} }
m_splitBlockBuf->load(&m_splitBlock, sizeof(ViewBlock)); m_splitBlockBuf->load(&m_splitBlock, sizeof(ViewBlock));
m_splitVertsBuf->load(m_splitVerts, sizeof(SplitVert) * 4); m_splitVertsBuf->load(m_splitVerts, sizeof(TexShaderVert) * 4);
} }
void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ) void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ)
{ {
View::draw(gfxQ); View::draw(gfxQ);
if (m_views[0]) if (m_views[0].m_view)
m_views[0]->draw(gfxQ); m_views[0].m_view->draw(gfxQ);
if (m_views[1]) if (m_views[1].m_view)
m_views[1]->draw(gfxQ); m_views[1].m_view->draw(gfxQ);
gfxQ->setShaderDataBinding(m_splitShaderBinding); gfxQ->setShaderDataBinding(m_splitShaderBinding);
gfxQ->draw(0, 4); gfxQ->draw(0, 4);

View File

@ -259,22 +259,22 @@ void TextView::Resources::init(boo::MetalDataFactory* factory, FontCache* fcache
#endif #endif
TextView::TextView(ViewResources& system, View& parentView, const FontAtlas& font, size_t capacity) TextView::TextView(ViewResources& res, View& parentView, const FontAtlas& font, size_t capacity)
: View(system, parentView), : View(res, parentView),
m_capacity(capacity), m_capacity(capacity),
m_fontAtlas(font) m_fontAtlas(font)
{ {
m_glyphBuf = m_glyphBuf =
system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex,
sizeof(RenderGlyph), capacity); sizeof(RenderGlyph), capacity);
boo::IShaderPipeline* shader; boo::IShaderPipeline* shader;
if (font.subpixel()) if (font.subpixel())
shader = system.m_textRes.m_subpixel; shader = res.m_textRes.m_subpixel;
else else
shader = system.m_textRes.m_regular; shader = res.m_textRes.m_regular;
if (!system.m_textRes.m_vtxFmt) if (!res.m_textRes.m_vtxFmt)
{ {
boo::VertexElementDescriptor vdescs[] = boo::VertexElementDescriptor vdescs[] =
{ {
@ -292,28 +292,28 @@ TextView::TextView(ViewResources& system, View& parentView, const FontAtlas& fon
{m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3}, {m_glyphBuf, nullptr, boo::VertexSemantic::UV4 | boo::VertexSemantic::Instanced, 3},
{m_glyphBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} {m_glyphBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced}
}; };
m_vtxFmt = system.m_factory->newVertexFormat(13, vdescs); m_vtxFmt = res.m_factory->newVertexFormat(13, vdescs);
boo::ITexture* texs[] = {m_fontAtlas.texture()}; boo::ITexture* texs[] = {m_fontAtlas.texture()};
m_shaderBinding = system.m_factory->newShaderDataBinding(shader, m_vtxFmt, m_shaderBinding = res.m_factory->newShaderDataBinding(shader, m_vtxFmt,
nullptr, m_glyphBuf, nullptr, 1, nullptr, m_glyphBuf, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf, (boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
1, texs); 1, texs);
} }
else else
{ {
boo::ITexture* texs[] = {m_fontAtlas.texture()}; boo::ITexture* texs[] = {m_fontAtlas.texture()};
m_shaderBinding = system.m_factory->newShaderDataBinding(shader, system.m_textRes.m_vtxFmt, m_shaderBinding = res.m_factory->newShaderDataBinding(shader, res.m_textRes.m_vtxFmt,
nullptr, m_glyphBuf, nullptr, 1, nullptr, m_glyphBuf, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf, (boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
1, texs); 1, texs);
} }
m_glyphs.reserve(capacity); m_glyphs.reserve(capacity);
commitResources(system); commitResources(res);
} }
TextView::TextView(ViewResources& system, View& parentView, FontTag font, size_t capacity) TextView::TextView(ViewResources& res, View& parentView, FontTag font, size_t capacity)
: TextView(system, parentView, system.m_textRes.m_fcache->lookupAtlas(font), capacity) {} : TextView(res, parentView, res.m_textRes.m_fcache->lookupAtlas(font), capacity) {}
TextView::RenderGlyph::RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const Zeus::CColor& defaultColor) TextView::RenderGlyph::RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const Zeus::CColor& defaultColor)
{ {
@ -383,7 +383,9 @@ void TextView::typesetGlyphs(const std::string& str, const Zeus::CColor& default
break; break;
} }
m_width = adv;
m_valid = false; m_valid = false;
updateSize();
} }
void TextView::typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaultColor) void TextView::typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaultColor)
{ {
@ -411,7 +413,9 @@ void TextView::typesetGlyphs(const std::wstring& str, const Zeus::CColor& defaul
break; break;
} }
m_width = adv;
m_valid = false; m_valid = false;
updateSize();
} }
void TextView::colorGlyphs(const Zeus::CColor& newColor) void TextView::colorGlyphs(const Zeus::CColor& newColor)
@ -427,6 +431,11 @@ void TextView::think()
{ {
} }
void TextView::resized(const boo::SWindowRect &rootView, const boo::SWindowRect& sub)
{
View::resized(rootView, sub);
}
void TextView::draw(boo::IGraphicsCommandQueue* gfxQ) void TextView::draw(boo::IGraphicsCommandQueue* gfxQ)
{ {
View::draw(gfxQ); View::draw(gfxQ);

View File

@ -3,6 +3,7 @@
#include "Specter/ViewResources.hpp" #include "Specter/ViewResources.hpp"
#define TOOLBAR_GAUGE 28 #define TOOLBAR_GAUGE 28
#define TOOLBAR_PADDING 10
namespace Specter namespace Specter
{ {
@ -20,10 +21,12 @@ void Toolbar::Resources::init(boo::IGraphicsDataFactory* factory, const ThemeDat
} }
Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos) Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos)
: View(res, parentView), m_tbPos(tbPos), m_gauge(res.pixelFactor() * TOOLBAR_GAUGE) : View(res, parentView), m_tbPos(tbPos),
m_gauge(res.pixelFactor() * TOOLBAR_GAUGE),
m_padding(res.pixelFactor() * TOOLBAR_PADDING)
{ {
m_tbBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); m_tbBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
m_tbVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(ToolbarVert), 10); m_tbVertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), 10);
if (!res.m_viewRes.m_texVtxFmt) if (!res.m_viewRes.m_texVtxFmt)
{ {
@ -55,19 +58,87 @@ Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos)
void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{ {
boo::SWindowRect childRect = subRect();
for (Child& c : m_children)
{
childRect.size[0] = c.m_view->nominalWidth();
childRect.size[1] = c.m_view->nominalHeight();
childRect.location[0] += m_padding;
childRect.location[1] = (m_gauge - childRect.size[1]) / 2 - 1;
if (childRect.coordInRect(coord))
{
if (!c.m_mouseDown)
{
c.m_view->mouseDown(coord, button, mod);
c.m_mouseDown = true;
}
}
childRect.location[0] += childRect.size[0];
}
} }
void Toolbar::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) void Toolbar::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{ {
for (Child& c : m_children)
{
if (c.m_mouseDown)
{
c.m_view->mouseUp(coord, button, mod);
c.m_mouseDown = false;
}
}
} }
void Toolbar::mouseMove(const boo::SWindowCoord& coord) void Toolbar::mouseMove(const boo::SWindowCoord& coord)
{ {
boo::SWindowRect childRect = subRect();
for (Child& c : m_children)
{
childRect.size[0] = c.m_view->nominalWidth();
childRect.size[1] = c.m_view->nominalHeight();
childRect.location[0] += m_padding;
childRect.location[1] = (m_gauge - childRect.size[1]) / 2 - 1;
if (childRect.coordInRect(coord))
{
if (!c.m_mouseIn)
{
c.m_view->mouseEnter(coord);
c.m_mouseIn = true;
}
c.m_view->mouseMove(coord);
}
else
{
if (c.m_mouseIn)
{
c.m_view->mouseLeave(coord);
c.m_mouseIn = false;
}
}
childRect.location[0] += childRect.size[0];
}
}
void Toolbar::mouseEnter(const boo::SWindowCoord& coord)
{
}
void Toolbar::mouseLeave(const boo::SWindowCoord& coord)
{
for (Child& c : m_children)
{
if (c.m_mouseIn)
{
c.m_view->mouseLeave(coord);
c.m_mouseIn = false;
}
}
} }
void Toolbar::resetResources(ViewResources& res) void Toolbar::resetResources(ViewResources& res)
{ {
m_gauge = res.pixelFactor() * TOOLBAR_GAUGE; m_gauge = res.pixelFactor() * TOOLBAR_GAUGE;
m_padding = res.pixelFactor() * TOOLBAR_PADDING;
setBackground(res.themeData().toolbarBackground()); setBackground(res.themeData().toolbarBackground());
updateSize(); updateSize();
} }
@ -76,9 +147,20 @@ void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{ {
View::resized(root, sub); View::resized(root, sub);
setHorizontalVerts(sub.size[0]); setHorizontalVerts(sub.size[0]);
m_tbVertsBuf->load(&m_tbVerts, sizeof(ToolbarVert) * 10); m_tbVertsBuf->load(&m_tbVerts, sizeof(TexShaderVert) * 10);
m_tbBlock.setViewRect(root, sub); m_tbBlock.setViewRect(root, sub);
m_tbBlockBuf->load(&m_tbBlock, sizeof(ViewBlock)); m_tbBlockBuf->load(&m_tbBlock, sizeof(ViewBlock));
boo::SWindowRect childRect = sub;
for (Child& c : m_children)
{
childRect.size[0] = c.m_view->nominalWidth();
childRect.size[1] = c.m_view->nominalHeight();
childRect.location[0] += m_padding;
childRect.location[1] = (m_gauge - childRect.size[1]) / 2 - 1;
c.m_view->resized(root, childRect);
childRect.location[0] += childRect.size[0];
}
} }
void Toolbar::draw(boo::IGraphicsCommandQueue* gfxQ) void Toolbar::draw(boo::IGraphicsCommandQueue* gfxQ)
@ -87,6 +169,9 @@ void Toolbar::draw(boo::IGraphicsCommandQueue* gfxQ)
gfxQ->setShaderDataBinding(m_tbShaderBinding); gfxQ->setShaderDataBinding(m_tbShaderBinding);
gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips);
gfxQ->draw(0, 10); gfxQ->draw(0, 10);
for (Child& c : m_children)
c.m_view->draw(gfxQ);
} }
} }

View File

@ -148,7 +148,7 @@ void View::Resources::init(boo::ID3DDataFactory* factory, const ThemeData& theme
boo::VertexElementDescriptor solidvdescs[] = boo::VertexElementDescriptor solidvdescs[] =
{ {
{nullptr, nullptr, boo::VertexSemantic::Position4}, {nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} {nullptr, nullptr, boo::VertexSemantic::Color}
}; };
m_solidVtxFmt = factory->newVertexFormat(2, solidvdescs); m_solidVtxFmt = factory->newVertexFormat(2, solidvdescs);
@ -252,7 +252,7 @@ void View::Resources::init(boo::MetalDataFactory* factory, const ThemeData& them
boo::VertexElementDescriptor solidvdescs[] = boo::VertexElementDescriptor solidvdescs[] =
{ {
{nullptr, nullptr, boo::VertexSemantic::Position4}, {nullptr, nullptr, boo::VertexSemantic::Position4},
{nullptr, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} {nullptr, nullptr, boo::VertexSemantic::Color}
}; };
m_solidVtxFmt = factory->newVertexFormat(2, solidvdescs); m_solidVtxFmt = factory->newVertexFormat(2, solidvdescs);
@ -276,15 +276,9 @@ void View::Resources::init(boo::MetalDataFactory* factory, const ThemeData& them
void View::buildResources(ViewResources& system) void View::buildResources(ViewResources& system)
{ {
m_bgColor = Zeus::CColor::skClear;
m_bgVertBuf = m_bgVertBuf =
system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex,
sizeof(Zeus::CVector3f), 4); sizeof(SolidShaderVert), 4);
m_bgInstBuf =
system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex,
sizeof(Zeus::CColor), 1);
m_viewVertBlockBuf = m_viewVertBlockBuf =
system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform,
@ -295,12 +289,12 @@ void View::buildResources(ViewResources& system)
boo::VertexElementDescriptor vdescs[] = boo::VertexElementDescriptor vdescs[] =
{ {
{m_bgVertBuf, nullptr, boo::VertexSemantic::Position4}, {m_bgVertBuf, nullptr, boo::VertexSemantic::Position4},
{m_bgInstBuf, nullptr, boo::VertexSemantic::Color | boo::VertexSemantic::Instanced} {m_bgVertBuf, nullptr, boo::VertexSemantic::Color}
}; };
m_bgVtxFmt = system.m_factory->newVertexFormat(2, vdescs); m_bgVtxFmt = system.m_factory->newVertexFormat(2, vdescs);
m_bgShaderBinding = m_bgShaderBinding =
system.m_factory->newShaderDataBinding(system.m_viewRes.m_solidShader, m_bgVtxFmt, system.m_factory->newShaderDataBinding(system.m_viewRes.m_solidShader, m_bgVtxFmt,
m_bgVertBuf, m_bgInstBuf, nullptr, 1, m_bgVertBuf, nullptr, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf, (boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
0, nullptr); 0, nullptr);
} }
@ -308,7 +302,7 @@ void View::buildResources(ViewResources& system)
{ {
m_bgShaderBinding = m_bgShaderBinding =
system.m_factory->newShaderDataBinding(system.m_viewRes.m_solidShader, system.m_viewRes.m_solidVtxFmt, system.m_factory->newShaderDataBinding(system.m_viewRes.m_solidShader, system.m_viewRes.m_solidVtxFmt,
m_bgVertBuf, m_bgInstBuf, nullptr, 1, m_bgVertBuf, nullptr, nullptr, 1,
(boo::IGraphicsBuffer**)&m_viewVertBlockBuf, (boo::IGraphicsBuffer**)&m_viewVertBlockBuf,
0, nullptr); 0, nullptr);
} }
@ -322,7 +316,7 @@ View::View(ViewResources& system)
} }
View::View(ViewResources& system, View& parentView) View::View(ViewResources& system, View& parentView)
: m_rootView(parentView.root()), : m_rootView(parentView.rootView()),
m_parentView(parentView) m_parentView(parentView)
{ {
buildResources(system); buildResources(system);
@ -337,12 +331,12 @@ void View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{ {
m_subRect = sub; m_subRect = sub;
m_viewVertBlock.setViewRect(root, sub); m_viewVertBlock.setViewRect(root, sub);
m_bgRect[0].assign(0.f, sub.size[1], 0.f); m_bgRect[0].m_pos.assign(0.f, sub.size[1], 0.f);
m_bgRect[1].assign(0.f, 0.f, 0.f); m_bgRect[1].m_pos.assign(0.f, 0.f, 0.f);
m_bgRect[2].assign(sub.size[0], sub.size[1], 0.f); m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
m_bgRect[3].assign(sub.size[0], 0.f, 0.f); m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock)); m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
m_bgVertBuf->load(m_bgRect, sizeof(Zeus::CVector3f) * 4); m_bgVertBuf->load(m_bgRect, sizeof(SolidShaderVert) * 4);
} }
void View::draw(boo::IGraphicsCommandQueue* gfxQ) void View::draw(boo::IGraphicsCommandQueue* gfxQ)
@ -354,7 +348,7 @@ void View::draw(boo::IGraphicsCommandQueue* gfxQ)
void View::commitResources(ViewResources& system) void View::commitResources(ViewResources& system)
{ {
m_gfxData.reset(system.m_factory->commit()); m_gfxData = system.m_factory->commit();
} }
} }

View File

@ -15,7 +15,7 @@ void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache,
m_monoFont = fcache->prepMonoFont(factory, AllCharFilter, false, 10.f, dpi); m_monoFont = fcache->prepMonoFont(factory, AllCharFilter, false, 10.f, dpi);
m_heading14 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 14.f, dpi); m_heading14 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 14.f, dpi);
m_heading18 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 18.f, dpi); m_heading18 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 18.f, dpi);
m_fontData.reset(factory->commit()); m_fontData = factory->commit();
switch (factory->platform()) switch (factory->platform())
{ {
case boo::IGraphicsDataFactory::Platform::OGL: case boo::IGraphicsDataFactory::Platform::OGL:
@ -35,7 +35,7 @@ void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache,
Log.report(LogVisor::FatalError, _S("unable to init view system for %s"), factory->platformName()); Log.report(LogVisor::FatalError, _S("unable to init view system for %s"), factory->platformName());
} }
fcache->closeBuiltinFonts(); fcache->closeBuiltinFonts();
m_resData.reset(factory->commit()); m_resData = factory->commit();
} }
void ViewResources::resetDPI(unsigned dpi) void ViewResources::resetDPI(unsigned dpi)
@ -45,7 +45,7 @@ void ViewResources::resetDPI(unsigned dpi)
m_monoFont = m_fcache->prepMonoFont(m_factory, AllCharFilter, false, 10.f, dpi); m_monoFont = m_fcache->prepMonoFont(m_factory, AllCharFilter, false, 10.f, dpi);
m_heading14 = m_fcache->prepMainFont(m_factory, LatinAndJapaneseCharFilter, false, 14.f, dpi); m_heading14 = m_fcache->prepMainFont(m_factory, LatinAndJapaneseCharFilter, false, 14.f, dpi);
m_heading18 = m_fcache->prepMainFont(m_factory, LatinAndJapaneseCharFilter, false, 18.f, dpi); m_heading18 = m_fcache->prepMainFont(m_factory, LatinAndJapaneseCharFilter, false, 18.f, dpi);
m_fontData.reset(m_factory->commit()); m_fontData = m_factory->commit();
m_fcache->closeBuiltinFonts(); m_fcache->closeBuiltinFonts();
} }