2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-03 07:55:52 +00:00

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; DeferredWindowEvents<RootView> m_events;
struct SplitMenuNode : IMenuNode struct SplitMenuSystem : IMenuNode
{ {
RootView& m_rv; RootView& m_rv;
std::string m_text; std::string m_text;
SplitView* m_splitView = nullptr; SplitView* m_splitView = nullptr;
SplitMenuNode(RootView& rv) enum class Phase
: m_rv(rv), m_text(rv.m_viewMan.translateOr("boundary_action", "Boundary Action")), {
m_splitActionNode(*this), m_joinActionNode(*this) {} 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;} const std::string* text() const {return &m_text;}
size_t subNodeCount() const {return 2;} size_t subNodeCount() const {return 2;}
IMenuNode* subNode(size_t idx) IMenuNode* subNode(size_t idx)
@ -56,29 +80,39 @@ class RootView : public View
return &m_splitActionNode; return &m_splitActionNode;
} }
boo::SWindowCoord m_deferredCoord;
bool m_deferredSplit = false;
bool m_deferredJoin = false;
void beginSplit();
void beginJoin();
void cancelAction();
struct SplitActionNode : IMenuNode struct SplitActionNode : IMenuNode
{ {
SplitMenuNode& m_smn; SplitMenuSystem& m_smn;
std::string m_text; std::string m_text;
SplitActionNode(SplitMenuNode& smn) SplitActionNode(SplitMenuSystem& smn);
: m_smn(smn), m_text(smn.m_rv.m_viewMan.translateOr("split", "Split")) {}
const std::string* text() const {return &m_text;} const std::string* text() const {return &m_text;}
void activated(const boo::SWindowCoord& coord) void activated(const boo::SWindowCoord& coord)
{ {
m_smn.m_deferredSplit = true;
m_smn.m_deferredCoord = coord;
} }
} m_splitActionNode; } m_splitActionNode;
struct JoinActionNode : IMenuNode struct JoinActionNode : IMenuNode
{ {
SplitMenuNode& m_smn; SplitMenuSystem& m_smn;
std::string m_text; std::string m_text;
JoinActionNode(SplitMenuNode& smn) JoinActionNode(SplitMenuSystem& smn);
: m_smn(smn), m_text(smn.m_rv.m_viewMan.translateOr("join", "Join")) {}
const std::string* text() const {return &m_text;} const std::string* text() const {return &m_text;}
void activated(const boo::SWindowCoord& coord) void activated(const boo::SWindowCoord& coord)
{ {
m_smn.m_deferredJoin = true;
m_smn.m_deferredCoord = coord;
} }
} m_joinActionNode; } m_joinActionNode;
} m_splitMenuNode; } m_splitMenuSystem;
public: public:
RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window); RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window);
@ -106,6 +140,7 @@ public:
void modKeyUp(boo::EModifierKey mod); void modKeyUp(boo::EModifierKey mod);
boo::ITextInputCallback* getTextInputCallback() {return m_activeTextView;} boo::ITextInputCallback* getTextInputCallback() {return m_activeTextView;}
void internalThink();
void dispatchEvents() {m_events.dispatchEvents();} void dispatchEvents() {m_events.dispatchEvents();}
void draw(boo::IGraphicsCommandQueue* gfxQ); void draw(boo::IGraphicsCommandQueue* gfxQ);
const boo::SWindowRect& rootRect() const {return m_rootRect;} const boo::SWindowRect& rootRect() const {return m_rootRect;}

View File

@ -20,6 +20,14 @@ public:
void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme); void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme);
}; };
enum class ArrowDir
{
Up,
Down,
Left,
Right
};
enum class Axis enum class Axis
{ {
Horizontal, Horizontal,
@ -74,6 +82,10 @@ public:
Axis axis() const {return m_axis;} Axis axis() const {return m_axis;}
float split() const {return m_slide;} float split() const {return m_slide;}
bool testSplitHover(const boo::SWindowCoord& coord); 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 startDragSplit(const boo::SWindowCoord& coord);
void endDragSplit(); void endDragSplit();
void moveDragSplit(const boo::SWindowCoord& coord); 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) RootView::RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window)
: View(res), m_window(window), m_viewMan(viewMan), m_viewRes(&res), m_events(*this), : View(res), m_window(window), m_viewMan(viewMan), m_viewRes(&res), m_events(*this),
m_splitMenuNode(*this) m_splitMenuSystem(*this)
{ {
window->setCallback(&m_events); window->setCallback(&m_events);
boo::SWindowRect rect = window->getWindowFrame(); boo::SWindowRect rect = window->getWindowFrame();
@ -18,6 +18,134 @@ RootView::RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* wind
resized(rect, rect); 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() void RootView::destroyed()
{ {
m_destroyed = true; m_destroyed = true;
@ -43,11 +171,36 @@ void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&)
m_rightClickMenuRootAndLoc.location[1] *= hr; m_rightClickMenuRootAndLoc.location[1] *= hr;
m_rightClickMenu.m_view->resized(root, m_rightClickMenuRootAndLoc); m_rightClickMenu.m_view->resized(root, m_rightClickMenuRootAndLoc);
} }
m_splitMenuSystem.resized();
m_resizeRTDirty = true; 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) 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.m_view)
{ {
if (!m_rightClickMenu.mouseDown(coord, button, mods)) 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) else if (button == boo::EMouseButton::Secondary)
{ {
m_splitMenuNode.m_splitView = m_hoverSplitDragView; m_splitMenuSystem.m_splitView = m_hoverSplitDragView;
adoptRightClickMenu(std::make_unique<Specter::Menu>(*m_viewRes, *this, &m_splitMenuNode), coord); adoptRightClickMenu(std::make_unique<Specter::Menu>(*m_viewRes, *this, &m_splitMenuSystem), coord);
} }
return; return;
} }
@ -84,8 +237,19 @@ void RootView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton butto
v->mouseDown(coord, button, mods); 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) 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) if (m_rightClickMenu.m_view)
{ {
m_rightClickMenu.mouseUp(coord, button, mods); 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); 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 SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCoord& coord) const
{ {
if (sv->testSplitHover(coord)) if (sv->testSplitHover(coord))
@ -132,6 +301,12 @@ SplitView* RootView::recursiveTestSplitHover(SplitView* sv, const boo::SWindowCo
void RootView::mouseMove(const boo::SWindowCoord& coord) 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) if (m_rightClickMenu.m_view)
{ {
m_hSplitHover = false; 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) void RootView::mouseEnter(const boo::SWindowCoord& coord)
{ {
for (View* v : m_views) for (View* v : m_views)
@ -217,6 +410,12 @@ void RootView::mouseEnter(const boo::SWindowCoord& coord)
void RootView::mouseLeave(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) if (m_rightClickMenu.m_view)
{ {
m_rightClickMenu.mouseLeave(coord); m_rightClickMenu.mouseLeave(coord);
@ -234,6 +433,11 @@ void RootView::mouseLeave(const boo::SWindowCoord& coord)
v->mouseLeave(coord); v->mouseLeave(coord);
} }
void RootView::SplitMenuSystem::mouseLeave(const boo::SWindowCoord& coord)
{
}
void RootView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) void RootView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll)
{ {
if (m_activeMenuButton) if (m_activeMenuButton)
@ -294,6 +498,8 @@ void RootView::specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool
m_window->setFullscreen(!m_window->isFullscreen()); m_window->setFullscreen(!m_window->isFullscreen());
return; return;
} }
if (key == boo::ESpecialKey::Esc && m_splitMenuSystem.m_phase != SplitMenuSystem::Phase::Inactive)
m_splitMenuSystem.cancelAction();
for (View* v : m_views) for (View* v : m_views)
v->specialKeyDown(key, mods, isRepeat); v->specialKeyDown(key, mods, isRepeat);
if (m_activeTextView) 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) void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
{ {
if (m_resizeRTDirty) if (m_resizeRTDirty)
@ -349,9 +577,22 @@ void RootView::draw(boo::IGraphicsCommandQueue* gfxQ)
v->draw(gfxQ); v->draw(gfxQ);
if (m_tooltip) if (m_tooltip)
m_tooltip->draw(gfxQ); m_tooltip->draw(gfxQ);
m_splitMenuSystem.draw(gfxQ);
if (m_rightClickMenu.m_view) if (m_rightClickMenu.m_view)
m_rightClickMenu.m_view->draw(gfxQ); m_rightClickMenu.m_view->draw(gfxQ);
gfxQ->resolveDisplay(m_renderTex); 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; 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) void SplitView::startDragSplit(const boo::SWindowCoord& coord)
{ {
m_dragging = true; m_dragging = true;