diff --git a/specter/CMakeLists.txt b/specter/CMakeLists.txt index f0684e98c..f19fd9fdd 100644 --- a/specter/CMakeLists.txt +++ b/specter/CMakeLists.txt @@ -40,6 +40,7 @@ list(APPEND SPECTER_HEADERS include/Specter/TextView.hpp include/Specter/MultiLineTextView.hpp include/Specter/Space.hpp + include/Specter/Toolbar.hpp include/Specter/Table.hpp include/Specter/Outliner.hpp include/Specter/Panel.hpp @@ -56,6 +57,7 @@ atdna(atdna_FontCache.cpp include/Specter/FontCache.hpp) list(APPEND SPECTER_SOURCES lib/Specter.cpp + lib/ViewResources.cpp lib/View.cpp lib/RootView.cpp lib/SplitView.cpp @@ -63,6 +65,7 @@ list(APPEND SPECTER_SOURCES lib/TextView.cpp lib/MultiLineTextView.cpp lib/Space.cpp + lib/Toolbar.cpp lib/Table.cpp lib/Outliner.cpp lib/Panel.cpp diff --git a/specter/include/Specter/Space.hpp b/specter/include/Specter/Space.hpp index a752aa38a..4d8077b08 100644 --- a/specter/include/Specter/Space.hpp +++ b/specter/include/Specter/Space.hpp @@ -1,4 +1,28 @@ #ifndef SPECTER_SPACE_HPP #define SPECTER_SPACE_HPP +#include "Specter/View.hpp" +#include "Specter/Toolbar.hpp" + +namespace Specter +{ + +class Space : public View +{ + Toolbar::Position m_tbPos; + std::unique_ptr m_toolbar; + std::unique_ptr m_contentView; +public: + Space(ViewResources& res, View& parentView, Toolbar::Position toolbarPos); + std::unique_ptr setContentView(std::unique_ptr&& view); + 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 resetResources(ViewResources& res); + void draw(boo::IGraphicsCommandQueue* gfxQ); +}; + +} + #endif // SPECTER_SPACE_HPP diff --git a/specter/include/Specter/SplitView.hpp b/specter/include/Specter/SplitView.hpp index 13bc86f24..a8b69a207 100644 --- a/specter/include/Specter/SplitView.hpp +++ b/specter/include/Specter/SplitView.hpp @@ -35,7 +35,7 @@ private: } std::unique_ptr m_views[2]; - VertexBlock m_splitBlock; + ViewBlock m_splitBlock; boo::IGraphicsBufferD* m_splitBlockBuf; struct SplitVert { @@ -70,7 +70,6 @@ private: boo::IGraphicsBufferD* m_splitVertsBuf; boo::IVertexFormat* m_splitVtxFmt; /* OpenGL only */ boo::IShaderDataBinding* m_splitShaderBinding; - bool m_splitValid = false; public: SplitView(ViewResources& res, View& parentView, Axis axis); std::unique_ptr setContentView(int slot, std::unique_ptr&& view); diff --git a/specter/include/Specter/Toolbar.hpp b/specter/include/Specter/Toolbar.hpp new file mode 100644 index 000000000..505f97def --- /dev/null +++ b/specter/include/Specter/Toolbar.hpp @@ -0,0 +1,105 @@ +#ifndef SPECTER_TOOLBAR_HPP +#define SPECTER_TOOLBAR_HPP + +#include "Specter/View.hpp" + +namespace Specter +{ + +class Toolbar : public View +{ +public: + class Resources + { + friend class ViewResources; + friend class Toolbar; + boo::ITextureS* m_shadingTex; + + void init(boo::IGraphicsDataFactory* factory); + }; + + enum class Position + { + Bottom, + Top + }; +private: + Position m_tbPos; + + std::unique_ptr m_contentView; + ViewBlock m_splitBlock; + boo::IGraphicsBufferD* m_tbBlockBuf; + struct ToolbarVert + { + Zeus::CVector3f m_pos; + Zeus::CVector2f m_uv; + } m_tbVerts[10]; + int m_gauge = 25; + + void setHorizontalVerts(int width) + { + m_tbVerts[0].m_pos.assign(0, 1 + m_gauge, 0); + m_tbVerts[0].m_uv.assign(0, 0); + m_tbVerts[1].m_pos.assign(0, -1 + m_gauge, 0); + m_tbVerts[1].m_uv.assign(0.5, 0); + m_tbVerts[2].m_pos.assign(width, 1 + m_gauge, 0); + m_tbVerts[2].m_uv.assign(0, 0); + m_tbVerts[3].m_pos.assign(width, -1 + m_gauge, 0); + m_tbVerts[3].m_uv.assign(0.5, 0); + m_tbVerts[4].m_pos.assign(width, -1 + m_gauge, 0); + m_tbVerts[4].m_uv.assign(0.5, 0); + + m_tbVerts[5].m_pos.assign(0, 1, 0); + m_tbVerts[5].m_uv.assign(0.5, 0); + m_tbVerts[6].m_pos.assign(0, 1, 0); + m_tbVerts[6].m_uv.assign(0.5, 0); + m_tbVerts[7].m_pos.assign(0, -1, 0); + m_tbVerts[7].m_uv.assign(1, 0); + m_tbVerts[8].m_pos.assign(width, 1, 0); + m_tbVerts[8].m_uv.assign(0.5, 0); + m_tbVerts[9].m_pos.assign(width, -1, 0); + m_tbVerts[9].m_uv.assign(1, 0); + } + + void setVerticalVerts(int height) + { + m_tbVerts[0].m_pos.assign(-1, height, 0); + m_tbVerts[0].m_uv.assign(0, 0); + m_tbVerts[1].m_pos.assign(-1, 0, 0); + m_tbVerts[1].m_uv.assign(0, 0); + m_tbVerts[2].m_pos.assign(1, height, 0); + m_tbVerts[2].m_uv.assign(0.5, 0); + m_tbVerts[3].m_pos.assign(1, 0, 0); + m_tbVerts[3].m_uv.assign(0.5, 0); + m_tbVerts[4].m_pos.assign(1, 0, 0); + m_tbVerts[4].m_uv.assign(0.5, 0); + + m_tbVerts[5].m_pos.assign(-1 + m_gauge, height, 0); + m_tbVerts[5].m_uv.assign(0.5, 0); + m_tbVerts[6].m_pos.assign(-1 + m_gauge, height, 0); + m_tbVerts[6].m_uv.assign(0.5, 0); + m_tbVerts[7].m_pos.assign(-1 + m_gauge, 0, 0); + m_tbVerts[7].m_uv.assign(0.5, 0); + m_tbVerts[8].m_pos.assign(1 + m_gauge, height, 0); + m_tbVerts[8].m_uv.assign(1, 0); + m_tbVerts[9].m_pos.assign(1 + m_gauge, 0, 0); + m_tbVerts[9].m_uv.assign(1, 0); + } + + 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 resetResources(ViewResources& res); + void draw(boo::IGraphicsCommandQueue* gfxQ); +}; + +} + +#endif // SPECTER_TOOLBAR_HPP diff --git a/specter/include/Specter/View.hpp b/specter/include/Specter/View.hpp index 0320f4329..443a0e5be 100644 --- a/specter/include/Specter/View.hpp +++ b/specter/include/Specter/View.hpp @@ -28,15 +28,14 @@ class View boo::IShaderDataBinding* m_bgShaderBinding; Zeus::CVector3f m_bgRect[4]; Zeus::CColor m_bgColor; - bool m_bgValid = false; std::unique_ptr m_gfxData; friend class RootView; void buildResources(ViewResources& res); - View(ViewResources& res, RootView& parentView); + View(ViewResources& res); protected: - struct VertexBlock + struct ViewBlock { Zeus::CMatrix4f m_mv; void setViewRect(const boo::SWindowRect& root, const boo::SWindowRect& sub) @@ -96,7 +95,11 @@ public: const boo::SWindowRect& subRect() const {return m_subRect;} void updateSize(); - void setBackground(Zeus::CColor color) {m_bgColor = color; m_bgValid = false;} + void setBackground(Zeus::CColor color) + { + m_bgColor = color; + m_bgInstBuf->load(&m_bgColor, sizeof(Zeus::CColor)); + } virtual void updateCVar(HECL::CVar* cvar) {} virtual void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {} diff --git a/specter/include/Specter/ViewResources.hpp b/specter/include/Specter/ViewResources.hpp index 3c9ae2f1e..75e63c658 100644 --- a/specter/include/Specter/ViewResources.hpp +++ b/specter/include/Specter/ViewResources.hpp @@ -3,6 +3,7 @@ #include "TextView.hpp" #include "RootView.hpp" +#include "Toolbar.hpp" namespace Specter { @@ -13,14 +14,15 @@ class ViewResources { m_viewRes.init(factory); m_textRes.init(factory, fcache); - m_splitViewRes.init(factory); + m_splitRes.init(factory); } public: boo::IGraphicsDataFactory* m_factory = nullptr; View::Resources m_viewRes; TextView::Resources m_textRes; - SplitView::Resources m_splitViewRes; + SplitView::Resources m_splitRes; + Toolbar::Resources m_toolbarRes; std::unique_ptr m_resData; Specter::FontTag m_mainFont; @@ -36,6 +38,9 @@ public: ViewResources& operator=(ViewResources&& other) = default; void init(boo::IGraphicsDataFactory* factory, FontCache* fcache, unsigned dpi); + + float m_pixelFactor = 0; + float pixelFactor() const {return m_pixelFactor;} }; } diff --git a/specter/lib/RootView.cpp b/specter/lib/RootView.cpp index 17affe782..9dd9c7e12 100644 --- a/specter/lib/RootView.cpp +++ b/specter/lib/RootView.cpp @@ -6,7 +6,7 @@ namespace Specter static LogVisor::LogModule Log("Specter::RootView"); RootView::RootView(ViewResources& res, boo::IWindow* window) -: View(res, *this), m_window(window), m_events(*this) +: View(res), m_window(window), m_events(*this) { window->setCallback(&m_events); boo::SWindowRect rect = window->getWindowFrame(); diff --git a/specter/lib/Space.cpp b/specter/lib/Space.cpp index e69de29bb..6aef52a95 100644 --- a/specter/lib/Space.cpp +++ b/specter/lib/Space.cpp @@ -0,0 +1,54 @@ +#include +#include "Specter/Space.hpp" +#include "Specter/ViewResources.hpp" + +namespace Specter +{ +static LogVisor::LogModule Log("Specter::Space"); + +Space::Space(ViewResources& res, View& parentView, Toolbar::Position tbPos) +: View(res, parentView), m_tbPos(tbPos) +{ + commitResources(res); + m_toolbar.reset(new Toolbar(res, *this, tbPos)); +} + +std::unique_ptr Space::setContentView(std::unique_ptr&& view) +{ + std::unique_ptr ret; + m_contentView.swap(ret); + m_contentView = std::move(view); + updateSize(); + return ret; +} + +void Space::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) +{ +} + +void Space::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) +{ +} + +void Space::mouseMove(const boo::SWindowCoord& coord) +{ +} + +void Space::resetResources(ViewResources& res) +{ + if (m_contentView) + m_contentView->resetResources(res); +} + +void Space::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) +{ + View::resized(root, sub); +} + +void Space::draw(boo::IGraphicsCommandQueue* gfxQ) +{ + View::draw(gfxQ); +} + +} + diff --git a/specter/lib/Specter.cpp b/specter/lib/Specter.cpp index dc5900d92..3cb962e87 100644 --- a/specter/lib/Specter.cpp +++ b/specter/lib/Specter.cpp @@ -1,36 +1,6 @@ -#include "Specter/ViewResources.hpp" +#include namespace Specter { static LogVisor::LogModule Log("Specter"); - -void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, unsigned dpi) -{ - m_factory = factory; - m_mainFont = fcache->prepMainFont(factory, AllCharFilter, false, 10.0, dpi); - m_monoFont = fcache->prepMonoFont(factory, AllCharFilter, false, 10.0, dpi); - m_heading14 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 14.0, dpi); - m_heading18 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 18.0, dpi); - switch (factory->platform()) - { - case boo::IGraphicsDataFactory::Platform::OGL: - init(static_cast(factory), fcache); - break; -#if _WIN32 - case boo::IGraphicsDataFactory::Platform::D3D11: - case boo::IGraphicsDataFactory::Platform::D3D12: - init(static_cast(factory), fcache); - break; -#elif BOO_HAS_METAL - case boo::IGraphicsDataFactory::Platform::Metal: - init(static_cast(factory), fcache); - break; -#endif - default: - Log.report(LogVisor::FatalError, _S("unable to init view system for %s"), factory->platformName()); - } - fcache->closeBuiltinFonts(); - m_resData.reset(factory->commit()); -} - } diff --git a/specter/lib/SplitView.cpp b/specter/lib/SplitView.cpp index de3092aa9..3a664ff4c 100644 --- a/specter/lib/SplitView.cpp +++ b/specter/lib/SplitView.cpp @@ -20,7 +20,7 @@ void SplitView::Resources::init(boo::IGraphicsDataFactory* factory) SplitView::SplitView(ViewResources& system, View& parentView, Axis axis) : View(system, parentView), m_axis(axis) { - m_splitBlockBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(VertexBlock), 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); if (!system.m_viewRes.m_texVtxFmt) @@ -32,7 +32,7 @@ SplitView::SplitView(ViewResources& system, View& parentView, Axis axis) }; m_splitVtxFmt = system.m_factory->newVertexFormat(2, vdescs); boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf}; - boo::ITexture* texs[] = {system.m_splitViewRes.m_shadingTex}; + boo::ITexture* texs[] = {system.m_splitRes.m_shadingTex}; m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader, m_splitVtxFmt, m_splitVertsBuf, nullptr, nullptr, 1, bufs, 1, texs); @@ -40,7 +40,7 @@ SplitView::SplitView(ViewResources& system, View& parentView, Axis axis) else { boo::IGraphicsBuffer* bufs[] = {m_splitBlockBuf}; - boo::ITexture* texs[] = {system.m_splitViewRes.m_shadingTex}; + boo::ITexture* texs[] = {system.m_splitRes.m_shadingTex}; m_splitShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader, system.m_viewRes.m_texVtxFmt, m_splitVertsBuf, nullptr, @@ -140,7 +140,8 @@ void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& su m_splitBlock.setViewRect(root, ssub); setVerticalVerts(ssub.size[1]); } - m_splitValid = false; + m_splitBlockBuf->load(&m_splitBlock, sizeof(ViewBlock)); + m_splitVertsBuf->load(m_splitVerts, sizeof(SplitVert) * 4); } void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ) @@ -150,13 +151,6 @@ void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ) m_views[0]->draw(gfxQ); if (m_views[1]) m_views[1]->draw(gfxQ); - - if (!m_splitValid) - { - m_splitBlockBuf->load(&m_splitBlock, sizeof(VertexBlock)); - m_splitVertsBuf->load(m_splitVerts, sizeof(SplitVert) * 4); - m_splitValid = true; - } gfxQ->setShaderDataBinding(m_splitShaderBinding); gfxQ->draw(0, 4); diff --git a/specter/lib/Toolbar.cpp b/specter/lib/Toolbar.cpp new file mode 100644 index 000000000..d88b68733 --- /dev/null +++ b/specter/lib/Toolbar.cpp @@ -0,0 +1,85 @@ +#include +#include "Specter/Toolbar.hpp" +#include "Specter/ViewResources.hpp" + +namespace Specter +{ +static LogVisor::LogModule Log("Specter::Space"); + +void Toolbar::Resources::init(boo::IGraphicsDataFactory* factory) +{ + static const Zeus::RGBA32 tex[3] = + { + {0,0,0,64}, + {0,0,0,0}, + {255,255,255,64} + }; + m_shadingTex = factory->newStaticTexture(3, 1, 1, boo::TextureFormat::RGBA8, tex, 12); +} + +Toolbar::Toolbar(ViewResources& system, View& parentView, Position tbPos) +: View(system, parentView), m_tbPos(tbPos), m_gauge(system.pixelFactor() * 25) +{ + m_tbBlockBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); + m_tbVertsBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(ToolbarVert), 10); + + if (!system.m_viewRes.m_texVtxFmt) + { + boo::VertexElementDescriptor vdescs[] = + { + {m_tbVertsBuf, nullptr, boo::VertexSemantic::Position4}, + {m_tbVertsBuf, nullptr, boo::VertexSemantic::UV4} + }; + m_tbVtxFmt = system.m_factory->newVertexFormat(2, vdescs); + boo::IGraphicsBuffer* bufs[] = {m_tbBlockBuf}; + boo::ITexture* texs[] = {system.m_toolbarRes.m_shadingTex}; + m_tbShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader, + m_tbVtxFmt, m_tbVertsBuf, nullptr, + nullptr, 1, bufs, 1, texs); + } + else + { + boo::IGraphicsBuffer* bufs[] = {m_tbBlockBuf}; + boo::ITexture* texs[] = {system.m_toolbarRes.m_shadingTex}; + m_tbShaderBinding = system.m_factory->newShaderDataBinding(system.m_viewRes.m_texShader, + system.m_viewRes.m_texVtxFmt, + m_tbVertsBuf, nullptr, + nullptr, 1, bufs, 1, texs); + } + + commitResources(system); +} + +void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) +{ +} + +void Toolbar::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) +{ +} + +void Toolbar::mouseMove(const boo::SWindowCoord& coord) +{ +} + +void Toolbar::resetResources(ViewResources& res) +{ + m_gauge = res.pixelFactor() * 25; + updateSize(); +} + +void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) +{ + View::resized(root, sub); + setHorizontalVerts(sub.size[0]); + m_tbVertsBuf->load(&m_tbVerts, sizeof(ToolbarVert) * 10); +} + +void Toolbar::draw(boo::IGraphicsCommandQueue* gfxQ) +{ + View::draw(gfxQ); + +} + +} + diff --git a/specter/lib/View.cpp b/specter/lib/View.cpp index 2ad23e980..437eaf99d 100644 --- a/specter/lib/View.cpp +++ b/specter/lib/View.cpp @@ -288,7 +288,7 @@ void View::buildResources(ViewResources& system) m_viewVertBlockBuf = system.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, - sizeof(VertexBlock), 1); + sizeof(ViewBlock), 1); if (!system.m_viewRes.m_solidVtxFmt) { @@ -314,9 +314,9 @@ void View::buildResources(ViewResources& system) } } -View::View(ViewResources& system, RootView& rootView) -: m_rootView(rootView), - m_parentView(rootView) +View::View(ViewResources& system) +: m_rootView(*static_cast(this)), + m_parentView(*static_cast(this)) { buildResources(system); } @@ -341,18 +341,12 @@ void View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) m_bgRect[1].assign(0.f, 0.f, 0.f); m_bgRect[2].assign(sub.size[0], sub.size[1], 0.f); m_bgRect[3].assign(sub.size[0], 0.f, 0.f); - m_bgValid = false; + m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock)); + m_bgVertBuf->load(m_bgRect, sizeof(Zeus::CVector3f) * 4); } void View::draw(boo::IGraphicsCommandQueue* gfxQ) { - if (!m_bgValid) - { - m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(VertexBlock)); - m_bgVertBuf->load(m_bgRect, sizeof(Zeus::CVector3f) * 4); - m_bgInstBuf->load(&m_bgColor, sizeof(Zeus::CColor)); - m_bgValid = true; - } gfxQ->setShaderDataBinding(m_bgShaderBinding); gfxQ->setDrawPrimitive(boo::Primitive::TriStrips); gfxQ->draw(0, 4); diff --git a/specter/lib/ViewResources.cpp b/specter/lib/ViewResources.cpp new file mode 100644 index 000000000..599a9f45c --- /dev/null +++ b/specter/lib/ViewResources.cpp @@ -0,0 +1,37 @@ +#include "Specter/ViewResources.hpp" + +namespace Specter +{ +static LogVisor::LogModule Log("Specter::ViewResources"); + +void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, unsigned dpi) +{ + m_pixelFactor = dpi / 72.f; + m_factory = factory; + m_mainFont = fcache->prepMainFont(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_heading18 = fcache->prepMainFont(factory, LatinAndJapaneseCharFilter, false, 18.f, dpi); + switch (factory->platform()) + { + case boo::IGraphicsDataFactory::Platform::OGL: + init(static_cast(factory), fcache); + break; +#if _WIN32 + case boo::IGraphicsDataFactory::Platform::D3D11: + case boo::IGraphicsDataFactory::Platform::D3D12: + init(static_cast(factory), fcache); + break; +#elif BOO_HAS_METAL + case boo::IGraphicsDataFactory::Platform::Metal: + init(static_cast(factory), fcache); + break; +#endif + default: + Log.report(LogVisor::FatalError, _S("unable to init view system for %s"), factory->platformName()); + } + fcache->closeBuiltinFonts(); + m_resData.reset(factory->commit()); +} + +}