2015-11-21 01:14:49 +00:00
|
|
|
#ifndef SPECTER_ROOTVIEW_HPP
|
|
|
|
#define SPECTER_ROOTVIEW_HPP
|
|
|
|
|
|
|
|
#include "View.hpp"
|
2015-12-05 00:42:46 +00:00
|
|
|
#include "ViewResources.hpp"
|
2015-11-29 02:55:30 +00:00
|
|
|
#include "MultiLineTextView.hpp"
|
2015-12-20 04:39:09 +00:00
|
|
|
#include "TextField.hpp"
|
2015-12-02 01:32:15 +00:00
|
|
|
#include "SplitView.hpp"
|
2015-12-07 00:52:07 +00:00
|
|
|
#include "Tooltip.hpp"
|
2015-11-22 04:32:12 +00:00
|
|
|
#include "FontCache.hpp"
|
2016-01-29 04:30:04 +00:00
|
|
|
#include "IMenuNode.hpp"
|
2015-12-01 00:35:45 +00:00
|
|
|
#include "DeferredWindowEvents.hpp"
|
2015-12-31 03:19:03 +00:00
|
|
|
#include "IViewManager.hpp"
|
2015-11-21 01:14:49 +00:00
|
|
|
#include <boo/boo.hpp>
|
|
|
|
|
|
|
|
namespace Specter
|
|
|
|
{
|
|
|
|
|
2015-12-01 00:35:45 +00:00
|
|
|
class RootView : public View
|
2015-11-21 01:14:49 +00:00
|
|
|
{
|
2015-11-21 23:45:02 +00:00
|
|
|
boo::IWindow* m_window = nullptr;
|
2015-11-26 07:35:43 +00:00
|
|
|
boo::ITextureR* m_renderTex = nullptr;
|
2015-12-01 00:35:45 +00:00
|
|
|
boo::SWindowRect m_rootRect = {};
|
2015-11-26 07:35:43 +00:00
|
|
|
bool m_resizeRTDirty = false;
|
2015-11-26 23:03:56 +00:00
|
|
|
bool m_destroyed = false;
|
2015-12-06 01:24:51 +00:00
|
|
|
IViewManager& m_viewMan;
|
2015-12-05 00:42:46 +00:00
|
|
|
ViewResources* m_viewRes;
|
2015-12-27 22:42:45 +00:00
|
|
|
ITextInputView* m_activeTextView = nullptr;
|
2015-12-20 21:59:23 +00:00
|
|
|
View* m_activeDragView = nullptr;
|
2016-01-15 23:32:14 +00:00
|
|
|
Button* m_activeMenuButton = nullptr;
|
2015-11-21 23:45:02 +00:00
|
|
|
|
2016-01-28 23:55:19 +00:00
|
|
|
ViewChild<std::unique_ptr<View>> m_rightClickMenu;
|
2016-01-29 04:30:04 +00:00
|
|
|
boo::SWindowRect m_rightClickMenuRootAndLoc;
|
2016-01-28 23:55:19 +00:00
|
|
|
|
2016-01-12 00:44:54 +00:00
|
|
|
SplitView* m_hoverSplitDragView = nullptr;
|
|
|
|
bool m_activeSplitDragView = false;
|
|
|
|
SplitView* recursiveTestSplitHover(SplitView* sv, const boo::SWindowCoord& coord) const;
|
|
|
|
|
2015-12-01 00:35:45 +00:00
|
|
|
DeferredWindowEvents<RootView> m_events;
|
|
|
|
|
2016-01-31 01:07:52 +00:00
|
|
|
struct SplitMenuSystem : IMenuNode
|
2016-01-29 04:30:04 +00:00
|
|
|
{
|
|
|
|
RootView& m_rv;
|
|
|
|
std::string m_text;
|
2016-01-31 01:07:52 +00:00
|
|
|
|
2016-01-29 04:30:04 +00:00
|
|
|
SplitView* m_splitView = nullptr;
|
2016-01-31 01:07:52 +00:00
|
|
|
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);
|
2016-01-29 04:30:04 +00:00
|
|
|
const std::string* text() const {return &m_text;}
|
|
|
|
size_t subNodeCount() const {return 2;}
|
|
|
|
IMenuNode* subNode(size_t idx)
|
|
|
|
{
|
|
|
|
if (idx)
|
|
|
|
return &m_joinActionNode;
|
|
|
|
else
|
|
|
|
return &m_splitActionNode;
|
|
|
|
}
|
|
|
|
|
2016-01-31 01:07:52 +00:00
|
|
|
boo::SWindowCoord m_deferredCoord;
|
|
|
|
bool m_deferredSplit = false;
|
|
|
|
bool m_deferredJoin = false;
|
|
|
|
|
|
|
|
void beginSplit();
|
|
|
|
void beginJoin();
|
|
|
|
void cancelAction();
|
|
|
|
|
2016-01-29 04:30:04 +00:00
|
|
|
struct SplitActionNode : IMenuNode
|
|
|
|
{
|
2016-01-31 01:07:52 +00:00
|
|
|
SplitMenuSystem& m_smn;
|
2016-01-29 04:30:04 +00:00
|
|
|
std::string m_text;
|
2016-01-31 01:07:52 +00:00
|
|
|
SplitActionNode(SplitMenuSystem& smn);
|
2016-01-29 04:30:04 +00:00
|
|
|
const std::string* text() const {return &m_text;}
|
|
|
|
void activated(const boo::SWindowCoord& coord)
|
|
|
|
{
|
2016-01-31 01:07:52 +00:00
|
|
|
m_smn.m_deferredSplit = true;
|
|
|
|
m_smn.m_deferredCoord = coord;
|
2016-01-29 04:30:04 +00:00
|
|
|
}
|
|
|
|
} m_splitActionNode;
|
|
|
|
struct JoinActionNode : IMenuNode
|
|
|
|
{
|
2016-01-31 01:07:52 +00:00
|
|
|
SplitMenuSystem& m_smn;
|
2016-01-29 04:30:04 +00:00
|
|
|
std::string m_text;
|
2016-01-31 01:07:52 +00:00
|
|
|
JoinActionNode(SplitMenuSystem& smn);
|
2016-01-29 04:30:04 +00:00
|
|
|
const std::string* text() const {return &m_text;}
|
|
|
|
void activated(const boo::SWindowCoord& coord)
|
|
|
|
{
|
2016-01-31 01:07:52 +00:00
|
|
|
m_smn.m_deferredJoin = true;
|
|
|
|
m_smn.m_deferredCoord = coord;
|
2016-01-29 04:30:04 +00:00
|
|
|
}
|
|
|
|
} m_joinActionNode;
|
2016-01-31 01:07:52 +00:00
|
|
|
} m_splitMenuSystem;
|
2016-01-29 04:30:04 +00:00
|
|
|
|
2015-11-26 07:35:43 +00:00
|
|
|
public:
|
2015-12-06 01:24:51 +00:00
|
|
|
RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window);
|
2015-11-30 00:21:42 +00:00
|
|
|
|
2015-11-26 23:03:56 +00:00
|
|
|
void destroyed();
|
|
|
|
bool isDestroyed() const {return m_destroyed;}
|
|
|
|
|
2015-12-05 00:42:46 +00:00
|
|
|
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
2015-11-21 01:14:49 +00:00
|
|
|
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 mouseEnter(const boo::SWindowCoord& coord);
|
|
|
|
void mouseLeave(const boo::SWindowCoord& coord);
|
|
|
|
void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll);
|
|
|
|
|
|
|
|
void touchDown(const boo::STouchCoord& coord, uintptr_t tid);
|
|
|
|
void touchUp(const boo::STouchCoord& coord, uintptr_t tid);
|
|
|
|
void touchMove(const boo::STouchCoord& coord, uintptr_t tid);
|
|
|
|
|
|
|
|
void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat);
|
|
|
|
void charKeyUp(unsigned long charCode, boo::EModifierKey mods);
|
|
|
|
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat);
|
|
|
|
void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods);
|
|
|
|
void modKeyDown(boo::EModifierKey mod, bool isRepeat);
|
|
|
|
void modKeyUp(boo::EModifierKey mod);
|
2015-12-27 22:42:45 +00:00
|
|
|
boo::ITextInputCallback* getTextInputCallback() {return m_activeTextView;}
|
2015-11-21 23:45:02 +00:00
|
|
|
|
2016-01-31 01:07:52 +00:00
|
|
|
void internalThink();
|
2015-12-01 00:35:45 +00:00
|
|
|
void dispatchEvents() {m_events.dispatchEvents();}
|
2015-11-21 23:45:02 +00:00
|
|
|
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
2015-11-30 00:21:42 +00:00
|
|
|
const boo::SWindowRect& rootRect() const {return m_rootRect;}
|
2015-11-22 04:32:12 +00:00
|
|
|
|
2015-11-30 00:21:42 +00:00
|
|
|
boo::IWindow* window() const {return m_window;}
|
2015-12-06 01:24:51 +00:00
|
|
|
IViewManager& viewManager() const {return m_viewMan;}
|
2015-12-08 04:26:29 +00:00
|
|
|
ViewResources& viewRes() const {return *m_viewRes;}
|
2016-01-10 06:40:23 +00:00
|
|
|
const IThemeData& themeData() const {return *m_viewRes->m_theme;}
|
2015-11-29 02:55:30 +00:00
|
|
|
|
2016-01-04 23:58:38 +00:00
|
|
|
std::vector<View*>& accessContentViews() {return m_views;}
|
|
|
|
|
2016-01-28 23:55:19 +00:00
|
|
|
void adoptRightClickMenu(std::unique_ptr<View>&& menu, const boo::SWindowCoord& coord)
|
|
|
|
{
|
|
|
|
m_rightClickMenu.m_view = std::move(menu);
|
2016-01-29 04:30:04 +00:00
|
|
|
m_rightClickMenuRootAndLoc = subRect();
|
|
|
|
m_rightClickMenuRootAndLoc.location[0] = coord.pixel[0];
|
|
|
|
m_rightClickMenuRootAndLoc.location[1] = coord.pixel[1];
|
|
|
|
updateSize();
|
2016-01-28 23:55:19 +00:00
|
|
|
}
|
|
|
|
View* getRightClickMenu() {return m_rightClickMenu.m_view.get();}
|
|
|
|
|
2015-12-27 22:42:45 +00:00
|
|
|
void setActiveTextView(ITextInputView* textView)
|
2015-12-20 04:39:09 +00:00
|
|
|
{
|
|
|
|
if (m_activeTextView)
|
|
|
|
m_activeTextView->setActive(false);
|
|
|
|
m_activeTextView = textView;
|
2015-12-20 21:59:23 +00:00
|
|
|
if (textView)
|
|
|
|
textView->setActive(true);
|
|
|
|
}
|
|
|
|
void setActiveDragView(View* dragView)
|
|
|
|
{
|
|
|
|
m_activeDragView = dragView;
|
2015-12-20 04:39:09 +00:00
|
|
|
}
|
2016-01-15 23:32:14 +00:00
|
|
|
void setActiveMenuButton(Button* button)
|
|
|
|
{
|
|
|
|
m_activeMenuButton = button;
|
|
|
|
}
|
|
|
|
void unsetActiveMenuButton(Button* button)
|
|
|
|
{
|
|
|
|
if (button == m_activeMenuButton)
|
|
|
|
m_activeMenuButton = nullptr;
|
|
|
|
}
|
2015-12-06 01:24:51 +00:00
|
|
|
|
2016-01-12 00:44:54 +00:00
|
|
|
void startSplitDrag(SplitView* sv, const boo::SWindowCoord& coord)
|
|
|
|
{
|
|
|
|
m_hoverSplitDragView = sv;
|
|
|
|
m_activeSplitDragView = true;
|
|
|
|
sv->startDragSplit(coord);
|
|
|
|
}
|
|
|
|
|
2015-12-22 01:33:27 +00:00
|
|
|
bool m_hSplitHover = false;
|
|
|
|
void setHorizontalSplitHover(bool hover)
|
|
|
|
{
|
|
|
|
m_hSplitHover = hover;
|
|
|
|
_updateCursor();
|
|
|
|
}
|
|
|
|
bool m_vSplitHover = false;
|
|
|
|
void setVerticalSplitHover(bool hover)
|
|
|
|
{
|
|
|
|
m_vSplitHover = hover;
|
|
|
|
_updateCursor();
|
|
|
|
}
|
|
|
|
bool m_textFieldHover = false;
|
|
|
|
void setTextFieldHover(bool hover)
|
|
|
|
{
|
|
|
|
m_textFieldHover = hover;
|
|
|
|
_updateCursor();
|
|
|
|
}
|
2016-01-10 06:40:23 +00:00
|
|
|
bool m_spaceCornerHover = false;
|
|
|
|
void setSpaceCornerHover(bool hover)
|
|
|
|
{
|
|
|
|
m_spaceCornerHover = hover;
|
|
|
|
_updateCursor();
|
|
|
|
}
|
2015-12-22 01:33:27 +00:00
|
|
|
|
2015-12-13 02:26:41 +00:00
|
|
|
void resetTooltip(ViewResources& res);
|
2015-12-06 01:24:51 +00:00
|
|
|
void displayTooltip(const std::string& name, const std::string& help);
|
|
|
|
|
2016-01-15 23:32:14 +00:00
|
|
|
private:
|
2015-12-22 01:33:27 +00:00
|
|
|
void _updateCursor()
|
|
|
|
{
|
2016-01-10 06:40:23 +00:00
|
|
|
if (m_spaceCornerHover)
|
|
|
|
m_window->setCursor(boo::EMouseCursor::Crosshairs);
|
|
|
|
else if (m_vSplitHover)
|
2015-12-22 01:33:27 +00:00
|
|
|
m_window->setCursor(boo::EMouseCursor::HorizontalArrow);
|
|
|
|
else if (m_hSplitHover)
|
|
|
|
m_window->setCursor(boo::EMouseCursor::VerticalArrow);
|
|
|
|
else if (m_textFieldHover)
|
|
|
|
m_window->setCursor(boo::EMouseCursor::IBeam);
|
|
|
|
else
|
|
|
|
m_window->setCursor(boo::EMouseCursor::Pointer);
|
|
|
|
}
|
|
|
|
|
2016-01-04 23:58:38 +00:00
|
|
|
std::vector<View*> m_views;
|
2015-12-07 00:52:07 +00:00
|
|
|
std::unique_ptr<Tooltip> m_tooltip;
|
2015-11-21 01:14:49 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // SPECTER_ROOTVIEW_HPP
|