From 21dece5b1e6be5aef7771f5a8cbc919b87c8569b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 30 Aug 2019 05:55:46 -0400 Subject: [PATCH] General: Include headers where applicable Ensures necessary dependencies are always included where applicable, as well as avoiding including dependencies where they aren't necessary. --- specter/include/specter/Button.hpp | 71 +++------ specter/include/specter/Control.hpp | 21 ++- specter/include/specter/FileBrowser.hpp | 91 ++++-------- specter/include/specter/FontCache.hpp | 19 ++- specter/include/specter/IMenuNode.hpp | 8 +- specter/include/specter/IViewManager.hpp | 12 +- specter/include/specter/Icon.hpp | 11 +- specter/include/specter/Menu.hpp | 18 ++- specter/include/specter/MessageWindow.hpp | 19 ++- specter/include/specter/ModalWindow.hpp | 14 +- specter/include/specter/MultiLineTextView.hpp | 15 +- specter/include/specter/NumericField.hpp | 14 +- specter/include/specter/Outliner.hpp | 7 + specter/include/specter/PathButtons.hpp | 49 ++----- specter/include/specter/RootView.hpp | 41 +++--- specter/include/specter/ScrollView.hpp | 35 ++--- specter/include/specter/Space.hpp | 30 ++-- specter/include/specter/SplitView.hpp | 5 +- specter/include/specter/Table.hpp | 39 ++--- specter/include/specter/TextField.hpp | 22 +-- specter/include/specter/Toolbar.hpp | 14 ++ specter/include/specter/Tooltip.hpp | 10 +- specter/include/specter/View.hpp | 32 +++-- specter/include/specter/ViewResources.hpp | 13 +- specter/lib/Button.cpp | 56 +++++++- specter/lib/Control.cpp | 6 + specter/lib/FileBrowser.cpp | 71 ++++++++- specter/lib/FontCache.cpp | 20 ++- specter/lib/Menu.cpp | 6 + specter/lib/MessageWindow.cpp | 20 ++- specter/lib/ModalWindow.cpp | 8 +- specter/lib/PathButtons.cpp | 136 ++++++++++++------ specter/lib/RootView.cpp | 27 +++- specter/lib/ScrollView.cpp | 29 +++- specter/lib/Space.cpp | 24 +++- specter/lib/Table.cpp | 32 ++++- specter/lib/TextField.cpp | 19 +++ specter/lib/Toolbar.cpp | 4 +- specter/lib/Tooltip.cpp | 6 +- specter/lib/View.cpp | 8 +- specter/lib/ViewResources.cpp | 3 + 41 files changed, 726 insertions(+), 359 deletions(-) diff --git a/specter/include/specter/Button.hpp b/specter/include/specter/Button.hpp index fe77a7956..4e90fce18 100644 --- a/specter/include/specter/Button.hpp +++ b/specter/include/specter/Button.hpp @@ -1,12 +1,24 @@ #pragma once -#include "specter/TextView.hpp" +#include +#include + #include "specter/Control.hpp" -#include "specter/Icon.hpp" +#include "specter/View.hpp" + +#include +#include namespace specter { +class IconView; +class TextView; + +struct Icon; class Button : public Control { + struct ButtonTarget; + struct MenuTarget; + public: enum class Style { Block, @@ -28,65 +40,34 @@ private: void _loadVerts() { m_vertsBinding.load(m_verts); } RectangleConstraint m_constraint; - int m_nomWidth, m_nomHeight; - int m_textWidth, m_textIconWidth; - struct ButtonTarget : View { - Button& m_button; + int m_nomWidth; + int m_nomHeight; - bool m_pressed = false; - bool m_hovered = false; + int m_textWidth; + int m_textIconWidth; - void setInactive(); - void setHover(); - void setPressed(); - void setDisabled(); - - void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseEnter(const boo::SWindowCoord&) override; - void mouseLeave(const boo::SWindowCoord&) override; - ButtonTarget(ViewResources& res, Button& button) : View(res, button), m_button(button) {} - }; ViewChild> m_buttonTarget; - - struct MenuTarget : View { - Button& m_button; - - bool m_pressed = false; - bool m_hovered = false; - - void setInactive(); - void setHover(); - void setPressed(); - void setDisabled(); - - void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseEnter(const boo::SWindowCoord&) override; - void mouseLeave(const boo::SWindowCoord&) override; - MenuTarget(ViewResources& res, Button& button) : View(res, button), m_button(button) {} - }; ViewChild> m_menuTarget; - ViewChild> m_modalMenu; public: class Resources { - friend class ViewResources; friend class Button; + friend class ViewResources; void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme); void destroy() {} }; - ~Button() override { closeMenu({}); } Button(ViewResources& res, View& parentView, IButtonBinding* controlBinding, std::string_view text, Icon* icon = nullptr, Style style = Style::Block, const zeus::CColor& bgColor = zeus::skWhite, RectangleConstraint constraint = RectangleConstraint()); Button(ViewResources& res, View& parentView, IButtonBinding* controlBinding, std::string_view text, const zeus::CColor& textColor, Icon* icon = nullptr, Style style = Style::Block, const zeus::CColor& bgColor = zeus::skWhite, RectangleConstraint constraint = RectangleConstraint()); + ~Button() override; + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; void mouseMove(const boo::SWindowCoord&) override; @@ -106,15 +87,7 @@ public: void closeMenu(const boo::SWindowCoord& coord); ViewChild>& getMenu() { return m_modalMenu; } - void setMultiplyColor(const zeus::CColor& color) override { - View::setMultiplyColor(color); - m_viewVertBlock.m_color = color; - if (m_viewVertBlockBuf) - m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock); - m_text->setMultiplyColor(color); - if (m_icon) - m_icon->setMultiplyColor(color); - } + void setMultiplyColor(const zeus::CColor& color) override; }; } // namespace specter diff --git a/specter/include/specter/Control.hpp b/specter/include/specter/Control.hpp index 3ca9251fb..bfc3cdc39 100644 --- a/specter/include/specter/Control.hpp +++ b/specter/include/specter/Control.hpp @@ -1,6 +1,19 @@ #pragma once -#include "View.hpp" +#include +#include +#include +#include +#include +#include + +#include "specter/View.hpp" + +#include + +namespace hecl { +class CVar; +} namespace specter { class Control; @@ -41,7 +54,7 @@ struct IButtonBinding : IControlBinding { virtual MenuStyle menuStyle(const specter::Button* button) const { return MenuStyle::None; } /** Called when user requests menu, Button assumes modal ownership */ - virtual std::unique_ptr buildMenu(const specter::Button* button) { return std::unique_ptr(); } + virtual std::unique_ptr buildMenu(const specter::Button* button) { return nullptr; } }; struct IFloatBinding : IControlBinding { @@ -80,8 +93,8 @@ struct CVarControlBinding : IControlBinding { static CVarControlBinding* castTo(IControlBinding* bind) { return bind->type() == ControlType::CVar ? static_cast(bind) : nullptr; } - std::string_view name(const Control* control) const override { return m_cvar->name(); } - std::string_view help(const Control* control) const override { return m_cvar->rawHelp(); } + std::string_view name(const Control* control) const override; + std::string_view help(const Control* control) const override; }; class Control : public View { diff --git a/specter/include/specter/FileBrowser.hpp b/specter/include/specter/FileBrowser.hpp index 91b89e3b0..b49743296 100644 --- a/specter/include/specter/FileBrowser.hpp +++ b/specter/include/specter/FileBrowser.hpp @@ -1,18 +1,28 @@ #pragma once -#include "View.hpp" -#include "ModalWindow.hpp" -#include "Button.hpp" -#include "TextField.hpp" -#include "ScrollView.hpp" -#include "Table.hpp" -#include "ViewResources.hpp" -#include "IViewManager.hpp" -#include "MessageWindow.hpp" -#include "PathButtons.hpp" -#include +#include +#include +#include +#include +#include + +#include "specter/ModalWindow.hpp" +#include "specter/PathButtons.hpp" +#include "specter/Table.hpp" +#include "specter/View.hpp" +#include "specter/ViewResources.hpp" + +#include + +namespace hecl { +class DirectoryEnumerator; +} namespace specter { +class MessageWindow; +class TextField; + +struct IViewManager; class FileBrowser : public ModalWindow, public IPathButtonsBinding { public: @@ -47,11 +57,7 @@ private: FileBrowser& m_fb; ViewChild> m_button; std::string m_text; - OKButton(FileBrowser& fb, ViewResources& res, std::string_view text) : m_fb(fb), m_text(text) { - m_button.m_view.reset( - new Button(res, fb, this, text, nullptr, Button::Style::Block, zeus::skWhite, - RectangleConstraint(100 * res.pixelFactor(), -1, RectangleConstraint::Test::Minimum))); - } + OKButton(FileBrowser& fb, ViewResources& res, std::string_view text); std::string_view name(const Control* control) const override { return m_text; } void activated(const Button* button, const boo::SWindowCoord&) override { m_fb.okActivated(true); } } m_ok; @@ -61,11 +67,7 @@ private: FileBrowser& m_fb; ViewChild> m_button; std::string m_text; - CancelButton(FileBrowser& fb, ViewResources& res, std::string_view text) : m_fb(fb), m_text(text) { - m_button.m_view.reset(new Button( - res, fb, this, text, nullptr, Button::Style::Block, zeus::skWhite, - RectangleConstraint(m_fb.m_ok.m_button.m_view->nominalWidth(), -1, RectangleConstraint::Test::Minimum))); - } + CancelButton(FileBrowser& fb, ViewResources& res, std::string_view text); std::string_view name(const Control* control) const override { return m_text; } void activated(const Button* button, const boo::SWindowCoord&) override { m_fb.cancelActivated(); } } m_cancel; @@ -77,8 +79,7 @@ private: struct FileFieldBind : IStringBinding { FileBrowser& m_browser; std::string m_name; - FileFieldBind(FileBrowser& browser, const IViewManager& vm) - : m_browser(browser), m_name(vm.translate()) {} + FileFieldBind(FileBrowser& browser, const IViewManager& vm); std::string_view name(const Control* control) const override { return m_name; } void changed(const Control* control, std::string_view val) override {} } m_fileFieldBind; @@ -143,30 +144,7 @@ private: void setColumnSplit(size_t cIdx, float split) override { m_columnSplits[cIdx] = split; } - void updateListing(const hecl::DirectoryEnumerator& dEnum) { - m_entries.clear(); - m_entries.reserve(dEnum.size()); - - for (const hecl::DirectoryEnumerator::Entry& d : dEnum) { - m_entries.emplace_back(); - Entry& ent = m_entries.back(); - ent.m_path = d.m_path; - hecl::SystemUTF8Conv nameUtf8(d.m_name); - ent.m_name = nameUtf8.str(); - if (d.m_isDir) { - if (hecl::SearchForProject(d.m_path)) - ent.m_type = m_projStr; - else - ent.m_type = m_dirStr; - } else { - ent.m_type = m_fileStr; - ent.m_size = hecl::HumanizeNumber(d.m_fileSz, 7, nullptr, int(hecl::HNScale::AutoScale), - hecl::HNFlags::B | hecl::HNFlags::Decimal); - } - } - - m_needsUpdate = false; - } + void updateListing(const hecl::DirectoryEnumerator& dEnum); bool m_sizeSort = false; SortDirection m_sortDir = SortDirection::Ascending; @@ -185,25 +163,11 @@ private: m_needsUpdate = true; } - void setSelectedRow(size_t rIdx) override { - if (rIdx != SIZE_MAX) - m_fb.m_fileField.m_view->setText(m_entries.at(rIdx).m_name); - else - m_fb.m_fileField.m_view->setText(""); - m_fb.m_fileField.m_view->clearErrorState(); - } + void setSelectedRow(size_t rIdx) override; void rowActivated(size_t rIdx) override { m_fb.okActivated(false); } - FileListingDataBind(FileBrowser& fb, const IViewManager& vm) : m_fb(fb) { - m_nameCol = vm.translate(); - m_typeCol = vm.translate(); - m_sizeCol = vm.translate(); - m_dirStr = vm.translate(); - m_projStr = vm.translate(); - m_fileStr = vm.translate(); - } - + FileListingDataBind(FileBrowser& fb, const IViewManager& vm); } m_fileListingBind; ViewChild> m_fileListing; @@ -266,6 +230,7 @@ public: : FileBrowser(res, parentView, title, type, hecl::GetcwdStr(), returnFunc) {} FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type, hecl::SystemStringView initialPath, std::function returnFunc); + ~FileBrowser() override; static std::vector PathComponents(hecl::SystemStringView path); static void SyncBookmarkSelections(Table& table, BookmarkDataBind& binding, const hecl::SystemString& sel); diff --git a/specter/include/specter/FontCache.hpp b/specter/include/specter/FontCache.hpp index 2584c0776..fc291e426 100644 --- a/specter/include/specter/FontCache.hpp +++ b/specter/include/specter/FontCache.hpp @@ -3,12 +3,27 @@ #include #include FT_FREETYPE_H -#include -#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include +#include +#include + +#include + +namespace hecl::Runtime { +class FileStoreManager; +} + namespace specter { class FontTag { friend class FontCache; diff --git a/specter/include/specter/IMenuNode.hpp b/specter/include/specter/IMenuNode.hpp index 1da8c8837..51044a083 100644 --- a/specter/include/specter/IMenuNode.hpp +++ b/specter/include/specter/IMenuNode.hpp @@ -1,6 +1,12 @@ #pragma once -#include "View.hpp" +#include +#include + +namespace boo { +struct ITexture; +struct SWindowCoord; +} // namespace boo namespace specter { diff --git a/specter/include/specter/IViewManager.hpp b/specter/include/specter/IViewManager.hpp index 19fe41e99..83fff1202 100644 --- a/specter/include/specter/IViewManager.hpp +++ b/specter/include/specter/IViewManager.hpp @@ -1,8 +1,16 @@ #pragma once +#include +#include + +#include "specter/SplitView.hpp" + #include -#include "SplitView.hpp" -#include +#include + +namespace boo { +struct SWindowCoord; +} namespace specter { struct ISpaceController; diff --git a/specter/include/specter/Icon.hpp b/specter/include/specter/Icon.hpp index 6b7511e44..52402226e 100644 --- a/specter/include/specter/Icon.hpp +++ b/specter/include/specter/Icon.hpp @@ -1,8 +1,17 @@ #pragma once -#include "View.hpp" +#include + +#include "specter/View.hpp" + +#include +#include +#include + +#include namespace specter { +class ViewResources; struct Icon { boo::ObjToken m_tex; diff --git a/specter/include/specter/Menu.hpp b/specter/include/specter/Menu.hpp index e6abb7ce4..a8877bdb3 100644 --- a/specter/include/specter/Menu.hpp +++ b/specter/include/specter/Menu.hpp @@ -1,11 +1,19 @@ #pragma once -#include "View.hpp" -#include "TextView.hpp" -#include "ScrollView.hpp" -#include "IMenuNode.hpp" +#include +#include +#include +#include + +#include "specter/View.hpp" + +#include namespace specter { +class ScrollView; +class TextView; + +struct IMenuNode; class Menu : public View { IMenuNode* m_rootNode; @@ -70,6 +78,8 @@ class Menu : public View { public: Menu(ViewResources& res, View& parentView, IMenuNode* rootNode); + ~Menu() override; + void reset(IMenuNode* rootNode); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; diff --git a/specter/include/specter/MessageWindow.hpp b/specter/include/specter/MessageWindow.hpp index ae4c9ae54..dc17bfe1a 100644 --- a/specter/include/specter/MessageWindow.hpp +++ b/specter/include/specter/MessageWindow.hpp @@ -1,10 +1,14 @@ #pragma once -#include "ModalWindow.hpp" -#include "MultiLineTextView.hpp" -#include "Button.hpp" +#include +#include +#include + +#include "specter/Button.hpp" +#include "specter/ModalWindow.hpp" namespace specter { +class MultiLineTextView; class MessageWindow : public ModalWindow { public: @@ -37,14 +41,9 @@ private: public: MessageWindow(ViewResources& res, View& parentView, Type type, std::string_view message, std::function func); + ~MessageWindow() override; - void updateContentOpacity(float opacity) override { - zeus::CColor color = zeus::CColor::lerp({1, 1, 1, 0}, {1, 1, 1, 1}, opacity); - ModalWindow::setMultiplyColor(color); - m_text->setMultiplyColor(color); - m_ok.m_view->setMultiplyColor(color); - m_cancel.m_view->setMultiplyColor(color); - } + void updateContentOpacity(float opacity) override; void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; diff --git a/specter/include/specter/ModalWindow.hpp b/specter/include/specter/ModalWindow.hpp index 87540edd6..8d1086200 100644 --- a/specter/include/specter/ModalWindow.hpp +++ b/specter/include/specter/ModalWindow.hpp @@ -1,9 +1,17 @@ #pragma once -#include -#include +#include + +#include "specter/View.hpp" + +#include +#include +#include namespace specter { +class TextView; +class ViewResources; + class ModalWindow : public View { public: enum class Phase { BuildIn, ResWait, Showing, BuildOut, Done }; @@ -55,6 +63,8 @@ protected: public: ModalWindow(ViewResources& res, View& parentView, const RectangleConstraint& constraint, const zeus::CColor& bgColor); ModalWindow(ViewResources& res, View& parentView, const RectangleConstraint& constraint); + ~ModalWindow() override; + void think() override; bool skipBuildInAnimation(); void close(bool skipAnimation = false); diff --git a/specter/include/specter/MultiLineTextView.hpp b/specter/include/specter/MultiLineTextView.hpp index b6e1c5ef1..5c19f7f16 100644 --- a/specter/include/specter/MultiLineTextView.hpp +++ b/specter/include/specter/MultiLineTextView.hpp @@ -1,10 +1,19 @@ #pragma once -#include "View.hpp" -#include "TextView.hpp" -#include "FontCache.hpp" +#include +#include +#include +#include + +#include "specter/FontCache.hpp" +#include "specter/TextView.hpp" +#include "specter/View.hpp" + +#include +#include namespace specter { +class ViewResources; class MultiLineTextView : public View { ViewResources& m_viewSystem; diff --git a/specter/include/specter/NumericField.hpp b/specter/include/specter/NumericField.hpp index 16d98e12a..c40955caa 100644 --- a/specter/include/specter/NumericField.hpp +++ b/specter/include/specter/NumericField.hpp @@ -1,8 +1,18 @@ #pragma once -#include "specter/TextView.hpp" +#include +#include + +#include "specter/View.hpp" + +namespace boo { +struct IGraphicsBufferD; +struct IGraphicsDataFactory; +struct IShaderDataBinding; +} // namespace boo namespace specter { +class TextView; class ViewResources; class NumericField : public View { @@ -27,8 +37,8 @@ class NumericField : public View { public: class Resources { - friend class ViewResources; friend class Button; + friend class ViewResources; void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme); }; diff --git a/specter/include/specter/Outliner.hpp b/specter/include/specter/Outliner.hpp index fdce1e224..143902591 100644 --- a/specter/include/specter/Outliner.hpp +++ b/specter/include/specter/Outliner.hpp @@ -1,5 +1,12 @@ #pragma once +#include +#include +#include +#include + +#include "specter/View.hpp" + namespace specter { class Outliner { class Node : public View { diff --git a/specter/include/specter/PathButtons.hpp b/specter/include/specter/PathButtons.hpp index cac69bb68..937c1132a 100644 --- a/specter/include/specter/PathButtons.hpp +++ b/specter/include/specter/PathButtons.hpp @@ -1,59 +1,34 @@ #pragma once -#include "Button.hpp" -#include "ScrollView.hpp" +#include +#include +#include + +#include "specter/ScrollView.hpp" + +#include namespace specter { +class ViewResources; struct IPathButtonsBinding { virtual void pathButtonActivated(size_t idx) = 0; }; class PathButtons : public ScrollView { - struct ContentView : public View { - PathButtons& m_pb; - boo::SWindowRect m_scissorRect; + struct ContentView; + struct PathButton; + friend struct PathButton; - void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseMove(const boo::SWindowCoord&) override; - void mouseLeave(const boo::SWindowCoord&) override; - - int nominalWidth() const override { - int ret = 0; - for (PathButton& b : m_pb.m_pathButtons) - ret += b.m_button.m_view->nominalWidth() + 2; - return ret; - } - int nominalHeight() const override { - return m_pb.m_pathButtons.size() ? m_pb.m_pathButtons[0].m_button.m_view->nominalHeight() : 0; - } - - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor) override; - void draw(boo::IGraphicsCommandQueue* gfxQ) override; - - ContentView(ViewResources& res, PathButtons& pb) : View(res, pb), m_pb(pb) {} - }; ViewChild> m_contentView; - int m_pathButtonPending = -1; IPathButtonsBinding& m_binding; bool m_fillContainer; - struct PathButton final : IButtonBinding { - PathButtons& m_pb; - size_t m_idx; - ViewChild> m_button; - PathButton(PathButtons& pb, ViewResources& res, size_t idx, const hecl::SystemString& str) : m_pb(pb), m_idx(idx) { - m_button.m_view.reset(new Button(res, pb, this, hecl::SystemUTF8Conv(str).str())); - } - std::string_view name(const Control* control) const override { return m_button.m_view->getText(); } - void activated(const Button* button, const boo::SWindowCoord&) override { m_pb.m_pathButtonPending = m_idx; } - }; - friend struct PathButton; std::vector m_pathButtons; public: PathButtons(ViewResources& res, View& parentView, IPathButtonsBinding& binding, bool fillContainer = false); + ~PathButtons() override; void setButtons(const std::vector& comps); void setMultiplyColor(const zeus::CColor& color) override; diff --git a/specter/include/specter/RootView.hpp b/specter/include/specter/RootView.hpp index 7979a2467..2bf6c5d56 100644 --- a/specter/include/specter/RootView.hpp +++ b/specter/include/specter/RootView.hpp @@ -1,18 +1,27 @@ #pragma once -#include "View.hpp" -#include "ViewResources.hpp" -#include "MultiLineTextView.hpp" -#include "TextField.hpp" -#include "SplitView.hpp" -#include "Tooltip.hpp" -#include "FontCache.hpp" -#include "IMenuNode.hpp" -#include "IViewManager.hpp" +#include +#include #include -#include "boo/boo.hpp" +#include +#include + +#include "specter/IMenuNode.hpp" +#include "specter/SplitView.hpp" +#include "specter/View.hpp" + +#include +#include +#include +#include namespace specter { +class Button; +class ITextInputView; +class Tooltip; +class ViewResources; + +struct IViewManager; class RootView : public View { boo::IWindow* m_window = nullptr; @@ -130,7 +139,7 @@ public: void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods) override; void modKeyDown(boo::EModifierKey mod, bool isRepeat) override; void modKeyUp(boo::EModifierKey mod) override; - boo::ITextInputCallback* getTextInputCallback() { return m_activeTextView; } + boo::ITextInputCallback* getTextInputCallback(); void internalThink(); void dispatchEvents() { m_events.dispatchEvents(); } @@ -140,7 +149,7 @@ public: boo::IWindow* window() const { return m_window; } IViewManager& viewManager() const { return m_viewMan; } ViewResources& viewRes() const { return *m_viewRes; } - const IThemeData& themeData() const { return *m_viewRes->m_theme; } + const IThemeData& themeData() const; const boo::ObjToken& renderTex() const { return m_renderTex; } std::vector& accessContentViews() { return m_views; } @@ -154,13 +163,7 @@ public: } View* getRightClickMenu() { return m_rightClickMenu.m_view.get(); } - void setActiveTextView(ITextInputView* textView) { - if (m_activeTextView) - m_activeTextView->setActive(false); - m_activeTextView = textView; - if (textView) - textView->setActive(true); - } + void setActiveTextView(ITextInputView* textView); void setActiveDragView(View* dragView) { m_activeDragView = dragView; } void unsetActiveDragView(View* dragView) { if (dragView == m_activeDragView) diff --git a/specter/include/specter/ScrollView.hpp b/specter/include/specter/ScrollView.hpp index 9b528e5c2..ebcf2c7a8 100644 --- a/specter/include/specter/ScrollView.hpp +++ b/specter/include/specter/ScrollView.hpp @@ -1,11 +1,18 @@ #pragma once -#include "Button.hpp" -#include "IViewManager.hpp" +#include +#include +#include + +#include "specter/Button.hpp" +#include "specter/View.hpp" namespace specter { -class ViewResources; class Button; +class Control; +class ViewResources; + +struct IViewManager; class ScrollView : public View { public: @@ -30,23 +37,11 @@ private: struct SideButtonBinding : IButtonBinding { ScrollView& m_sv; std::string m_leftName, m_rightName; - SideButtonBinding(ScrollView& sv, IViewManager& vm) - : m_sv(sv) - , m_leftName(vm.translate()) - , m_rightName(vm.translate()) {} - std::string_view name(const Control* control) const override { - return (control == reinterpret_cast(m_sv.m_sideButtons[0].m_view.get())) ? m_leftName.c_str() - : m_rightName.c_str(); - } - void down(const Button* button, const boo::SWindowCoord& coord) override { - if (button == m_sv.m_sideButtons[0].m_view.get()) - m_sv.m_sideButtonState = SideButtonState::ScrollRight; - else - m_sv.m_sideButtonState = SideButtonState::ScrollLeft; - } - void up(const Button* button, const boo::SWindowCoord& coord) override { - m_sv.m_sideButtonState = SideButtonState::None; - } + + SideButtonBinding(ScrollView& sv, IViewManager& vm); + std::string_view name(const Control* control) const override; + void down(const Button* button, const boo::SWindowCoord& coord) override; + void up(const Button* button, const boo::SWindowCoord& coord) override; } m_sideButtonBind; ViewChild> m_sideButtons[2]; diff --git a/specter/include/specter/Space.hpp b/specter/include/specter/Space.hpp index 18aebf71d..6e8f2eab5 100644 --- a/specter/include/specter/Space.hpp +++ b/specter/include/specter/Space.hpp @@ -1,11 +1,14 @@ #pragma once -#include "View.hpp" -#include "Toolbar.hpp" -#include "SplitView.hpp" +#include + +#include "specter/SplitView.hpp" +#include "specter/Toolbar.hpp" +#include "specter/View.hpp" namespace specter { -class Space; +class ViewResources; + struct ISplitSpaceController; struct ISpaceController { @@ -20,7 +23,10 @@ struct ISplitSpaceController { }; class Space : public View { + struct CornerView; friend class RootView; + friend struct CornerView; + ISpaceController& m_controller; Toolbar::Position m_tbPos; ViewChild> m_toolbar; @@ -29,25 +35,13 @@ class Space : public View { bool m_cornerDrag = false; int m_cornerDragPoint[2]; - struct CornerView : View { - Space& m_space; - VertexBufferBindingSolid m_vertexBinding; - bool m_flip; - CornerView(ViewResources& res, Space& space, const zeus::CColor& triColor); - void mouseEnter(const boo::SWindowCoord&) override; - void mouseLeave(const boo::SWindowCoord&) override; - void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - using View::resized; - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, bool flip); - void draw(boo::IGraphicsCommandQueue* gfxQ) override; - }; - friend struct CornerView; ViewChild> m_cornerView; public: Space(ViewResources& res, View& parentView, ISpaceController& controller, Toolbar::Position toolbarPos, unsigned tbUnits); + ~Space() override; + View* setContentView(View* view); Toolbar* toolbar() { return m_toolbar.m_view.get(); } void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; diff --git a/specter/include/specter/SplitView.hpp b/specter/include/specter/SplitView.hpp index f9000feda..c3f61e5a1 100644 --- a/specter/include/specter/SplitView.hpp +++ b/specter/include/specter/SplitView.hpp @@ -2,6 +2,9 @@ #include "specter/View.hpp" +#include +#include + namespace specter { struct ISplitSpaceController; @@ -11,8 +14,8 @@ class SplitView : public View { public: class Resources { - friend class ViewResources; friend class SplitView; + friend class ViewResources; boo::ObjToken m_shadingTex; void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme); diff --git a/specter/include/specter/Table.hpp b/specter/include/specter/Table.hpp index 455a1a755..b00c9a7b5 100644 --- a/specter/include/specter/Table.hpp +++ b/specter/include/specter/Table.hpp @@ -1,13 +1,19 @@ #pragma once -#include "View.hpp" -#include "ScrollView.hpp" -#include "TextView.hpp" #include +#include +#include +#include +#include +#include + +#include "specter/View.hpp" namespace specter { #define SPECTER_TABLE_MAX_ROWS 128ul +class ScrollView; + enum class SortDirection { None, Ascending, Descending }; struct ITableDataBinding { @@ -31,6 +37,8 @@ struct ITableStateBinding { }; class Table : public View { + struct CellView; + ITableDataBinding* m_data; ITableStateBinding* m_state; @@ -41,28 +49,6 @@ class Table : public View { size_t m_deferredActivation = SIZE_MAX; size_t m_clickFrames = 15; - struct CellView : public View { - Table& m_t; - std::unique_ptr m_text; - size_t m_c = SIZE_MAX, m_r = SIZE_MAX; - boo::SWindowRect m_scissorRect; - uint64_t m_textHash = 0; - CellView(Table& t, ViewResources& res); - - bool m_selected = false; - void select(); - void deselect(); - void reset(); - bool reset(size_t c); - bool reset(size_t c, size_t r); - - void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; - void mouseEnter(const boo::SWindowCoord&) override; - void mouseLeave(const boo::SWindowCoord&) override; - void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor) override; - void draw(boo::IGraphicsCommandQueue* gfxQ) override; - }; std::vector>> m_headerViews; using ColumnPool = std::array>, SPECTER_TABLE_MAX_ROWS>, 2>; std::vector m_cellPools; @@ -94,7 +80,7 @@ class Table : public View { RowsView(Table& t, ViewResources& res); int nominalHeight() const override; - int nominalWidth() const override { return m_t.m_scroll.m_view->nominalWidth(); } + int nominalWidth() const override; void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; void mouseMove(const boo::SWindowCoord&) override; @@ -111,6 +97,7 @@ class Table : public View { public: Table(ViewResources& res, View& parentView, ITableDataBinding* data, ITableStateBinding* state = nullptr, size_t maxColumns = 8); + ~Table() override; void cycleSortColumn(size_t c); void selectRow(size_t r); diff --git a/specter/include/specter/TextField.hpp b/specter/include/specter/TextField.hpp index 7b668c840..305bb3599 100644 --- a/specter/include/specter/TextField.hpp +++ b/specter/include/specter/TextField.hpp @@ -1,10 +1,17 @@ #pragma once -#include "Control.hpp" -#include "TextView.hpp" +#include +#include +#include +#include + +#include "specter/Control.hpp" + #include namespace specter { +class TextView; +class ViewResources; class TextField : public ITextInputView { bool m_hasTextSet = false; @@ -60,6 +67,7 @@ class TextField : public ITextInputView { public: TextField(ViewResources& res, View& parentView, IStringBinding* strBind); + ~TextField() override; std::string_view getText() const { return m_textStr; } void setText(std::string_view str); @@ -103,15 +111,7 @@ public: void setSelectionRange(size_t start, size_t count); void clearSelectionRange(); - void setMultiplyColor(const zeus::CColor& color) override { - View::setMultiplyColor(color); - m_viewVertBlock.m_color = color; - if (m_viewVertBlockBuf) - m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock); - m_text->setMultiplyColor(color); - if (m_errText) - m_errText->setMultiplyColor(color); - } + void setMultiplyColor(const zeus::CColor& color) override; private: void _setCursorPos(); diff --git a/specter/include/specter/Toolbar.hpp b/specter/include/specter/Toolbar.hpp index ce2a4abd7..23398a909 100644 --- a/specter/include/specter/Toolbar.hpp +++ b/specter/include/specter/Toolbar.hpp @@ -1,7 +1,19 @@ #pragma once +#include + #include "specter/View.hpp" +#include +#include +#include + +#include + +namespace boo { +struct IGraphicsCommandQueue; +} + namespace specter { #define SPECTER_TOOLBAR_GAUGE 28 @@ -35,6 +47,8 @@ private: public: Toolbar(ViewResources& res, View& parentView, Position toolbarPos, unsigned units); + ~Toolbar() override; + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; void mouseMove(const boo::SWindowCoord&) override; diff --git a/specter/include/specter/Tooltip.hpp b/specter/include/specter/Tooltip.hpp index 12ef3cb0a..79580d65b 100644 --- a/specter/include/specter/Tooltip.hpp +++ b/specter/include/specter/Tooltip.hpp @@ -1,9 +1,15 @@ #pragma once +#include +#include + #include "specter/View.hpp" -#include "specter/MultiLineTextView.hpp" + +#include namespace specter { +class MultiLineTextView; +class TextView; class Tooltip : public View { ViewBlock m_ttBlock; @@ -26,6 +32,8 @@ class Tooltip : public View { public: Tooltip(ViewResources& res, View& parentView, std::string_view title, std::string_view message); + ~Tooltip() override; + void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub) override; void draw(boo::IGraphicsCommandQueue* gfxQ) override; diff --git a/specter/include/specter/View.hpp b/specter/include/specter/View.hpp index d2a1d484d..eee603430 100644 --- a/specter/include/specter/View.hpp +++ b/specter/include/specter/View.hpp @@ -1,19 +1,31 @@ #pragma once -#include "boo/boo.hpp" +#include #include -#include "zeus/CVector3f.hpp" -#include "zeus/CMatrix4f.hpp" -#include "zeus/CTransform.hpp" -#include "zeus/CColor.hpp" -#include "hecl/CVar.hpp" -#include "hecl/UniformBufferPool.hpp" -#include "hecl/VertexBufferPool.hpp" +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace boo { +struct IGraphicsCommandQueue; +} namespace specter { class IThemeData; -class ViewResources; class RootView; +class Space; +class SplitView; +class ViewResources; extern zeus::CMatrix4f g_PlatformMatrix; @@ -67,8 +79,6 @@ public: } }; -class Space; -class SplitView; class View { public: struct SolidShaderVert { diff --git a/specter/include/specter/ViewResources.hpp b/specter/include/specter/ViewResources.hpp index 2d64ff0e6..16ac14524 100644 --- a/specter/include/specter/ViewResources.hpp +++ b/specter/include/specter/ViewResources.hpp @@ -1,12 +1,15 @@ #pragma once -#include "TextView.hpp" -#include "SplitView.hpp" -#include "Toolbar.hpp" -#include "Button.hpp" - +#include #include +#include "specter/Button.hpp" +#include "specter/SplitView.hpp" +#include "specter/TextView.hpp" +#include "specter/Toolbar.hpp" + +#include + namespace specter { class IThemeData { public: diff --git a/specter/lib/Button.cpp b/specter/lib/Button.cpp index 9947156bd..449408cf7 100644 --- a/specter/lib/Button.cpp +++ b/specter/lib/Button.cpp @@ -1,11 +1,51 @@ -#include "logvisor/logvisor.hpp" #include "specter/Button.hpp" -#include "specter/ViewResources.hpp" + +#include "specter/Icon.hpp" #include "specter/RootView.hpp" +#include "specter/TextView.hpp" +#include "specter/ViewResources.hpp" + +#include namespace specter { static logvisor::Module Log("specter::Button"); +struct Button::ButtonTarget : View { + Button& m_button; + + bool m_pressed = false; + bool m_hovered = false; + + void setInactive(); + void setHover(); + void setPressed(); + void setDisabled(); + + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; + void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; + void mouseEnter(const boo::SWindowCoord&) override; + void mouseLeave(const boo::SWindowCoord&) override; + ButtonTarget(ViewResources& res, Button& button) : View(res, button), m_button(button) {} +}; + +struct Button::MenuTarget : View { + Button& m_button; + + bool m_pressed = false; + bool m_hovered = false; + + void setInactive(); + void setHover(); + void setPressed(); + void setDisabled(); + + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; + void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; + void mouseEnter(const boo::SWindowCoord&) override; + void mouseLeave(const boo::SWindowCoord&) override; + MenuTarget(ViewResources& res, Button& button) : View(res, button), m_button(button) {} +}; + void Button::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme) {} Button::Button(ViewResources& res, View& parentView, IButtonBinding* controlBinding, std::string_view text, Icon* icon, @@ -66,6 +106,8 @@ Button::Button(ViewResources& res, View& parentView, IButtonBinding* controlBind setText(m_textStr); } +Button::~Button() { closeMenu({}); } + void Button::setText(std::string_view text) { setText(text, m_textColor); } void Button::setText(std::string_view text, const zeus::CColor& textColor) { @@ -449,6 +491,16 @@ void Button::closeMenu(const boo::SWindowCoord& coord) { m_menuTarget.mouseMove(coord); } +void Button::setMultiplyColor(const zeus::CColor& color) { + View::setMultiplyColor(color); + m_viewVertBlock.m_color = color; + if (m_viewVertBlockBuf) + m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock); + m_text->setMultiplyColor(color); + if (m_icon) + m_icon->setMultiplyColor(color); +} + void Button::think() { if (m_modalMenu.m_view) m_modalMenu.m_view->think(); diff --git a/specter/lib/Control.cpp b/specter/lib/Control.cpp index 96a015795..ad20714d8 100644 --- a/specter/lib/Control.cpp +++ b/specter/lib/Control.cpp @@ -1,7 +1,13 @@ #include "specter/Control.hpp" +#include + namespace specter { +std::string_view CVarControlBinding::name([[maybe_unused]] const Control* control) const { return m_cvar->name(); } + +std::string_view CVarControlBinding::help([[maybe_unused]] const Control* control) const { return m_cvar->rawHelp(); } + Control::Control(ViewResources& res, View& parentView, IControlBinding* controlBinding) : View(res, parentView), m_controlBinding(controlBinding) {} diff --git a/specter/lib/FileBrowser.cpp b/specter/lib/FileBrowser.cpp index ceb56d8ac..3ae19a947 100644 --- a/specter/lib/FileBrowser.cpp +++ b/specter/lib/FileBrowser.cpp @@ -1,6 +1,13 @@ #include "specter/FileBrowser.hpp" -#include "specter/RootView.hpp" + +#include "specter/Button.hpp" +#include "specter/IViewManager.hpp" #include "specter/MessageWindow.hpp" +#include "specter/RootView.hpp" +#include "specter/TextField.hpp" + +#include +#include namespace specter { static logvisor::Module Log("specter::FileBrowser"); @@ -99,6 +106,8 @@ FileBrowser::FileBrowser(ViewResources& res, View& parentView, std::string_view updateContentOpacity(0.0); } +FileBrowser::~FileBrowser() = default; + void FileBrowser::SyncBookmarkSelections(Table& table, BookmarkDataBind& binding, const hecl::SystemString& sel) { size_t idx = 0; for (const BookmarkDataBind::Entry& e : binding.m_entries) { @@ -298,6 +307,9 @@ void FileBrowser::cancelActivated() { close(); } +FileBrowser::FileFieldBind::FileFieldBind(FileBrowser& browser, const IViewManager& vm) +: m_browser(browser), m_name(vm.translate()) {} + void FileBrowser::pathButtonActivated(size_t idx) { if (idx >= m_comps.size()) return; @@ -317,6 +329,50 @@ void FileBrowser::pathButtonActivated(size_t idx) { navigateToPath(dir); } +void FileBrowser::FileListingDataBind::updateListing(const hecl::DirectoryEnumerator& dEnum) { + m_entries.clear(); + m_entries.reserve(dEnum.size()); + + for (const hecl::DirectoryEnumerator::Entry& d : dEnum) { + m_entries.emplace_back(); + Entry& ent = m_entries.back(); + ent.m_path = d.m_path; + hecl::SystemUTF8Conv nameUtf8(d.m_name); + ent.m_name = nameUtf8.str(); + if (d.m_isDir) { + if (hecl::SearchForProject(d.m_path)) + ent.m_type = m_projStr; + else + ent.m_type = m_dirStr; + } else { + ent.m_type = m_fileStr; + ent.m_size = hecl::HumanizeNumber(d.m_fileSz, 7, nullptr, int(hecl::HNScale::AutoScale), + hecl::HNFlags::B | hecl::HNFlags::Decimal); + } + } + + m_needsUpdate = false; +} + +void FileBrowser::FileListingDataBind::setSelectedRow(size_t rIdx) { + if (rIdx != SIZE_MAX) { + m_fb.m_fileField.m_view->setText(m_entries.at(rIdx).m_name); + } else { + m_fb.m_fileField.m_view->setText(""); + } + + m_fb.m_fileField.m_view->clearErrorState(); +} + +FileBrowser::FileListingDataBind::FileListingDataBind(FileBrowser& fb, const IViewManager& vm) : m_fb(fb) { + m_nameCol = vm.translate(); + m_typeCol = vm.translate(); + m_sizeCol = vm.translate(); + m_dirStr = vm.translate(); + m_projStr = vm.translate(); + m_fileStr = vm.translate(); +} + void FileBrowser::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { if (skipBuildInAnimation() || closed()) return; @@ -530,4 +586,17 @@ void FileBrowser::RightSide::draw(boo::IGraphicsCommandQueue* gfxQ) { m_fb.m_fileField.m_view->draw(gfxQ); } +FileBrowser::OKButton::OKButton(FileBrowser& fb, ViewResources& res, std::string_view text) : m_fb(fb), m_text(text) { + m_button.m_view.reset( + new Button(res, fb, this, text, nullptr, Button::Style::Block, zeus::skWhite, + RectangleConstraint(100 * res.pixelFactor(), -1, RectangleConstraint::Test::Minimum))); +} + +FileBrowser::CancelButton::CancelButton(FileBrowser& fb, ViewResources& res, std::string_view text) +: m_fb(fb), m_text(text) { + m_button.m_view.reset(new Button( + res, fb, this, text, nullptr, Button::Style::Block, zeus::skWhite, + RectangleConstraint(m_fb.m_ok.m_button.m_view->nominalWidth(), -1, RectangleConstraint::Test::Minimum))); +} + } // namespace specter diff --git a/specter/lib/FontCache.cpp b/specter/lib/FontCache.cpp index ae49ba4f2..1add829ac 100644 --- a/specter/lib/FontCache.cpp +++ b/specter/lib/FontCache.cpp @@ -3,10 +3,17 @@ #endif #include "specter/FontCache.hpp" -#include "logvisor/logvisor.hpp" -#include + +#include #include -#include +#include +#include + +#include +#include +#include + +#include #include FT_GZIP_H #include FT_SYSTEM_H @@ -15,6 +22,13 @@ #include #include +#include +#include + +#include +#include +#include + extern "C" const uint8_t DROIDSANS_PERMISSIVE[]; extern "C" size_t DROIDSANS_PERMISSIVE_SZ; diff --git a/specter/lib/Menu.cpp b/specter/lib/Menu.cpp index 7d113453f..27ceefa0c 100644 --- a/specter/lib/Menu.cpp +++ b/specter/lib/Menu.cpp @@ -1,5 +1,9 @@ #include "specter/Menu.hpp" + +#include "specter/IMenuNode.hpp" #include "specter/RootView.hpp" +#include "specter/ScrollView.hpp" +#include "specter/TextView.hpp" #include "specter/ViewResources.hpp" #define ROW_HEIGHT 18 @@ -20,6 +24,8 @@ Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode) : View(res reset(rootNode); } +Menu::~Menu() = default; + void Menu::reset(IMenuNode* rootNode) { m_rootNode = rootNode; m_thisNode = rootNode; diff --git a/specter/lib/MessageWindow.cpp b/specter/lib/MessageWindow.cpp index feadf148d..7d3f7f4cd 100644 --- a/specter/lib/MessageWindow.cpp +++ b/specter/lib/MessageWindow.cpp @@ -1,7 +1,13 @@ #include "specter/MessageWindow.hpp" -#include "specter/ViewResources.hpp" -#include "specter/RootView.hpp" + +#include "specter/IViewManager.hpp" #include "specter/Menu.hpp" +#include "specter/MultiLineTextView.hpp" +#include "specter/RootView.hpp" +#include "specter/ViewResources.hpp" + +#include +#include namespace specter { @@ -26,6 +32,16 @@ MessageWindow::MessageWindow(ViewResources& res, View& parentView, Type type, st updateContentOpacity(0.0); } +MessageWindow::~MessageWindow() = default; + +void MessageWindow::updateContentOpacity(float opacity) { + zeus::CColor color = zeus::CColor::lerp({1, 1, 1, 0}, {1, 1, 1, 1}, opacity); + ModalWindow::setMultiplyColor(color); + m_text->setMultiplyColor(color); + m_ok.m_view->setMultiplyColor(color); + m_cancel.m_view->setMultiplyColor(color); +} + void MessageWindow::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) { if (closed() || skipBuildInAnimation()) return; diff --git a/specter/lib/ModalWindow.cpp b/specter/lib/ModalWindow.cpp index 5957f7d03..8b63c77a8 100644 --- a/specter/lib/ModalWindow.cpp +++ b/specter/lib/ModalWindow.cpp @@ -1,6 +1,10 @@ #include "specter/ModalWindow.hpp" -#include "specter/ViewResources.hpp" + +#include "specter/MultiLineTextView.hpp" #include "specter/RootView.hpp" +#include "specter/ViewResources.hpp" + +#include namespace specter { @@ -300,6 +304,8 @@ ModalWindow::ModalWindow(ViewResources& res, View& parentView, const RectangleCo _loadVerts(); } +ModalWindow::~ModalWindow() = default; + static float CubicEase(float t) { t *= 2.f; if (t < 1) diff --git a/specter/lib/PathButtons.cpp b/specter/lib/PathButtons.cpp index 72e8c0518..d4ff13b56 100644 --- a/specter/lib/PathButtons.cpp +++ b/specter/lib/PathButtons.cpp @@ -1,8 +1,95 @@ #include "specter/PathButtons.hpp" + +#include "specter/Button.hpp" #include "specter/RootView.hpp" #include "specter/ViewResources.hpp" namespace specter { +struct PathButtons::PathButton final : IButtonBinding { + PathButtons& m_pb; + size_t m_idx; + ViewChild> m_button; + + PathButton(PathButtons& pb, ViewResources& res, size_t idx, const hecl::SystemString& str) : m_pb(pb), m_idx(idx) { + m_button.m_view.reset(new Button(res, pb, this, hecl::SystemUTF8Conv(str).str())); + } + + std::string_view name(const Control* control) const override { return m_button.m_view->getText(); } + void activated(const Button* button, const boo::SWindowCoord&) override { m_pb.m_pathButtonPending = m_idx; } +}; + +struct PathButtons::ContentView : public View { + PathButtons& m_pb; + boo::SWindowRect m_scissorRect; + + ContentView(ViewResources& res, PathButtons& pb) : View(res, pb), m_pb(pb) {} + + void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) override { + for (PathButton& b : m_pb.m_pathButtons) { + b.m_button.mouseDown(coord, button, mod); + } + } + + void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) override { + for (PathButton& b : m_pb.m_pathButtons) { + b.m_button.mouseUp(coord, button, mod); + } + + if (m_pb.m_pathButtonPending >= 0) { + m_pb.m_binding.pathButtonActivated(m_pb.m_pathButtonPending); + m_pb.m_pathButtonPending = -1; + } + } + + void mouseMove(const boo::SWindowCoord& coord) override { + for (PathButton& b : m_pb.m_pathButtons) { + b.m_button.mouseMove(coord); + } + } + + void mouseLeave(const boo::SWindowCoord& coord) override { + for (PathButton& b : m_pb.m_pathButtons) { + b.m_button.mouseLeave(coord); + } + } + + int nominalWidth() const override { + int ret = 0; + for (const PathButton& b : m_pb.m_pathButtons) { + ret += b.m_button.m_view->nominalWidth() + 2; + } + return ret; + } + + int nominalHeight() const override { + return m_pb.m_pathButtons.size() ? m_pb.m_pathButtons[0].m_button.m_view->nominalHeight() : 0; + } + + void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor) override { + View::resized(root, sub); + + m_scissorRect = scissor; + m_scissorRect.size[1] += 2; + + boo::SWindowRect pathRect = sub; + for (PathButton& b : m_pb.m_pathButtons) { + pathRect.size[0] = b.m_button.m_view->nominalWidth(); + pathRect.size[1] = b.m_button.m_view->nominalHeight(); + b.m_button.m_view->resized(root, pathRect); + pathRect.location[0] += pathRect.size[0] + 2; + } + } + + void draw(boo::IGraphicsCommandQueue* gfxQ) override { + gfxQ->setScissor(m_scissorRect); + + for (PathButton& b : m_pb.m_pathButtons) { + b.m_button.m_view->draw(gfxQ); + } + + gfxQ->setScissor(rootView().subRect()); + } +}; PathButtons::PathButtons(ViewResources& res, View& parentView, IPathButtonsBinding& binding, bool fillContainer) : ScrollView(res, parentView, ScrollView::Style::SideButtons), m_binding(binding), m_fillContainer(fillContainer) { @@ -10,6 +97,8 @@ PathButtons::PathButtons(ViewResources& res, View& parentView, IPathButtonsBindi setContentView(m_contentView.m_view.get()); } +PathButtons::~PathButtons() = default; + void PathButtons::setButtons(const std::vector& comps) { m_pathButtons.clear(); m_pathButtons.reserve(comps.size()); @@ -25,46 +114,6 @@ void PathButtons::setMultiplyColor(const zeus::CColor& color) { b.m_button.m_view->setMultiplyColor(color); } -void PathButtons::ContentView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, - boo::EModifierKey mod) { - for (PathButton& b : m_pb.m_pathButtons) - b.m_button.mouseDown(coord, button, mod); -} - -void PathButtons::ContentView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, - boo::EModifierKey mod) { - for (PathButton& b : m_pb.m_pathButtons) - b.m_button.mouseUp(coord, button, mod); - if (m_pb.m_pathButtonPending >= 0) { - m_pb.m_binding.pathButtonActivated(m_pb.m_pathButtonPending); - m_pb.m_pathButtonPending = -1; - } -} - -void PathButtons::ContentView::mouseMove(const boo::SWindowCoord& coord) { - for (PathButton& b : m_pb.m_pathButtons) - b.m_button.mouseMove(coord); -} - -void PathButtons::ContentView::mouseLeave(const boo::SWindowCoord& coord) { - for (PathButton& b : m_pb.m_pathButtons) - b.m_button.mouseLeave(coord); -} - -void PathButtons::ContentView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, - const boo::SWindowRect& scissor) { - View::resized(root, sub); - m_scissorRect = scissor; - m_scissorRect.size[1] += 2; - boo::SWindowRect pathRect = sub; - for (PathButton& b : m_pb.m_pathButtons) { - pathRect.size[0] = b.m_button.m_view->nominalWidth(); - pathRect.size[1] = b.m_button.m_view->nominalHeight(); - b.m_button.m_view->resized(root, pathRect); - pathRect.location[0] += pathRect.size[0] + 2; - } -} - void PathButtons::containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { if (m_fillContainer) { boo::SWindowRect fillRect = sub; @@ -73,11 +122,4 @@ void PathButtons::containerResized(const boo::SWindowRect& root, const boo::SWin } } -void PathButtons::ContentView::draw(boo::IGraphicsCommandQueue* gfxQ) { - gfxQ->setScissor(m_scissorRect); - for (PathButton& b : m_pb.m_pathButtons) - b.m_button.m_view->draw(gfxQ); - gfxQ->setScissor(rootView().subRect()); -} - } // namespace specter diff --git a/specter/lib/RootView.cpp b/specter/lib/RootView.cpp index 84e9bc449..1140c9104 100644 --- a/specter/lib/RootView.cpp +++ b/specter/lib/RootView.cpp @@ -1,7 +1,14 @@ #include "specter/RootView.hpp" -#include "specter/ViewResources.hpp" -#include "specter/Space.hpp" + +#include "specter/Button.hpp" +#include "specter/Control.hpp" +#include "specter/IViewManager.hpp" #include "specter/Menu.hpp" +#include "specter/Space.hpp" +#include "specter/Tooltip.hpp" +#include "specter/ViewResources.hpp" + +#include namespace specter { static logvisor::Module Log("specter::RootView"); @@ -497,6 +504,8 @@ void RootView::modKeyUp(boo::EModifierKey mod) { m_activeTextView->modKeyUp(mod); } +boo::ITextInputCallback* RootView::getTextInputCallback() { return m_activeTextView; } + void RootView::resetTooltip(ViewResources& res) { m_tooltip.reset( new Tooltip(res, *this, "Test", @@ -528,6 +537,18 @@ void RootView::internalThink() { m_rightClickMenu.m_view->think(); } +void RootView::setActiveTextView(ITextInputView* textView) { + if (m_activeTextView) { + m_activeTextView->setActive(false); + } + + m_activeTextView = textView; + + if (textView) { + textView->setActive(true); + } +} + void RootView::draw(boo::IGraphicsCommandQueue* gfxQ) { if (m_resizeRTDirty) { gfxQ->resizeRenderTexture(m_renderTex, m_rootRect.size[0], m_rootRect.size[1]); @@ -549,6 +570,8 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ) { gfxQ->resolveDisplay(m_renderTex); } +const IThemeData& RootView::themeData() const { return *m_viewRes->m_theme; } + void RootView::SplitMenuSystem::draw(boo::IGraphicsCommandQueue* gfxQ) { if (m_phase == Phase::Inactive) return; diff --git a/specter/lib/ScrollView.cpp b/specter/lib/ScrollView.cpp index e8fb6cfe5..64550d9fb 100644 --- a/specter/lib/ScrollView.cpp +++ b/specter/lib/ScrollView.cpp @@ -1,7 +1,11 @@ #include "specter/ScrollView.hpp" -#include "specter/ViewResources.hpp" -#include "specter/RootView.hpp" + +#include + #include "specter/Button.hpp" +#include "specter/IViewManager.hpp" +#include "specter/RootView.hpp" +#include "specter/ViewResources.hpp" namespace specter { #define MAX_SCROLL_SPEED 100 @@ -20,6 +24,27 @@ ScrollView::ScrollView(ViewResources& res, View& parentView, Style style) } } +ScrollView::SideButtonBinding::SideButtonBinding(ScrollView& sv, IViewManager& vm) +: m_sv(sv), m_leftName(vm.translate()), m_rightName(vm.translate()) {} + +std::string_view ScrollView::SideButtonBinding::name(const Control* control) const { + return (control == reinterpret_cast(m_sv.m_sideButtons[0].m_view.get())) ? m_leftName.c_str() + : m_rightName.c_str(); +} + +void ScrollView::SideButtonBinding::down(const Button* button, [[maybe_unused]] const boo::SWindowCoord& coord) { + if (button == m_sv.m_sideButtons[0].m_view.get()) { + m_sv.m_sideButtonState = SideButtonState::ScrollRight; + } else { + m_sv.m_sideButtonState = SideButtonState::ScrollLeft; + } +} + +void ScrollView::SideButtonBinding::up([[maybe_unused]] const Button* button, + [[maybe_unused]] const boo::SWindowCoord& coord) { + m_sv.m_sideButtonState = SideButtonState::None; +} + bool ScrollView::_scroll(const boo::SScrollDelta& scroll) { if (m_contentView.m_view) { float ratioX = subRect().size[0] / float(m_contentView.m_view->nominalWidth()); diff --git a/specter/lib/Space.cpp b/specter/lib/Space.cpp index 972c1eaac..e444799b0 100644 --- a/specter/lib/Space.cpp +++ b/specter/lib/Space.cpp @@ -1,7 +1,10 @@ -#include "logvisor/logvisor.hpp" #include "specter/Space.hpp" -#include "specter/ViewResources.hpp" + +#include "specter/IViewManager.hpp" #include "specter/RootView.hpp" +#include "specter/ViewResources.hpp" + +#include namespace specter { static logvisor::Module Log("specter::Space"); @@ -17,6 +20,21 @@ static logvisor::Module Log("specter::Space"); static const zeus::CColor TriColor = {0.75, 0.75, 0.75, 1.0}; +struct Space::CornerView : View { + Space& m_space; + VertexBufferBindingSolid m_vertexBinding; + bool m_flip; + + CornerView(ViewResources& res, Space& space, const zeus::CColor& triColor); + void mouseEnter(const boo::SWindowCoord&) override; + void mouseLeave(const boo::SWindowCoord&) override; + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; + void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; + using View::resized; + void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, bool flip); + void draw(boo::IGraphicsCommandQueue* gfxQ) override; +}; + Space::Space(ViewResources& res, View& parentView, ISpaceController& controller, Toolbar::Position tbPos, unsigned tbUnits) : View(res, parentView), m_controller(controller), m_tbPos(tbPos) { @@ -31,6 +49,8 @@ Space::Space(ViewResources& res, View& parentView, ISpaceController& controller, m_toolbar.m_view.reset(new Toolbar(res, *this, tbPos, tbUnits)); } +Space::~Space() = default; + Space::CornerView::CornerView(ViewResources& res, Space& space, const zeus::CColor& triColor) : View(res, space), m_space(space) { commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool { diff --git a/specter/lib/Table.cpp b/specter/lib/Table.cpp index 3e46362bb..c5563633f 100644 --- a/specter/lib/Table.cpp +++ b/specter/lib/Table.cpp @@ -1,13 +1,39 @@ #include "specter/Table.hpp" -#include "specter/ViewResources.hpp" + #include "specter/RootView.hpp" #include "specter/ScrollView.hpp" +#include "specter/TextView.hpp" +#include "specter/ViewResources.hpp" namespace specter { static logvisor::Module Log("specter::Table"); #define ROW_HEIGHT 18 #define CELL_MARGIN 1 +struct Table::CellView : public View { + Table& m_t; + std::unique_ptr m_text; + size_t m_c = SIZE_MAX, m_r = SIZE_MAX; + boo::SWindowRect m_scissorRect; + uint64_t m_textHash = 0; + bool m_selected = false; + + CellView(Table& t, ViewResources& res); + + void select(); + void deselect(); + void reset(); + bool reset(size_t c); + bool reset(size_t c, size_t r); + + void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; + void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) override; + void mouseEnter(const boo::SWindowCoord&) override; + void mouseLeave(const boo::SWindowCoord&) override; + void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor) override; + void draw(boo::IGraphicsCommandQueue* gfxQ) override; +}; + Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data, ITableStateBinding* state, size_t maxColumns) : View(res, parentView) @@ -31,6 +57,8 @@ Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data, ITab updateData(); } +Table::~Table() = default; + Table::RowsView::RowsView(Table& t, ViewResources& res) : View(res, t), m_t(t), m_verts(new SolidShaderVert[SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6]) { commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool { @@ -659,6 +687,8 @@ int Table::RowsView::nominalHeight() const { return rows * (ROW_HEIGHT + CELL_MARGIN * 2) * pf; } +int Table::RowsView::nominalWidth() const { return m_t.m_scroll.m_view->nominalWidth(); } + void Table::RowsView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor) { View::resized(root, sub); diff --git a/specter/lib/TextField.cpp b/specter/lib/TextField.cpp index d13cea921..3e924469a 100644 --- a/specter/lib/TextField.cpp +++ b/specter/lib/TextField.cpp @@ -1,5 +1,7 @@ #include "specter/TextField.hpp" + #include "specter/RootView.hpp" +#include "specter/TextView.hpp" #include "specter/ViewResources.hpp" namespace specter { @@ -22,6 +24,8 @@ TextField::TextField(ViewResources& res, View& parentView, IStringBinding* strBi setText(strBind->getDefault(this)); } +TextField::~TextField() = default; + void TextField::_setText() { if (m_hasTextSet) { _clearSelectionRange(); @@ -721,6 +725,21 @@ void TextField::clearSelectionRange() { m_hasSelectionSet = false; } +void TextField::setMultiplyColor(const zeus::CColor& color) { + View::setMultiplyColor(color); + m_viewVertBlock.m_color = color; + + if (m_viewVertBlockBuf) { + m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock); + } + + m_text->setMultiplyColor(color); + + if (m_errText) { + m_errText->setMultiplyColor(color); + } +} + void TextField::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { float pf = rootView().viewRes().pixelFactor(); int width = sub.size[0]; diff --git a/specter/lib/Toolbar.cpp b/specter/lib/Toolbar.cpp index 3b071972c..ccf55205b 100644 --- a/specter/lib/Toolbar.cpp +++ b/specter/lib/Toolbar.cpp @@ -31,7 +31,9 @@ Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos, unsigned setBackground(res.themeData().toolbarBackground()); } -void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { +Toolbar::~Toolbar() = default; + + void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { for (std::vector>& u : m_children) for (ViewChild& c : u) c.mouseDown(coord, button, mod); diff --git a/specter/lib/Tooltip.cpp b/specter/lib/Tooltip.cpp index 09d7b5c17..e2a30cd93 100644 --- a/specter/lib/Tooltip.cpp +++ b/specter/lib/Tooltip.cpp @@ -1,6 +1,8 @@ #include "specter/Tooltip.hpp" -#include "specter/ViewResources.hpp" + +#include "specter/MultiLineTextView.hpp" #include "specter/RootView.hpp" +#include "specter/ViewResources.hpp" namespace specter { @@ -44,6 +46,8 @@ Tooltip::Tooltip(ViewResources& res, View& parentView, std::string_view title, s m_nomHeight = m_title->nominalHeight() + m_message->nominalHeight() + margin.second * 3; } +Tooltip::~Tooltip() = default; + void Tooltip::setVerts(int width, int height, float pf) { std::pair margin = m_cornersFilled[0]->queryGlyphDimensions(0); width = std::max(width, margin.first * 2); diff --git a/specter/lib/View.cpp b/specter/lib/View.cpp index 9e9a2fdb2..4024394ea 100644 --- a/specter/lib/View.cpp +++ b/specter/lib/View.cpp @@ -1,7 +1,11 @@ #include "specter/View.hpp" -#include "specter/ViewResources.hpp" + #include "specter/RootView.hpp" -#include "hecl/Pipeline.hpp" +#include "specter/ViewResources.hpp" + +#include +#include +#include namespace specter { static logvisor::Module Log("specter::View"); diff --git a/specter/lib/ViewResources.cpp b/specter/lib/ViewResources.cpp index 1cf6eba26..2c30de94b 100644 --- a/specter/lib/ViewResources.cpp +++ b/specter/lib/ViewResources.cpp @@ -1,5 +1,8 @@ #include "specter/ViewResources.hpp" +#include +#include + namespace specter { static logvisor::Module Log("specter::ViewResources");