Interactive split and join graphics

This commit is contained in:
Jack Andersen 2016-01-30 15:07:52 -10:00
parent a5954a9d7c
commit deba946807
4 changed files with 578 additions and 15 deletions

View File

@ -38,14 +38,38 @@ class RootView : public View
DeferredWindowEvents<RootView> m_events;
struct SplitMenuNode : IMenuNode
struct SplitMenuSystem : IMenuNode
{
RootView& m_rv;
std::string m_text;
SplitView* m_splitView = nullptr;
SplitMenuNode(RootView& rv)
: m_rv(rv), m_text(rv.m_viewMan.translateOr("boundary_action", "Boundary Action")),
m_splitActionNode(*this), m_joinActionNode(*this) {}
enum class Phase
{
Inactive,
InteractiveSplit,
InteractiveJoin,
} m_phase = Phase::Inactive;
bool m_draw = false;
int m_interactiveSlot = 0;
float m_interactiveSplit = 0.5;
VertexBufferBinding m_vertsBinding;
ViewBlock m_viewBlock;
boo::IGraphicsBufferD* m_viewVertBlockBuf;
SolidShaderVert m_verts[32];
void setArrowVerts(const boo::SWindowRect& rect, SplitView::ArrowDir dir);
void setLineVerts(const boo::SWindowRect& rect, float split, SplitView::Axis axis);
void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods);
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods);
void mouseMove(const boo::SWindowCoord& coord);
void mouseLeave(const boo::SWindowCoord& coord);
void resized();
void draw(boo::IGraphicsCommandQueue* gfxQ);
SplitMenuSystem(RootView& rv);
const std::string* text() const {return &m_text;}
size_t subNodeCount() const {return 2;}
IMenuNode* subNode(size_t idx)
@ -56,29 +80,39 @@ class RootView : public View
return &m_splitActionNode;
}
boo::SWindowCoord m_deferredCoord;
bool m_deferredSplit = false;
bool m_deferredJoin = false;
void beginSplit();
void beginJoin();
void cancelAction();
struct SplitActionNode : IMenuNode
{
SplitMenuNode& m_smn;
SplitMenuSystem& m_smn;
std::string m_text;
SplitActionNode(SplitMenuNode& smn)
: m_smn(smn), m_text(smn.m_rv.m_viewMan.translateOr("split", "Split")) {}
SplitActionNode(SplitMenuSystem& smn);
const std::string* text() const {return &m_text;}
void activated(const boo::SWindowCoord& coord)
{
m_smn.m_deferredSplit = true;
m_smn.m_deferredCoord = coord;
}
} m_splitActionNode;
struct JoinActionNode : IMenuNode
{
SplitMenuNode& m_smn;
SplitMenuSystem& m_smn;
std::string m_text;
JoinActionNode(SplitMenuNode& smn)
: m_smn(smn), m_text(smn.m_rv.m_viewMan.translateOr("join", "Join")) {}
JoinActionNode(SplitMenuSystem& smn);
const std::string* text() const {return &m_text;}
void activated(const boo::SWindowCoord& coord)
{
m_smn.m_deferredJoin = true;
m_smn.m_deferredCoord = coord;
}
} m_joinActionNode;
} m_splitMenuNode;
} m_splitMenuSystem;
public:
RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window);
@ -106,6 +140,7 @@ public:
void modKeyUp(boo::EModifierKey mod);
boo::ITextInputCallback* getTextInputCallback() {return m_activeTextView;}
void internalThink();
void dispatchEvents() {m_events.dispatchEvents();}
void draw(boo::IGraphicsCommandQueue* gfxQ);
const boo::SWindowRect& rootRect() const {return m_rootRect;}

View File

@ -20,6 +20,14 @@ public:
void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme);
};
enum class ArrowDir
{
Up,
Down,
Left,
Right
};
enum class Axis
{
Horizontal,
@ -64,7 +72,7 @@ private:
}
VertexBufferBinding m_splitVertsBinding;
public:
SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller,
Axis axis, float split, int clearanceA=-1, int clearanceB=-1);
@ -74,6 +82,10 @@ 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);
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);
void startDragSplit(const boo::SWindowCoord& coord);
void endDragSplit();
void moveDragSplit(const boo::SWindowCoord& coord);

View File

@ -9,7 +9,7 @@ static LogVisor::LogModule Log("Specter::RootView");
RootView::RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window)
: View(res), m_window(window), m_viewMan(viewMan), m_viewRes(&res), m_events(*this),
m_splitMenuNode(*this)
m_splitMenuSystem(*this)
{
window->setCallback(&m_events);
boo::SWindowRect rect = window->getWindowFrame();
@ -18,6 +18,134 @@ RootView::RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* wind
resized(rect, rect);
}
RootView::SplitMenuSystem::SplitMenuSystem(RootView& rv)
: m_rv(rv), m_text(rv.m_viewMan.translateOr("boundary_action", "Boundary Action")),
m_splitActionNode(*this), m_joinActionNode(*this)
{
m_viewVertBlockBuf = rv.m_viewRes->m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(View::ViewBlock), 1);
m_vertsBinding.initSolid(*rv.m_viewRes, 32, m_viewVertBlockBuf);
Zeus::CColor col = {0.0,0.0,0.0,0.5};
for (int i=0 ; i<32 ; ++i)
m_verts[i].m_color = col;
m_verts[0].m_pos.assign(0.0, 0.25, 0);
m_verts[1].m_pos.assign(0.0, 0.0, 0);
m_verts[2].m_pos.assign(0.375, 0.25, 0);
m_verts[3].m_pos.assign(0.375, 0.0, 0);
m_verts[4].m_pos = m_verts[3].m_pos;
m_verts[5].m_pos.assign(0.0, 1.0, 0);
m_verts[6].m_pos = m_verts[5].m_pos;
m_verts[7].m_pos = m_verts[0].m_pos;
m_verts[8].m_pos.assign(0.5, 1.0, 0);
m_verts[9].m_pos.assign(0.25, 0.25, 0);
m_verts[10].m_pos.assign(0.5, 0.5, 0);
m_verts[11].m_pos = m_verts[10].m_pos;
m_verts[12].m_pos = m_verts[8].m_pos;
m_verts[13].m_pos = m_verts[12].m_pos;
m_verts[14].m_pos = m_verts[11].m_pos;
m_verts[15].m_pos.assign(1.0, 1.0, 0);
m_verts[16].m_pos.assign(1.0, 0.25, 0);
m_verts[17].m_pos = m_verts[16].m_pos;
m_verts[18].m_pos = m_verts[14].m_pos;
m_verts[19].m_pos = m_verts[18].m_pos;
m_verts[20].m_pos.assign(0.75, 0.25, 0);
m_verts[21].m_pos = m_verts[17].m_pos;
m_verts[22].m_pos = m_verts[21].m_pos;
m_verts[23].m_pos.assign(0.625, 0.25, 0);
m_verts[24].m_pos = m_verts[23].m_pos;
m_verts[25].m_pos.assign(0.625, 0.0, 0);
m_verts[26].m_pos = m_verts[22].m_pos;
m_verts[27].m_pos.assign(1.0, 0.0, 0);
m_verts[28].m_pos.assign(-1.0, 1.0, 0);
m_verts[29].m_pos.assign(-1.0, -1.0, 0);
m_verts[30].m_pos.assign(1.0, 1.0, 0);
m_verts[31].m_pos.assign(1.0, -1.0, 0);
m_vertsBinding.load(m_verts, sizeof(m_verts));
}
RootView::SplitMenuSystem::SplitActionNode::SplitActionNode(SplitMenuSystem& smn)
: m_smn(smn), m_text(smn.m_rv.m_viewMan.translateOr("split", "Split")) {}
RootView::SplitMenuSystem::JoinActionNode::JoinActionNode(SplitMenuSystem& smn)
: m_smn(smn), m_text(smn.m_rv.m_viewMan.translateOr("join", "Join")) {}
void RootView::SplitMenuSystem::setArrowVerts(const boo::SWindowRect& rect, SplitView::ArrowDir dir)
{
const boo::SWindowRect& root = m_rv.subRect();
if (dir == SplitView::ArrowDir::Left || dir == SplitView::ArrowDir::Right)
{
m_viewBlock.m_mv[0][1] = 2.0f * rect.size[1] / float(root.size[1]);
m_viewBlock.m_mv[0][0] = 0.0f;
m_viewBlock.m_mv[1][0] = 2.0f * (dir == SplitView::ArrowDir::Left ? -rect.size[0] : rect.size[0]) /
float(root.size[0]);
m_viewBlock.m_mv[1][1] = 0.0f;
m_viewBlock.m_mv[3][0] = 2.0f * (rect.location[0] + (dir == SplitView::ArrowDir::Left ? rect.size[0] : 0)) /
float(root.size[0]) - 1.0f;
m_viewBlock.m_mv[3][1] = 2.0f * rect.location[1] / float(root.size[1]) - 1.0f;
}
else
{
m_viewBlock.m_mv[0][0] = 2.0f * rect.size[0] / float(root.size[0]);
m_viewBlock.m_mv[0][1] = 0.0f;
m_viewBlock.m_mv[1][1] = 2.0f * (dir == SplitView::ArrowDir::Down ? -rect.size[1] : rect.size[1]) /
float(root.size[1]);
m_viewBlock.m_mv[1][0] = 0.0f;
m_viewBlock.m_mv[3][0] = 2.0f * rect.location[0] / float(root.size[0]) - 1.0f;
m_viewBlock.m_mv[3][1] = 2.0f * (rect.location[1] + (dir == SplitView::ArrowDir::Down ? rect.size[1] : 0)) /
float(root.size[1]) - 1.0f;
}
m_viewVertBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
}
void RootView::SplitMenuSystem::setLineVerts(const boo::SWindowRect& rect, float split, SplitView::Axis axis)
{
const boo::SWindowRect& root = m_rv.subRect();
if (axis == SplitView::Axis::Horizontal)
{
m_viewBlock.m_mv[0][0] = rect.size[0] / float(root.size[0]);
m_viewBlock.m_mv[0][1] = 0.0f;
m_viewBlock.m_mv[1][1] = 2.0f / float(root.size[1]);
m_viewBlock.m_mv[1][0] = 0.0f;
m_viewBlock.m_mv[3][0] = 2.0f * (rect.location[0] + rect.size[0] / 2.0f) / float(root.size[0]) - 1.0f;
m_viewBlock.m_mv[3][1] = (rect.location[1] + split * rect.size[1]) * m_viewBlock.m_mv[1][1] - 1.0f;
}
else
{
m_viewBlock.m_mv[0][0] = 2.0f / float(root.size[0]);
m_viewBlock.m_mv[0][1] = 0.0f;
m_viewBlock.m_mv[1][1] = rect.size[1] / float(root.size[1]);
m_viewBlock.m_mv[1][0] = 0.0f;
m_viewBlock.m_mv[3][0] = (rect.location[0] + split * rect.size[0]) * m_viewBlock.m_mv[0][0] - 1.0f;
m_viewBlock.m_mv[3][1] = 2.0f * (rect.location[1] + rect.size[1] / 2.0f) / float(root.size[1]) - 1.0f;
}
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;
@ -43,11 +171,36 @@ void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&)
m_rightClickMenuRootAndLoc.location[1] *= hr;
m_rightClickMenu.m_view->resized(root, m_rightClickMenuRootAndLoc);
}
m_splitMenuSystem.resized();
m_resizeRTDirty = true;
}
void RootView::SplitMenuSystem::resized()
{
if (m_phase == Phase::InteractiveJoin)
{
boo::SWindowRect rect;
SplitView::ArrowDir arrow;
m_splitView->getJoinArrowHover(m_interactiveSlot, rect, arrow);
setArrowVerts(rect, arrow);
}
else if (m_phase == Phase::InteractiveSplit)
{
boo::SWindowRect rect;
SplitView::Axis axis;
m_splitView->getSplitLineHover(m_interactiveSlot, rect, axis);
setLineVerts(rect, m_interactiveSplit, axis);
}
}
void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
{
if (m_splitMenuSystem.m_phase != SplitMenuSystem::Phase::Inactive)
{
m_splitMenuSystem.mouseDown(coord, button, mods);
return;
}
if (m_rightClickMenu.m_view)
{
if (!m_rightClickMenu.mouseDown(coord, button, mods))
@ -72,8 +225,8 @@ void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton butto
}
else if (button == boo::EMouseButton::Secondary)
{
m_splitMenuNode.m_splitView = m_hoverSplitDragView;
adoptRightClickMenu(std::make_unique<Specter::Menu>(*m_viewRes, *this, &m_splitMenuNode), coord);
m_splitMenuSystem.m_splitView = m_hoverSplitDragView;
adoptRightClickMenu(std::make_unique<Specter::Menu>(*m_viewRes, *this, &m_splitMenuSystem), coord);
}
return;
}
@ -84,8 +237,19 @@ void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton butto
v->mouseDown(coord, button, mods);
}
void RootView::SplitMenuSystem::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
{
}
void RootView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
{
if (m_splitMenuSystem.m_phase != SplitMenuSystem::Phase::Inactive)
{
m_splitMenuSystem.mouseUp(coord, button, mods);
return;
}
if (m_rightClickMenu.m_view)
{
m_rightClickMenu.mouseUp(coord, button, mods);
@ -113,6 +277,11 @@ void RootView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button,
v->mouseUp(coord, button, mods);
}
void RootView::SplitMenuSystem::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
{
}
SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCoord& coord) const
{
if (sv->testSplitHover(coord))
@ -132,6 +301,12 @@ SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCo
void RootView::mouseMove(const boo::SWindowCoord& coord)
{
if (m_splitMenuSystem.m_phase != SplitMenuSystem::Phase::Inactive)
{
m_splitMenuSystem.mouseMove(coord);
return;
}
if (m_rightClickMenu.m_view)
{
m_hSplitHover = false;
@ -209,6 +384,24 @@ void RootView::mouseMove(const boo::SWindowCoord& coord)
}
}
void RootView::SplitMenuSystem::mouseMove(const boo::SWindowCoord& coord)
{
if (m_phase == Phase::InteractiveJoin)
{
boo::SWindowRect rect;
SplitView::ArrowDir arrow;
if (m_splitView->testJoinArrowHover(coord, m_interactiveSlot, rect, arrow))
setArrowVerts(rect, arrow);
}
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);
}
}
void RootView::mouseEnter(const boo::SWindowCoord& coord)
{
for (View* v : m_views)
@ -217,6 +410,12 @@ void RootView::mouseEnter(const boo::SWindowCoord& coord)
void RootView::mouseLeave(const boo::SWindowCoord& coord)
{
if (m_splitMenuSystem.m_phase != SplitMenuSystem::Phase::Inactive)
{
m_splitMenuSystem.mouseLeave(coord);
return;
}
if (m_rightClickMenu.m_view)
{
m_rightClickMenu.mouseLeave(coord);
@ -234,6 +433,11 @@ void RootView::mouseLeave(const boo::SWindowCoord& coord)
v->mouseLeave(coord);
}
void RootView::SplitMenuSystem::mouseLeave(const boo::SWindowCoord& coord)
{
}
void RootView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll)
{
if (m_activeMenuButton)
@ -294,6 +498,8 @@ void RootView::specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool
m_window->setFullscreen(!m_window->isFullscreen());
return;
}
if (key == boo::ESpecialKey::Esc && m_splitMenuSystem.m_phase != SplitMenuSystem::Phase::Inactive)
m_splitMenuSystem.cancelAction();
for (View* v : m_views)
v->specialKeyDown(key, mods, isRepeat);
if (m_activeTextView)
@ -333,6 +539,28 @@ void RootView::displayTooltip(const std::string& name, const std::string& help)
{
}
void RootView::internalThink()
{
if (m_splitMenuSystem.m_deferredSplit)
{
m_splitMenuSystem.m_deferredSplit = false;
m_rightClickMenu.m_view.reset();
m_splitMenuSystem.beginSplit();
m_splitMenuSystem.mouseMove(m_splitMenuSystem.m_deferredCoord);
}
if (m_splitMenuSystem.m_deferredJoin)
{
m_splitMenuSystem.m_deferredJoin = false;
m_rightClickMenu.m_view.reset();
m_splitMenuSystem.beginJoin();
m_splitMenuSystem.mouseMove(m_splitMenuSystem.m_deferredCoord);
}
if (m_rightClickMenu.m_view)
m_rightClickMenu.m_view->think();
}
void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
{
if (m_resizeRTDirty)
@ -349,9 +577,22 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
v->draw(gfxQ);
if (m_tooltip)
m_tooltip->draw(gfxQ);
m_splitMenuSystem.draw(gfxQ);
if (m_rightClickMenu.m_view)
m_rightClickMenu.m_view->draw(gfxQ);
gfxQ->resolveDisplay(m_renderTex);
}
void RootView::SplitMenuSystem::draw(boo::IGraphicsCommandQueue* gfxQ)
{
if (m_phase == Phase::Inactive || !m_draw)
return;
gfxQ->setShaderDataBinding(m_vertsBinding);
gfxQ->setDrawPrimitive(boo::Primitive::TriStrips);
if (m_phase == Phase::InteractiveJoin)
gfxQ->draw(0, 28);
else
gfxQ->draw(28, 4);
}
}

View File

@ -99,6 +99,281 @@ bool SplitView::testSplitHover(const boo::SWindowCoord& coord)
return false;
}
bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& slotOut, boo::SWindowRect& rectOut, ArrowDir& dirOut)
{
if (!subRect().coordInRect(coord))
return false;
if (m_axis == Axis::Horizontal)
{
int slidePx = subRect().size[1] * m_slide;
if (coord.pixel[1] - subRect().location[1] - slidePx >= 0)
{
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);
}
slotOut = 1;
rectOut = subRect();
rectOut.location[1] += slidePx;
rectOut.size[1] -= slidePx;
dirOut = ArrowDir::Up;
return true;
}
else
{
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);
}
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 (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);
}
slotOut = 1;
rectOut = subRect();
rectOut.location[0] += slidePx;
rectOut.size[0] -= slidePx;
dirOut = ArrowDir::Right;
return true;
}
else
{
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);
}
slotOut = 0;
rectOut = subRect();
rectOut.size[0] = slidePx;
dirOut = ArrowDir::Left;
return true;
}
}
}
void SplitView::getJoinArrowHover(int slot, boo::SWindowRect& rectOut, ArrowDir& dirOut)
{
if (m_axis == Axis::Horizontal)
{
int slidePx = subRect().size[1] * m_slide;
if (slot == 1)
{
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->getJoinArrowHover(0, rectOut, dirOut);
}
rectOut = subRect();
rectOut.location[1] += slidePx;
rectOut.size[1] -= slidePx;
dirOut = ArrowDir::Up;
}
else
{
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->getJoinArrowHover(1, rectOut, dirOut);
}
rectOut = subRect();
rectOut.size[1] = slidePx;
dirOut = ArrowDir::Down;
}
}
else
{
int slidePx = subRect().size[0] * m_slide;
if (slot == 1)
{
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->getJoinArrowHover(0, rectOut, dirOut);
}
rectOut = subRect();
rectOut.location[0] += slidePx;
rectOut.size[0] -= slidePx;
dirOut = ArrowDir::Right;
}
else
{
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->getJoinArrowHover(1, rectOut, dirOut);
}
rectOut = subRect();
rectOut.size[0] = slidePx;
dirOut = ArrowDir::Left;
}
}
}
bool SplitView::testSplitLineHover(const boo::SWindowCoord& coord, int& slotOut,
boo::SWindowRect& rectOut, float& splitOut, Axis& axisOut)
{
if (!subRect().coordInRect(coord))
return false;
if (m_axis == Axis::Horizontal)
{
int slidePx = subRect().size[1] * m_slide;
if (coord.pixel[1] - subRect().location[1] - slidePx >= 0)
{
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->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut);
}
slotOut = 1;
rectOut = subRect();
rectOut.location[1] += slidePx;
rectOut.size[1] -= slidePx;
splitOut = (coord.pixel[0] - rectOut.location[0]) / float(rectOut.size[0]);
axisOut = Axis::Vertical;
return true;
}
else
{
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->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut);
}
slotOut = 0;
rectOut = subRect();
rectOut.size[1] = slidePx;
splitOut = (coord.pixel[0] - rectOut.location[0]) / float(rectOut.size[0]);
axisOut = Axis::Vertical;
return true;
}
}
else
{
int slidePx = subRect().size[0] * m_slide;
if (coord.pixel[0] - subRect().location[0] - slidePx >= 0)
{
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->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut);
}
slotOut = 1;
rectOut = subRect();
rectOut.location[0] += slidePx;
rectOut.size[0] -= slidePx;
splitOut = (coord.pixel[1] - rectOut.location[1]) / float(rectOut.size[1]);
axisOut = Axis::Horizontal;
return true;
}
else
{
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->testSplitLineHover(coord, slotOut, rectOut, splitOut, axisOut);
}
slotOut = 0;
rectOut = subRect();
rectOut.size[0] = slidePx;
splitOut = (coord.pixel[1] - rectOut.location[1]) / float(rectOut.size[1]);
axisOut = Axis::Horizontal;
return true;
}
}
}
void SplitView::getSplitLineHover(int slot, boo::SWindowRect& rectOut, Axis& axisOut)
{
if (m_axis == Axis::Horizontal)
{
int slidePx = subRect().size[1] * m_slide;
if (slot == 1)
{
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->getSplitLineHover(0, rectOut, axisOut);
}
rectOut = subRect();
rectOut.location[1] += slidePx;
rectOut.size[1] -= slidePx;
axisOut = Axis::Vertical;
}
else
{
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->getSplitLineHover(1, rectOut, axisOut);
}
rectOut = subRect();
rectOut.size[1] = slidePx;
axisOut = Axis::Vertical;
}
}
else
{
int slidePx = subRect().size[0] * m_slide;
if (slot == 1)
{
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->getSplitLineHover(0, rectOut, axisOut);
}
rectOut = subRect();
rectOut.location[0] += slidePx;
rectOut.size[0] -= slidePx;
axisOut = Axis::Horizontal;
}
else
{
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->getSplitLineHover(1, rectOut, axisOut);
}
rectOut = subRect();
rectOut.size[0] = slidePx;
axisOut = Axis::Horizontal;
}
}
}
void SplitView::startDragSplit(const boo::SWindowCoord& coord)
{
m_dragging = true;