lots of split and join functionality added

This commit is contained in:
Jack Andersen 2016-01-31 15:12:30 -10:00
parent deba946807
commit dde8624b6b
6 changed files with 206 additions and 54 deletions

View File

@ -50,9 +50,9 @@ class RootView : public View
InteractiveSplit,
InteractiveJoin,
} m_phase = Phase::Inactive;
bool m_draw = false;
int m_interactiveSlot = 0;
float m_interactiveSplit = 0.5;
bool m_interactiveDown = false;
VertexBufferBinding m_vertsBinding;
ViewBlock m_viewBlock;
@ -84,10 +84,6 @@ class RootView : public View
bool m_deferredSplit = false;
bool m_deferredJoin = false;
void beginSplit();
void beginJoin();
void cancelAction();
struct SplitActionNode : IMenuNode
{
SplitMenuSystem& m_smn;
@ -174,6 +170,11 @@ public:
{
m_activeDragView = dragView;
}
void unsetActiveDragView(View* dragView)
{
if (dragView == m_activeDragView)
m_activeDragView = nullptr;
}
void setActiveMenuButton(Button* button)
{
m_activeMenuButton = button;
@ -219,6 +220,13 @@ public:
void resetTooltip(ViewResources& res);
void displayTooltip(const std::string& name, const std::string& help);
void beginInteractiveJoin(SplitView* sv, const boo::SWindowCoord& coord)
{
m_splitMenuSystem.m_phase = SplitMenuSystem::Phase::InteractiveJoin;
m_splitMenuSystem.m_splitView = sv;
m_splitMenuSystem.mouseMove(coord);
}
private:
void _updateCursor()
{

View File

@ -14,17 +14,18 @@ struct ISpaceController
{
virtual bool spaceSplitAllowed() const {return false;}
virtual ISplitSpaceController* spaceSplit(SplitView::Axis axis, int thisSlot) {return nullptr;}
virtual ISpaceController* spaceJoin(int keepSlot) {return nullptr;}
};
struct ISplitSpaceController
{
virtual SplitView* splitView()=0;
virtual void updateSplit(float split)=0;
virtual void joinViews(SplitView* thisSplit, int thisSlot, SplitView* otherSplit, int otherSlot)=0;
};
class Space : public View
{
friend class RootView;
ISpaceController& m_controller;
Toolbar::Position m_tbPos;
ViewChild<std::unique_ptr<Toolbar>> m_toolbar;
@ -62,6 +63,8 @@ public:
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
void draw(boo::IGraphicsCommandQueue* gfxQ);
SplitView* findSplitViewOnSide(SplitView::Axis axis, int side);
void setMultiplyColor(const Zeus::CColor& color)
{
View::setMultiplyColor(color);

View File

@ -10,6 +10,7 @@ struct ISplitSpaceController;
class SplitView : public View
{
friend class RootView;
friend class Space;
public:
class Resources
{
@ -82,7 +83,9 @@ public:
Axis axis() const {return m_axis;}
float split() const {return m_slide;}
bool testSplitHover(const boo::SWindowCoord& coord);
bool testJoinArrowHover(const boo::SWindowCoord& coord, int& slotOut, boo::SWindowRect& rectOut, ArrowDir& dirOut);
bool testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlotOut,
SplitView*& splitOut, int& slotOut,
boo::SWindowRect& rectOut, ArrowDir& dirOut, int forceSlot=-1);
void getJoinArrowHover(int slot, boo::SWindowRect& rectOut, ArrowDir& dirOut);
bool testSplitLineHover(const boo::SWindowCoord& coord, int& slotOut, boo::SWindowRect& rectOut, float& splitOut, Axis& axisOut);
void getSplitLineHover(int slot, boo::SWindowRect& rectOut, Axis& axisOut);

View File

@ -128,24 +128,6 @@ void RootView::SplitMenuSystem::setLineVerts(const boo::SWindowRect& rect, float
m_viewVertBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
}
void RootView::SplitMenuSystem::beginSplit()
{
m_phase = Phase::InteractiveSplit;
m_draw = true;
}
void RootView::SplitMenuSystem::beginJoin()
{
m_phase = Phase::InteractiveJoin;
m_draw = true;
}
void RootView::SplitMenuSystem::cancelAction()
{
m_phase = Phase::Inactive;
m_draw = false;
}
void RootView::destroyed()
{
m_destroyed = true;
@ -239,7 +221,28 @@ void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton butto
void RootView::SplitMenuSystem::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
{
if (m_phase == Phase::InteractiveJoin)
{
int origDummy;
SplitView* selSplit;
boo::SWindowRect rect;
SplitView::ArrowDir arrow;
if (m_splitView->testJoinArrowHover(coord, origDummy, selSplit, m_interactiveSlot, rect, arrow))
{
setArrowVerts(rect, arrow);
m_interactiveDown = true;
}
}
else if (m_phase == Phase::InteractiveSplit)
{
boo::SWindowRect rect;
SplitView::Axis axis;
if (m_splitView->testSplitLineHover(coord, m_interactiveSlot, rect, m_interactiveSplit, axis))
{
setLineVerts(rect, m_interactiveSplit, axis);
m_interactiveDown = true;
}
}
}
void RootView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
@ -279,7 +282,43 @@ void RootView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button,
void RootView::SplitMenuSystem::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
{
if (m_phase == Phase::InteractiveJoin)
{
int origSlot;
SplitView* selSplit;
boo::SWindowRect rect;
SplitView::ArrowDir arrow;
if (m_splitView->testJoinArrowHover(coord, origSlot, selSplit, m_interactiveSlot, rect, arrow))
{
setArrowVerts(rect, arrow);
if (m_interactiveDown)
{
m_interactiveDown = false;
m_phase = Phase::Inactive;
m_splitView->m_controller->joinViews(m_splitView, origSlot, selSplit, m_interactiveSlot);
}
}
}
else if (m_phase == Phase::InteractiveSplit)
{
boo::SWindowRect rect;
SplitView::Axis axis;
if (m_splitView->testSplitLineHover(coord, m_interactiveSlot, rect, m_interactiveSplit, axis))
{
setLineVerts(rect, m_interactiveSplit, axis);
if (m_interactiveDown)
{
m_interactiveDown = false;
m_phase = Phase::Inactive;
Space* space = dynamic_cast<Space*>(m_splitView->m_views[m_interactiveSlot].m_view);
if (space && space->m_controller.spaceSplitAllowed())
{
ISplitSpaceController* ss = space->m_controller.spaceSplit(axis, 0);
ss->splitView()->setSplit(m_interactiveSplit);
}
}
}
}
}
SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCoord& coord) const
@ -347,10 +386,6 @@ void RootView::mouseMove(const boo::SWindowCoord& coord)
sv = recursiveTestSplitHover(sv, coord);
if (sv)
{
if (sv->axis() == SplitView::Axis::Horizontal)
setHorizontalSplitHover(true);
else
setVerticalSplitHover(true);
m_hoverSplitDragView = sv;
break;
}
@ -371,6 +406,14 @@ void RootView::mouseMove(const boo::SWindowCoord& coord)
v->mouseMove(coord);
}
if (m_hoverSplitDragView)
{
if (m_hoverSplitDragView->axis() == SplitView::Axis::Horizontal)
setHorizontalSplitHover(true);
else
setVerticalSplitHover(true);
}
boo::SWindowRect ttrect = m_rootRect;
ttrect.location[0] = coord.pixel[0];
ttrect.location[1] = coord.pixel[1];
@ -388,9 +431,11 @@ void RootView::SplitMenuSystem::mouseMove(const boo::SWindowCoord& coord)
{
if (m_phase == Phase::InteractiveJoin)
{
int origDummy;
SplitView* selSplit;
boo::SWindowRect rect;
SplitView::ArrowDir arrow;
if (m_splitView->testJoinArrowHover(coord, m_interactiveSlot, rect, arrow))
if (m_splitView->testJoinArrowHover(coord, origDummy, selSplit, m_interactiveSlot, rect, arrow))
setArrowVerts(rect, arrow);
}
else if (m_phase == Phase::InteractiveSplit)
@ -499,7 +544,7 @@ void RootView::specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool
return;
}
if (key == boo::ESpecialKey::Esc && m_splitMenuSystem.m_phase != SplitMenuSystem::Phase::Inactive)
m_splitMenuSystem.cancelAction();
m_splitMenuSystem.m_phase = SplitMenuSystem::Phase::Inactive;
for (View* v : m_views)
v->specialKeyDown(key, mods, isRepeat);
if (m_activeTextView)
@ -545,7 +590,7 @@ void RootView::internalThink()
{
m_splitMenuSystem.m_deferredSplit = false;
m_rightClickMenu.m_view.reset();
m_splitMenuSystem.beginSplit();
m_splitMenuSystem.m_phase = SplitMenuSystem::Phase::InteractiveSplit;
m_splitMenuSystem.mouseMove(m_splitMenuSystem.m_deferredCoord);
}
@ -553,7 +598,7 @@ void RootView::internalThink()
{
m_splitMenuSystem.m_deferredJoin = false;
m_rightClickMenu.m_view.reset();
m_splitMenuSystem.beginJoin();
m_splitMenuSystem.m_phase = SplitMenuSystem::Phase::InteractiveJoin;
m_splitMenuSystem.mouseMove(m_splitMenuSystem.m_deferredCoord);
}
@ -585,7 +630,7 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
void RootView::SplitMenuSystem::draw(boo::IGraphicsCommandQueue* gfxQ)
{
if (m_phase == Phase::Inactive || !m_draw)
if (m_phase == Phase::Inactive)
return;
gfxQ->setShaderDataBinding(m_vertsBinding);
gfxQ->setDrawPrimitive(boo::Primitive::TriStrips);

View File

@ -129,6 +129,7 @@ void Space::CornerView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseBut
m_space.m_cornerDrag = true;
m_space.m_cornerDragPoint[0] = coord.pixel[0];
m_space.m_cornerDragPoint[1] = coord.pixel[1];
rootView().setActiveDragView(&m_space);
}
}
@ -142,7 +143,10 @@ void Space::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, bo
void Space::CornerView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (button == boo::EMouseButton::Primary)
{
m_space.m_cornerDrag = false;
rootView().unsetActiveDragView(&m_space);
}
}
void Space::mouseMove(const boo::SWindowCoord& coord)
@ -150,20 +154,82 @@ void Space::mouseMove(const boo::SWindowCoord& coord)
if (m_cornerDrag)
{
float pf = rootView().viewRes().pixelFactor();
if (coord.pixel[0] < m_cornerDragPoint[0] - CORNER_DRAG_THRESHOLD * pf)
{
if (m_cornerView.m_view->m_flip)
{
if (coord.pixel[0] < m_cornerDragPoint[0] - CORNER_DRAG_THRESHOLD * pf)
m_cornerDrag = false;
rootView().unsetActiveDragView(this);
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 1, coord);
}
else
{
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Vertical, 0);
if (sv)
{
m_cornerDrag = false;
rootView().unsetActiveDragView(this);
rootView().beginInteractiveJoin(sv, coord);
}
}
}
else if (coord.pixel[1] < m_cornerDragPoint[1] - CORNER_DRAG_THRESHOLD * pf)
{
if (m_cornerView.m_view->m_flip)
{
m_cornerDrag = false;
rootView().unsetActiveDragView(this);
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 1, coord);
}
else
{
if (coord.pixel[0] > m_cornerDragPoint[0] + CORNER_DRAG_THRESHOLD * pf)
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Horizontal, 0);
if (sv)
{
m_cornerDrag = false;
rootView().unsetActiveDragView(this);
rootView().beginInteractiveJoin(sv, coord);
}
}
}
else if (coord.pixel[0] > m_cornerDragPoint[0] + CORNER_DRAG_THRESHOLD * pf)
{
if (!m_cornerView.m_view->m_flip)
{
m_cornerDrag = false;
rootView().unsetActiveDragView(this);
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 0, coord);
}
else
{
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Vertical, 1);
if (sv)
{
m_cornerDrag = false;
rootView().unsetActiveDragView(this);
rootView().beginInteractiveJoin(sv, coord);
}
}
}
else if (coord.pixel[1] > m_cornerDragPoint[1] + CORNER_DRAG_THRESHOLD * pf)
{
if (!m_cornerView.m_view->m_flip)
{
m_cornerDrag = false;
rootView().unsetActiveDragView(this);
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 0, coord);
}
else
{
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Horizontal, 1);
if (sv)
{
m_cornerDrag = false;
rootView().unsetActiveDragView(this);
rootView().beginInteractiveJoin(sv, coord);
}
}
}
}
else
{
@ -197,6 +263,20 @@ void Space::CornerView::mouseLeave(const boo::SWindowCoord& coord)
rootView().setSpaceCornerHover(false);
}
SplitView* Space::findSplitViewOnSide(SplitView::Axis axis, int side)
{
SplitView* ret = dynamic_cast<SplitView*>(&parentView());
while (ret)
{
if (ret->axis() != axis)
return nullptr;
if (ret->m_views[side ^ 1].m_view == this)
return ret;
ret = dynamic_cast<SplitView*>(&ret->parentView());
}
return nullptr;
}
void Space::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{
View::resized(root, sub);

View File

@ -99,74 +99,87 @@ bool SplitView::testSplitHover(const boo::SWindowCoord& coord)
return false;
}
bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& slotOut, boo::SWindowRect& rectOut, ArrowDir& dirOut)
bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlotOut,
SplitView*& splitOut, int& slotOut,
boo::SWindowRect& rectOut, ArrowDir& dirOut, int forceSlot)
{
if (!subRect().coordInRect(coord))
return false;
int origDummy;
ArrowDir dirDummy;
if (m_axis == Axis::Horizontal)
{
int slidePx = subRect().size[1] * m_slide;
if (coord.pixel[1] - subRect().location[1] - slidePx >= 0)
if ((forceSlot == -1 && coord.pixel[1] - subRect().location[1] - slidePx >= 0) || forceSlot == 1)
{
origSlotOut = 0;
dirOut = ArrowDir::Up;
if (m_views[1].m_view)
{
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view);
if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->testJoinArrowHover(coord, slotOut, rectOut, dirOut);
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0);
}
splitOut = this;
slotOut = 1;
rectOut = subRect();
rectOut.location[1] += slidePx;
rectOut.size[1] -= slidePx;
dirOut = ArrowDir::Up;
return true;
}
else
{
origSlotOut = 1;
dirOut = ArrowDir::Down;
if (m_views[0].m_view)
{
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view);
if (chSplit && chSplit->m_axis == Axis::Horizontal)
return chSplit->testJoinArrowHover(coord, slotOut, rectOut, dirOut);
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1);
}
splitOut = this;
slotOut = 0;
rectOut = subRect();
rectOut.size[1] = slidePx;
dirOut = ArrowDir::Down;
return true;
}
}
else
{
int slidePx = subRect().size[0] * m_slide;
if (coord.pixel[0] - subRect().location[0] - slidePx >= 0)
if ((forceSlot == -1 && coord.pixel[0] - subRect().location[0] - slidePx >= 0) || forceSlot == 1)
{
origSlotOut = 0;
dirOut = ArrowDir::Right;
if (m_views[1].m_view)
{
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[1].m_view);
if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->testJoinArrowHover(coord, slotOut, rectOut, dirOut);
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0);
}
splitOut = this;
slotOut = 1;
rectOut = subRect();
rectOut.location[0] += slidePx;
rectOut.size[0] -= slidePx;
dirOut = ArrowDir::Right;
return true;
}
else
{
origSlotOut = 1;
dirOut = ArrowDir::Left;
if (m_views[0].m_view)
{
SplitView* chSplit = dynamic_cast<SplitView*>(m_views[0].m_view);
if (chSplit && chSplit->m_axis == Axis::Vertical)
return chSplit->testJoinArrowHover(coord, slotOut, rectOut, dirOut);
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1);
}
splitOut = this;
slotOut = 0;
rectOut = subRect();
rectOut.size[0] = slidePx;
dirOut = ArrowDir::Left;
return true;
}
}