#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) { m_contentView.m_view.reset(new ContentView(res, *this)); setContentView(m_contentView.m_view.get()); } PathButtons::~PathButtons() = default; void PathButtons::setButtons(const std::vector& comps) { m_pathButtons.clear(); m_pathButtons.reserve(comps.size()); size_t idx = 0; ViewResources& res = rootView().viewRes(); for (const hecl::SystemString& c : comps) m_pathButtons.emplace_back(*this, res, idx++, c); } void PathButtons::setMultiplyColor(const zeus::CColor& color) { ScrollView::setMultiplyColor(color); for (PathButton& b : m_pathButtons) b.m_button.m_view->setMultiplyColor(color); } void PathButtons::containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { if (m_fillContainer) { boo::SWindowRect fillRect = sub; fillRect.size[1] = 20 * rootView().viewRes().pixelFactor(); View::resized(root, fillRect); } } } // namespace specter