metaforce/specter/include/Specter/View.hpp

302 lines
8.1 KiB
C++
Raw Normal View History

2015-11-21 01:14:49 +00:00
#ifndef SPECTER_VIEW_HPP
#define SPECTER_VIEW_HPP
2015-11-21 23:45:02 +00:00
#include <boo/boo.hpp>
2015-11-25 01:46:30 +00:00
#include "CVector3f.hpp"
#include "CMatrix4f.hpp"
#include "CTransform.hpp"
#include "CColor.hpp"
2015-12-02 21:11:50 +00:00
#include "HECL/CVar.hpp"
2015-11-21 23:45:02 +00:00
2015-11-26 00:24:01 +00:00
#include <boo/graphicsdev/GL.hpp>
#include <boo/graphicsdev/D3D.hpp>
#include <boo/graphicsdev/Metal.hpp>
2015-11-21 01:14:49 +00:00
namespace Specter
{
2015-12-04 01:35:01 +00:00
class ThemeData;
class ViewResources;
2015-11-29 02:55:30 +00:00
class RootView;
2015-11-21 01:14:49 +00:00
2015-12-20 04:39:09 +00:00
class RectangleConstraint
{
public:
enum class Test
{
Fixed,
Minimum,
Maximum
};
private:
int m_x, m_y;
Test m_xtest, m_ytest;
public:
RectangleConstraint(int x=-1, int y=-1, Test xtest=Test::Fixed, Test ytest=Test::Fixed)
: m_x(x), m_y(y), m_xtest(xtest), m_ytest(ytest) {}
std::pair<int,int> solve(int x, int y) const
{
std::pair<int,int> ret;
if (m_x < 0)
ret.first = x;
else
{
switch (m_xtest)
{
case Test::Fixed:
ret.first = m_x;
break;
case Test::Minimum:
ret.first = std::max(m_x, x);
break;
case Test::Maximum:
ret.first = std::min(m_x, x);
break;
}
}
if (m_y < 0)
ret.second = y;
else
{
switch (m_ytest)
{
case Test::Fixed:
ret.second = m_y;
break;
case Test::Minimum:
ret.second = std::max(m_y, y);
break;
case Test::Maximum:
ret.second = std::min(m_y, y);
break;
}
}
return ret;
}
};
2015-11-21 01:14:49 +00:00
class View
{
2015-12-05 00:42:46 +00:00
public:
struct SolidShaderVert
{
Zeus::CVector3f m_pos;
Zeus::CColor m_color = Zeus::CColor::skClear;
};
struct TexShaderVert
{
Zeus::CVector3f m_pos;
Zeus::CVector2f m_uv;
};
private:
2015-11-29 02:55:30 +00:00
RootView& m_rootView;
View& m_parentView;
boo::SWindowRect m_subRect;
2015-11-26 00:24:01 +00:00
boo::IGraphicsBufferD* m_bgVertBuf;
boo::IVertexFormat* m_bgVtxFmt = nullptr; /* OpenGL only */
boo::IShaderDataBinding* m_bgShaderBinding;
2015-12-05 00:42:46 +00:00
SolidShaderVert m_bgRect[4];
2015-12-18 03:26:10 +00:00
boo::GraphicsDataToken m_gfxData;
2015-11-26 07:35:43 +00:00
2015-11-29 02:55:30 +00:00
friend class RootView;
void buildResources(ViewResources& res);
View(ViewResources& res);
2015-11-29 02:55:30 +00:00
2015-11-26 07:35:43 +00:00
protected:
struct ViewBlock
2015-11-26 07:35:43 +00:00
{
Zeus::CMatrix4f m_mv;
Zeus::CColor m_color = Zeus::CColor::skWhite;
2015-11-26 23:03:56 +00:00
void setViewRect(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{
m_mv[0][0] = 2.0f / root.size[0];
m_mv[1][1] = 2.0f / root.size[1];
m_mv[3][0] = sub.location[0] * m_mv[0][0] - 1.0f;
m_mv[3][1] = sub.location[1] * m_mv[1][1] - 1.0f;
}
2015-11-26 07:35:43 +00:00
} m_viewVertBlock;
#define SPECTER_VIEW_VERT_BLOCK_GLSL\
"uniform SpecterViewBlock\n"\
"{\n"\
" mat4 mv;\n"\
" vec4 mulColor;\n"\
2015-11-26 07:35:43 +00:00
"};\n"
2015-11-27 22:20:22 +00:00
#define SPECTER_VIEW_VERT_BLOCK_HLSL\
"cbuffer SpecterViewBlock : register(b0)\n"\
"{\n"\
" float4x4 mv;\n"\
" float4 mulColor;\n"\
2015-11-27 22:20:22 +00:00
"};\n"
2015-11-28 04:05:27 +00:00
#define SPECTER_VIEW_VERT_BLOCK_METAL\
"struct SpecterViewBlock\n"\
"{\n"\
" float4x4 mv;\n"\
" float4 mulColor;\n"\
2015-11-28 04:05:27 +00:00
"};\n"
2015-11-26 07:35:43 +00:00
boo::IGraphicsBufferD* m_viewVertBlockBuf;
2015-11-26 00:24:01 +00:00
public:
struct Resources
2015-11-26 00:24:01 +00:00
{
boo::IShaderPipeline* m_solidShader = nullptr;
2015-11-30 00:21:42 +00:00
boo::IVertexFormat* m_solidVtxFmt = nullptr; /* Not OpenGL */
boo::IShaderPipeline* m_texShader = nullptr;
boo::IVertexFormat* m_texVtxFmt = nullptr; /* Not OpenGL */
2015-11-26 00:24:01 +00:00
2015-12-04 01:35:01 +00:00
void init(boo::GLDataFactory* factory, const ThemeData& theme);
2015-11-26 00:24:01 +00:00
#if _WIN32
2015-12-04 01:35:01 +00:00
void init(boo::ID3DDataFactory* factory, const ThemeData& theme);
2015-11-26 00:24:01 +00:00
#elif BOO_HAS_METAL
2015-12-04 01:35:01 +00:00
void init(boo::MetalDataFactory* factory, const ThemeData& theme);
2015-11-26 00:24:01 +00:00
#endif
};
2015-11-25 01:46:30 +00:00
protected:
View(ViewResources& res, View& parentView);
void commitResources(ViewResources& res);
2015-11-26 00:24:01 +00:00
2015-11-21 23:45:02 +00:00
public:
2015-11-30 00:21:42 +00:00
virtual ~View() {}
2015-11-26 23:03:56 +00:00
View() = delete;
2015-11-30 00:21:42 +00:00
View(const View& other) = delete;
View& operator=(const View& other) = delete;
2015-11-29 02:55:30 +00:00
2015-12-05 00:42:46 +00:00
View& parentView() {return m_parentView;}
RootView& rootView() {return m_rootView;}
2015-12-29 02:02:43 +00:00
const RootView& rootView() const {return m_rootView;}
2015-11-30 00:21:42 +00:00
const boo::SWindowRect& subRect() const {return m_subRect;}
2015-12-05 00:42:46 +00:00
int width() const {return m_subRect.size[0];}
int height() const {return m_subRect.size[1];}
2015-11-29 02:55:30 +00:00
void updateSize();
2015-12-05 00:42:46 +00:00
void setBackground(const Zeus::CColor& color)
{
2015-12-05 00:42:46 +00:00
for (int i=0 ; i<4 ; ++i)
m_bgRect[i].m_color = color;
m_bgVertBuf->load(&m_bgRect, sizeof(SolidShaderVert) * 4);
}
2016-01-04 23:58:38 +00:00
virtual void setMultiplyColor(const Zeus::CColor& color)
{
m_viewVertBlock.m_color = color;
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
}
2015-11-30 00:21:42 +00:00
2015-12-05 00:42:46 +00:00
virtual int nominalWidth() const {return 0;}
virtual int nominalHeight() const {return 0;}
2015-12-20 04:39:09 +00:00
virtual void setActive(bool) {}
2015-11-30 00:21:42 +00:00
virtual void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {}
virtual void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey) {}
virtual void mouseMove(const boo::SWindowCoord&) {}
2015-12-05 00:42:46 +00:00
virtual void mouseEnter(const boo::SWindowCoord&) {}
virtual void mouseLeave(const boo::SWindowCoord&) {}
2015-12-20 04:39:09 +00:00
virtual void scroll(const boo::SWindowCoord&, const boo::SScrollDelta&) {}
virtual void touchDown(const boo::STouchCoord&, uintptr_t) {}
virtual void touchUp(const boo::STouchCoord&, uintptr_t) {}
virtual void touchMove(const boo::STouchCoord&, uintptr_t) {}
virtual void charKeyDown(unsigned long, boo::EModifierKey, bool) {}
virtual void charKeyUp(unsigned long, boo::EModifierKey) {}
virtual void specialKeyDown(boo::ESpecialKey, boo::EModifierKey, bool) {}
virtual void specialKeyUp(boo::ESpecialKey, boo::EModifierKey) {}
virtual void modKeyDown(boo::EModifierKey, bool) {}
virtual void modKeyUp(boo::EModifierKey) {}
2015-12-07 00:52:07 +00:00
virtual void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
2015-12-29 02:02:43 +00:00
virtual void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub,
const boo::SWindowRect& scissor) {resized(root, sub);}
2015-12-20 04:39:09 +00:00
virtual void think() {}
2015-11-26 00:24:01 +00:00
virtual void draw(boo::IGraphicsCommandQueue* gfxQ);
2015-11-21 01:14:49 +00:00
};
2015-12-20 21:59:23 +00:00
template <class ViewPtrType>
struct ViewChild
{
ViewPtrType m_view = ViewPtrType();
bool m_mouseIn = false;
2015-12-20 21:59:23 +00:00
int m_mouseDown = 0;
2016-01-01 00:12:19 +00:00
bool mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (!m_view)
2016-01-01 00:12:19 +00:00
return false;
if (m_view->subRect().coordInRect(coord))
{
2015-12-20 21:59:23 +00:00
if ((m_mouseDown & 1 << int(button)) == 0)
{
m_view->mouseDown(coord, button, mod);
2015-12-20 21:59:23 +00:00
m_mouseDown |= 1 << int(button);
}
2016-01-01 00:12:19 +00:00
return true;
}
2016-01-01 00:12:19 +00:00
return false;
}
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (!m_view)
return;
2015-12-20 21:59:23 +00:00
if ((m_mouseDown & 1 << int(button)) != 0)
{
m_view->mouseUp(coord, button, mod);
2015-12-20 21:59:23 +00:00
m_mouseDown &= ~(1 << int(button));
}
}
void mouseMove(const boo::SWindowCoord& coord)
{
if (!m_view)
return;
if (m_view->subRect().coordInRect(coord))
{
if (!m_mouseIn)
{
m_view->mouseEnter(coord);
m_mouseIn = true;
}
m_view->mouseMove(coord);
}
else
{
if (m_mouseIn)
{
m_view->mouseLeave(coord);
m_mouseIn = false;
}
}
}
void mouseEnter(const boo::SWindowCoord& coord)
{
if (!m_view)
return;
}
void mouseLeave(const boo::SWindowCoord& coord)
{
if (!m_view)
return;
if (m_mouseIn)
{
m_view->mouseLeave(coord);
m_mouseIn = false;
}
}
void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll)
{
if (!m_view)
return;
if (m_mouseIn)
m_view->scroll(coord, scroll);
}
};
2015-11-21 01:14:49 +00:00
}
#endif // SPECTER_VIEW_HPP