Made SplashScreen background a generic ModalWindow class

This commit is contained in:
Jack Andersen 2015-12-15 11:53:15 -10:00
parent edf329ca65
commit 962639c684
16 changed files with 789 additions and 14 deletions

View File

@ -35,6 +35,7 @@ list(APPEND SPECTER_HEADERS
include/Specter/DeferredWindowEvents.hpp include/Specter/DeferredWindowEvents.hpp
include/Specter/View.hpp include/Specter/View.hpp
include/Specter/RootView.hpp include/Specter/RootView.hpp
include/Specter/ModalWindow.hpp
include/Specter/Tooltip.hpp include/Specter/Tooltip.hpp
include/Specter/SplitView.hpp include/Specter/SplitView.hpp
include/Specter/ScrollView.hpp include/Specter/ScrollView.hpp
@ -52,6 +53,7 @@ list(APPEND SPECTER_HEADERS
include/Specter/Menu.hpp include/Specter/Menu.hpp
include/Specter/Node.hpp include/Specter/Node.hpp
include/Specter/NodeSocket.hpp include/Specter/NodeSocket.hpp
include/Specter/FileBrowser.hpp
include/Specter/FontCache.hpp include/Specter/FontCache.hpp
include/Specter/Translator.hpp) include/Specter/Translator.hpp)
@ -62,6 +64,7 @@ list(APPEND SPECTER_SOURCES
lib/ViewResources.cpp lib/ViewResources.cpp
lib/View.cpp lib/View.cpp
lib/RootView.cpp lib/RootView.cpp
lib/ModalWindow.cpp
lib/Tooltip.cpp lib/Tooltip.cpp
lib/SplitView.cpp lib/SplitView.cpp
lib/ScrollView.cpp lib/ScrollView.cpp
@ -79,6 +82,7 @@ list(APPEND SPECTER_SOURCES
lib/Menu.cpp lib/Menu.cpp
lib/Node.cpp lib/Node.cpp
lib/NodeSocket.cpp lib/NodeSocket.cpp
lib/FileBrowser.cpp
lib/FontCache.cpp lib/FontCache.cpp
lib/Translator.cpp lib/Translator.cpp
atdna_FontCache.cpp) atdna_FontCache.cpp)

View File

@ -63,9 +63,18 @@ public:
void setText(const std::string& text, const Zeus::CColor& textColor); void setText(const std::string& text, const Zeus::CColor& textColor);
void setText(const std::string& text); void setText(const std::string& text);
const std::string& getText() const {return m_textStr;}
void colorGlyphs(const Zeus::CColor& newColor); void colorGlyphs(const Zeus::CColor& newColor);
int nominalWidth() const {return m_nomWidth;} int nominalWidth() const {return m_nomWidth;}
int nominalHeight() const {return m_nomHeight;} int nominalHeight() const {return m_nomHeight;}
void setMultiplyColor(const Zeus::CColor& color)
{
View::setMultiplyColor(color);
m_bBlock.m_color = color;
m_bBlockBuf->load(&m_bBlock, sizeof(ViewBlock));
m_text->setMultiplyColor(color);
}
}; };
} }

View File

@ -10,7 +10,7 @@ namespace Specter
struct IControlBinding struct IControlBinding
{ {
virtual const char* name() const=0; virtual const char* name() const=0;
virtual const char* help() const=0; virtual const char* help() const {return nullptr;}
}; };
struct IButtonBinding : IControlBinding struct IButtonBinding : IControlBinding

View File

@ -0,0 +1,58 @@
#ifndef SPECTER_FILEBROWSER_HPP
#define SPECTER_FILEBROWSER_HPP
#include "View.hpp"
#include "ModalWindow.hpp"
#include "Button.hpp"
#include "TextField.hpp"
#include "ScrollView.hpp"
#include "Table.hpp"
#include <HECL/HECL.hpp>
namespace Specter
{
class FileBrowser : public ModalWindow
{
std::vector<HECL::SystemString> m_comps;
void pathButtonActivated(size_t idx);
struct PathButton : Specter::IButtonBinding
{
FileBrowser& m_fb;
size_t m_idx;
Specter::ViewChild<Specter::Button> m_button;
PathButton(FileBrowser& fb, ViewResources& res, size_t idx, const HECL::SystemString& str)
: m_fb(fb), m_idx(idx)
{
HECL::SystemUTF8View utf8View(str);
m_button.m_view.reset(new Specter::Button(res, fb, this, utf8View));
}
const char* name() const {return m_button.m_view->getText().c_str();}
void activated(const boo::SWindowCoord&) {m_fb.pathButtonActivated(m_idx);}
};
friend struct PathButton;
std::vector<PathButton> m_pathButtons;
Specter::ViewChild<Specter::TextField> m_fileField;
Specter::ViewChild<Specter::ScrollView> m_fileScroll;
Specter::ViewChild<Specter::Table> m_fileListing;
public:
FileBrowser(ViewResources& res, View& parentView)
: FileBrowser(res, parentView, HECL::GetcwdStr()) {}
FileBrowser(ViewResources& res, View& parentView, const HECL::SystemString& initialPath);
void updateContentOpacity(float opacity);
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
void mouseMove(const boo::SWindowCoord&);
void mouseEnter(const boo::SWindowCoord&);
void mouseLeave(const boo::SWindowCoord&);
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
void draw(boo::IGraphicsCommandQueue* gfxQ);
};
}
#endif // SPECTER_FILEBROWSER_HPP

View File

@ -0,0 +1,71 @@
#ifndef SPECTER_MODAL_WINDOW_HPP
#define SPECTER_MODAL_WINDOW_HPP
#include <Specter/View.hpp>
#include <Specter/MultiLineTextView.hpp>
namespace Specter
{
class ModalWindow : public View
{
unsigned m_frame = 0;
unsigned m_contentStartFrame = 0;
float m_lineTime = 0.0;
enum class Phase
{
BuildIn,
ResWait,
Showing,
BuildOut,
Done
} m_phase = Phase::BuildIn;
int m_width = 0;
int m_height = 0;
int m_widthConstrain;
int m_heightConstrain;
Zeus::CColor m_windowBg;
Zeus::CColor m_windowBgClear;
Zeus::CColor m_line1;
Zeus::CColor m_line2;
ViewBlock m_viewBlock;
boo::IGraphicsBufferD* m_viewBlockBuf;
struct
{
SolidShaderVert lineVerts[22];
SolidShaderVert fillVerts[16];
} m_verts;
void setLineVerts(int width, int height, float pf, float t);
void setLineColors(float t);
void setFillVerts(int width, int height, float pf);
void setFillColors(float t);
boo::IGraphicsBufferD* m_vertsBuf;
boo::IVertexFormat* m_vertsVtxFmt; /* OpenGL only */
boo::IShaderDataBinding* m_vertsShaderBinding;
boo::IGraphicsDataToken m_windowGfxData;
std::unique_ptr<TextView> m_cornersOutline[4];
std::unique_ptr<TextView> m_cornersFilled[4];
protected:
virtual void updateContentOpacity(float opacity) {}
public:
ModalWindow(ViewResources& res, View& parentView, int widthConstrain=-1, int heightConstrain=-1);
void think();
bool skipBuildInAnimation();
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
void draw(boo::IGraphicsCommandQueue* gfxQ);
};
}
#endif // SPECTER_MODAL_WINDOW_HPP

View File

@ -9,9 +9,17 @@ class ViewResources;
class ScrollView : public View class ScrollView : public View
{ {
View& m_contentView;
public: public:
ScrollView(ViewResources& res, View& parentView, View& contentView); enum class Style
{
};
private:
View* m_contentView = nullptr;
public:
ScrollView(ViewResources& res, View& parentView);
}; };
} }

View File

@ -1,4 +1,17 @@
#ifndef SPECTER_TABLE_HPP #ifndef SPECTER_TABLE_HPP
#define SPECTER_TABLE_HPP #define SPECTER_TABLE_HPP
#include "View.hpp"
namespace Specter
{
class Table : public View
{
public:
Table(ViewResources& res, View& parentView);
};
}
#endif // SPECTER_TABLE_HPP #endif // SPECTER_TABLE_HPP

View File

@ -1,4 +1,17 @@
#ifndef SPECTER_TEXTFIELD_HPP #ifndef SPECTER_TEXTFIELD_HPP
#define SPECTER_TEXTFIELD_HPP #define SPECTER_TEXTFIELD_HPP
#include "View.hpp"
namespace Specter
{
class TextField : public View
{
public:
TextField(ViewResources& res, View& parentView);
};
}
#endif // SPECTER_TEXTFIELD_HPP #endif // SPECTER_TEXTFIELD_HPP

View File

@ -49,6 +49,7 @@ protected:
struct ViewBlock struct ViewBlock
{ {
Zeus::CMatrix4f m_mv; Zeus::CMatrix4f m_mv;
Zeus::CColor m_color = Zeus::CColor::skWhite;
void setViewRect(const boo::SWindowRect& root, const boo::SWindowRect& sub) void setViewRect(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{ {
m_mv[0][0] = 2.0f / root.size[0]; m_mv[0][0] = 2.0f / root.size[0];
@ -61,16 +62,19 @@ protected:
"uniform SpecterViewBlock\n"\ "uniform SpecterViewBlock\n"\
"{\n"\ "{\n"\
" mat4 mv;\n"\ " mat4 mv;\n"\
" vec4 mulColor;\n"\
"};\n" "};\n"
#define SPECTER_VIEW_VERT_BLOCK_HLSL\ #define SPECTER_VIEW_VERT_BLOCK_HLSL\
"cbuffer SpecterViewBlock : register(b0)\n"\ "cbuffer SpecterViewBlock : register(b0)\n"\
"{\n"\ "{\n"\
" float4x4 mv;\n"\ " float4x4 mv;\n"\
" float4 mulColor;\n"\
"};\n" "};\n"
#define SPECTER_VIEW_VERT_BLOCK_METAL\ #define SPECTER_VIEW_VERT_BLOCK_METAL\
"struct SpecterViewBlock\n"\ "struct SpecterViewBlock\n"\
"{\n"\ "{\n"\
" float4x4 mv;\n"\ " float4x4 mv;\n"\
" float4 mulColor;\n"\
"};\n" "};\n"
boo::IGraphicsBufferD* m_viewVertBlockBuf; boo::IGraphicsBufferD* m_viewVertBlockBuf;
@ -114,6 +118,11 @@ public:
m_bgRect[i].m_color = color; m_bgRect[i].m_color = color;
m_bgVertBuf->load(&m_bgRect, sizeof(SolidShaderVert) * 4); m_bgVertBuf->load(&m_bgRect, sizeof(SolidShaderVert) * 4);
} }
void setMultiplyColor(const Zeus::CColor& color)
{
m_viewVertBlock.m_color = color;
m_viewVertBlockBuf->load(&m_viewVertBlock, sizeof(ViewBlock));
}
virtual int nominalWidth() const {return 0;} virtual int nominalWidth() const {return 0;}
virtual int nominalHeight() const {return 0;} virtual int nominalHeight() const {return 0;}
@ -128,6 +137,79 @@ public:
virtual void draw(boo::IGraphicsCommandQueue* gfxQ); virtual void draw(boo::IGraphicsCommandQueue* gfxQ);
}; };
template <class ViewType>
struct ViewChild
{
std::unique_ptr<ViewType> m_view;
bool m_mouseIn = false;
bool m_mouseDown = false;
void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (!m_view)
return;
if (m_view->subRect().coordInRect(coord))
{
if (!m_mouseDown)
{
m_view->mouseDown(coord, button, mod);
m_mouseDown = true;
}
}
}
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (!m_view)
return;
if (m_mouseDown)
{
m_view->mouseUp(coord, button, mod);
m_mouseDown = false;
}
}
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;
}
}
};
} }
#endif // SPECTER_VIEW_HPP #endif // SPECTER_VIEW_HPP

129
specter/lib/FileBrowser.cpp Normal file
View File

@ -0,0 +1,129 @@
#include "Specter/FileBrowser.hpp"
#include "Specter/RootView.hpp"
namespace Specter
{
#define BROWSER_MARGIN 30
#define BROWSER_MIN_WIDTH 100
#define BROWSER_MIN_HEIGHT 100
static std::vector<HECL::SystemString> PathComponents(const HECL::SystemString& path)
{
std::vector<HECL::SystemString> ret;
HECL::SystemString sPath = path;
HECL::SanitizePath(sPath);
if (sPath.empty())
return ret;
auto it = sPath.cbegin();
if (*it == _S('/'))
{
ret.push_back("/");
++it;
}
HECL::SystemString comp;
for (; it != sPath.cend() ; ++it)
{
if (*it == _S('/'))
{
if (comp.empty())
continue;
ret.push_back(std::move(comp));
comp.clear();
continue;
}
comp += *it;
}
if (comp.size())
ret.push_back(std::move(comp));
return ret;
}
FileBrowser::FileBrowser(ViewResources& res, View& parentView, const HECL::SystemString& initialPath)
: ModalWindow(res, parentView), m_comps(PathComponents(initialPath))
{
commitResources(res);
setBackground({0,0,0,0.5});
m_pathButtons.reserve(m_comps.size());
size_t idx = 0;
for (const HECL::SystemString& c : m_comps)
m_pathButtons.emplace_back(*this, res, idx++, c);
updateContentOpacity(0.0);
}
void FileBrowser::updateContentOpacity(float opacity)
{
Zeus::CColor color = Zeus::CColor::lerp({1,1,1,0}, {1,1,1,1}, opacity);
for (PathButton& b : m_pathButtons)
b.m_button.m_view->setMultiplyColor(color);
}
void FileBrowser::pathButtonActivated(size_t idx)
{
}
void FileBrowser::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
if (skipBuildInAnimation())
return;
for (PathButton& b : m_pathButtons)
b.m_button.mouseDown(coord, button, mod);
}
void FileBrowser::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
{
for (PathButton& b : m_pathButtons)
b.m_button.mouseUp(coord, button, mod);
}
void FileBrowser::mouseMove(const boo::SWindowCoord& coord)
{
for (PathButton& b : m_pathButtons)
b.m_button.mouseMove(coord);
}
void FileBrowser::mouseEnter(const boo::SWindowCoord& coord)
{
for (PathButton& b : m_pathButtons)
b.m_button.mouseEnter(coord);
}
void FileBrowser::mouseLeave(const boo::SWindowCoord& coord)
{
for (PathButton& b : m_pathButtons)
b.m_button.mouseLeave(coord);
}
void FileBrowser::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{
ModalWindow::resized(root, root);
float pf = rootView().viewRes().pixelFactor();
boo::SWindowRect centerRect = sub;
centerRect.size[0] = std::max(root.size[0] - BROWSER_MARGIN * 2 * pf, BROWSER_MIN_WIDTH * pf);
centerRect.size[1] = std::max(root.size[1] - BROWSER_MARGIN * 2 * pf, BROWSER_MIN_HEIGHT * pf);
centerRect.location[0] = root.size[0] / 2 - (centerRect.size[0] / 2.0);
centerRect.location[1] = root.size[1] / 2 - (centerRect.size[1] / 2.0);
boo::SWindowRect pathRect = centerRect;
pathRect.location[0] += 10 * pf;
pathRect.location[1] += pathRect.size[1] - 20 * pf;
for (PathButton& b : m_pathButtons)
{
pathRect.size[0] = b.m_button.m_view->nominalWidth();
pathRect.size[1] = b.m_button.m_view->nominalHeight();
b.m_button.m_view->resized(root, pathRect);
pathRect.location[0] += pathRect.size[0];
}
}
void FileBrowser::draw(boo::IGraphicsCommandQueue* gfxQ)
{
ModalWindow::draw(gfxQ);
for (PathButton& b : m_pathButtons)
b.m_button.m_view->draw(gfxQ);
}
}

357
specter/lib/ModalWindow.cpp Normal file
View File

@ -0,0 +1,357 @@
#include "Specter/ModalWindow.hpp"
#include "Specter/ViewResources.hpp"
#include "Specter/RootView.hpp"
namespace Specter
{
#define WIRE_START 0
#define WIRE_FRAMES 60
#define SOLID_START 40
#define SOLID_FRAMES 40
#define CONTENT_START 80
#define CONTENT_FRAMES 40
#define LINE_WIDTH 2
#define CONTENT_MARGIN 10
#define WINDOW_MIN_DIM 16
void ModalWindow::setLineVerts(int width, int height, float pf, float t)
{
std::pair<int,int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
float t1 = Zeus::Math::clamp(0.f, t * 2.f, 1.f);
float t2 = Zeus::Math::clamp(0.f, t * 2.f - 1.f, 1.f);
float lineLeft = 0;
float lineRight = pf*LINE_WIDTH;
float lineTop = height-margin.second;
float lineBottom = margin.second;
m_verts.lineVerts[0].m_pos.assign(lineLeft, lineTop, 0);
m_verts.lineVerts[1].m_pos = Zeus::CVector3f::lerp({lineLeft, lineTop, 0}, {lineLeft, lineBottom, 0}, t1);
m_verts.lineVerts[2].m_pos.assign(lineRight, lineTop, 0);
m_verts.lineVerts[3].m_pos = Zeus::CVector3f::lerp({lineRight, lineTop, 0}, {lineRight, lineBottom, 0}, t1);
m_verts.lineVerts[4].m_pos = m_verts.lineVerts[3].m_pos;
lineLeft = margin.first;
lineRight = width-margin.first;
lineTop = height;
lineBottom = height-pf*LINE_WIDTH;
m_verts.lineVerts[5].m_pos.assign(lineLeft, lineTop, 0);
m_verts.lineVerts[6].m_pos = m_verts.lineVerts[5].m_pos;
m_verts.lineVerts[7].m_pos.assign(lineLeft, lineBottom, 0);
m_verts.lineVerts[8].m_pos = Zeus::CVector3f::lerp({lineLeft, lineTop, 0}, {lineRight, lineTop, 0}, t1);
m_verts.lineVerts[9].m_pos = Zeus::CVector3f::lerp({lineLeft, lineBottom, 0}, {lineRight, lineBottom, 0}, t1);
m_verts.lineVerts[10].m_pos = m_verts.lineVerts[9].m_pos;
lineLeft = width-pf*LINE_WIDTH;
lineRight = width;
lineTop = height-margin.second;
lineBottom = margin.second;
m_verts.lineVerts[11].m_pos.assign(lineLeft, lineTop, 0);
m_verts.lineVerts[12].m_pos = m_verts.lineVerts[11].m_pos;
m_verts.lineVerts[13].m_pos = Zeus::CVector3f::lerp({lineLeft, lineTop, 0}, {lineLeft, lineBottom, 0}, t2);
m_verts.lineVerts[14].m_pos.assign(lineRight, lineTop, 0);
m_verts.lineVerts[15].m_pos = Zeus::CVector3f::lerp({lineRight, lineTop, 0}, {lineRight, lineBottom, 0}, t2);
m_verts.lineVerts[16].m_pos = m_verts.lineVerts[15].m_pos;
lineLeft = margin.first;
lineRight = width-margin.first;
lineTop = pf*LINE_WIDTH;
lineBottom = 0;
m_verts.lineVerts[17].m_pos.assign(lineLeft, lineTop, 0);
m_verts.lineVerts[18].m_pos = m_verts.lineVerts[17].m_pos;
m_verts.lineVerts[19].m_pos.assign(lineLeft, lineBottom, 0);
m_verts.lineVerts[20].m_pos = Zeus::CVector3f::lerp({lineLeft, lineTop, 0}, {lineRight, lineTop, 0}, t2);
m_verts.lineVerts[21].m_pos = Zeus::CVector3f::lerp({lineLeft, lineBottom, 0}, {lineRight, lineBottom, 0}, t2);
}
void ModalWindow::setLineColors(float t)
{
float t1 = Zeus::Math::clamp(0.f, t * 2.f, 1.f);
float t2 = Zeus::Math::clamp(0.f, t * 2.f - 1.f, 1.f);
float t3 = Zeus::Math::clamp(0.f, t * 2.f - 2.f, 1.f);
Zeus::CColor c1 = Zeus::CColor::lerp(m_line1, m_line2, t1);
Zeus::CColor c2 = Zeus::CColor::lerp(m_line1, m_line2, t2);
Zeus::CColor c3 = Zeus::CColor::lerp(m_line1, m_line2, t3);
m_cornersOutline[0]->colorGlyphs(c1);
if (t < 0.5)
{
m_cornersOutline[1]->colorGlyphs(Zeus::CColor::skClear);
m_cornersOutline[2]->colorGlyphs(Zeus::CColor::skClear);
m_cornersOutline[3]->colorGlyphs(Zeus::CColor::skClear);
}
else if (t < 1.0)
{
m_cornersOutline[1]->colorGlyphs(c2);
m_cornersOutline[3]->colorGlyphs(c2);
}
else
{
m_cornersOutline[1]->colorGlyphs(c2);
m_cornersOutline[2]->colorGlyphs(c3);
m_cornersOutline[3]->colorGlyphs(c2);
}
m_verts.lineVerts[0].m_color = c1;
m_verts.lineVerts[1].m_color = c2;
m_verts.lineVerts[2].m_color = m_verts.lineVerts[0].m_color;
m_verts.lineVerts[3].m_color = m_verts.lineVerts[1].m_color;
m_verts.lineVerts[4].m_color = m_verts.lineVerts[3].m_color;
m_verts.lineVerts[5].m_color = c1;
m_verts.lineVerts[6].m_color = m_verts.lineVerts[5].m_color;
m_verts.lineVerts[7].m_color = m_verts.lineVerts[6].m_color;
m_verts.lineVerts[8].m_color = c2;
m_verts.lineVerts[9].m_color = m_verts.lineVerts[8].m_color;
m_verts.lineVerts[10].m_color = m_verts.lineVerts[9].m_color;
m_verts.lineVerts[11].m_color = c2;
m_verts.lineVerts[12].m_color = m_verts.lineVerts[11].m_color;
m_verts.lineVerts[13].m_color = c3;
m_verts.lineVerts[14].m_color = m_verts.lineVerts[12].m_color;
m_verts.lineVerts[15].m_color = m_verts.lineVerts[13].m_color;
m_verts.lineVerts[16].m_color = m_verts.lineVerts[15].m_color;
m_verts.lineVerts[17].m_color = c2;
m_verts.lineVerts[18].m_color = m_verts.lineVerts[17].m_color;
m_verts.lineVerts[19].m_color = m_verts.lineVerts[18].m_color;
m_verts.lineVerts[20].m_color = c3;
m_verts.lineVerts[21].m_color = m_verts.lineVerts[20].m_color;
}
void ModalWindow::setFillVerts(int width, int height, float pf)
{
std::pair<int,int> margin = m_cornersFilled[0]->queryGlyphDimensions(0);
float fillLeft = pf*LINE_WIDTH;
float fillRight = width-pf*LINE_WIDTH;
float fillTop = height-margin.second;
float fillBottom = margin.second;
m_verts.fillVerts[0].m_pos.assign(fillLeft, fillTop, 0);
m_verts.fillVerts[1].m_pos.assign(fillLeft, fillBottom, 0);
m_verts.fillVerts[2].m_pos.assign(fillRight, fillTop, 0);
m_verts.fillVerts[3].m_pos.assign(fillRight, fillBottom, 0);
m_verts.fillVerts[4].m_pos = m_verts.fillVerts[3].m_pos;
fillLeft = margin.first;
fillRight = width-margin.first;
fillTop = height-pf*LINE_WIDTH;
fillBottom = height-margin.second;
m_verts.fillVerts[5].m_pos.assign(fillLeft, fillTop, 0);
m_verts.fillVerts[6].m_pos = m_verts.fillVerts[5].m_pos;
m_verts.fillVerts[7].m_pos.assign(fillLeft, fillBottom, 0);
m_verts.fillVerts[8].m_pos.assign(fillRight, fillTop, 0);
m_verts.fillVerts[9].m_pos.assign(fillRight, fillBottom, 0);
m_verts.fillVerts[10].m_pos = m_verts.fillVerts[9].m_pos;
fillLeft = margin.first;
fillRight = width-margin.first;
fillTop = margin.second;
fillBottom = pf*LINE_WIDTH;
m_verts.fillVerts[11].m_pos.assign(fillLeft, fillTop, 0);
m_verts.fillVerts[12].m_pos = m_verts.fillVerts[11].m_pos;
m_verts.fillVerts[13].m_pos.assign(fillLeft, fillBottom, 0);
m_verts.fillVerts[14].m_pos.assign(fillRight, fillTop, 0);
m_verts.fillVerts[15].m_pos.assign(fillRight, fillBottom, 0);
}
void ModalWindow::setFillColors(float t)
{
t = Zeus::Math::clamp(0.f, t, 1.f);
Zeus::CColor color = Zeus::CColor::lerp(m_windowBgClear, m_windowBg, t);
for (int i=0 ; i<16 ; ++i)
m_verts.fillVerts[i].m_color = color;
for (int i=0 ; i<4 ; ++i)
m_cornersFilled[i]->colorGlyphs(color);
}
ModalWindow::ModalWindow(ViewResources& res, View& parentView, int widthConstrain, int heightConstrain)
: View(res, parentView),
m_widthConstrain(widthConstrain),
m_heightConstrain(heightConstrain),
m_windowBg(res.themeData().splashBackground()),
m_windowBgClear(m_windowBg),
m_line1(res.themeData().splash1()),
m_line2(res.themeData().splash2())
{
m_windowBgClear[3] = 0.0;
m_viewBlockBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Uniform, sizeof(ViewBlock), 1);
m_vertsBuf = res.m_factory->newDynamicBuffer(boo::BufferUse::Vertex, sizeof(SolidShaderVert), 38);
if (!res.m_viewRes.m_solidVtxFmt)
{
boo::VertexElementDescriptor vdescs[] =
{
{m_vertsBuf, nullptr, boo::VertexSemantic::Position4},
{m_vertsBuf, nullptr, boo::VertexSemantic::Color}
};
m_vertsVtxFmt = res.m_factory->newVertexFormat(2, vdescs);
boo::IGraphicsBuffer* bufs[] = {m_viewBlockBuf};
m_vertsShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader,
m_vertsVtxFmt, m_vertsBuf, nullptr,
nullptr, 1, bufs, 0, nullptr);
}
else
{
boo::IGraphicsBuffer* bufs[] = {m_viewBlockBuf};
m_vertsShaderBinding = res.m_factory->newShaderDataBinding(res.m_viewRes.m_solidShader,
res.m_viewRes.m_solidVtxFmt,
m_vertsBuf, nullptr,
nullptr, 1, bufs, 0, nullptr);
}
m_windowGfxData = res.m_factory->commit();
for (int i=0 ; i<4 ; ++i)
{
m_cornersOutline[i].reset(new Specter::TextView(res, *this, res.m_curveFont, Specter::TextView::Alignment::Left, 1));
m_cornersFilled[i].reset(new Specter::TextView(res, *this, res.m_curveFont, Specter::TextView::Alignment::Left, 1));
}
m_cornersOutline[0]->typesetGlyphs(L"\xF4F0");
m_cornersFilled[0]->typesetGlyphs(L"\xF4F1", res.themeData().splashBackground());
m_cornersOutline[1]->typesetGlyphs(L"\xF4F2");
m_cornersFilled[1]->typesetGlyphs(L"\xF4F3", res.themeData().splashBackground());
m_cornersOutline[2]->typesetGlyphs(L"\xF4F4");
m_cornersFilled[2]->typesetGlyphs(L"\xF4F5", res.themeData().splashBackground());
m_cornersOutline[3]->typesetGlyphs(L"\xF4F6");
m_cornersFilled[3]->typesetGlyphs(L"\xF4F7", res.themeData().splashBackground());
setLineColors(0.0);
setFillColors(0.0);
m_vertsBuf->load(&m_verts, sizeof(m_verts));
}
static float CubicEase(float t)
{
t *= 2.f;
if (t < 1) return 1.f/2.f*t*t*t;
t -= 2.f;
return 1.f/2.f*(t*t*t + 2.f);
}
void ModalWindow::think()
{
Specter::ViewResources& res = rootView().viewRes();
float pf = res.pixelFactor();
if (m_phase == Phase::BuildIn)
{
bool loadVerts = false;
if (m_frame > WIRE_START)
{
float wt = (m_frame-WIRE_START) / float(WIRE_FRAMES);
wt = Zeus::Math::clamp(0.f, wt, 2.f);
m_lineTime = CubicEase(wt);
setLineVerts(m_width, m_height, pf, m_lineTime);
setLineColors(wt);
loadVerts = true;
}
if (m_frame > SOLID_START)
{
float ft = (m_frame-SOLID_START) / float(SOLID_FRAMES);
ft = Zeus::Math::clamp(0.f, ft, 2.f);
setFillColors(ft);
loadVerts = true;
}
if (res.fontCacheReady() && m_frame > CONTENT_START)
{
if (!m_contentStartFrame)
m_contentStartFrame = m_frame;
float tt = (m_frame-m_contentStartFrame) / float(CONTENT_FRAMES);
tt = Zeus::Math::clamp(0.f, tt, 1.f);
updateContentOpacity(tt);
if (tt == 1.f)
m_phase = Phase::Showing;
}
if (loadVerts)
m_vertsBuf->load(&m_verts, sizeof(m_verts));
++m_frame;
}
else if (m_phase == Phase::ResWait)
{
if (res.fontCacheReady())
{
updateContentOpacity(1.0);
m_phase = Phase::Showing;
}
}
}
bool ModalWindow::skipBuildInAnimation()
{
if (m_phase != Phase::BuildIn)
return false;
Specter::ViewResources& res = rootView().viewRes();
float pf = res.pixelFactor();
m_lineTime = 1.0;
setLineVerts(m_width, m_height, pf, 1.0);
setLineColors(2.0);
setFillColors(2.0);
m_vertsBuf->load(&m_verts, sizeof(m_verts));
m_phase = Phase::ResWait;
return true;
}
void ModalWindow::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
{
float pf = rootView().viewRes().pixelFactor();
boo::SWindowRect centerRect = sub;
m_width = m_widthConstrain < 0 ? root.size[0] - CONTENT_MARGIN * pf * 2 : m_widthConstrain;
m_height = m_heightConstrain < 0 ? root.size[1] - CONTENT_MARGIN * pf * 2 : m_heightConstrain;
m_width = std::max(m_width, int(WINDOW_MIN_DIM * pf));
m_height = std::max(m_height, int(WINDOW_MIN_DIM * pf));
centerRect.size[0] = m_width;
centerRect.size[1] = m_height;
centerRect.location[0] = root.size[0] / 2 - m_width / 2.0;
centerRect.location[1] = root.size[1] / 2 - m_height / 2.0;
View::resized(root, centerRect);
m_viewBlock.setViewRect(root, centerRect);
m_viewBlockBuf->load(&m_viewBlock, sizeof(m_viewBlock));
setLineVerts(m_width, m_height, pf, m_lineTime);
setFillVerts(m_width, m_height, pf);
m_vertsBuf->load(&m_verts, sizeof(m_verts));
boo::SWindowRect cornerRect = centerRect;
cornerRect.size[0] = cornerRect.size[1] = 8 * pf;
cornerRect.location[1] = centerRect.location[1] + m_height - 8 * pf;
m_cornersOutline[0]->resized(root, cornerRect);
m_cornersFilled[0]->resized(root, cornerRect);
cornerRect.location[0] = centerRect.location[0] + m_width - 8 * pf;
m_cornersOutline[1]->resized(root, cornerRect);
m_cornersFilled[1]->resized(root, cornerRect);
cornerRect.location[1] = centerRect.location[1];
m_cornersOutline[2]->resized(root, cornerRect);
m_cornersFilled[2]->resized(root, cornerRect);
cornerRect.location[0] = centerRect.location[0];
m_cornersOutline[3]->resized(root, cornerRect);
m_cornersFilled[3]->resized(root, cornerRect);
}
void ModalWindow::draw(boo::IGraphicsCommandQueue* gfxQ)
{
gfxQ->setShaderDataBinding(m_vertsShaderBinding);
gfxQ->setDrawPrimitive(boo::Primitive::TriStrips);
if (m_frame > WIRE_START)
gfxQ->draw(0, 22);
if (m_frame > SOLID_START)
gfxQ->draw(22, 16);
m_cornersFilled[0]->draw(gfxQ);
m_cornersFilled[1]->draw(gfxQ);
m_cornersFilled[2]->draw(gfxQ);
m_cornersFilled[3]->draw(gfxQ);
m_cornersOutline[0]->draw(gfxQ);
m_cornersOutline[1]->draw(gfxQ);
m_cornersOutline[2]->draw(gfxQ);
m_cornersOutline[3]->draw(gfxQ);
}
}

View File

@ -3,8 +3,8 @@
namespace Specter namespace Specter
{ {
ScrollView::ScrollView(ViewResources& system, View& parentView, View& contentView) ScrollView::ScrollView(ViewResources& system, View& parentView)
: View(system, parentView), m_contentView(contentView) : View(system, parentView)
{ {
} }

View File

@ -0,0 +1,11 @@
#include "Specter/Table.hpp"
namespace Specter
{
Table::Table(ViewResources& res, View& parentView)
: View(res, parentView)
{
}
}

View File

@ -0,0 +1,11 @@
#include "Specter/TextField.hpp"
namespace Specter
{
TextField::TextField(ViewResources& res, View& parentView)
: View(res, parentView)
{
}
}

View File

@ -29,7 +29,7 @@ void TextView::Resources::init(boo::GLDataFactory* factory, FontCache* fcache)
"void main()\n" "void main()\n"
"{\n" "{\n"
" vtf.uv = uvIn[gl_VertexID];\n" " vtf.uv = uvIn[gl_VertexID];\n"
" vtf.color = colorIn;\n" " vtf.color = colorIn * mulColor;\n"
" gl_Position = mv * mvMtx * vec4(posIn[gl_VertexID], 1.0);\n" " gl_Position = mv * mvMtx * vec4(posIn[gl_VertexID], 1.0);\n"
"}\n"; "}\n";
@ -104,7 +104,7 @@ void TextView::Resources::init(boo::ID3DDataFactory* factory, FontCache* fcache)
"{\n" "{\n"
" VertToFrag vtf;\n" " VertToFrag vtf;\n"
" vtf.uv = v.uvIn[vertId];\n" " vtf.uv = v.uvIn[vertId];\n"
" vtf.color = v.colorIn;\n" " vtf.color = v.colorIn * mulColor;\n"
" vtf.position = mul(mv, mul(v.mvMtx, float4(v.posIn[vertId], 1.0)));\n" " vtf.position = mul(mv, mul(v.mvMtx, float4(v.posIn[vertId], 1.0)));\n"
" return vtf;\n" " return vtf;\n"
"}\n"; "}\n";
@ -211,7 +211,7 @@ void TextView::Resources::init(boo::MetalDataFactory* factory, FontCache* fcache
" VertToFrag vtf;\n" " VertToFrag vtf;\n"
" constant VertData& v = va[instId];\n" " constant VertData& v = va[instId];\n"
" vtf.uv = v.uvIn[vertId];\n" " vtf.uv = v.uvIn[vertId];\n"
" vtf.color = v.colorIn;\n" " vtf.color = v.colorIn * view.mulColor;\n"
" vtf.position = view.mv * v.mvMtx * float4(v.posIn[vertId], 1.0);\n" " vtf.position = view.mv * v.mvMtx * float4(v.posIn[vertId], 1.0);\n"
" return vtf;\n" " return vtf;\n"
"}\n"; "}\n";

View File

@ -19,7 +19,7 @@ void View::Resources::init(boo::GLDataFactory* factory, const ThemeData& theme)
"out VertToFrag vtf;\n" "out VertToFrag vtf;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" vtf.color = colorIn;\n" " vtf.color = colorIn * mulColor;\n"
" gl_Position = mv * vec4(posIn, 1.0);\n" " gl_Position = mv * vec4(posIn, 1.0);\n"
"}\n"; "}\n";
@ -43,12 +43,14 @@ void View::Resources::init(boo::GLDataFactory* factory, const ThemeData& theme)
SPECTER_VIEW_VERT_BLOCK_GLSL SPECTER_VIEW_VERT_BLOCK_GLSL
"struct VertToFrag\n" "struct VertToFrag\n"
"{\n" "{\n"
" vec4 color;\n"
" vec2 uv;\n" " vec2 uv;\n"
"};\n" "};\n"
"out VertToFrag vtf;\n" "out VertToFrag vtf;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" vtf.uv = uvIn;\n" " vtf.uv = uvIn;\n"
" vtf.color = mulColor;\n"
" gl_Position = mv * vec4(posIn, 1.0);\n" " gl_Position = mv * vec4(posIn, 1.0);\n"
"}\n"; "}\n";
@ -56,6 +58,7 @@ void View::Resources::init(boo::GLDataFactory* factory, const ThemeData& theme)
"#version 330\n" "#version 330\n"
"struct VertToFrag\n" "struct VertToFrag\n"
"{\n" "{\n"
" vec4 color;\n"
" vec2 uv;\n" " vec2 uv;\n"
"};\n" "};\n"
"in VertToFrag vtf;\n" "in VertToFrag vtf;\n"
@ -63,7 +66,7 @@ void View::Resources::init(boo::GLDataFactory* factory, const ThemeData& theme)
"layout(location=0) out vec4 colorOut;\n" "layout(location=0) out vec4 colorOut;\n"
"void main()\n" "void main()\n"
"{\n" "{\n"
" colorOut = texture(tex, vtf.uv);\n" " colorOut = texture(tex, vtf.uv) * vtf.color;\n"
"}\n"; "}\n";
static const char* BlockNames[] = {"SpecterViewBlock"}; static const char* BlockNames[] = {"SpecterViewBlock"};
@ -96,7 +99,7 @@ void View::Resources::init(boo::ID3DDataFactory* factory, const ThemeData& theme
"VertToFrag main(in VertData v)\n" "VertToFrag main(in VertData v)\n"
"{\n" "{\n"
" VertToFrag vtf;\n" " VertToFrag vtf;\n"
" vtf.color = v.colorIn;\n" " vtf.color = v.colorIn * mulColor;\n"
" vtf.position = mul(mv, float4(v.posIn, 1.0));\n" " vtf.position = mul(mv, float4(v.posIn, 1.0));\n"
" return vtf;\n" " return vtf;\n"
"}\n"; "}\n";
@ -122,12 +125,14 @@ void View::Resources::init(boo::ID3DDataFactory* factory, const ThemeData& theme
"struct VertToFrag\n" "struct VertToFrag\n"
"{\n" "{\n"
" float4 position : SV_Position;\n" " float4 position : SV_Position;\n"
" float4 color : COLOR;\n"
" float2 uv : UV;\n" " float2 uv : UV;\n"
"};\n" "};\n"
"VertToFrag main(in VertData v)\n" "VertToFrag main(in VertData v)\n"
"{\n" "{\n"
" VertToFrag vtf;\n" " VertToFrag vtf;\n"
" vtf.uv = v.uvIn;\n" " vtf.uv = v.uvIn;\n"
" vtf.color = mulColor;\n"
" vtf.position = mul(mv, float4(v.posIn, 1.0));\n" " vtf.position = mul(mv, float4(v.posIn, 1.0));\n"
" return vtf;\n" " return vtf;\n"
"}\n"; "}\n";
@ -136,13 +141,14 @@ void View::Resources::init(boo::ID3DDataFactory* factory, const ThemeData& theme
"struct VertToFrag\n" "struct VertToFrag\n"
"{\n" "{\n"
" float4 position : SV_Position;\n" " float4 position : SV_Position;\n"
" float4 color : COLOR;\n"
" float2 uv : UV;\n" " float2 uv : UV;\n"
"};\n" "};\n"
"Texture2D tex : register(t0);\n" "Texture2D tex : register(t0);\n"
"SamplerState samp : register(s0);\n" "SamplerState samp : register(s0);\n"
"float4 main(in VertToFrag vtf) : SV_Target0\n" "float4 main(in VertToFrag vtf) : SV_Target0\n"
"{\n" "{\n"
" return tex.Sample(samp, vtf.uv);\n" " return tex.Sample(samp, vtf.uv) * vtf.color;\n"
"}\n"; "}\n";
boo::VertexElementDescriptor solidvdescs[] = boo::VertexElementDescriptor solidvdescs[] =
@ -195,7 +201,7 @@ void View::Resources::init(boo::MetalDataFactory* factory, const ThemeData& them
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpecterViewBlock& view [[ buffer(2) ]])\n" "vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpecterViewBlock& view [[ buffer(2) ]])\n"
"{\n" "{\n"
" VertToFrag vtf;\n" " VertToFrag vtf;\n"
" vtf.color = v.colorIn;\n" " vtf.color = v.colorIn * view.mulColor;\n"
" vtf.position = view.mv * float4(v.posIn, 1.0);\n" " vtf.position = view.mv * float4(v.posIn, 1.0);\n"
" return vtf;\n" " return vtf;\n"
"}\n"; "}\n";
@ -225,12 +231,14 @@ void View::Resources::init(boo::MetalDataFactory* factory, const ThemeData& them
"struct VertToFrag\n" "struct VertToFrag\n"
"{\n" "{\n"
" float4 position [[ position ]];\n" " float4 position [[ position ]];\n"
" float4 color;\n"
" float2 uv;\n" " float2 uv;\n"
"};\n" "};\n"
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpecterViewBlock& view [[ buffer(2) ]])\n" "vertex VertToFrag vmain(VertData v [[ stage_in ]], constant SpecterViewBlock& view [[ buffer(2) ]])\n"
"{\n" "{\n"
" VertToFrag vtf;\n" " VertToFrag vtf;\n"
" vtf.uv = v.uvIn;\n" " vtf.uv = v.uvIn;\n"
" vtf.color = view.mulColor;\n"
" vtf.position = view.mv * float4(v.posIn, 1.0);\n" " vtf.position = view.mv * float4(v.posIn, 1.0);\n"
" return vtf;\n" " return vtf;\n"
"}\n"; "}\n";
@ -242,11 +250,12 @@ void View::Resources::init(boo::MetalDataFactory* factory, const ThemeData& them
"struct VertToFrag\n" "struct VertToFrag\n"
"{\n" "{\n"
" float4 position [[ position ]];\n" " float4 position [[ position ]];\n"
" float4 color;\n"
" float2 uv;\n" " float2 uv;\n"
"};\n" "};\n"
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]], texture2d<float> tex [[ texture(0) ]])\n" "fragment float4 fmain(VertToFrag vtf [[ stage_in ]], texture2d<float> tex [[ texture(0) ]])\n"
"{\n" "{\n"
" return tex.sample(samp, vtf.uv);\n" " return tex.sample(samp, vtf.uv) * vtf.color;\n"
"}\n"; "}\n";
boo::VertexElementDescriptor solidvdescs[] = boo::VertexElementDescriptor solidvdescs[] =