mirror of https://github.com/AxioDL/metaforce.git
Much more reliable space splitting
This commit is contained in:
parent
c38e4dd101
commit
54a5abc921
|
@ -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<HECL::SystemString>* recentProjects() const {return nullptr;}
|
||||
virtual void pushRecentProject(const HECL::SystemString& path) {}
|
||||
|
|
|
@ -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<RootView> 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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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&);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
namespace Specter
|
||||
{
|
||||
#define SPECTER_TOOLBAR_GAUGE 28
|
||||
|
||||
class Toolbar : public View
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<SplitView*>(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<SplitView*>(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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue