diff --git a/specter/include/Specter/IViewManager.hpp b/specter/include/Specter/IViewManager.hpp index 4182bfd7f..6e5d86227 100644 --- a/specter/include/Specter/IViewManager.hpp +++ b/specter/include/Specter/IViewManager.hpp @@ -21,7 +21,8 @@ public: return vor; } - virtual void deferSpaceSplit(ISpaceController* split, SplitView::Axis axis, int thisSlot) {} + virtual void deferSpaceSplit(ISpaceController* split, SplitView::Axis axis, int thisSlot, + const boo::SWindowCoord& coord) {} virtual const std::vector* recentProjects() const {return nullptr;} virtual void pushRecentProject(const HECL::SystemString& path) {} diff --git a/specter/include/Specter/RootView.hpp b/specter/include/Specter/RootView.hpp index b0ca867a6..256c6cecc 100644 --- a/specter/include/Specter/RootView.hpp +++ b/specter/include/Specter/RootView.hpp @@ -27,6 +27,10 @@ class RootView : public View ITextInputView* m_activeTextView = nullptr; View* m_activeDragView = nullptr; + SplitView* m_hoverSplitDragView = nullptr; + bool m_activeSplitDragView = false; + SplitView* recursiveTestSplitHover(SplitView* sv, const boo::SWindowCoord& coord) const; + DeferredWindowEvents m_events; public: @@ -79,6 +83,13 @@ public: m_activeDragView = dragView; } + void startSplitDrag(SplitView* sv, const boo::SWindowCoord& coord) + { + m_hoverSplitDragView = sv; + m_activeSplitDragView = true; + sv->startDragSplit(coord); + } + bool m_hSplitHover = false; void setHorizontalSplitHover(bool hover) { @@ -107,7 +118,7 @@ public: void resetTooltip(ViewResources& res); void displayTooltip(const std::string& name, const std::string& help); -private: +private: void _updateCursor() { if (m_spaceCornerHover) diff --git a/specter/include/Specter/Space.hpp b/specter/include/Specter/Space.hpp index 530a10b22..cd80cb7fb 100644 --- a/specter/include/Specter/Space.hpp +++ b/specter/include/Specter/Space.hpp @@ -20,7 +20,7 @@ struct ISpaceController struct ISplitSpaceController { virtual SplitView* splitView()=0; - virtual void setSplit(float split)=0; + virtual void updateSplit(float split)=0; }; class Space : public View diff --git a/specter/include/Specter/SplitView.hpp b/specter/include/Specter/SplitView.hpp index f60b4c93d..a38fcbe7b 100644 --- a/specter/include/Specter/SplitView.hpp +++ b/specter/include/Specter/SplitView.hpp @@ -5,9 +5,11 @@ namespace Specter { +struct ISplitSpaceController; class SplitView : public View { + friend class RootView; public: class Resources { @@ -24,6 +26,7 @@ public: Vertical }; private: + ISplitSpaceController* m_controller; Axis m_axis; float m_slide = 0.5; void _setSplit(float slide); @@ -63,11 +66,17 @@ private: VertexBufferBinding m_splitVertsBinding; public: - SplitView(ViewResources& res, View& parentView, Axis axis, int clearanceA=-1, int clearanceB=-1); + SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller, + Axis axis, float split, int clearanceA=-1, int clearanceB=-1); View* setContentView(int slot, View* view); - void setSplit(float slide); + void setSplit(float split); void setAxis(Axis axis); + Axis axis() const {return m_axis;} + float split() const {return m_slide;} + bool testSplitHover(const boo::SWindowCoord& coord); void startDragSplit(const boo::SWindowCoord& coord); + void endDragSplit(); + void moveDragSplit(const boo::SWindowCoord& coord); void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey); void mouseMove(const boo::SWindowCoord&); diff --git a/specter/include/Specter/Toolbar.hpp b/specter/include/Specter/Toolbar.hpp index e9585ca81..08f38ce6d 100644 --- a/specter/include/Specter/Toolbar.hpp +++ b/specter/include/Specter/Toolbar.hpp @@ -5,6 +5,7 @@ namespace Specter { +#define SPECTER_TOOLBAR_GAUGE 28 class Toolbar : public View { diff --git a/specter/lib/FileBrowser.cpp b/specter/lib/FileBrowser.cpp index 768da783f..54b85b25e 100644 --- a/specter/lib/FileBrowser.cpp +++ b/specter/lib/FileBrowser.cpp @@ -85,11 +85,10 @@ FileBrowser::FileBrowser(ViewResources& res, View& parentView, const std::string navigateToPath(initialPath); - m_split.m_view.reset(new SplitView(res, *this, SplitView::Axis::Vertical, + m_split.m_view.reset(new SplitView(res, *this, nullptr, SplitView::Axis::Vertical, 0.2, 200 * res.pixelFactor(), 400 * res.pixelFactor())); m_split.m_view->setContentView(0, &m_left); m_split.m_view->setContentView(1, &m_right); - m_split.m_view->setSplit(0.2); updateContentOpacity(0.0); } diff --git a/specter/lib/RootView.cpp b/specter/lib/RootView.cpp index 92fcfb949..f7de53643 100644 --- a/specter/lib/RootView.cpp +++ b/specter/lib/RootView.cpp @@ -14,7 +14,6 @@ RootView::RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* wind m_renderTex = res.m_factory->newRenderTexture(rect.size[0], rect.size[1], 1); commitResources(res); resized(rect, rect); - printf("New RootView: %p\n", this); } void RootView::destroyed() @@ -37,6 +36,13 @@ void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&) void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) { + if (m_hoverSplitDragView) + { + m_activeSplitDragView = true; + m_hoverSplitDragView->startDragSplit(coord); + return; + } + if (m_activeTextView && !m_activeTextView->subRect().coordInRect(coord)) setActiveTextView(nullptr); for (View* v : m_views) @@ -45,12 +51,76 @@ void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton butto void RootView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) { + if (m_activeSplitDragView && button == boo::EMouseButton::Primary) + { + m_activeSplitDragView = false; + m_hoverSplitDragView->endDragSplit(); + m_spaceCornerHover = false; + m_hSplitHover = false; + m_vSplitHover = false; + _updateCursor(); + } + for (View* v : m_views) v->mouseUp(coord, button, mods); } +SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCoord& coord) const +{ + if (sv->testSplitHover(coord)) + return sv; + for (int i=0 ; i<2 ; ++i) + { + SplitView* child = dynamic_cast(sv->m_views[i].m_view); + if (child) + { + SplitView* res = recursiveTestSplitHover(child, coord); + if (res) + return res; + } + } + return nullptr; +} + void RootView::mouseMove(const boo::SWindowCoord& coord) { + if (m_activeSplitDragView) + { + m_hoverSplitDragView->moveDragSplit(coord); + m_spaceCornerHover = false; + if (m_hoverSplitDragView->axis() == SplitView::Axis::Horizontal) + setHorizontalSplitHover(true); + else + setVerticalSplitHover(true); + return; + } + + m_hoverSplitDragView = nullptr; + if (!m_spaceCornerHover) + { + for (View* v : m_views) + { + SplitView* sv = dynamic_cast(v); + if (sv) + sv = recursiveTestSplitHover(sv, coord); + if (sv) + { + if (sv->axis() == SplitView::Axis::Horizontal) + setHorizontalSplitHover(true); + else + setVerticalSplitHover(true); + m_hoverSplitDragView = sv; + break; + } + else + { + m_hSplitHover = false; + m_vSplitHover = false; + _updateCursor(); + } + } + } + if (m_activeDragView) m_activeDragView->mouseMove(coord); else diff --git a/specter/lib/Space.cpp b/specter/lib/Space.cpp index b94f40b91..b1dfe8c6a 100644 --- a/specter/lib/Space.cpp +++ b/specter/lib/Space.cpp @@ -25,7 +25,6 @@ Space::Space(ViewResources& res, View& parentView, ISpaceController& controller, m_cornerView.m_view.reset(new CornerView(res, *this, spaceTriangleColor())); if (tbPos != Toolbar::Position::None) m_toolbar.m_view.reset(new Toolbar(res, *this, tbPos)); - printf("New Space: %p\n", this); } Space::CornerView::CornerView(ViewResources& res, Space& space, const Zeus::CColor& triColor) @@ -110,7 +109,6 @@ View* Space::setContentView(View* view) View* ret = m_contentView.m_view; m_contentView.m_view = view; updateSize(); - printf("Set Space: %p [%p]\n", this, view); return ret; } @@ -153,16 +151,16 @@ void Space::mouseMove(const boo::SWindowCoord& coord) if (m_cornerView.m_view->m_flip) { if (coord.pixel[0] < m_cornerDragPoint[0] - CORNER_DRAG_THRESHOLD * pf) - rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 1); + rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 1, coord); else if (coord.pixel[1] < m_cornerDragPoint[1] - CORNER_DRAG_THRESHOLD * pf) - rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 1); + rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 1, coord); } else { if (coord.pixel[0] > m_cornerDragPoint[0] + CORNER_DRAG_THRESHOLD * pf) - rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 0); + rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 0, coord); else if (coord.pixel[1] > m_cornerDragPoint[1] + CORNER_DRAG_THRESHOLD * pf) - rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 0); + rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 0, coord); } } else diff --git a/specter/lib/SplitView.cpp b/specter/lib/SplitView.cpp index 6b14d780b..28fc3a6af 100644 --- a/specter/lib/SplitView.cpp +++ b/specter/lib/SplitView.cpp @@ -2,6 +2,7 @@ #include "Specter/SplitView.hpp" #include "Specter/RootView.hpp" #include "Specter/ViewResources.hpp" +#include "Specter/Space.hpp" namespace Specter { @@ -18,13 +19,14 @@ void SplitView::Resources::init(boo::IGraphicsDataFactory* factory, const ITheme m_shadingTex = factory->newStaticTexture(3, 1, 1, boo::TextureFormat::RGBA8, tex, 12); } -SplitView::SplitView(ViewResources& res, View& parentView, Axis axis, int clearanceA, int clearanceB) -: View(res, parentView), m_axis(axis), m_clearanceA(clearanceA), m_clearanceB(clearanceB) +SplitView::SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller, + Axis axis, float split, int clearanceA, int clearanceB) +: View(res, parentView), m_controller(controller), m_axis(axis), m_slide(split), + m_clearanceA(clearanceA), m_clearanceB(clearanceB) { m_splitBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1); m_splitVertsBinding.initTex(res, 4, m_splitBlockBuf, res.m_splitRes.m_shadingTex); commitResources(res); - printf("New SplitView: %p\n", this); } View* SplitView::setContentView(int slot, View* view) @@ -36,7 +38,6 @@ View* SplitView::setContentView(int slot, View* view) m_views[slot].m_mouseDown = 0; m_views[slot].m_mouseIn = false; updateSize(); - printf("Set SplitView: %p [%d,%p]\n", this, slot, view); return ret; } @@ -65,6 +66,8 @@ void SplitView::_setSplit(float slide) } m_slide = std::min(std::max(m_slide, 0.0f), 1.0f); } + if (m_controller) + m_controller->updateSplit(m_slide); } void SplitView::setSplit(float slide) @@ -79,80 +82,59 @@ void SplitView::setAxis(Axis axis) setSplit(m_slide); } +bool SplitView::testSplitHover(const boo::SWindowCoord& coord) +{ + if (m_axis == Axis::Horizontal) + { + int slidePx = subRect().size[1] * m_slide; + if (abs(int(coord.pixel[1] - subRect().location[1]) - slidePx) < 4) + return true; + } + else if (m_axis == Axis::Vertical) + { + int slidePx = subRect().size[0] * m_slide; + if (abs(int(coord.pixel[0] - subRect().location[0]) - slidePx) < 4) + return true; + } + return false; +} + void SplitView::startDragSplit(const boo::SWindowCoord& coord) { m_dragging = true; - mouseMove(coord); + if (m_axis == Axis::Horizontal) + setSplit((coord.pixel[1] - subRect().location[1]) / float(subRect().size[1])); + else if (m_axis == Axis::Vertical) + setSplit((coord.pixel[0] - subRect().location[0]) / float(subRect().size[0])); +} + +void SplitView::endDragSplit() +{ + m_dragging = false; +} + +void SplitView::moveDragSplit(const boo::SWindowCoord& coord) +{ + if (m_axis == Axis::Horizontal) + setSplit((coord.pixel[1] - subRect().location[1]) / float(subRect().size[1])); + else if (m_axis == Axis::Vertical) + setSplit((coord.pixel[0] - subRect().location[0]) / float(subRect().size[0])); } void SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - if (!rootView().m_spaceCornerHover) - { - if (m_axis == Axis::Horizontal) - { - int slidePx = subRect().size[1] * m_slide; - if (abs(int(coord.pixel[1] - subRect().location[1]) - slidePx) < 4) - { - if (button == boo::EMouseButton::Primary) - { - m_dragging = true; - setSplit((coord.pixel[1] - subRect().location[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] - subRect().location[0]) - slidePx) < 4) - { - if (button == boo::EMouseButton::Primary) - { - m_dragging = true; - setSplit((coord.pixel[0] - subRect().location[0]) / float(subRect().size[0])); - } - else if (button == boo::EMouseButton::Secondary) - { - // TODO: Split menu - } - return; - } - } - } m_views[0].mouseDown(coord, button, mod); m_views[1].mouseDown(coord, button, mod); } void SplitView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) { - if (button == boo::EMouseButton::Primary) - m_dragging = false; m_views[0].mouseUp(coord, button, mod); m_views[1].mouseUp(coord, button, mod); } void SplitView::mouseMove(const boo::SWindowCoord& coord) { - if (m_axis == Axis::Horizontal) - { - if (m_dragging) - setSplit((coord.pixel[1] - subRect().location[1]) / float(subRect().size[1])); - int slidePx = subRect().size[1] * m_slide; - rootView().setHorizontalSplitHover(abs(int(coord.pixel[1] - subRect().location[1]) - slidePx) < 4); - } - else if (m_axis == Axis::Vertical) - { - if (m_dragging) - setSplit((coord.pixel[0] - subRect().location[0]) / float(subRect().size[0])); - int slidePx = subRect().size[0] * m_slide; - rootView().setVerticalSplitHover(abs(int(coord.pixel[0] - subRect().location[0]) - slidePx) < 4); - } - m_views[0].mouseMove(coord); m_views[1].mouseMove(coord); } diff --git a/specter/lib/Toolbar.cpp b/specter/lib/Toolbar.cpp index 216c800a5..5a70d0640 100644 --- a/specter/lib/Toolbar.cpp +++ b/specter/lib/Toolbar.cpp @@ -2,7 +2,6 @@ #include "Specter/Toolbar.hpp" #include "Specter/ViewResources.hpp" -#define TOOLBAR_GAUGE 28 #define TOOLBAR_PADDING 10 namespace Specter @@ -23,7 +22,7 @@ void Toolbar::Resources::init(boo::IGraphicsDataFactory* factory, const IThemeDa Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos) : View(res, parentView), m_tbPos(tbPos), - m_nomHeight(res.pixelFactor() * TOOLBAR_GAUGE), + m_nomHeight(res.pixelFactor() * SPECTER_TOOLBAR_GAUGE), m_padding(res.pixelFactor() * TOOLBAR_PADDING) { m_tbBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);