mirror of https://github.com/AxioDL/metaforce.git
585 lines
20 KiB
C++
585 lines
20 KiB
C++
#include "specter/RootView.hpp"
|
|
|
|
#include "specter/Button.hpp"
|
|
#include "specter/Control.hpp"
|
|
#include "specter/IViewManager.hpp"
|
|
#include "specter/Menu.hpp"
|
|
#include "specter/Space.hpp"
|
|
#include "specter/Tooltip.hpp"
|
|
#include "specter/ViewResources.hpp"
|
|
|
|
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
|
|
|
namespace specter {
|
|
|
|
RootView::RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window)
|
|
: View(res), m_window(window), m_viewMan(viewMan), m_viewRes(&res), m_events(*this) {
|
|
window->setCallback(&m_events);
|
|
boo::SWindowRect rect = window->getWindowFrame();
|
|
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) {
|
|
buildResources(ctx, res);
|
|
m_splitMenuSystem.emplace(*this, ctx);
|
|
m_renderTex = ctx.newRenderTexture(rect.size[0], rect.size[1], boo::TextureClampMode::ClampToEdge, 3, 3);
|
|
return true;
|
|
});
|
|
resized(rect, rect);
|
|
}
|
|
|
|
RootView::~RootView() { m_window->setCallback(nullptr); }
|
|
|
|
RootView::SplitMenuSystem::SplitMenuSystem(RootView& rv, boo::IGraphicsDataFactory::Context& ctx)
|
|
: m_rv(rv)
|
|
, m_text(rv.m_viewMan.translate<locale::boundary_action>())
|
|
, m_splitActionNode(*this)
|
|
, m_joinActionNode(*this) {
|
|
ViewResources& res = *rv.m_viewRes;
|
|
m_viewVertBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
|
m_vertsBinding.init(ctx, res, 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<decltype(m_verts)>(m_verts);
|
|
}
|
|
|
|
RootView::SplitMenuSystem::SplitActionNode::SplitActionNode(SplitMenuSystem& smn)
|
|
: m_smn(smn), m_text(smn.m_rv.m_viewMan.translate<locale::split>()) {}
|
|
|
|
RootView::SplitMenuSystem::JoinActionNode::JoinActionNode(SplitMenuSystem& smn)
|
|
: m_smn(smn), m_text(smn.m_rv.m_viewMan.translate<locale::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.access().finalAssign(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.access().finalAssign(m_viewBlock);
|
|
}
|
|
|
|
void RootView::destroyed() { m_destroyed = true; }
|
|
|
|
void RootView::resized(const boo::SWindowRect& root, const boo::SWindowRect&) {
|
|
m_rootRect = root;
|
|
m_rootRect.location[0] = 0;
|
|
m_rootRect.location[1] = 0;
|
|
View::resized(m_rootRect, m_rootRect);
|
|
for (View* v : m_views)
|
|
v->resized(m_rootRect, m_rootRect);
|
|
if (m_tooltip)
|
|
m_tooltip->resized(m_rootRect, m_rootRect);
|
|
if (m_rightClickMenu.m_view) {
|
|
float wr = root.size[0] / float(m_rightClickMenuRootAndLoc.size[0]);
|
|
float hr = root.size[1] / float(m_rightClickMenuRootAndLoc.size[1]);
|
|
m_rightClickMenuRootAndLoc.size[0] = root.size[0];
|
|
m_rightClickMenuRootAndLoc.size[1] = root.size[1];
|
|
m_rightClickMenuRootAndLoc.location[0] *= wr;
|
|
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))
|
|
m_rightClickMenu.m_view.reset();
|
|
return;
|
|
}
|
|
|
|
if (m_activeMenuButton) {
|
|
ViewChild<std::unique_ptr<View>>& mv = m_activeMenuButton->getMenu();
|
|
if (!mv.mouseDown(coord, button, mods))
|
|
m_activeMenuButton->closeMenu(coord);
|
|
return;
|
|
}
|
|
|
|
if (m_hoverSplitDragView) {
|
|
if (button == boo::EMouseButton::Primary) {
|
|
m_activeSplitDragView = true;
|
|
m_hoverSplitDragView->startDragSplit(coord);
|
|
} else if (button == boo::EMouseButton::Secondary) {
|
|
m_splitMenuSystem->m_splitView = m_hoverSplitDragView;
|
|
adoptRightClickMenu(std::make_unique<specter::Menu>(*m_viewRes, *this, &*m_splitMenuSystem), coord);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (m_activeTextView && !m_activeTextView->subRect().coordInRect(coord))
|
|
setActiveTextView(nullptr);
|
|
for (View* v : m_views)
|
|
v->mouseDown(coord, button, mods);
|
|
}
|
|
|
|
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) {
|
|
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);
|
|
return;
|
|
}
|
|
|
|
if (m_activeMenuButton) {
|
|
ViewChild<std::unique_ptr<View>>& mv = m_activeMenuButton->getMenu();
|
|
mv.mouseUp(coord, button, mods);
|
|
return;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
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 = m_splitView->m_views[m_interactiveSlot].m_view->castToSpace();
|
|
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 {
|
|
if (sv->testSplitHover(coord))
|
|
return sv;
|
|
for (int i = 0; i < 2; ++i) {
|
|
SplitView* child = sv->m_views[i].m_view->castToSplitView();
|
|
if (child) {
|
|
SplitView* res = recursiveTestSplitHover(child, coord);
|
|
if (res)
|
|
return res;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
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;
|
|
m_vSplitHover = false;
|
|
_updateCursor();
|
|
m_rightClickMenu.mouseMove(coord);
|
|
return;
|
|
}
|
|
|
|
if (m_activeMenuButton) {
|
|
m_hSplitHover = false;
|
|
m_vSplitHover = false;
|
|
_updateCursor();
|
|
ViewChild<std::unique_ptr<View>>& mv = m_activeMenuButton->getMenu();
|
|
mv.mouseMove(coord);
|
|
return;
|
|
}
|
|
|
|
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 = v->castToSplitView();
|
|
if (sv)
|
|
sv = recursiveTestSplitHover(sv, coord);
|
|
if (sv) {
|
|
m_hoverSplitDragView = sv;
|
|
break;
|
|
} else {
|
|
m_hSplitHover = false;
|
|
m_vSplitHover = false;
|
|
_updateCursor();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m_activeDragView)
|
|
m_activeDragView->mouseMove(coord);
|
|
else {
|
|
for (View* v : m_views)
|
|
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];
|
|
if (m_tooltip) {
|
|
if (coord.pixel[0] + m_tooltip->nominalWidth() > m_rootRect.size[0])
|
|
ttrect.location[0] -= m_tooltip->nominalWidth();
|
|
if (coord.pixel[1] + m_tooltip->nominalHeight() > m_rootRect.size[1])
|
|
ttrect.location[1] -= m_tooltip->nominalHeight();
|
|
m_tooltip->resized(m_rootRect, ttrect);
|
|
}
|
|
}
|
|
|
|
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, origDummy, selSplit, 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)
|
|
v->mouseEnter(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);
|
|
return;
|
|
}
|
|
|
|
if (m_activeMenuButton) {
|
|
ViewChild<std::unique_ptr<View>>& mv = m_activeMenuButton->getMenu();
|
|
mv.mouseLeave(coord);
|
|
return;
|
|
}
|
|
|
|
for (View* v : m_views)
|
|
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) {
|
|
ViewChild<std::unique_ptr<View>>& mv = m_activeMenuButton->getMenu();
|
|
mv.scroll(coord, scroll);
|
|
return;
|
|
}
|
|
|
|
for (View* v : m_views)
|
|
v->scroll(coord, scroll);
|
|
}
|
|
|
|
void RootView::touchDown(const boo::STouchCoord& coord, uintptr_t tid) {
|
|
for (View* v : m_views)
|
|
v->touchDown(coord, tid);
|
|
}
|
|
|
|
void RootView::touchUp(const boo::STouchCoord& coord, uintptr_t tid) {
|
|
for (View* v : m_views)
|
|
v->touchUp(coord, tid);
|
|
}
|
|
|
|
void RootView::touchMove(const boo::STouchCoord& coord, uintptr_t tid) {
|
|
for (View* v : m_views)
|
|
v->touchMove(coord, tid);
|
|
}
|
|
|
|
void RootView::charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat) {
|
|
for (View* v : m_views)
|
|
v->charKeyDown(charCode, mods, isRepeat);
|
|
if (m_activeTextView && True(mods & (boo::EModifierKey::Ctrl | boo::EModifierKey::Command))) {
|
|
if (charCode == 'c' || charCode == 'C')
|
|
m_activeTextView->clipboardCopy();
|
|
else if (charCode == 'x' || charCode == 'X')
|
|
m_activeTextView->clipboardCut();
|
|
else if (charCode == 'v' || charCode == 'V')
|
|
m_activeTextView->clipboardPaste();
|
|
}
|
|
}
|
|
|
|
void RootView::charKeyUp(unsigned long charCode, boo::EModifierKey mods) {
|
|
for (View* v : m_views)
|
|
v->charKeyUp(charCode, mods);
|
|
}
|
|
|
|
void RootView::specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat) {
|
|
if (key == boo::ESpecialKey::Enter && True(mods & boo::EModifierKey::Alt)) {
|
|
m_window->setFullscreen(!m_window->isFullscreen());
|
|
return;
|
|
}
|
|
if (key == boo::ESpecialKey::Esc && m_splitMenuSystem->m_phase != SplitMenuSystem::Phase::Inactive) {
|
|
m_splitMenuSystem->m_phase = SplitMenuSystem::Phase::Inactive;
|
|
return;
|
|
}
|
|
for (View* v : m_views)
|
|
v->specialKeyDown(key, mods, isRepeat);
|
|
if (m_activeTextView)
|
|
m_activeTextView->specialKeyDown(key, mods, isRepeat);
|
|
}
|
|
|
|
void RootView::specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods) {
|
|
for (View* v : m_views)
|
|
v->specialKeyUp(key, mods);
|
|
if (m_activeTextView)
|
|
m_activeTextView->specialKeyUp(key, mods);
|
|
}
|
|
|
|
void RootView::modKeyDown(boo::EModifierKey mod, bool isRepeat) {
|
|
for (View* v : m_views)
|
|
v->modKeyDown(mod, isRepeat);
|
|
if (m_activeTextView)
|
|
m_activeTextView->modKeyDown(mod, isRepeat);
|
|
}
|
|
|
|
void RootView::modKeyUp(boo::EModifierKey mod) {
|
|
for (View* v : m_views)
|
|
v->modKeyUp(mod);
|
|
if (m_activeTextView)
|
|
m_activeTextView->modKeyUp(mod);
|
|
}
|
|
|
|
boo::ITextInputCallback* RootView::getTextInputCallback() { return m_activeTextView; }
|
|
|
|
void RootView::resetTooltip(ViewResources& res) {
|
|
m_tooltip = std::make_unique<Tooltip>(
|
|
res, *this, "Test",
|
|
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi hendrerit nisl quis lobortis mattis. "
|
|
"Mauris efficitur, est a vestibulum iaculis, leo orci pellentesque nunc, non rutrum ipsum lectus "
|
|
"eget nisl. Aliquam accumsan vestibulum turpis. Duis id lacus ac lectus sollicitudin posuere vel sit "
|
|
"amet metus. Aenean nec tortor id enim efficitur accumsan vitae eu ante. Lorem ipsum dolor sit amet, "
|
|
"consectetur adipiscing elit. Fusce magna eros, lacinia a leo eget, volutpat rhoncus urna.");
|
|
}
|
|
|
|
void RootView::displayTooltip(std::string_view name, std::string_view help) {}
|
|
|
|
void RootView::internalThink() {
|
|
if (m_splitMenuSystem->m_deferredSplit) {
|
|
m_splitMenuSystem->m_deferredSplit = false;
|
|
m_rightClickMenu.m_view.reset();
|
|
m_splitMenuSystem->m_phase = SplitMenuSystem::Phase::InteractiveSplit;
|
|
m_splitMenuSystem->mouseMove(m_splitMenuSystem->m_deferredCoord);
|
|
}
|
|
|
|
if (m_splitMenuSystem->m_deferredJoin) {
|
|
m_splitMenuSystem->m_deferredJoin = false;
|
|
m_rightClickMenu.m_view.reset();
|
|
m_splitMenuSystem->m_phase = SplitMenuSystem::Phase::InteractiveJoin;
|
|
m_splitMenuSystem->mouseMove(m_splitMenuSystem->m_deferredCoord);
|
|
}
|
|
|
|
if (m_rightClickMenu.m_view)
|
|
m_rightClickMenu.m_view->think();
|
|
}
|
|
|
|
void RootView::setActiveTextView(ITextInputView* textView) {
|
|
if (m_activeTextView) {
|
|
m_activeTextView->setActive(false);
|
|
}
|
|
|
|
m_activeTextView = textView;
|
|
|
|
if (textView) {
|
|
textView->setActive(true);
|
|
}
|
|
}
|
|
|
|
void RootView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
|
if (m_resizeRTDirty) {
|
|
gfxQ->resizeRenderTexture(m_renderTex, m_rootRect.size[0], m_rootRect.size[1]);
|
|
m_resizeRTDirty = false;
|
|
gfxQ->schedulePostFrameHandler([&]() { m_events.m_resizeCv.notify_one(); });
|
|
}
|
|
m_viewRes->updateBuffers();
|
|
gfxQ->setRenderTarget(m_renderTex);
|
|
gfxQ->setViewport(m_rootRect);
|
|
gfxQ->setScissor(m_rootRect);
|
|
View::draw(gfxQ);
|
|
for (View* v : m_views)
|
|
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);
|
|
}
|
|
|
|
const IThemeData& RootView::themeData() const { return *m_viewRes->m_theme; }
|
|
|
|
void RootView::SplitMenuSystem::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
|
if (m_phase == Phase::Inactive)
|
|
return;
|
|
gfxQ->setShaderDataBinding(m_vertsBinding);
|
|
if (m_phase == Phase::InteractiveJoin)
|
|
gfxQ->draw(0, 28);
|
|
else
|
|
gfxQ->draw(28, 4);
|
|
}
|
|
|
|
} // namespace specter
|