mirror of https://github.com/AxioDL/metaforce.git
New code style refactor
This commit is contained in:
parent
4fc3e42912
commit
dcbc001cd2
|
@ -4,130 +4,117 @@
|
|||
#include "specter/Control.hpp"
|
||||
#include "specter/Icon.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class Button : public Control
|
||||
{
|
||||
class Button : public Control {
|
||||
public:
|
||||
enum class Style
|
||||
{
|
||||
Block,
|
||||
Text,
|
||||
};
|
||||
enum class Style {
|
||||
Block,
|
||||
Text,
|
||||
};
|
||||
|
||||
private:
|
||||
Style m_style;
|
||||
IButtonBinding::MenuStyle m_menuStyle = IButtonBinding::MenuStyle::None;
|
||||
zeus::CColor m_textColor;
|
||||
zeus::CColor m_bgColor;
|
||||
std::string m_textStr;
|
||||
std::unique_ptr<TextView> m_text;
|
||||
std::unique_ptr<IconView> m_icon;
|
||||
Style m_style;
|
||||
IButtonBinding::MenuStyle m_menuStyle = IButtonBinding::MenuStyle::None;
|
||||
zeus::CColor m_textColor;
|
||||
zeus::CColor m_bgColor;
|
||||
std::string m_textStr;
|
||||
std::unique_ptr<TextView> m_text;
|
||||
std::unique_ptr<IconView> m_icon;
|
||||
|
||||
SolidShaderVert m_verts[40];
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
SolidShaderVert m_verts[40];
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
|
||||
void _loadVerts()
|
||||
{
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
}
|
||||
void _loadVerts() { m_vertsBinding.load<decltype(m_verts)>(m_verts); }
|
||||
|
||||
RectangleConstraint m_constraint;
|
||||
int m_nomWidth, m_nomHeight;
|
||||
int m_textWidth, m_textIconWidth;
|
||||
RectangleConstraint m_constraint;
|
||||
int m_nomWidth, m_nomHeight;
|
||||
int m_textWidth, m_textIconWidth;
|
||||
|
||||
struct ButtonTarget : View
|
||||
{
|
||||
Button& m_button;
|
||||
struct ButtonTarget : View {
|
||||
Button& m_button;
|
||||
|
||||
bool m_pressed = false;
|
||||
bool m_hovered = false;
|
||||
bool m_pressed = false;
|
||||
bool m_hovered = false;
|
||||
|
||||
void setInactive();
|
||||
void setHover();
|
||||
void setPressed();
|
||||
void setDisabled();
|
||||
void setInactive();
|
||||
void setHover();
|
||||
void setPressed();
|
||||
void setDisabled();
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
ButtonTarget(ViewResources& res, Button& button) : View(res, button), m_button(button) {}
|
||||
};
|
||||
ViewChild<std::unique_ptr<ButtonTarget>> m_buttonTarget;
|
||||
|
||||
struct MenuTarget : View
|
||||
{
|
||||
Button& m_button;
|
||||
|
||||
bool m_pressed = false;
|
||||
bool m_hovered = false;
|
||||
|
||||
void setInactive();
|
||||
void setHover();
|
||||
void setPressed();
|
||||
void setDisabled();
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
MenuTarget(ViewResources& res, Button& button) : View(res, button), m_button(button) {}
|
||||
};
|
||||
ViewChild<std::unique_ptr<MenuTarget>> m_menuTarget;
|
||||
|
||||
ViewChild<std::unique_ptr<View>> m_modalMenu;
|
||||
|
||||
public:
|
||||
class Resources
|
||||
{
|
||||
friend class ViewResources;
|
||||
friend class Button;
|
||||
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
|
||||
void destroy() {}
|
||||
};
|
||||
|
||||
~Button() {closeMenu({});}
|
||||
Button(ViewResources& res, View& parentView,
|
||||
IButtonBinding* controlBinding, std::string_view text, Icon* icon=nullptr,
|
||||
Style style=Style::Block, const zeus::CColor& bgColor=zeus::CColor::skWhite,
|
||||
RectangleConstraint constraint=RectangleConstraint());
|
||||
Button(ViewResources& res, View& parentView,
|
||||
IButtonBinding* controlBinding, std::string_view text, const zeus::CColor& textColor,
|
||||
Icon* icon=nullptr, Style style=Style::Block, const zeus::CColor& bgColor=zeus::CColor::skWhite,
|
||||
RectangleConstraint constraint=RectangleConstraint());
|
||||
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 think();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
ButtonTarget(ViewResources& res, Button& button) : View(res, button), m_button(button) {}
|
||||
};
|
||||
ViewChild<std::unique_ptr<ButtonTarget>> m_buttonTarget;
|
||||
|
||||
void setText(std::string_view text, const zeus::CColor& textColor);
|
||||
void setText(std::string_view text);
|
||||
void setIcon(Icon* icon=nullptr);
|
||||
std::string_view getText() const {return m_textStr;}
|
||||
void colorGlyphs(const zeus::CColor& newColor);
|
||||
int nominalWidth() const {return m_nomWidth;}
|
||||
int nominalHeight() const {return m_nomHeight;}
|
||||
struct MenuTarget : View {
|
||||
Button& m_button;
|
||||
|
||||
void closeMenu(const boo::SWindowCoord& coord);
|
||||
ViewChild<std::unique_ptr<View>>& getMenu() {return m_modalMenu;}
|
||||
bool m_pressed = false;
|
||||
bool m_hovered = false;
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
View::setMultiplyColor(color);
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock);
|
||||
m_text->setMultiplyColor(color);
|
||||
if (m_icon)
|
||||
m_icon->setMultiplyColor(color);
|
||||
}
|
||||
void setInactive();
|
||||
void setHover();
|
||||
void setPressed();
|
||||
void setDisabled();
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
MenuTarget(ViewResources& res, Button& button) : View(res, button), m_button(button) {}
|
||||
};
|
||||
ViewChild<std::unique_ptr<MenuTarget>> m_menuTarget;
|
||||
|
||||
ViewChild<std::unique_ptr<View>> m_modalMenu;
|
||||
|
||||
public:
|
||||
class Resources {
|
||||
friend class ViewResources;
|
||||
friend class Button;
|
||||
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
|
||||
void destroy() {}
|
||||
};
|
||||
|
||||
~Button() { closeMenu({}); }
|
||||
Button(ViewResources& res, View& parentView, IButtonBinding* controlBinding, std::string_view text,
|
||||
Icon* icon = nullptr, Style style = Style::Block, const zeus::CColor& bgColor = zeus::CColor::skWhite,
|
||||
RectangleConstraint constraint = RectangleConstraint());
|
||||
Button(ViewResources& res, View& parentView, IButtonBinding* controlBinding, std::string_view text,
|
||||
const zeus::CColor& textColor, Icon* icon = nullptr, Style style = Style::Block,
|
||||
const zeus::CColor& bgColor = zeus::CColor::skWhite, RectangleConstraint constraint = RectangleConstraint());
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void think();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
void setText(std::string_view text, const zeus::CColor& textColor);
|
||||
void setText(std::string_view text);
|
||||
void setIcon(Icon* icon = nullptr);
|
||||
std::string_view getText() const { return m_textStr; }
|
||||
void colorGlyphs(const zeus::CColor& newColor);
|
||||
int nominalWidth() const { return m_nomWidth; }
|
||||
int nominalHeight() const { return m_nomHeight; }
|
||||
|
||||
void closeMenu(const boo::SWindowCoord& coord);
|
||||
ViewChild<std::unique_ptr<View>>& getMenu() { return m_modalMenu; }
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color) {
|
||||
View::setMultiplyColor(color);
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock);
|
||||
m_text->setMultiplyColor(color);
|
||||
if (m_icon)
|
||||
m_icon->setMultiplyColor(color);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -2,119 +2,106 @@
|
|||
|
||||
#include "View.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
class Control;
|
||||
class Button;
|
||||
|
||||
enum class ControlType
|
||||
{
|
||||
Button,
|
||||
Float,
|
||||
Int,
|
||||
String,
|
||||
CVar
|
||||
enum class ControlType { Button, Float, Int, String, CVar };
|
||||
|
||||
struct IControlBinding {
|
||||
virtual ControlType type() const = 0;
|
||||
virtual std::string_view name(const Control* control) const = 0;
|
||||
virtual std::string_view help(const Control* control) const { return {}; }
|
||||
};
|
||||
|
||||
struct IControlBinding
|
||||
{
|
||||
virtual ControlType type() const = 0;
|
||||
virtual std::string_view name(const Control* control) const=0;
|
||||
virtual std::string_view help(const Control* control) const {return {};}
|
||||
struct IButtonBinding : IControlBinding {
|
||||
ControlType type() const { return ControlType::Button; }
|
||||
static IButtonBinding* castTo(IControlBinding* bind) {
|
||||
return bind->type() == ControlType::Button ? static_cast<IButtonBinding*>(bind) : nullptr;
|
||||
}
|
||||
|
||||
/** Pressed/Released while Hovering action,
|
||||
* cancellable by holding the button and releasing outside */
|
||||
virtual void activated(const Button* button, const boo::SWindowCoord& coord) {}
|
||||
|
||||
/** Pass-through down action */
|
||||
virtual void down(const Button* button, const boo::SWindowCoord& coord) {}
|
||||
|
||||
/** Pass-through up action */
|
||||
virtual void up(const Button* button, const boo::SWindowCoord& coord) {}
|
||||
|
||||
/** Optional style of menu to bind to button */
|
||||
enum class MenuStyle {
|
||||
None, /**< No menu; normal button */
|
||||
Primary, /**< Menu button replaces normal button */
|
||||
Auxiliary /**< Menu button placed alongside normal button */
|
||||
};
|
||||
|
||||
/** Informs button which MenuStyle to present to user */
|
||||
virtual MenuStyle menuStyle(const specter::Button* button) const { return MenuStyle::None; }
|
||||
|
||||
/** Called when user requests menu, Button assumes modal ownership */
|
||||
virtual std::unique_ptr<View> buildMenu(const specter::Button* button) { return std::unique_ptr<View>(); }
|
||||
};
|
||||
|
||||
struct IButtonBinding : IControlBinding
|
||||
{
|
||||
ControlType type() const { return ControlType::Button; }
|
||||
static IButtonBinding* castTo(IControlBinding* bind)
|
||||
{ return bind->type() == ControlType::Button ? static_cast<IButtonBinding*>(bind) : nullptr; }
|
||||
|
||||
/** Pressed/Released while Hovering action,
|
||||
* cancellable by holding the button and releasing outside */
|
||||
virtual void activated(const Button* button, const boo::SWindowCoord& coord) {}
|
||||
|
||||
/** Pass-through down action */
|
||||
virtual void down(const Button* button, const boo::SWindowCoord& coord) {}
|
||||
|
||||
/** Pass-through up action */
|
||||
virtual void up(const Button* button, const boo::SWindowCoord& coord) {}
|
||||
|
||||
/** Optional style of menu to bind to button */
|
||||
enum class MenuStyle
|
||||
{
|
||||
None, /**< No menu; normal button */
|
||||
Primary, /**< Menu button replaces normal button */
|
||||
Auxiliary /**< Menu button placed alongside normal button */
|
||||
};
|
||||
|
||||
/** Informs button which MenuStyle to present to user */
|
||||
virtual MenuStyle menuStyle(const specter::Button* button) const {return MenuStyle::None;}
|
||||
|
||||
/** Called when user requests menu, Button assumes modal ownership */
|
||||
virtual std::unique_ptr<View> buildMenu(const specter::Button* button) {return std::unique_ptr<View>();}
|
||||
struct IFloatBinding : IControlBinding {
|
||||
ControlType type() const { return ControlType::Float; }
|
||||
static IFloatBinding* castTo(IControlBinding* bind) {
|
||||
return bind->type() == ControlType::Float ? static_cast<IFloatBinding*>(bind) : nullptr;
|
||||
}
|
||||
virtual float getDefault(const Control* control) const { return 0.0; }
|
||||
virtual std::pair<float, float> getBounds(const Control* control) const { return std::make_pair(FLT_MIN, FLT_MAX); }
|
||||
virtual void changed(const Control* control, float val) = 0;
|
||||
};
|
||||
|
||||
struct IFloatBinding : IControlBinding
|
||||
{
|
||||
ControlType type() const { return ControlType::Float; }
|
||||
static IFloatBinding* castTo(IControlBinding* bind)
|
||||
{ return bind->type() == ControlType::Float ? static_cast<IFloatBinding*>(bind) : nullptr; }
|
||||
virtual float getDefault(const Control* control) const {return 0.0;}
|
||||
virtual std::pair<float,float> getBounds(const Control* control) const {return std::make_pair(FLT_MIN, FLT_MAX);}
|
||||
virtual void changed(const Control* control, float val)=0;
|
||||
struct IIntBinding : IControlBinding {
|
||||
ControlType type() const { return ControlType::Int; }
|
||||
static IIntBinding* castTo(IControlBinding* bind) {
|
||||
return bind->type() == ControlType::Int ? static_cast<IIntBinding*>(bind) : nullptr;
|
||||
}
|
||||
virtual int getDefault(const Control* control) const { return 0; }
|
||||
virtual std::pair<int, int> getBounds(const Control* control) const { return std::make_pair(INT_MIN, INT_MAX); }
|
||||
virtual void changed(const Control* control, int val) = 0;
|
||||
};
|
||||
|
||||
struct IIntBinding : IControlBinding
|
||||
{
|
||||
ControlType type() const { return ControlType::Int; }
|
||||
static IIntBinding* castTo(IControlBinding* bind)
|
||||
{ return bind->type() == ControlType::Int ? static_cast<IIntBinding*>(bind) : nullptr; }
|
||||
virtual int getDefault(const Control* control) const {return 0;}
|
||||
virtual std::pair<int,int> getBounds(const Control* control) const {return std::make_pair(INT_MIN, INT_MAX);}
|
||||
virtual void changed(const Control* control, int val)=0;
|
||||
struct IStringBinding : IControlBinding {
|
||||
ControlType type() const { return ControlType::String; }
|
||||
static IStringBinding* castTo(IControlBinding* bind) {
|
||||
return bind->type() == ControlType::String ? static_cast<IStringBinding*>(bind) : nullptr;
|
||||
}
|
||||
virtual std::string getDefault(const Control* control) const { return ""; }
|
||||
virtual void changed(const Control* control, std::string_view val) = 0;
|
||||
};
|
||||
|
||||
struct IStringBinding : IControlBinding
|
||||
{
|
||||
ControlType type() const { return ControlType::String; }
|
||||
static IStringBinding* castTo(IControlBinding* bind)
|
||||
{ return bind->type() == ControlType::String ? static_cast<IStringBinding*>(bind) : nullptr; }
|
||||
virtual std::string getDefault(const Control* control) const {return "";}
|
||||
virtual void changed(const Control* control, std::string_view val)=0;
|
||||
struct CVarControlBinding : IControlBinding {
|
||||
hecl::CVar* m_cvar;
|
||||
CVarControlBinding(hecl::CVar* cvar) : m_cvar(cvar) {}
|
||||
ControlType type() const { return ControlType::CVar; }
|
||||
static CVarControlBinding* castTo(IControlBinding* bind) {
|
||||
return bind->type() == ControlType::CVar ? static_cast<CVarControlBinding*>(bind) : nullptr;
|
||||
}
|
||||
std::string_view name(const Control* control) const { return m_cvar->name(); }
|
||||
std::string_view help(const Control* control) const { return m_cvar->rawHelp(); }
|
||||
};
|
||||
|
||||
struct CVarControlBinding : IControlBinding
|
||||
{
|
||||
hecl::CVar* m_cvar;
|
||||
CVarControlBinding(hecl::CVar* cvar)
|
||||
: m_cvar(cvar) {}
|
||||
ControlType type() const { return ControlType::CVar; }
|
||||
static CVarControlBinding* castTo(IControlBinding* bind)
|
||||
{ return bind->type() == ControlType::CVar ? static_cast<CVarControlBinding*>(bind) : nullptr; }
|
||||
std::string_view name(const Control* control) const {return m_cvar->name();}
|
||||
std::string_view help(const Control* control) const {return m_cvar->rawHelp();}
|
||||
};
|
||||
|
||||
class Control : public View
|
||||
{
|
||||
class Control : public View {
|
||||
protected:
|
||||
IControlBinding* m_controlBinding = nullptr;
|
||||
IControlBinding* m_controlBinding = nullptr;
|
||||
|
||||
public:
|
||||
Control(ViewResources& res, View& parentView, IControlBinding* controlBinding);
|
||||
Control(ViewResources& res, View& parentView, IControlBinding* controlBinding);
|
||||
};
|
||||
|
||||
class ITextInputView : public Control, public boo::ITextInputCallback
|
||||
{
|
||||
|
||||
class ITextInputView : public Control, public boo::ITextInputCallback {
|
||||
protected:
|
||||
static std::recursive_mutex m_textInputLk;
|
||||
ITextInputView(ViewResources& res, View& parentView,
|
||||
IControlBinding* controlBinding)
|
||||
: Control(res, parentView, controlBinding) {}
|
||||
static std::recursive_mutex m_textInputLk;
|
||||
ITextInputView(ViewResources& res, View& parentView, IControlBinding* controlBinding)
|
||||
: Control(res, parentView, controlBinding) {}
|
||||
|
||||
public:
|
||||
virtual void clipboardCopy() {}
|
||||
virtual void clipboardCut() {}
|
||||
virtual void clipboardPaste() {}
|
||||
virtual void clipboardCopy() {}
|
||||
virtual void clipboardCut() {}
|
||||
virtual void clipboardPaste() {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -12,343 +12,286 @@
|
|||
#include "PathButtons.hpp"
|
||||
#include <hecl/hecl.hpp>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class FileBrowser : public ModalWindow, public IPathButtonsBinding
|
||||
{
|
||||
class FileBrowser : public ModalWindow, public IPathButtonsBinding {
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
SaveFile,
|
||||
SaveDirectory,
|
||||
OpenFile,
|
||||
OpenDirectory,
|
||||
NewHECLProject,
|
||||
OpenHECLProject
|
||||
};
|
||||
enum class Type { SaveFile, SaveDirectory, OpenFile, OpenDirectory, NewHECLProject, OpenHECLProject };
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
hecl::SystemString m_path;
|
||||
std::vector<hecl::SystemString> m_comps;
|
||||
bool m_showingHidden = false;
|
||||
Type m_type;
|
||||
hecl::SystemString m_path;
|
||||
std::vector<hecl::SystemString> m_comps;
|
||||
bool m_showingHidden = false;
|
||||
|
||||
class LeftSide : public View
|
||||
{
|
||||
friend class FileBrowser;
|
||||
FileBrowser& m_fb;
|
||||
LeftSide(FileBrowser& fb, ViewResources& res) : View(res, fb), m_fb(fb) {}
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
} m_left;
|
||||
class LeftSide : public View {
|
||||
friend class FileBrowser;
|
||||
FileBrowser& m_fb;
|
||||
LeftSide(FileBrowser& fb, ViewResources& res) : View(res, fb), m_fb(fb) {}
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
} m_left;
|
||||
|
||||
class RightSide : public View
|
||||
{
|
||||
friend class FileBrowser;
|
||||
FileBrowser& m_fb;
|
||||
RightSide(FileBrowser& fb, ViewResources& res) : View(res, fb), m_fb(fb) {}
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
} m_right;
|
||||
class RightSide : public View {
|
||||
friend class FileBrowser;
|
||||
FileBrowser& m_fb;
|
||||
RightSide(FileBrowser& fb, ViewResources& res) : View(res, fb), m_fb(fb) {}
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
} m_right;
|
||||
|
||||
ViewChild<std::unique_ptr<SplitView>> m_split;
|
||||
ViewChild<std::unique_ptr<SplitView>> m_split;
|
||||
|
||||
void okActivated(bool viaButton);
|
||||
struct OKButton : IButtonBinding
|
||||
{
|
||||
FileBrowser& m_fb;
|
||||
ViewChild<std::unique_ptr<Button>> m_button;
|
||||
std::string m_text;
|
||||
OKButton(FileBrowser& fb, ViewResources& res, std::string_view text)
|
||||
: m_fb(fb), m_text(text)
|
||||
{
|
||||
m_button.m_view.reset(new Button(res, fb, this, text, nullptr, Button::Style::Block, zeus::CColor::skWhite,
|
||||
RectangleConstraint(100 * res.pixelFactor(), -1, RectangleConstraint::Test::Minimum)));
|
||||
}
|
||||
std::string_view name(const Control* control) const {return m_text;}
|
||||
void activated(const Button* button, const boo::SWindowCoord&) {m_fb.okActivated(true);}
|
||||
} m_ok;
|
||||
void okActivated(bool viaButton);
|
||||
struct OKButton : IButtonBinding {
|
||||
FileBrowser& m_fb;
|
||||
ViewChild<std::unique_ptr<Button>> m_button;
|
||||
std::string m_text;
|
||||
OKButton(FileBrowser& fb, ViewResources& res, std::string_view text) : m_fb(fb), m_text(text) {
|
||||
m_button.m_view.reset(
|
||||
new Button(res, fb, this, text, nullptr, Button::Style::Block, zeus::CColor::skWhite,
|
||||
RectangleConstraint(100 * res.pixelFactor(), -1, RectangleConstraint::Test::Minimum)));
|
||||
}
|
||||
std::string_view name(const Control* control) const { return m_text; }
|
||||
void activated(const Button* button, const boo::SWindowCoord&) { m_fb.okActivated(true); }
|
||||
} m_ok;
|
||||
|
||||
void cancelActivated();
|
||||
struct CancelButton : IButtonBinding
|
||||
{
|
||||
FileBrowser& m_fb;
|
||||
ViewChild<std::unique_ptr<Button>> m_button;
|
||||
std::string m_text;
|
||||
CancelButton(FileBrowser& fb, ViewResources& res, std::string_view text)
|
||||
: m_fb(fb), m_text(text)
|
||||
{
|
||||
m_button.m_view.reset(new Button(res, fb, this, text, nullptr, Button::Style::Block, zeus::CColor::skWhite,
|
||||
RectangleConstraint(m_fb.m_ok.m_button.m_view->nominalWidth(), -1, RectangleConstraint::Test::Minimum)));
|
||||
}
|
||||
std::string_view name(const Control* control) const {return m_text;}
|
||||
void activated(const Button* button, const boo::SWindowCoord&) {m_fb.cancelActivated();}
|
||||
} m_cancel;
|
||||
void cancelActivated();
|
||||
struct CancelButton : IButtonBinding {
|
||||
FileBrowser& m_fb;
|
||||
ViewChild<std::unique_ptr<Button>> m_button;
|
||||
std::string m_text;
|
||||
CancelButton(FileBrowser& fb, ViewResources& res, std::string_view text) : m_fb(fb), m_text(text) {
|
||||
m_button.m_view.reset(new Button(
|
||||
res, fb, this, text, nullptr, Button::Style::Block, zeus::CColor::skWhite,
|
||||
RectangleConstraint(m_fb.m_ok.m_button.m_view->nominalWidth(), -1, RectangleConstraint::Test::Minimum)));
|
||||
}
|
||||
std::string_view name(const Control* control) const { return m_text; }
|
||||
void activated(const Button* button, const boo::SWindowCoord&) { m_fb.cancelActivated(); }
|
||||
} m_cancel;
|
||||
|
||||
void pathButtonActivated(size_t idx);
|
||||
ViewChild<std::unique_ptr<PathButtons>> m_pathButtons;
|
||||
void pathButtonActivated(size_t idx);
|
||||
ViewChild<std::unique_ptr<PathButtons>> m_pathButtons;
|
||||
|
||||
ViewChild<std::unique_ptr<TextField>> m_fileField;
|
||||
struct FileFieldBind : IStringBinding
|
||||
{
|
||||
FileBrowser& m_browser;
|
||||
std::string m_name;
|
||||
FileFieldBind(FileBrowser& browser, const IViewManager& vm)
|
||||
: m_browser(browser), m_name(vm.translateOr("file_name", "File Name")) {}
|
||||
std::string_view name(const Control* control) const {return m_name;}
|
||||
void changed(const Control* control, std::string_view val)
|
||||
{
|
||||
}
|
||||
} m_fileFieldBind;
|
||||
ViewChild<std::unique_ptr<TextField>> m_fileField;
|
||||
struct FileFieldBind : IStringBinding {
|
||||
FileBrowser& m_browser;
|
||||
std::string m_name;
|
||||
FileFieldBind(FileBrowser& browser, const IViewManager& vm)
|
||||
: m_browser(browser), m_name(vm.translateOr("file_name", "File Name")) {}
|
||||
std::string_view name(const Control* control) const { return m_name; }
|
||||
void changed(const Control* control, std::string_view val) {}
|
||||
} m_fileFieldBind;
|
||||
|
||||
std::unique_ptr<MessageWindow> m_confirmWindow;
|
||||
std::unique_ptr<MessageWindow> m_confirmWindow;
|
||||
|
||||
struct FileListingDataBind : ITableDataBinding, ITableStateBinding
|
||||
{
|
||||
FileBrowser& m_fb;
|
||||
struct FileListingDataBind : ITableDataBinding, ITableStateBinding {
|
||||
FileBrowser& m_fb;
|
||||
|
||||
struct Entry
|
||||
{
|
||||
hecl::SystemString m_path;
|
||||
std::string m_name;
|
||||
std::string m_type;
|
||||
std::string m_size;
|
||||
};
|
||||
std::vector<Entry> m_entries;
|
||||
|
||||
std::string m_nameCol;
|
||||
std::string m_typeCol;
|
||||
std::string m_sizeCol;
|
||||
|
||||
std::string m_dirStr;
|
||||
std::string m_projStr;
|
||||
std::string m_fileStr;
|
||||
|
||||
size_t columnCount() const {return 3;}
|
||||
size_t rowCount() const {return m_entries.size();}
|
||||
|
||||
std::string_view header(size_t cIdx) const
|
||||
{
|
||||
switch (cIdx)
|
||||
{
|
||||
case 0:
|
||||
return m_nameCol;
|
||||
case 1:
|
||||
return m_typeCol;
|
||||
case 2:
|
||||
return m_sizeCol;
|
||||
default: break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string_view cell(size_t cIdx, size_t rIdx) const
|
||||
{
|
||||
switch (cIdx)
|
||||
{
|
||||
case 0:
|
||||
return m_entries.at(rIdx).m_name;
|
||||
case 1:
|
||||
return m_entries.at(rIdx).m_type;
|
||||
case 2:
|
||||
return m_entries.at(rIdx).m_size;
|
||||
default: break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float m_columnSplits[3] = {0.0f, 0.7f, 0.9f};
|
||||
|
||||
bool columnSplitResizeAllowed() const {return true;}
|
||||
|
||||
float getColumnSplit(size_t cIdx) const
|
||||
{
|
||||
return m_columnSplits[cIdx];
|
||||
}
|
||||
|
||||
void setColumnSplit(size_t cIdx, float split)
|
||||
{
|
||||
m_columnSplits[cIdx] = split;
|
||||
}
|
||||
|
||||
void updateListing(const hecl::DirectoryEnumerator& dEnum)
|
||||
{
|
||||
m_entries.clear();
|
||||
m_entries.reserve(dEnum.size());
|
||||
|
||||
for (const hecl::DirectoryEnumerator::Entry& d : dEnum)
|
||||
{
|
||||
m_entries.emplace_back();
|
||||
Entry& ent = m_entries.back();
|
||||
ent.m_path = d.m_path;
|
||||
hecl::SystemUTF8Conv nameUtf8(d.m_name);
|
||||
ent.m_name = nameUtf8.str();
|
||||
if (d.m_isDir)
|
||||
{
|
||||
if (hecl::SearchForProject(d.m_path))
|
||||
ent.m_type = m_projStr;
|
||||
else
|
||||
ent.m_type = m_dirStr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ent.m_type = m_fileStr;
|
||||
ent.m_size = hecl::HumanizeNumber(d.m_fileSz, 7, nullptr, int(hecl::HNScale::AutoScale),
|
||||
hecl::HNFlags::B | hecl::HNFlags::Decimal);
|
||||
}
|
||||
}
|
||||
|
||||
m_needsUpdate = false;
|
||||
}
|
||||
|
||||
bool m_sizeSort = false;
|
||||
SortDirection m_sortDir = SortDirection::Ascending;
|
||||
bool m_needsUpdate = false;
|
||||
|
||||
SortDirection getSort(size_t& cIdx) const
|
||||
{
|
||||
cIdx = m_sizeSort ? 2 : 0;
|
||||
return m_sortDir;
|
||||
}
|
||||
|
||||
void setSort(size_t cIdx, SortDirection dir)
|
||||
{
|
||||
if (cIdx == 1)
|
||||
return;
|
||||
m_sizeSort = cIdx == 2;
|
||||
m_sortDir = dir;
|
||||
m_needsUpdate = true;
|
||||
}
|
||||
|
||||
void setSelectedRow(size_t rIdx)
|
||||
{
|
||||
if (rIdx != -1)
|
||||
m_fb.m_fileField.m_view->setText(m_entries.at(rIdx).m_name);
|
||||
else
|
||||
m_fb.m_fileField.m_view->setText("");
|
||||
m_fb.m_fileField.m_view->clearErrorState();
|
||||
}
|
||||
|
||||
void rowActivated(size_t rIdx)
|
||||
{
|
||||
m_fb.okActivated(false);
|
||||
}
|
||||
|
||||
FileListingDataBind(FileBrowser& fb, const IViewManager& vm)
|
||||
: m_fb(fb)
|
||||
{
|
||||
m_nameCol = vm.translateOr("name", "Name");
|
||||
m_typeCol = vm.translateOr("type", "Type");
|
||||
m_sizeCol = vm.translateOr("size", "Size");
|
||||
m_dirStr = vm.translateOr("directory", "Directory");
|
||||
m_projStr = vm.translateOr("hecl_project", "HECL Project");
|
||||
m_fileStr = vm.translateOr("file", "File");
|
||||
}
|
||||
|
||||
} m_fileListingBind;
|
||||
ViewChild<std::unique_ptr<Table>> m_fileListing;
|
||||
|
||||
struct BookmarkDataBind : ITableDataBinding, ITableStateBinding
|
||||
{
|
||||
FileBrowser& m_fb;
|
||||
BookmarkDataBind(FileBrowser& fb) : m_fb(fb) {}
|
||||
|
||||
struct Entry
|
||||
{
|
||||
hecl::SystemString m_path;
|
||||
std::string m_name;
|
||||
|
||||
Entry(std::pair<hecl::SystemString, std::string>&& path)
|
||||
: m_path(std::move(path.first)), m_name(std::move(path.second)) {}
|
||||
|
||||
Entry(hecl::SystemStringView path)
|
||||
: m_path(path)
|
||||
{
|
||||
hecl::SystemUTF8Conv utf8(path);
|
||||
if (utf8.str().size() == 1 && utf8.str()[0] == '/')
|
||||
{
|
||||
m_name = "/";
|
||||
return;
|
||||
}
|
||||
size_t lastSlash = utf8.str().rfind('/');
|
||||
if (lastSlash != std::string::npos)
|
||||
m_name.assign(utf8.str().cbegin() + lastSlash + 1, utf8.str().cend());
|
||||
else
|
||||
m_name = utf8.str();
|
||||
}
|
||||
};
|
||||
std::vector<Entry> m_entries;
|
||||
|
||||
size_t columnCount() const {return 1;}
|
||||
size_t rowCount() const {return m_entries.size();}
|
||||
|
||||
std::string_view cell(size_t, size_t rIdx) const
|
||||
{
|
||||
return m_entries.at(rIdx).m_name;
|
||||
}
|
||||
|
||||
void setSelectedRow(size_t rIdx)
|
||||
{
|
||||
if (rIdx != -1)
|
||||
m_fb.navigateToPath(m_entries.at(rIdx).m_path);
|
||||
}
|
||||
|
||||
void rowActivated(size_t rIdx)
|
||||
{
|
||||
m_fb.okActivated(true);
|
||||
}
|
||||
struct Entry {
|
||||
hecl::SystemString m_path;
|
||||
std::string m_name;
|
||||
std::string m_type;
|
||||
std::string m_size;
|
||||
};
|
||||
std::vector<Entry> m_entries;
|
||||
|
||||
BookmarkDataBind m_systemBookmarkBind;
|
||||
std::unique_ptr<TextView> m_systemBookmarksLabel;
|
||||
ViewChild<std::unique_ptr<Table>> m_systemBookmarks;
|
||||
std::string m_nameCol;
|
||||
std::string m_typeCol;
|
||||
std::string m_sizeCol;
|
||||
|
||||
BookmarkDataBind m_projectBookmarkBind;
|
||||
std::unique_ptr<TextView> m_projectBookmarksLabel;
|
||||
ViewChild<std::unique_ptr<Table>> m_projectBookmarks;
|
||||
std::string m_dirStr;
|
||||
std::string m_projStr;
|
||||
std::string m_fileStr;
|
||||
|
||||
BookmarkDataBind m_recentBookmarkBind;
|
||||
std::unique_ptr<TextView> m_recentBookmarksLabel;
|
||||
ViewChild<std::unique_ptr<Table>> m_recentBookmarks;
|
||||
size_t columnCount() const { return 3; }
|
||||
size_t rowCount() const { return m_entries.size(); }
|
||||
|
||||
std::function<void(bool, hecl::SystemStringView)> m_returnFunc;
|
||||
std::string_view header(size_t cIdx) const {
|
||||
switch (cIdx) {
|
||||
case 0:
|
||||
return m_nameCol;
|
||||
case 1:
|
||||
return m_typeCol;
|
||||
case 2:
|
||||
return m_sizeCol;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string_view cell(size_t cIdx, size_t rIdx) const {
|
||||
switch (cIdx) {
|
||||
case 0:
|
||||
return m_entries.at(rIdx).m_name;
|
||||
case 1:
|
||||
return m_entries.at(rIdx).m_type;
|
||||
case 2:
|
||||
return m_entries.at(rIdx).m_size;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
float m_columnSplits[3] = {0.0f, 0.7f, 0.9f};
|
||||
|
||||
bool columnSplitResizeAllowed() const { return true; }
|
||||
|
||||
float getColumnSplit(size_t cIdx) const { return m_columnSplits[cIdx]; }
|
||||
|
||||
void setColumnSplit(size_t cIdx, float split) { m_columnSplits[cIdx] = split; }
|
||||
|
||||
void updateListing(const hecl::DirectoryEnumerator& dEnum) {
|
||||
m_entries.clear();
|
||||
m_entries.reserve(dEnum.size());
|
||||
|
||||
for (const hecl::DirectoryEnumerator::Entry& d : dEnum) {
|
||||
m_entries.emplace_back();
|
||||
Entry& ent = m_entries.back();
|
||||
ent.m_path = d.m_path;
|
||||
hecl::SystemUTF8Conv nameUtf8(d.m_name);
|
||||
ent.m_name = nameUtf8.str();
|
||||
if (d.m_isDir) {
|
||||
if (hecl::SearchForProject(d.m_path))
|
||||
ent.m_type = m_projStr;
|
||||
else
|
||||
ent.m_type = m_dirStr;
|
||||
} else {
|
||||
ent.m_type = m_fileStr;
|
||||
ent.m_size = hecl::HumanizeNumber(d.m_fileSz, 7, nullptr, int(hecl::HNScale::AutoScale),
|
||||
hecl::HNFlags::B | hecl::HNFlags::Decimal);
|
||||
}
|
||||
}
|
||||
|
||||
m_needsUpdate = false;
|
||||
}
|
||||
|
||||
bool m_sizeSort = false;
|
||||
SortDirection m_sortDir = SortDirection::Ascending;
|
||||
bool m_needsUpdate = false;
|
||||
|
||||
SortDirection getSort(size_t& cIdx) const {
|
||||
cIdx = m_sizeSort ? 2 : 0;
|
||||
return m_sortDir;
|
||||
}
|
||||
|
||||
void setSort(size_t cIdx, SortDirection dir) {
|
||||
if (cIdx == 1)
|
||||
return;
|
||||
m_sizeSort = cIdx == 2;
|
||||
m_sortDir = dir;
|
||||
m_needsUpdate = true;
|
||||
}
|
||||
|
||||
void setSelectedRow(size_t rIdx) {
|
||||
if (rIdx != -1)
|
||||
m_fb.m_fileField.m_view->setText(m_entries.at(rIdx).m_name);
|
||||
else
|
||||
m_fb.m_fileField.m_view->setText("");
|
||||
m_fb.m_fileField.m_view->clearErrorState();
|
||||
}
|
||||
|
||||
void rowActivated(size_t rIdx) { m_fb.okActivated(false); }
|
||||
|
||||
FileListingDataBind(FileBrowser& fb, const IViewManager& vm) : m_fb(fb) {
|
||||
m_nameCol = vm.translateOr("name", "Name");
|
||||
m_typeCol = vm.translateOr("type", "Type");
|
||||
m_sizeCol = vm.translateOr("size", "Size");
|
||||
m_dirStr = vm.translateOr("directory", "Directory");
|
||||
m_projStr = vm.translateOr("hecl_project", "HECL Project");
|
||||
m_fileStr = vm.translateOr("file", "File");
|
||||
}
|
||||
|
||||
} m_fileListingBind;
|
||||
ViewChild<std::unique_ptr<Table>> m_fileListing;
|
||||
|
||||
struct BookmarkDataBind : ITableDataBinding, ITableStateBinding {
|
||||
FileBrowser& m_fb;
|
||||
BookmarkDataBind(FileBrowser& fb) : m_fb(fb) {}
|
||||
|
||||
struct Entry {
|
||||
hecl::SystemString m_path;
|
||||
std::string m_name;
|
||||
|
||||
Entry(std::pair<hecl::SystemString, std::string>&& path)
|
||||
: m_path(std::move(path.first)), m_name(std::move(path.second)) {}
|
||||
|
||||
Entry(hecl::SystemStringView path) : m_path(path) {
|
||||
hecl::SystemUTF8Conv utf8(path);
|
||||
if (utf8.str().size() == 1 && utf8.str()[0] == '/') {
|
||||
m_name = "/";
|
||||
return;
|
||||
}
|
||||
size_t lastSlash = utf8.str().rfind('/');
|
||||
if (lastSlash != std::string::npos)
|
||||
m_name.assign(utf8.str().cbegin() + lastSlash + 1, utf8.str().cend());
|
||||
else
|
||||
m_name = utf8.str();
|
||||
}
|
||||
};
|
||||
std::vector<Entry> m_entries;
|
||||
|
||||
size_t columnCount() const { return 1; }
|
||||
size_t rowCount() const { return m_entries.size(); }
|
||||
|
||||
std::string_view cell(size_t, size_t rIdx) const { return m_entries.at(rIdx).m_name; }
|
||||
|
||||
void setSelectedRow(size_t rIdx) {
|
||||
if (rIdx != -1)
|
||||
m_fb.navigateToPath(m_entries.at(rIdx).m_path);
|
||||
}
|
||||
|
||||
void rowActivated(size_t rIdx) { m_fb.okActivated(true); }
|
||||
};
|
||||
|
||||
BookmarkDataBind m_systemBookmarkBind;
|
||||
std::unique_ptr<TextView> m_systemBookmarksLabel;
|
||||
ViewChild<std::unique_ptr<Table>> m_systemBookmarks;
|
||||
|
||||
BookmarkDataBind m_projectBookmarkBind;
|
||||
std::unique_ptr<TextView> m_projectBookmarksLabel;
|
||||
ViewChild<std::unique_ptr<Table>> m_projectBookmarks;
|
||||
|
||||
BookmarkDataBind m_recentBookmarkBind;
|
||||
std::unique_ptr<TextView> m_recentBookmarksLabel;
|
||||
ViewChild<std::unique_ptr<Table>> m_recentBookmarks;
|
||||
|
||||
std::function<void(bool, hecl::SystemStringView)> m_returnFunc;
|
||||
|
||||
public:
|
||||
FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type,
|
||||
std::function<void(bool, hecl::SystemStringView)> returnFunc)
|
||||
: FileBrowser(res, parentView, title, type, hecl::GetcwdStr(), returnFunc) {}
|
||||
FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type,
|
||||
hecl::SystemStringView initialPath,
|
||||
std::function<void(bool, hecl::SystemStringView)> returnFunc);
|
||||
FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type,
|
||||
std::function<void(bool, hecl::SystemStringView)> returnFunc)
|
||||
: FileBrowser(res, parentView, title, type, hecl::GetcwdStr(), returnFunc) {}
|
||||
FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type,
|
||||
hecl::SystemStringView initialPath, std::function<void(bool, hecl::SystemStringView)> returnFunc);
|
||||
|
||||
static std::vector<hecl::SystemString> PathComponents(hecl::SystemStringView path);
|
||||
static void SyncBookmarkSelections(Table& table, BookmarkDataBind& binding,
|
||||
const hecl::SystemString& sel);
|
||||
static std::vector<hecl::SystemString> PathComponents(hecl::SystemStringView path);
|
||||
static void SyncBookmarkSelections(Table& table, BookmarkDataBind& binding, const hecl::SystemString& sel);
|
||||
|
||||
void navigateToPath(hecl::SystemStringView path);
|
||||
bool showingHidden() const {return m_showingHidden;}
|
||||
void setShowingHidden(bool showingHidden)
|
||||
{
|
||||
m_showingHidden = showingHidden;
|
||||
navigateToPath(m_path);
|
||||
}
|
||||
void updateContentOpacity(float opacity);
|
||||
void navigateToPath(hecl::SystemStringView path);
|
||||
bool showingHidden() const { return m_showingHidden; }
|
||||
void setShowingHidden(bool showingHidden) {
|
||||
m_showingHidden = showingHidden;
|
||||
navigateToPath(m_path);
|
||||
}
|
||||
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 mouseLeave(const boo::SWindowCoord&);
|
||||
void scroll(const boo::SWindowCoord&, const boo::SScrollDelta&);
|
||||
void touchDown(const boo::STouchCoord&, uintptr_t);
|
||||
void touchUp(const boo::STouchCoord&, uintptr_t);
|
||||
void touchMove(const boo::STouchCoord&, uintptr_t);
|
||||
void charKeyDown(unsigned long, boo::EModifierKey, bool);
|
||||
void specialKeyDown(boo::ESpecialKey, boo::EModifierKey, bool);
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void scroll(const boo::SWindowCoord&, const boo::SScrollDelta&);
|
||||
void touchDown(const boo::STouchCoord&, uintptr_t);
|
||||
void touchUp(const boo::STouchCoord&, uintptr_t);
|
||||
void touchMove(const boo::STouchCoord&, uintptr_t);
|
||||
void charKeyDown(unsigned long, boo::EModifierKey, bool);
|
||||
void specialKeyDown(boo::ESpecialKey, boo::EModifierKey, bool);
|
||||
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void think();
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void think();
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -9,194 +9,188 @@
|
|||
#include <athena/FileWriter.hpp>
|
||||
#include <athena/DNA.hpp>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
class FontTag
|
||||
{
|
||||
friend class FontCache;
|
||||
uint64_t m_hash = 0;
|
||||
FontTag(std::string_view name, bool subpixel, float points, unsigned dpi);
|
||||
namespace specter {
|
||||
class FontTag {
|
||||
friend class FontCache;
|
||||
uint64_t m_hash = 0;
|
||||
FontTag(std::string_view name, bool subpixel, float points, unsigned dpi);
|
||||
|
||||
public:
|
||||
FontTag() = default;
|
||||
operator bool() const {return m_hash != 0;}
|
||||
uint64_t hash() const {return m_hash;}
|
||||
bool operator==(const FontTag& other) const {return m_hash == other.m_hash;}
|
||||
FontTag() = default;
|
||||
operator bool() const { return m_hash != 0; }
|
||||
uint64_t hash() const { return m_hash; }
|
||||
bool operator==(const FontTag& other) const { return m_hash == other.m_hash; }
|
||||
};
|
||||
}
|
||||
} // namespace specter
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <> struct hash<specter::FontTag>
|
||||
{
|
||||
size_t operator() (const specter::FontTag& handle) const noexcept
|
||||
{return size_t(handle.hash());}
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<specter::FontTag> {
|
||||
size_t operator()(const specter::FontTag& handle) const noexcept { return size_t(handle.hash()); }
|
||||
};
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class FreeTypeGZipMemFace {
|
||||
FT_Library m_lib;
|
||||
FT_StreamRec m_comp = {};
|
||||
FT_StreamRec m_decomp = {};
|
||||
FT_Face m_face = nullptr;
|
||||
|
||||
class FreeTypeGZipMemFace
|
||||
{
|
||||
FT_Library m_lib;
|
||||
FT_StreamRec m_comp = {};
|
||||
FT_StreamRec m_decomp = {};
|
||||
FT_Face m_face = nullptr;
|
||||
public:
|
||||
FreeTypeGZipMemFace(FT_Library lib, const uint8_t* data, size_t sz);
|
||||
FreeTypeGZipMemFace(const FreeTypeGZipMemFace& other) = delete;
|
||||
FreeTypeGZipMemFace& operator=(const FreeTypeGZipMemFace& other) = delete;
|
||||
~FreeTypeGZipMemFace() {close();}
|
||||
void open();
|
||||
void close();
|
||||
operator FT_Face() {open(); return m_face;}
|
||||
FreeTypeGZipMemFace(FT_Library lib, const uint8_t* data, size_t sz);
|
||||
FreeTypeGZipMemFace(const FreeTypeGZipMemFace& other) = delete;
|
||||
FreeTypeGZipMemFace& operator=(const FreeTypeGZipMemFace& other) = delete;
|
||||
~FreeTypeGZipMemFace() { close(); }
|
||||
void open();
|
||||
void close();
|
||||
operator FT_Face() {
|
||||
open();
|
||||
return m_face;
|
||||
}
|
||||
};
|
||||
|
||||
using FCharFilter = std::pair<std::string, std::function<bool(uint32_t)>>;
|
||||
|
||||
class FontAtlas
|
||||
{
|
||||
FT_Face m_face;
|
||||
std::vector<uint8_t> m_texmap;
|
||||
boo::ObjToken<boo::ITextureSA> m_tex;
|
||||
uint32_t m_dpi;
|
||||
FT_Fixed m_ftXscale;
|
||||
FT_UShort m_ftXPpem;
|
||||
FT_Pos m_lineHeight;
|
||||
unsigned m_finalHeight;
|
||||
unsigned m_fullTexmapLayers;
|
||||
bool m_subpixel;
|
||||
bool m_ready = false;
|
||||
class FontAtlas {
|
||||
FT_Face m_face;
|
||||
std::vector<uint8_t> m_texmap;
|
||||
boo::ObjToken<boo::ITextureSA> m_tex;
|
||||
uint32_t m_dpi;
|
||||
FT_Fixed m_ftXscale;
|
||||
FT_UShort m_ftXPpem;
|
||||
FT_Pos m_lineHeight;
|
||||
unsigned m_finalHeight;
|
||||
unsigned m_fullTexmapLayers;
|
||||
bool m_subpixel;
|
||||
bool m_ready = false;
|
||||
|
||||
public:
|
||||
struct Glyph
|
||||
{
|
||||
atUint32 m_unicodePoint;
|
||||
atUint32 m_glyphIdx;
|
||||
atUint32 m_layerIdx;
|
||||
float m_layerFloat;
|
||||
float m_uv[4];
|
||||
atInt32 m_leftPadding;
|
||||
atInt32 m_advance;
|
||||
atInt32 m_width;
|
||||
atInt32 m_height;
|
||||
atInt32 m_verticalOffset;
|
||||
};
|
||||
struct Glyph {
|
||||
atUint32 m_unicodePoint;
|
||||
atUint32 m_glyphIdx;
|
||||
atUint32 m_layerIdx;
|
||||
float m_layerFloat;
|
||||
float m_uv[4];
|
||||
atInt32 m_leftPadding;
|
||||
atInt32 m_advance;
|
||||
atInt32 m_width;
|
||||
atInt32 m_height;
|
||||
atInt32 m_verticalOffset;
|
||||
};
|
||||
|
||||
private:
|
||||
std::vector<Glyph> m_glyphs;
|
||||
std::unordered_map<atUint16, std::vector<std::pair<atUint16, atInt16>>> m_kernAdjs;
|
||||
std::vector<Glyph> m_glyphs;
|
||||
std::unordered_map<atUint16, std::vector<std::pair<atUint16, atInt16>>> m_kernAdjs;
|
||||
|
||||
struct TT_KernHead : athena::io::DNA<athena::Big>
|
||||
{
|
||||
AT_DECL_DNA
|
||||
Value<atUint32> length;
|
||||
Value<atUint16> coverage;
|
||||
};
|
||||
struct TT_KernHead : athena::io::DNA<athena::Big> {
|
||||
AT_DECL_DNA
|
||||
Value<atUint32> length;
|
||||
Value<atUint16> coverage;
|
||||
};
|
||||
|
||||
struct TT_KernSubHead : athena::io::DNA<athena::Big>
|
||||
{
|
||||
AT_DECL_DNA
|
||||
Value<atUint16> nPairs;
|
||||
Value<atUint16> searchRange;
|
||||
Value<atUint16> entrySelector;
|
||||
Value<atUint16> rangeShift;
|
||||
};
|
||||
struct TT_KernSubHead : athena::io::DNA<athena::Big> {
|
||||
AT_DECL_DNA
|
||||
Value<atUint16> nPairs;
|
||||
Value<atUint16> searchRange;
|
||||
Value<atUint16> entrySelector;
|
||||
Value<atUint16> rangeShift;
|
||||
};
|
||||
|
||||
struct TT_KernPair : athena::io::DNA<athena::Big>
|
||||
{
|
||||
AT_DECL_DNA
|
||||
Value<atUint16> left;
|
||||
Value<atUint16> right;
|
||||
Value<atInt16> value;
|
||||
};
|
||||
struct TT_KernPair : athena::io::DNA<athena::Big> {
|
||||
AT_DECL_DNA
|
||||
Value<atUint16> left;
|
||||
Value<atUint16> right;
|
||||
Value<atInt16> value;
|
||||
};
|
||||
|
||||
void buildKernTable(FT_Face face);
|
||||
void buildKernTable(FT_Face face);
|
||||
|
||||
std::unordered_map<atUint32, size_t> m_glyphLookup;
|
||||
std::unordered_map<atUint32, size_t> m_glyphLookup;
|
||||
|
||||
public:
|
||||
FontAtlas(FT_Face face, uint32_t dpi,
|
||||
bool subpixel, FCharFilter& filter, athena::io::FileWriter& writer);
|
||||
FontAtlas(FT_Face face, uint32_t dpi,
|
||||
bool subpixel, FCharFilter& filter, athena::io::FileReader& reader);
|
||||
FontAtlas(const FontAtlas& other) = delete;
|
||||
FontAtlas& operator=(const FontAtlas& other) = delete;
|
||||
FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& filter, athena::io::FileWriter& writer);
|
||||
FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& filter, athena::io::FileReader& reader);
|
||||
FontAtlas(const FontAtlas& other) = delete;
|
||||
FontAtlas& operator=(const FontAtlas& other) = delete;
|
||||
|
||||
uint32_t dpi() const {return m_dpi;}
|
||||
FT_Fixed FT_Xscale() const {return m_ftXscale;}
|
||||
FT_UShort FT_XPPem() const {return m_ftXPpem;}
|
||||
FT_Pos FT_LineHeight() const {return m_lineHeight;}
|
||||
bool isReady() const { return m_ready; }
|
||||
boo::ObjToken<boo::ITextureSA> texture(boo::IGraphicsDataFactory* gf) const;
|
||||
bool subpixel() const {return m_subpixel;}
|
||||
uint32_t dpi() const { return m_dpi; }
|
||||
FT_Fixed FT_Xscale() const { return m_ftXscale; }
|
||||
FT_UShort FT_XPPem() const { return m_ftXPpem; }
|
||||
FT_Pos FT_LineHeight() const { return m_lineHeight; }
|
||||
bool isReady() const { return m_ready; }
|
||||
boo::ObjToken<boo::ITextureSA> texture(boo::IGraphicsDataFactory* gf) const;
|
||||
bool subpixel() const { return m_subpixel; }
|
||||
|
||||
const Glyph* lookupGlyph(atUint32 charcode) const
|
||||
{
|
||||
auto search = m_glyphLookup.find(charcode);
|
||||
if (search == m_glyphLookup.end())
|
||||
return nullptr;
|
||||
return &m_glyphs[search->second];
|
||||
}
|
||||
atInt16 lookupKern(atUint32 leftIdx, atUint32 rightIdx) const
|
||||
{
|
||||
auto pairSearch = m_kernAdjs.find(leftIdx);
|
||||
if (pairSearch == m_kernAdjs.cend())
|
||||
return 0;
|
||||
for (const std::pair<atUint16, atInt16>& p : pairSearch->second)
|
||||
if (p.first == rightIdx)
|
||||
return p.second;
|
||||
return 0;
|
||||
}
|
||||
const Glyph* lookupGlyph(atUint32 charcode) const {
|
||||
auto search = m_glyphLookup.find(charcode);
|
||||
if (search == m_glyphLookup.end())
|
||||
return nullptr;
|
||||
return &m_glyphs[search->second];
|
||||
}
|
||||
atInt16 lookupKern(atUint32 leftIdx, atUint32 rightIdx) const {
|
||||
auto pairSearch = m_kernAdjs.find(leftIdx);
|
||||
if (pairSearch == m_kernAdjs.cend())
|
||||
return 0;
|
||||
for (const std::pair<atUint16, atInt16>& p : pairSearch->second)
|
||||
if (p.first == rightIdx)
|
||||
return p.second;
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
extern const FCharFilter AllCharFilter;
|
||||
extern const FCharFilter LatinCharFilter;
|
||||
extern const FCharFilter LatinAndJapaneseCharFilter;
|
||||
|
||||
class FontCache
|
||||
{
|
||||
const hecl::Runtime::FileStoreManager& m_fileMgr;
|
||||
hecl::SystemString m_cacheRoot;
|
||||
struct Library
|
||||
{
|
||||
FT_Library m_lib;
|
||||
Library();
|
||||
~Library();
|
||||
operator FT_Library() {return m_lib;}
|
||||
} m_fontLib;
|
||||
FreeTypeGZipMemFace m_regFace;
|
||||
FreeTypeGZipMemFace m_monoFace;
|
||||
FreeTypeGZipMemFace m_curvesFace;
|
||||
class FontCache {
|
||||
const hecl::Runtime::FileStoreManager& m_fileMgr;
|
||||
hecl::SystemString m_cacheRoot;
|
||||
struct Library {
|
||||
FT_Library m_lib;
|
||||
Library();
|
||||
~Library();
|
||||
operator FT_Library() { return m_lib; }
|
||||
} m_fontLib;
|
||||
FreeTypeGZipMemFace m_regFace;
|
||||
FreeTypeGZipMemFace m_monoFace;
|
||||
FreeTypeGZipMemFace m_curvesFace;
|
||||
|
||||
std::unordered_map<FontTag, std::unique_ptr<FontAtlas>> m_cachedAtlases;
|
||||
|
||||
std::unordered_map<FontTag, std::unique_ptr<FontAtlas>> m_cachedAtlases;
|
||||
public:
|
||||
FontCache(const hecl::Runtime::FileStoreManager& fileMgr);
|
||||
FontCache(const FontCache& other) = delete;
|
||||
FontCache& operator=(const FontCache& other) = delete;
|
||||
FontCache(const hecl::Runtime::FileStoreManager& fileMgr);
|
||||
FontCache(const FontCache& other) = delete;
|
||||
FontCache& operator=(const FontCache& other) = delete;
|
||||
|
||||
FontTag prepCustomFont(std::string_view name, FT_Face face,
|
||||
FCharFilter filter=AllCharFilter, bool subpixel=false,
|
||||
float points=10.0, uint32_t dpi=72);
|
||||
FontTag prepCustomFont(std::string_view name, FT_Face face, FCharFilter filter = AllCharFilter, bool subpixel = false,
|
||||
float points = 10.0, uint32_t dpi = 72);
|
||||
|
||||
FontTag prepMainFont(FCharFilter filter=AllCharFilter,
|
||||
bool subpixel=false, float points=10.0, uint32_t dpi=72)
|
||||
{return prepCustomFont("droidsans-permissive", m_regFace, filter, subpixel, points, dpi);}
|
||||
FontTag prepMainFont(FCharFilter filter = AllCharFilter, bool subpixel = false, float points = 10.0,
|
||||
uint32_t dpi = 72) {
|
||||
return prepCustomFont("droidsans-permissive", m_regFace, filter, subpixel, points, dpi);
|
||||
}
|
||||
|
||||
FontTag prepMonoFont(FCharFilter filter=AllCharFilter,
|
||||
bool subpixel=false, float points=10.0, uint32_t dpi=72)
|
||||
{return prepCustomFont("bmonofont", m_monoFace, filter, subpixel, points, dpi);}
|
||||
FontTag prepMonoFont(FCharFilter filter = AllCharFilter, bool subpixel = false, float points = 10.0,
|
||||
uint32_t dpi = 72) {
|
||||
return prepCustomFont("bmonofont", m_monoFace, filter, subpixel, points, dpi);
|
||||
}
|
||||
|
||||
FontTag prepCurvesFont(FCharFilter filter=AllCharFilter,
|
||||
bool subpixel=false, float points=10.0, uint32_t dpi=72)
|
||||
{return prepCustomFont("spectercurves", m_curvesFace, filter, subpixel, points, dpi);}
|
||||
FontTag prepCurvesFont(FCharFilter filter = AllCharFilter, bool subpixel = false, float points = 10.0,
|
||||
uint32_t dpi = 72) {
|
||||
return prepCustomFont("spectercurves", m_curvesFace, filter, subpixel, points, dpi);
|
||||
}
|
||||
|
||||
void closeBuiltinFonts() {m_regFace.close(); m_monoFace.close(); m_curvesFace.close();}
|
||||
void closeBuiltinFonts() {
|
||||
m_regFace.close();
|
||||
m_monoFace.close();
|
||||
m_curvesFace.close();
|
||||
}
|
||||
|
||||
const FontAtlas& lookupAtlas(FontTag tag) const;
|
||||
const FontAtlas& lookupAtlas(FontTag tag) const;
|
||||
|
||||
void destroyAtlases() {m_cachedAtlases.clear();}
|
||||
void destroyAtlases() { m_cachedAtlases.clear(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -2,17 +2,14 @@
|
|||
|
||||
#include "View.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
struct IMenuNode
|
||||
{
|
||||
virtual boo::ITexture* icon() const {return nullptr;}
|
||||
virtual const std::string* text() const {return nullptr;}
|
||||
virtual size_t subNodeCount() const {return 0;}
|
||||
virtual IMenuNode* subNode(size_t idx) {return nullptr;}
|
||||
virtual void activated(const boo::SWindowCoord& coord) {}
|
||||
struct IMenuNode {
|
||||
virtual boo::ITexture* icon() const { return nullptr; }
|
||||
virtual const std::string* text() const { return nullptr; }
|
||||
virtual size_t subNodeCount() const { return 0; }
|
||||
virtual IMenuNode* subNode(size_t idx) { return nullptr; }
|
||||
virtual void activated(const boo::SWindowCoord& coord) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -4,31 +4,27 @@
|
|||
#include "SplitView.hpp"
|
||||
#include <hecl/hecl.hpp>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
struct ISpaceController;
|
||||
|
||||
struct IViewManager
|
||||
{
|
||||
struct IViewManager {
|
||||
public:
|
||||
virtual const Translator* getTranslator() const {return nullptr;}
|
||||
virtual std::string_view translateOr(std::string_view key, std::string_view vor) const
|
||||
{
|
||||
const Translator* trans = getTranslator();
|
||||
if (trans)
|
||||
return trans->translateOr(key, vor);
|
||||
return vor;
|
||||
}
|
||||
virtual const Translator* getTranslator() const { return nullptr; }
|
||||
virtual std::string_view translateOr(std::string_view key, std::string_view vor) const {
|
||||
const Translator* trans = getTranslator();
|
||||
if (trans)
|
||||
return trans->translateOr(key, vor);
|
||||
return vor;
|
||||
}
|
||||
|
||||
virtual void deferSpaceSplit(ISpaceController* split, SplitView::Axis axis, int thisSlot,
|
||||
const boo::SWindowCoord& coord) {}
|
||||
virtual void deferSpaceSplit(ISpaceController* split, SplitView::Axis axis, int thisSlot,
|
||||
const boo::SWindowCoord& coord) {}
|
||||
|
||||
virtual const std::vector<hecl::SystemString>* recentProjects() const {return nullptr;}
|
||||
virtual void pushRecentProject(hecl::SystemStringView path) {}
|
||||
virtual const std::vector<hecl::SystemString>* recentProjects() const { return nullptr; }
|
||||
virtual void pushRecentProject(hecl::SystemStringView path) {}
|
||||
|
||||
virtual const std::vector<hecl::SystemString>* recentFiles() const {return nullptr;}
|
||||
virtual void pushRecentFile(hecl::SystemStringView path) {}
|
||||
virtual const std::vector<hecl::SystemString>* recentFiles() const { return nullptr; }
|
||||
virtual void pushRecentFile(hecl::SystemStringView path) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -2,71 +2,63 @@
|
|||
|
||||
#include "View.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
struct Icon
|
||||
{
|
||||
boo::ObjToken<boo::ITexture> m_tex;
|
||||
zeus::CVector2f m_uvCoords[4];
|
||||
Icon() = default;
|
||||
Icon(const boo::ObjToken<boo::ITexture>& tex, float rect[4])
|
||||
: m_tex(tex)
|
||||
{
|
||||
m_uvCoords[0][0] = rect[0];
|
||||
m_uvCoords[0][1] = -rect[3];
|
||||
struct Icon {
|
||||
boo::ObjToken<boo::ITexture> m_tex;
|
||||
zeus::CVector2f m_uvCoords[4];
|
||||
Icon() = default;
|
||||
Icon(const boo::ObjToken<boo::ITexture>& tex, float rect[4]) : m_tex(tex) {
|
||||
m_uvCoords[0][0] = rect[0];
|
||||
m_uvCoords[0][1] = -rect[3];
|
||||
|
||||
m_uvCoords[1][0] = rect[0];
|
||||
m_uvCoords[1][1] = -rect[1];
|
||||
m_uvCoords[1][0] = rect[0];
|
||||
m_uvCoords[1][1] = -rect[1];
|
||||
|
||||
m_uvCoords[2][0] = rect[2];
|
||||
m_uvCoords[2][1] = -rect[3];
|
||||
m_uvCoords[2][0] = rect[2];
|
||||
m_uvCoords[2][1] = -rect[3];
|
||||
|
||||
m_uvCoords[3][0] = rect[2];
|
||||
m_uvCoords[3][1] = -rect[1];
|
||||
}
|
||||
m_uvCoords[3][0] = rect[2];
|
||||
m_uvCoords[3][1] = -rect[1];
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t COLS, size_t ROWS>
|
||||
class IconAtlas
|
||||
{
|
||||
boo::ObjToken<boo::ITextureS> m_tex;
|
||||
Icon m_icons[COLS][ROWS];
|
||||
class IconAtlas {
|
||||
boo::ObjToken<boo::ITextureS> m_tex;
|
||||
Icon m_icons[COLS][ROWS];
|
||||
|
||||
Icon MakeIcon(float x, float y) {
|
||||
float rect[] = {x / float(COLS), y / float(ROWS), x / float(COLS) + 1.f / float(COLS),
|
||||
y / float(ROWS) + 1.f / float(ROWS)};
|
||||
return Icon(m_tex.get(), rect);
|
||||
}
|
||||
|
||||
Icon MakeIcon(float x, float y)
|
||||
{
|
||||
float rect[] = {x / float(COLS), y / float(ROWS),
|
||||
x / float(COLS) + 1.f / float(COLS), y / float(ROWS) + 1.f / float(ROWS)};
|
||||
return Icon(m_tex.get(), rect);
|
||||
}
|
||||
public:
|
||||
IconAtlas() = default;
|
||||
operator bool() const {return m_tex;}
|
||||
void initializeAtlas(const boo::ObjToken<boo::ITextureS>& tex)
|
||||
{
|
||||
m_tex = tex;
|
||||
for (int c=0 ; c<COLS ; ++c)
|
||||
for (int r=0 ; r<ROWS ; ++r)
|
||||
m_icons[c][r] = MakeIcon(c, r);
|
||||
}
|
||||
void destroyAtlas()
|
||||
{
|
||||
for (int c=0 ; c<COLS ; ++c)
|
||||
for (int r=0 ; r<ROWS ; ++r)
|
||||
m_icons[c][r].m_tex.reset();
|
||||
m_tex.reset();
|
||||
}
|
||||
Icon& getIcon(size_t c, size_t r) {return m_icons[c][r];}
|
||||
IconAtlas() = default;
|
||||
operator bool() const { return m_tex; }
|
||||
void initializeAtlas(const boo::ObjToken<boo::ITextureS>& tex) {
|
||||
m_tex = tex;
|
||||
for (int c = 0; c < COLS; ++c)
|
||||
for (int r = 0; r < ROWS; ++r)
|
||||
m_icons[c][r] = MakeIcon(c, r);
|
||||
}
|
||||
void destroyAtlas() {
|
||||
for (int c = 0; c < COLS; ++c)
|
||||
for (int r = 0; r < ROWS; ++r)
|
||||
m_icons[c][r].m_tex.reset();
|
||||
m_tex.reset();
|
||||
}
|
||||
Icon& getIcon(size_t c, size_t r) { return m_icons[c][r]; }
|
||||
};
|
||||
|
||||
class IconView : public View
|
||||
{
|
||||
VertexBufferBindingTex m_vertexBinding;
|
||||
class IconView : public View {
|
||||
VertexBufferBindingTex m_vertexBinding;
|
||||
|
||||
public:
|
||||
IconView(ViewResources& res, View& parentView, Icon& icon);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
IconView(ViewResources& res, View& parentView, Icon& icon);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -5,89 +5,82 @@
|
|||
#include "ScrollView.hpp"
|
||||
#include "IMenuNode.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class Menu : public View
|
||||
{
|
||||
IMenuNode* m_rootNode;
|
||||
IMenuNode* m_thisNode;
|
||||
std::unique_ptr<Menu> m_subMenu;
|
||||
std::unique_ptr<TextView> m_headText;
|
||||
class Menu : public View {
|
||||
IMenuNode* m_rootNode;
|
||||
IMenuNode* m_thisNode;
|
||||
std::unique_ptr<Menu> m_subMenu;
|
||||
std::unique_ptr<TextView> m_headText;
|
||||
|
||||
int m_cWidth, m_cHeight, m_cTop;
|
||||
int m_cWidth, m_cHeight, m_cTop;
|
||||
|
||||
SolidShaderVert m_verts[8];
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void setVerts(int width, int height, float pf);
|
||||
SolidShaderVert m_verts[8];
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void setVerts(int width, int height, float pf);
|
||||
|
||||
struct ContentView : View
|
||||
{
|
||||
Menu& m_menu;
|
||||
ContentView(ViewResources& res, Menu& menu);
|
||||
struct ContentView : View {
|
||||
Menu& m_menu;
|
||||
ContentView(ViewResources& res, Menu& menu);
|
||||
|
||||
boo::SWindowRect m_scissorRect;
|
||||
SolidShaderVert m_hlVerts[4];
|
||||
VertexBufferBindingSolid m_hlVertsBinding;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
SolidShaderVert m_hlVerts[4];
|
||||
VertexBufferBindingSolid m_hlVertsBinding;
|
||||
|
||||
size_t m_highlightedItem = -1;
|
||||
void setHighlightedItem(size_t idx);
|
||||
void unsetHighlightedItem(size_t idx)
|
||||
{
|
||||
if (m_highlightedItem == idx)
|
||||
setHighlightedItem(-1);
|
||||
}
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub,
|
||||
const boo::SWindowRect& scissor);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
int nominalWidth() const {return m_menu.m_cWidth;}
|
||||
int nominalHeight() const {return m_menu.m_cHeight;}
|
||||
};
|
||||
std::unique_ptr<ContentView> m_content;
|
||||
ViewChild<std::unique_ptr<ScrollView>> m_scroll;
|
||||
|
||||
struct ItemView : View
|
||||
{
|
||||
Menu& m_menu;
|
||||
std::unique_ptr<TextView> m_textView;
|
||||
size_t m_idx;
|
||||
IMenuNode* m_node;
|
||||
ItemView(ViewResources& res, Menu& menu, std::string_view text, size_t idx, IMenuNode* node);
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
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);
|
||||
};
|
||||
std::vector<ViewChild<std::unique_ptr<ItemView>>> m_items;
|
||||
IMenuNode* m_deferredActivation = nullptr;
|
||||
|
||||
Menu(ViewResources& res, View& parentView, IMenuNode* rootNode, IMenuNode* thisNode);
|
||||
|
||||
public:
|
||||
Menu(ViewResources& res, View& parentView, IMenuNode* rootNode);
|
||||
void reset(IMenuNode* rootNode);
|
||||
size_t m_highlightedItem = -1;
|
||||
void setHighlightedItem(size_t idx);
|
||||
void unsetHighlightedItem(size_t idx) {
|
||||
if (m_highlightedItem == idx)
|
||||
setHighlightedItem(-1);
|
||||
}
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void scroll(const boo::SWindowCoord&, const boo::SScrollDelta&);
|
||||
|
||||
void think();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
int nominalWidth() const { return m_menu.m_cWidth; }
|
||||
int nominalHeight() const { return m_menu.m_cHeight; }
|
||||
};
|
||||
std::unique_ptr<ContentView> m_content;
|
||||
ViewChild<std::unique_ptr<ScrollView>> m_scroll;
|
||||
|
||||
struct ItemView : View {
|
||||
Menu& m_menu;
|
||||
std::unique_ptr<TextView> m_textView;
|
||||
size_t m_idx;
|
||||
IMenuNode* m_node;
|
||||
ItemView(ViewResources& res, Menu& menu, std::string_view text, size_t idx, IMenuNode* node);
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
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);
|
||||
};
|
||||
std::vector<ViewChild<std::unique_ptr<ItemView>>> m_items;
|
||||
IMenuNode* m_deferredActivation = nullptr;
|
||||
|
||||
Menu(ViewResources& res, View& parentView, IMenuNode* rootNode, IMenuNode* thisNode);
|
||||
|
||||
public:
|
||||
Menu(ViewResources& res, View& parentView, IMenuNode* rootNode);
|
||||
void reset(IMenuNode* rootNode);
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void scroll(const boo::SWindowCoord&, const boo::SScrollDelta&);
|
||||
|
||||
void think();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -4,73 +4,56 @@
|
|||
#include "MultiLineTextView.hpp"
|
||||
#include "Button.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class MessageWindow : public ModalWindow
|
||||
{
|
||||
class MessageWindow : public ModalWindow {
|
||||
public:
|
||||
enum class Type
|
||||
{
|
||||
InfoOk,
|
||||
ErrorOk,
|
||||
ConfirmOkCancel
|
||||
};
|
||||
enum class Type { InfoOk, ErrorOk, ConfirmOkCancel };
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
std::function<void(bool ok)> m_func;
|
||||
Type m_type;
|
||||
std::function<void(bool ok)> m_func;
|
||||
|
||||
std::unique_ptr<MultiLineTextView> m_text;
|
||||
std::unique_ptr<MultiLineTextView> m_text;
|
||||
|
||||
struct OKBinding : IButtonBinding
|
||||
{
|
||||
MessageWindow& m_mw;
|
||||
std::string m_name;
|
||||
OKBinding(MessageWindow& mw, std::string_view name) : m_mw(mw), m_name(name) {}
|
||||
std::string_view name(const Control* control) const {return m_name;}
|
||||
void activated(const Button* button, const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_mw.m_func(true);
|
||||
}
|
||||
} m_okBind;
|
||||
ViewChild<std::unique_ptr<Button>> m_ok;
|
||||
struct OKBinding : IButtonBinding {
|
||||
MessageWindow& m_mw;
|
||||
std::string m_name;
|
||||
OKBinding(MessageWindow& mw, std::string_view name) : m_mw(mw), m_name(name) {}
|
||||
std::string_view name(const Control* control) const { return m_name; }
|
||||
void activated(const Button* button, const boo::SWindowCoord& coord) { m_mw.m_func(true); }
|
||||
} m_okBind;
|
||||
ViewChild<std::unique_ptr<Button>> m_ok;
|
||||
|
||||
struct CancelBinding : IButtonBinding
|
||||
{
|
||||
MessageWindow& m_mw;
|
||||
std::string m_name;
|
||||
CancelBinding(MessageWindow& mw, std::string_view name) : m_mw(mw), m_name(name) {}
|
||||
std::string_view name(const Control* control) const {return m_name;}
|
||||
void activated(const Button* button, const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_mw.m_func(false);
|
||||
}
|
||||
} m_cancelBind;
|
||||
ViewChild<std::unique_ptr<Button>> m_cancel;
|
||||
struct CancelBinding : IButtonBinding {
|
||||
MessageWindow& m_mw;
|
||||
std::string m_name;
|
||||
CancelBinding(MessageWindow& mw, std::string_view name) : m_mw(mw), m_name(name) {}
|
||||
std::string_view name(const Control* control) const { return m_name; }
|
||||
void activated(const Button* button, const boo::SWindowCoord& coord) { m_mw.m_func(false); }
|
||||
} m_cancelBind;
|
||||
ViewChild<std::unique_ptr<Button>> m_cancel;
|
||||
|
||||
public:
|
||||
MessageWindow(ViewResources& res, View& parentView,
|
||||
Type type, std::string_view message, std::function<void(bool ok)> func);
|
||||
MessageWindow(ViewResources& res, View& parentView, Type type, std::string_view message,
|
||||
std::function<void(bool ok)> func);
|
||||
|
||||
void updateContentOpacity(float opacity)
|
||||
{
|
||||
zeus::CColor color = zeus::CColor::lerp({1,1,1,0}, {1,1,1,1}, opacity);
|
||||
ModalWindow::setMultiplyColor(color);
|
||||
m_text->setMultiplyColor(color);
|
||||
m_ok.m_view->setMultiplyColor(color);
|
||||
m_cancel.m_view->setMultiplyColor(color);
|
||||
}
|
||||
void updateContentOpacity(float opacity) {
|
||||
zeus::CColor color = zeus::CColor::lerp({1, 1, 1, 0}, {1, 1, 1, 1}, opacity);
|
||||
ModalWindow::setMultiplyColor(color);
|
||||
m_text->setMultiplyColor(color);
|
||||
m_ok.m_view->setMultiplyColor(color);
|
||||
m_cancel.m_view->setMultiplyColor(color);
|
||||
}
|
||||
|
||||
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 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);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -3,82 +3,66 @@
|
|||
#include <specter/View.hpp>
|
||||
#include <specter/MultiLineTextView.hpp>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
class ModalWindow : public View
|
||||
{
|
||||
namespace specter {
|
||||
class ModalWindow : public View {
|
||||
public:
|
||||
enum class Phase
|
||||
{
|
||||
BuildIn,
|
||||
ResWait,
|
||||
Showing,
|
||||
BuildOut,
|
||||
Done
|
||||
};
|
||||
enum class Phase { BuildIn, ResWait, Showing, BuildOut, Done };
|
||||
|
||||
private:
|
||||
int m_frame = 0;
|
||||
int m_contentStartFrame = 0;
|
||||
float m_lineTime = 0.0;
|
||||
int m_frame = 0;
|
||||
int m_contentStartFrame = 0;
|
||||
float m_lineTime = 0.0;
|
||||
|
||||
Phase m_phase = Phase::BuildIn;
|
||||
Phase m_phase = Phase::BuildIn;
|
||||
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
RectangleConstraint m_constraint;
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
RectangleConstraint m_constraint;
|
||||
|
||||
zeus::CColor m_windowBg;
|
||||
zeus::CColor m_windowBgClear;
|
||||
zeus::CColor m_line1;
|
||||
zeus::CColor m_line2;
|
||||
zeus::CColor m_line2Clear;
|
||||
zeus::CColor m_windowBg;
|
||||
zeus::CColor m_windowBgClear;
|
||||
zeus::CColor m_line1;
|
||||
zeus::CColor m_line2;
|
||||
zeus::CColor m_line2Clear;
|
||||
|
||||
ViewBlock m_viewBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_viewBlockBuf;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
SolidShaderVert lineVerts[22];
|
||||
SolidShaderVert fillVerts[16];
|
||||
} m_verts;
|
||||
SolidShaderVert _m_verts[38];
|
||||
};
|
||||
ViewBlock m_viewBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_viewBlockBuf;
|
||||
union {
|
||||
struct {
|
||||
SolidShaderVert lineVerts[22];
|
||||
SolidShaderVert fillVerts[16];
|
||||
} m_verts;
|
||||
SolidShaderVert _m_verts[38];
|
||||
};
|
||||
|
||||
void setLineVerts(int width, int height, float pf, float t);
|
||||
void setLineVertsOut(int width, int height, float pf, float t);
|
||||
void setLineColors(float t);
|
||||
void setLineColorsOut(float t);
|
||||
void setFillVerts(int width, int height, float pf);
|
||||
void setFillColors(float t);
|
||||
void setLineVerts(int width, int height, float pf, float t);
|
||||
void setLineVertsOut(int width, int height, float pf, float t);
|
||||
void setLineColors(float t);
|
||||
void setLineColorsOut(float t);
|
||||
void setFillVerts(int width, int height, float pf);
|
||||
void setFillColors(float t);
|
||||
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void _loadVerts()
|
||||
{
|
||||
m_vertsBinding.load<decltype(_m_verts)>(_m_verts);
|
||||
}
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void _loadVerts() { m_vertsBinding.load<decltype(_m_verts)>(_m_verts); }
|
||||
|
||||
std::unique_ptr<TextView> m_cornersOutline[4];
|
||||
std::unique_ptr<TextView> m_cornersFilled[4];
|
||||
std::unique_ptr<TextView> m_cornersOutline[4];
|
||||
std::unique_ptr<TextView> m_cornersFilled[4];
|
||||
|
||||
protected:
|
||||
virtual void updateContentOpacity(float opacity) {}
|
||||
RectangleConstraint& constraint() {return m_constraint;}
|
||||
virtual void updateContentOpacity(float opacity) {}
|
||||
RectangleConstraint& constraint() { return m_constraint; }
|
||||
|
||||
public:
|
||||
ModalWindow(ViewResources& res, View& parentView, const RectangleConstraint& constraint, const zeus::CColor& bgColor);
|
||||
ModalWindow(ViewResources& res, View& parentView, const RectangleConstraint& constraint);
|
||||
void think();
|
||||
bool skipBuildInAnimation();
|
||||
void close(bool skipAnimation=false);
|
||||
bool closed() const {return m_phase >= Phase::BuildOut;}
|
||||
ModalWindow::Phase phase() const {return m_phase;}
|
||||
ModalWindow(ViewResources& res, View& parentView, const RectangleConstraint& constraint, const zeus::CColor& bgColor);
|
||||
ModalWindow(ViewResources& res, View& parentView, const RectangleConstraint& constraint);
|
||||
void think();
|
||||
bool skipBuildInAnimation();
|
||||
void close(bool skipAnimation = false);
|
||||
bool closed() const { return m_phase >= Phase::BuildOut; }
|
||||
ModalWindow::Phase phase() const { return m_phase; }
|
||||
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -4,50 +4,43 @@
|
|||
#include "TextView.hpp"
|
||||
#include "FontCache.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class MultiLineTextView : public View
|
||||
{
|
||||
ViewResources& m_viewSystem;
|
||||
std::vector<std::unique_ptr<TextView>> m_lines;
|
||||
const FontAtlas& m_fontAtlas;
|
||||
TextView::Alignment m_align;
|
||||
size_t m_lineCapacity;
|
||||
float m_lineHeight;
|
||||
int m_width;
|
||||
std::string LineWrap(std::string_view str, int wrap);
|
||||
std::wstring LineWrap(std::wstring_view str, int wrap);
|
||||
class MultiLineTextView : public View {
|
||||
ViewResources& m_viewSystem;
|
||||
std::vector<std::unique_ptr<TextView>> m_lines;
|
||||
const FontAtlas& m_fontAtlas;
|
||||
TextView::Alignment m_align;
|
||||
size_t m_lineCapacity;
|
||||
float m_lineHeight;
|
||||
int m_width;
|
||||
std::string LineWrap(std::string_view str, int wrap);
|
||||
std::wstring LineWrap(std::wstring_view str, int wrap);
|
||||
|
||||
public:
|
||||
MultiLineTextView(ViewResources& res, View& parentView, const FontAtlas& font,
|
||||
TextView::Alignment align=TextView::Alignment::Left,
|
||||
size_t lineCapacity=256, float lineHeight=1.0);
|
||||
MultiLineTextView(ViewResources& res, View& parentView, FontTag font,
|
||||
TextView::Alignment align=TextView::Alignment::Left,
|
||||
size_t lineCapacity=256, float lineHeight=1.0);
|
||||
MultiLineTextView(ViewResources& res, View& parentView, const FontAtlas& font,
|
||||
TextView::Alignment align = TextView::Alignment::Left, size_t lineCapacity = 256,
|
||||
float lineHeight = 1.0);
|
||||
MultiLineTextView(ViewResources& res, View& parentView, FontTag font,
|
||||
TextView::Alignment align = TextView::Alignment::Left, size_t lineCapacity = 256,
|
||||
float lineHeight = 1.0);
|
||||
|
||||
void typesetGlyphs(std::string_view str,
|
||||
const zeus::CColor& defaultColor=zeus::CColor::skWhite,
|
||||
unsigned wrap=0);
|
||||
void typesetGlyphs(std::wstring_view str,
|
||||
const zeus::CColor& defaultColor=zeus::CColor::skWhite,
|
||||
unsigned wrap=0);
|
||||
void typesetGlyphs(std::string_view str, const zeus::CColor& defaultColor = zeus::CColor::skWhite, unsigned wrap = 0);
|
||||
void typesetGlyphs(std::wstring_view str, const zeus::CColor& defaultColor = zeus::CColor::skWhite,
|
||||
unsigned wrap = 0);
|
||||
|
||||
void colorGlyphs(const zeus::CColor& newColor);
|
||||
void colorGlyphs(const zeus::CColor& newColor);
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
for (std::unique_ptr<TextView>& l : m_lines)
|
||||
l->setMultiplyColor(color);
|
||||
}
|
||||
void setMultiplyColor(const zeus::CColor& color) {
|
||||
for (std::unique_ptr<TextView>& l : m_lines)
|
||||
l->setMultiplyColor(color);
|
||||
}
|
||||
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
int nominalWidth() const {return m_width;}
|
||||
int nominalHeight() const {return (int(m_lineHeight * m_fontAtlas.FT_LineHeight()) >> 6) * m_lines.size();}
|
||||
int nominalWidth() const { return m_width; }
|
||||
int nominalHeight() const { return (int(m_lineHeight * m_fontAtlas.FT_LineHeight()) >> 6) * m_lines.size(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
#pragma once
|
||||
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
#pragma once
|
||||
|
||||
|
|
|
@ -2,51 +2,48 @@
|
|||
|
||||
#include "specter/TextView.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
class ViewResources;
|
||||
|
||||
class NumericField : public View
|
||||
{
|
||||
std::string m_textStr;
|
||||
std::unique_ptr<TextView> m_text;
|
||||
SolidShaderVert m_verts[28];
|
||||
class NumericField : public View {
|
||||
std::string m_textStr;
|
||||
std::unique_ptr<TextView> m_text;
|
||||
SolidShaderVert m_verts[28];
|
||||
|
||||
ViewBlock m_bBlock;
|
||||
boo::IGraphicsBufferD* m_bBlockBuf;
|
||||
ViewBlock m_bBlock;
|
||||
boo::IGraphicsBufferD* m_bBlockBuf;
|
||||
|
||||
boo::IGraphicsBufferD* m_bVertsBuf;
|
||||
boo::IShaderDataBinding* m_bShaderBinding;
|
||||
boo::IGraphicsBufferD* m_bVertsBuf;
|
||||
boo::IShaderDataBinding* m_bShaderBinding;
|
||||
|
||||
int m_nomWidth, m_nomHeight;
|
||||
bool m_pressed = false;
|
||||
bool m_hovered = false;
|
||||
int m_nomWidth, m_nomHeight;
|
||||
bool m_pressed = false;
|
||||
bool m_hovered = false;
|
||||
|
||||
void setInactive();
|
||||
void setHover();
|
||||
void setPressed();
|
||||
void setDisabled();
|
||||
|
||||
void setInactive();
|
||||
void setHover();
|
||||
void setPressed();
|
||||
void setDisabled();
|
||||
public:
|
||||
class Resources
|
||||
{
|
||||
friend class ViewResources;
|
||||
friend class Button;
|
||||
class Resources {
|
||||
friend class ViewResources;
|
||||
friend class Button;
|
||||
|
||||
void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme);
|
||||
};
|
||||
void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme);
|
||||
};
|
||||
|
||||
NumericField(ViewResources& res, View& parentView, std::string_view text);
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
NumericField(ViewResources& res, View& parentView, std::string_view text);
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
void setText(std::string_view text);
|
||||
int nominalWidth() const {return m_nomWidth;}
|
||||
int nominalHeight() const {return m_nomHeight;}
|
||||
void setText(std::string_view text);
|
||||
int nominalWidth() const { return m_nomWidth; }
|
||||
int nominalHeight() const { return m_nomHeight; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -1,42 +1,36 @@
|
|||
#pragma once
|
||||
|
||||
namespace specter
|
||||
{
|
||||
class Outliner
|
||||
{
|
||||
class Node : public View
|
||||
{
|
||||
struct INodeController
|
||||
{
|
||||
virtual boo::ITexture* icon() const { return nullptr; }
|
||||
virtual const std::string* text() const { return nullptr; }
|
||||
virtual size_t subNodeCount() const { return 0; }
|
||||
virtual INodeController* subNode(size_t idx) { return nullptr; }
|
||||
virtual void activated(const boo::SWindowCoord& coord) {}
|
||||
};
|
||||
|
||||
std::string m_description;
|
||||
std::vector<std::unique_ptr<Node>> m_children;
|
||||
bool m_collapsible;
|
||||
bool m_collapsed;
|
||||
|
||||
public:
|
||||
class Resources
|
||||
{
|
||||
friend class ViewResources;
|
||||
|
||||
void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme);
|
||||
};
|
||||
|
||||
Node(ViewResources& res, View& parentView, std::string_view description);
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
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);
|
||||
void think();
|
||||
namespace specter {
|
||||
class Outliner {
|
||||
class Node : public View {
|
||||
struct INodeController {
|
||||
virtual boo::ITexture* icon() const { return nullptr; }
|
||||
virtual const std::string* text() const { return nullptr; }
|
||||
virtual size_t subNodeCount() const { return 0; }
|
||||
virtual INodeController* subNode(size_t idx) { return nullptr; }
|
||||
virtual void activated(const boo::SWindowCoord& coord) {}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
std::string m_description;
|
||||
std::vector<std::unique_ptr<Node>> m_children;
|
||||
bool m_collapsible;
|
||||
bool m_collapsed;
|
||||
|
||||
public:
|
||||
class Resources {
|
||||
friend class ViewResources;
|
||||
|
||||
void init(boo::IGraphicsDataFactory* factory, const IThemeData& theme);
|
||||
};
|
||||
|
||||
Node(ViewResources& res, View& parentView, std::string_view description);
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
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);
|
||||
void think();
|
||||
};
|
||||
};
|
||||
} // namespace specter
|
||||
|
|
|
@ -1,2 +1 @@
|
|||
#pragma once
|
||||
|
||||
|
|
|
@ -3,74 +3,63 @@
|
|||
#include "Button.hpp"
|
||||
#include "ScrollView.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
struct IPathButtonsBinding
|
||||
{
|
||||
virtual void pathButtonActivated(size_t idx)=0;
|
||||
struct IPathButtonsBinding {
|
||||
virtual void pathButtonActivated(size_t idx) = 0;
|
||||
};
|
||||
|
||||
class PathButtons : public ScrollView
|
||||
{
|
||||
struct ContentView : public View
|
||||
{
|
||||
PathButtons& m_pb;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
class PathButtons : public ScrollView {
|
||||
struct ContentView : public View {
|
||||
PathButtons& m_pb;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
|
||||
int nominalWidth() const
|
||||
{
|
||||
int ret = 0;
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
ret += b.m_button.m_view->nominalWidth() + 2;
|
||||
return ret;
|
||||
}
|
||||
int nominalHeight() const
|
||||
{
|
||||
return m_pb.m_pathButtons.size() ? m_pb.m_pathButtons[0].m_button.m_view->nominalHeight() : 0;
|
||||
}
|
||||
int nominalWidth() const {
|
||||
int ret = 0;
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
ret += b.m_button.m_view->nominalWidth() + 2;
|
||||
return ret;
|
||||
}
|
||||
int nominalHeight() const {
|
||||
return m_pb.m_pathButtons.size() ? m_pb.m_pathButtons[0].m_button.m_view->nominalHeight() : 0;
|
||||
}
|
||||
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
ContentView(ViewResources& res, PathButtons& pb)
|
||||
: View(res, pb), m_pb(pb) {}
|
||||
};
|
||||
ViewChild<std::unique_ptr<ContentView>> m_contentView;
|
||||
ContentView(ViewResources& res, PathButtons& pb) : View(res, pb), m_pb(pb) {}
|
||||
};
|
||||
ViewChild<std::unique_ptr<ContentView>> m_contentView;
|
||||
|
||||
int m_pathButtonPending = -1;
|
||||
IPathButtonsBinding& m_binding;
|
||||
bool m_fillContainer;
|
||||
struct PathButton final : IButtonBinding
|
||||
{
|
||||
PathButtons& m_pb;
|
||||
size_t m_idx;
|
||||
ViewChild<std::unique_ptr<Button>> m_button;
|
||||
PathButton(PathButtons& pb, ViewResources& res, size_t idx, const hecl::SystemString& str)
|
||||
: m_pb(pb), m_idx(idx)
|
||||
{
|
||||
m_button.m_view.reset(new Button(res, pb, this, hecl::SystemUTF8Conv(str).str()));
|
||||
}
|
||||
std::string_view name(const Control* control) const {return m_button.m_view->getText();}
|
||||
void activated(const Button* button, const boo::SWindowCoord&) {m_pb.m_pathButtonPending = m_idx;}
|
||||
};
|
||||
friend struct PathButton;
|
||||
std::vector<PathButton> m_pathButtons;
|
||||
int m_pathButtonPending = -1;
|
||||
IPathButtonsBinding& m_binding;
|
||||
bool m_fillContainer;
|
||||
struct PathButton final : IButtonBinding {
|
||||
PathButtons& m_pb;
|
||||
size_t m_idx;
|
||||
ViewChild<std::unique_ptr<Button>> m_button;
|
||||
PathButton(PathButtons& pb, ViewResources& res, size_t idx, const hecl::SystemString& str) : m_pb(pb), m_idx(idx) {
|
||||
m_button.m_view.reset(new Button(res, pb, this, hecl::SystemUTF8Conv(str).str()));
|
||||
}
|
||||
std::string_view name(const Control* control) const { return m_button.m_view->getText(); }
|
||||
void activated(const Button* button, const boo::SWindowCoord&) { m_pb.m_pathButtonPending = m_idx; }
|
||||
};
|
||||
friend struct PathButton;
|
||||
std::vector<PathButton> m_pathButtons;
|
||||
|
||||
public:
|
||||
PathButtons(ViewResources& res, View& parentView, IPathButtonsBinding& binding, bool fillContainer=false);
|
||||
PathButtons(ViewResources& res, View& parentView, IPathButtonsBinding& binding, bool fillContainer = false);
|
||||
|
||||
void setButtons(const std::vector<hecl::SystemString>& comps);
|
||||
void setMultiplyColor(const zeus::CColor& color);
|
||||
void setButtons(const std::vector<hecl::SystemString>& comps);
|
||||
void setMultiplyColor(const zeus::CColor& color);
|
||||
|
||||
/* Fill all available space in container when requested */
|
||||
void containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
/* Fill all available space in container when requested */
|
||||
void containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -12,242 +12,215 @@
|
|||
#include "optional.hpp"
|
||||
#include "boo/boo.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class RootView : public View
|
||||
{
|
||||
boo::IWindow* m_window = nullptr;
|
||||
boo::ObjToken<boo::ITextureR> m_renderTex;
|
||||
boo::SWindowRect m_rootRect = {};
|
||||
bool m_resizeRTDirty = false;
|
||||
bool m_destroyed = false;
|
||||
IViewManager& m_viewMan;
|
||||
ViewResources* m_viewRes;
|
||||
ITextInputView* m_activeTextView = nullptr;
|
||||
View* m_activeDragView = nullptr;
|
||||
Button* m_activeMenuButton = nullptr;
|
||||
class RootView : public View {
|
||||
boo::IWindow* m_window = nullptr;
|
||||
boo::ObjToken<boo::ITextureR> m_renderTex;
|
||||
boo::SWindowRect m_rootRect = {};
|
||||
bool m_resizeRTDirty = false;
|
||||
bool m_destroyed = false;
|
||||
IViewManager& m_viewMan;
|
||||
ViewResources* m_viewRes;
|
||||
ITextInputView* m_activeTextView = nullptr;
|
||||
View* m_activeDragView = nullptr;
|
||||
Button* m_activeMenuButton = nullptr;
|
||||
|
||||
ViewChild<std::unique_ptr<View>> m_rightClickMenu;
|
||||
boo::SWindowRect m_rightClickMenuRootAndLoc;
|
||||
ViewChild<std::unique_ptr<View>> m_rightClickMenu;
|
||||
boo::SWindowRect m_rightClickMenuRootAndLoc;
|
||||
|
||||
SplitView* m_hoverSplitDragView = nullptr;
|
||||
bool m_activeSplitDragView = false;
|
||||
SplitView* recursiveTestSplitHover(SplitView* sv, const boo::SWindowCoord& coord) const;
|
||||
SplitView* m_hoverSplitDragView = nullptr;
|
||||
bool m_activeSplitDragView = false;
|
||||
SplitView* recursiveTestSplitHover(SplitView* sv, const boo::SWindowCoord& coord) const;
|
||||
|
||||
boo::DeferredWindowEvents<RootView> m_events;
|
||||
boo::DeferredWindowEvents<RootView> m_events;
|
||||
|
||||
struct SplitMenuSystem : IMenuNode
|
||||
{
|
||||
RootView& m_rv;
|
||||
std::string m_text;
|
||||
struct SplitMenuSystem : IMenuNode {
|
||||
RootView& m_rv;
|
||||
std::string m_text;
|
||||
|
||||
SplitView* m_splitView = nullptr;
|
||||
enum class Phase
|
||||
{
|
||||
Inactive,
|
||||
InteractiveSplit,
|
||||
InteractiveJoin,
|
||||
} m_phase = Phase::Inactive;
|
||||
int m_interactiveSlot = 0;
|
||||
float m_interactiveSplit = 0.5;
|
||||
bool m_interactiveDown = false;
|
||||
SplitView* m_splitView = nullptr;
|
||||
enum class Phase {
|
||||
Inactive,
|
||||
InteractiveSplit,
|
||||
InteractiveJoin,
|
||||
} m_phase = Phase::Inactive;
|
||||
int m_interactiveSlot = 0;
|
||||
float m_interactiveSplit = 0.5;
|
||||
bool m_interactiveDown = false;
|
||||
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
ViewBlock m_viewBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token 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);
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
ViewBlock m_viewBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token 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, boo::IGraphicsDataFactory::Context& ctx);
|
||||
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;
|
||||
}
|
||||
|
||||
boo::SWindowCoord m_deferredCoord;
|
||||
bool m_deferredSplit = false;
|
||||
bool m_deferredJoin = false;
|
||||
|
||||
struct SplitActionNode : IMenuNode
|
||||
{
|
||||
SplitMenuSystem& m_smn;
|
||||
std::string m_text;
|
||||
SplitActionNode(SplitMenuSystem& smn);
|
||||
const std::string* text() const {return &m_text;}
|
||||
void activated(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_smn.m_deferredSplit = true;
|
||||
m_smn.m_deferredCoord = coord;
|
||||
}
|
||||
} m_splitActionNode;
|
||||
struct JoinActionNode : IMenuNode
|
||||
{
|
||||
SplitMenuSystem& m_smn;
|
||||
std::string m_text;
|
||||
JoinActionNode(SplitMenuSystem& smn);
|
||||
const std::string* text() const {return &m_text;}
|
||||
void activated(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_smn.m_deferredJoin = true;
|
||||
m_smn.m_deferredCoord = coord;
|
||||
}
|
||||
} m_joinActionNode;
|
||||
};
|
||||
std::experimental::optional<SplitMenuSystem> m_splitMenuSystem;
|
||||
|
||||
public:
|
||||
RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window);
|
||||
~RootView();
|
||||
|
||||
void destroyed();
|
||||
bool isDestroyed() const {return m_destroyed;}
|
||||
|
||||
void resized(const boo::SWindowRect& rect, bool) { resized(rect, rect); }
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
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);
|
||||
boo::ITextInputCallback* getTextInputCallback() {return m_activeTextView;}
|
||||
|
||||
void internalThink();
|
||||
void dispatchEvents() {m_events.dispatchEvents();}
|
||||
void resized();
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
const boo::SWindowRect& rootRect() const {return m_rootRect;}
|
||||
|
||||
boo::IWindow* window() const {return m_window;}
|
||||
IViewManager& viewManager() const {return m_viewMan;}
|
||||
ViewResources& viewRes() const {return *m_viewRes;}
|
||||
const IThemeData& themeData() const {return *m_viewRes->m_theme;}
|
||||
const boo::ObjToken<boo::ITextureR>& renderTex() const {return m_renderTex;}
|
||||
|
||||
std::vector<View*>& accessContentViews() {return m_views;}
|
||||
|
||||
void adoptRightClickMenu(std::unique_ptr<View>&& menu, const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_rightClickMenu.m_view = std::move(menu);
|
||||
m_rightClickMenuRootAndLoc = subRect();
|
||||
m_rightClickMenuRootAndLoc.location[0] = coord.pixel[0];
|
||||
m_rightClickMenuRootAndLoc.location[1] = coord.pixel[1];
|
||||
updateSize();
|
||||
}
|
||||
View* getRightClickMenu() {return m_rightClickMenu.m_view.get();}
|
||||
|
||||
void setActiveTextView(ITextInputView* textView)
|
||||
{
|
||||
if (m_activeTextView)
|
||||
m_activeTextView->setActive(false);
|
||||
m_activeTextView = textView;
|
||||
if (textView)
|
||||
textView->setActive(true);
|
||||
}
|
||||
void setActiveDragView(View* dragView)
|
||||
{
|
||||
m_activeDragView = dragView;
|
||||
}
|
||||
void unsetActiveDragView(View* dragView)
|
||||
{
|
||||
if (dragView == m_activeDragView)
|
||||
m_activeDragView = nullptr;
|
||||
}
|
||||
void setActiveMenuButton(Button* button)
|
||||
{
|
||||
m_activeMenuButton = button;
|
||||
}
|
||||
void unsetActiveMenuButton(Button* button)
|
||||
{
|
||||
if (button == m_activeMenuButton)
|
||||
m_activeMenuButton = nullptr;
|
||||
SplitMenuSystem(RootView& rv, boo::IGraphicsDataFactory::Context& ctx);
|
||||
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;
|
||||
}
|
||||
|
||||
void startSplitDrag(SplitView* sv, const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_hoverSplitDragView = sv;
|
||||
m_activeSplitDragView = true;
|
||||
sv->startDragSplit(coord);
|
||||
}
|
||||
boo::SWindowCoord m_deferredCoord;
|
||||
bool m_deferredSplit = false;
|
||||
bool m_deferredJoin = false;
|
||||
|
||||
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();
|
||||
}
|
||||
bool m_spaceCornerHover = false;
|
||||
void setSpaceCornerHover(bool hover)
|
||||
{
|
||||
m_spaceCornerHover = hover;
|
||||
_updateCursor();
|
||||
}
|
||||
struct SplitActionNode : IMenuNode {
|
||||
SplitMenuSystem& m_smn;
|
||||
std::string m_text;
|
||||
SplitActionNode(SplitMenuSystem& smn);
|
||||
const std::string* text() const { return &m_text; }
|
||||
void activated(const boo::SWindowCoord& coord) {
|
||||
m_smn.m_deferredSplit = true;
|
||||
m_smn.m_deferredCoord = coord;
|
||||
}
|
||||
} m_splitActionNode;
|
||||
struct JoinActionNode : IMenuNode {
|
||||
SplitMenuSystem& m_smn;
|
||||
std::string m_text;
|
||||
JoinActionNode(SplitMenuSystem& smn);
|
||||
const std::string* text() const { return &m_text; }
|
||||
void activated(const boo::SWindowCoord& coord) {
|
||||
m_smn.m_deferredJoin = true;
|
||||
m_smn.m_deferredCoord = coord;
|
||||
}
|
||||
} m_joinActionNode;
|
||||
};
|
||||
std::experimental::optional<SplitMenuSystem> m_splitMenuSystem;
|
||||
|
||||
void resetTooltip(ViewResources& res);
|
||||
void displayTooltip(std::string_view name, std::string_view help);
|
||||
public:
|
||||
RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window);
|
||||
~RootView();
|
||||
|
||||
void beginInteractiveJoin(SplitView* sv, const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_splitMenuSystem->m_phase = SplitMenuSystem::Phase::InteractiveJoin;
|
||||
m_splitMenuSystem->m_splitView = sv;
|
||||
m_splitMenuSystem->mouseMove(coord);
|
||||
}
|
||||
void destroyed();
|
||||
bool isDestroyed() const { return m_destroyed; }
|
||||
|
||||
void resized(const boo::SWindowRect& rect, bool) { resized(rect, rect); }
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
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);
|
||||
boo::ITextInputCallback* getTextInputCallback() { return m_activeTextView; }
|
||||
|
||||
void internalThink();
|
||||
void dispatchEvents() { m_events.dispatchEvents(); }
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
const boo::SWindowRect& rootRect() const { return m_rootRect; }
|
||||
|
||||
boo::IWindow* window() const { return m_window; }
|
||||
IViewManager& viewManager() const { return m_viewMan; }
|
||||
ViewResources& viewRes() const { return *m_viewRes; }
|
||||
const IThemeData& themeData() const { return *m_viewRes->m_theme; }
|
||||
const boo::ObjToken<boo::ITextureR>& renderTex() const { return m_renderTex; }
|
||||
|
||||
std::vector<View*>& accessContentViews() { return m_views; }
|
||||
|
||||
void adoptRightClickMenu(std::unique_ptr<View>&& menu, const boo::SWindowCoord& coord) {
|
||||
m_rightClickMenu.m_view = std::move(menu);
|
||||
m_rightClickMenuRootAndLoc = subRect();
|
||||
m_rightClickMenuRootAndLoc.location[0] = coord.pixel[0];
|
||||
m_rightClickMenuRootAndLoc.location[1] = coord.pixel[1];
|
||||
updateSize();
|
||||
}
|
||||
View* getRightClickMenu() { return m_rightClickMenu.m_view.get(); }
|
||||
|
||||
void setActiveTextView(ITextInputView* textView) {
|
||||
if (m_activeTextView)
|
||||
m_activeTextView->setActive(false);
|
||||
m_activeTextView = textView;
|
||||
if (textView)
|
||||
textView->setActive(true);
|
||||
}
|
||||
void setActiveDragView(View* dragView) { m_activeDragView = dragView; }
|
||||
void unsetActiveDragView(View* dragView) {
|
||||
if (dragView == m_activeDragView)
|
||||
m_activeDragView = nullptr;
|
||||
}
|
||||
void setActiveMenuButton(Button* button) { m_activeMenuButton = button; }
|
||||
void unsetActiveMenuButton(Button* button) {
|
||||
if (button == m_activeMenuButton)
|
||||
m_activeMenuButton = nullptr;
|
||||
}
|
||||
|
||||
void startSplitDrag(SplitView* sv, const boo::SWindowCoord& coord) {
|
||||
m_hoverSplitDragView = sv;
|
||||
m_activeSplitDragView = true;
|
||||
sv->startDragSplit(coord);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
bool m_spaceCornerHover = false;
|
||||
void setSpaceCornerHover(bool hover) {
|
||||
m_spaceCornerHover = hover;
|
||||
_updateCursor();
|
||||
}
|
||||
|
||||
void resetTooltip(ViewResources& res);
|
||||
void displayTooltip(std::string_view name, std::string_view help);
|
||||
|
||||
void beginInteractiveJoin(SplitView* sv, const boo::SWindowCoord& coord) {
|
||||
m_splitMenuSystem->m_phase = SplitMenuSystem::Phase::InteractiveJoin;
|
||||
m_splitMenuSystem->m_splitView = sv;
|
||||
m_splitMenuSystem->mouseMove(coord);
|
||||
}
|
||||
|
||||
private:
|
||||
void _updateCursor()
|
||||
{
|
||||
if (m_spaceCornerHover)
|
||||
m_window->setCursor(boo::EMouseCursor::Crosshairs);
|
||||
else if (m_vSplitHover)
|
||||
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);
|
||||
}
|
||||
void _updateCursor() {
|
||||
if (m_spaceCornerHover)
|
||||
m_window->setCursor(boo::EMouseCursor::Crosshairs);
|
||||
else if (m_vSplitHover)
|
||||
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);
|
||||
}
|
||||
|
||||
std::vector<View*> m_views;
|
||||
std::unique_ptr<Tooltip> m_tooltip;
|
||||
std::vector<View*> m_views;
|
||||
std::unique_ptr<Tooltip> m_tooltip;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -3,98 +3,78 @@
|
|||
#include "Button.hpp"
|
||||
#include "IViewManager.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
class ViewResources;
|
||||
class Button;
|
||||
|
||||
class ScrollView : public View
|
||||
{
|
||||
class ScrollView : public View {
|
||||
public:
|
||||
enum class Style
|
||||
{
|
||||
Plain,
|
||||
ThinIndicator,
|
||||
SideButtons
|
||||
};
|
||||
enum class Style { Plain, ThinIndicator, SideButtons };
|
||||
|
||||
private:
|
||||
Style m_style;
|
||||
ScissorViewChild<View*> m_contentView;
|
||||
int m_scroll[2] = {};
|
||||
int m_targetScroll[2] = {};
|
||||
Style m_style;
|
||||
ScissorViewChild<View*> m_contentView;
|
||||
int m_scroll[2] = {};
|
||||
int m_targetScroll[2] = {};
|
||||
|
||||
size_t m_consecutiveIdx = 0;
|
||||
double m_consecutiveScroll[16][2] = {};
|
||||
size_t m_consecutiveIdx = 0;
|
||||
double m_consecutiveScroll[16][2] = {};
|
||||
|
||||
bool m_drawInd = false;
|
||||
bool m_drawSideButtons = false;
|
||||
bool m_drawInd = false;
|
||||
bool m_drawSideButtons = false;
|
||||
|
||||
SolidShaderVert m_verts[4];
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
SolidShaderVert m_verts[4];
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
|
||||
enum class SideButtonState
|
||||
{
|
||||
None,
|
||||
ScrollLeft,
|
||||
ScrollRight
|
||||
} m_sideButtonState = SideButtonState::None;
|
||||
struct SideButtonBinding : IButtonBinding
|
||||
{
|
||||
ScrollView& m_sv;
|
||||
std::string m_leftName, m_rightName;
|
||||
SideButtonBinding(ScrollView& sv, IViewManager& vm)
|
||||
: m_sv(sv),
|
||||
m_leftName(vm.translateOr("scroll_left", "Scroll Left")),
|
||||
m_rightName(vm.translateOr("scroll_right", "Scroll Right")) {}
|
||||
std::string_view name(const Control* control) const
|
||||
{
|
||||
return (control == reinterpret_cast<Control*>(m_sv.m_sideButtons[0].m_view.get())) ?
|
||||
m_leftName.c_str() : m_rightName.c_str();
|
||||
}
|
||||
void down(const Button* button, const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (button == m_sv.m_sideButtons[0].m_view.get())
|
||||
m_sv.m_sideButtonState = SideButtonState::ScrollRight;
|
||||
else
|
||||
m_sv.m_sideButtonState = SideButtonState::ScrollLeft;
|
||||
}
|
||||
void up(const Button* button, const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_sv.m_sideButtonState = SideButtonState::None;
|
||||
}
|
||||
} m_sideButtonBind;
|
||||
ViewChild<std::unique_ptr<Button>> m_sideButtons[2];
|
||||
enum class SideButtonState { None, ScrollLeft, ScrollRight } m_sideButtonState = SideButtonState::None;
|
||||
struct SideButtonBinding : IButtonBinding {
|
||||
ScrollView& m_sv;
|
||||
std::string m_leftName, m_rightName;
|
||||
SideButtonBinding(ScrollView& sv, IViewManager& vm)
|
||||
: m_sv(sv)
|
||||
, m_leftName(vm.translateOr("scroll_left", "Scroll Left"))
|
||||
, m_rightName(vm.translateOr("scroll_right", "Scroll Right")) {}
|
||||
std::string_view name(const Control* control) const {
|
||||
return (control == reinterpret_cast<Control*>(m_sv.m_sideButtons[0].m_view.get())) ? m_leftName.c_str()
|
||||
: m_rightName.c_str();
|
||||
}
|
||||
void down(const Button* button, const boo::SWindowCoord& coord) {
|
||||
if (button == m_sv.m_sideButtons[0].m_view.get())
|
||||
m_sv.m_sideButtonState = SideButtonState::ScrollRight;
|
||||
else
|
||||
m_sv.m_sideButtonState = SideButtonState::ScrollLeft;
|
||||
}
|
||||
void up(const Button* button, const boo::SWindowCoord& coord) { m_sv.m_sideButtonState = SideButtonState::None; }
|
||||
} m_sideButtonBind;
|
||||
ViewChild<std::unique_ptr<Button>> m_sideButtons[2];
|
||||
|
||||
bool _scroll(const boo::SScrollDelta& scroll);
|
||||
int scrollAreaWidth() const;
|
||||
bool _scroll(const boo::SScrollDelta& scroll);
|
||||
int scrollAreaWidth() const;
|
||||
|
||||
public:
|
||||
ScrollView(ViewResources& res, View& parentView, Style style);
|
||||
void setContentView(View* v)
|
||||
{
|
||||
m_contentView.m_view = v;
|
||||
updateSize();
|
||||
}
|
||||
ScrollView(ViewResources& res, View& parentView, Style style);
|
||||
void setContentView(View* v) {
|
||||
m_contentView.m_view = v;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
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 scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll);
|
||||
int getScrollX() const {return m_scroll[0];}
|
||||
int getScrollY() const {return m_scroll[1];}
|
||||
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 scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll);
|
||||
int getScrollX() const { return m_scroll[0]; }
|
||||
int getScrollY() const { return m_scroll[1]; }
|
||||
|
||||
int nominalWidth() const {return subRect().size[0];}
|
||||
int nominalHeight() const {return subRect().size[1];}
|
||||
int nominalWidth() const { return subRect().size[0]; }
|
||||
int nominalHeight() const { return subRect().size[1]; }
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color);
|
||||
void setMultiplyColor(const zeus::CColor& color);
|
||||
|
||||
void think();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
void think();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -4,79 +4,72 @@
|
|||
#include "Toolbar.hpp"
|
||||
#include "SplitView.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
class Space;
|
||||
struct ISplitSpaceController;
|
||||
|
||||
struct ISpaceController
|
||||
{
|
||||
virtual bool spaceSplitAllowed() const {return false;}
|
||||
virtual ISplitSpaceController* spaceSplit(SplitView::Axis axis, int thisSlot) {return nullptr;}
|
||||
struct ISpaceController {
|
||||
virtual bool spaceSplitAllowed() const { return false; }
|
||||
virtual ISplitSpaceController* spaceSplit(SplitView::Axis axis, int thisSlot) { return nullptr; }
|
||||
};
|
||||
|
||||
struct ISplitSpaceController
|
||||
{
|
||||
virtual SplitView* splitView()=0;
|
||||
virtual void updateSplit(float split)=0;
|
||||
virtual void joinViews(SplitView* thisSplit, int thisSlot, SplitView* otherSplit, int otherSlot)=0;
|
||||
struct ISplitSpaceController {
|
||||
virtual SplitView* splitView() = 0;
|
||||
virtual void updateSplit(float split) = 0;
|
||||
virtual void joinViews(SplitView* thisSplit, int thisSlot, SplitView* otherSplit, int otherSlot) = 0;
|
||||
};
|
||||
|
||||
class Space : public View
|
||||
{
|
||||
friend class RootView;
|
||||
ISpaceController& m_controller;
|
||||
Toolbar::Position m_tbPos;
|
||||
ViewChild<std::unique_ptr<Toolbar>> m_toolbar;
|
||||
ViewChild<View*> m_contentView;
|
||||
class Space : public View {
|
||||
friend class RootView;
|
||||
ISpaceController& m_controller;
|
||||
Toolbar::Position m_tbPos;
|
||||
ViewChild<std::unique_ptr<Toolbar>> m_toolbar;
|
||||
ViewChild<View*> m_contentView;
|
||||
|
||||
bool m_cornerDrag = false;
|
||||
int m_cornerDragPoint[2];
|
||||
bool m_cornerDrag = false;
|
||||
int m_cornerDragPoint[2];
|
||||
|
||||
struct CornerView : View
|
||||
{
|
||||
Space& m_space;
|
||||
VertexBufferBindingSolid m_vertexBinding;
|
||||
bool m_flip;
|
||||
CornerView(ViewResources& res, Space& space, const zeus::CColor& triColor);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
using View::resized;
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, bool flip);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
friend struct CornerView;
|
||||
ViewChild<std::unique_ptr<CornerView>> m_cornerView;
|
||||
|
||||
public:
|
||||
Space(ViewResources& res, View& parentView, ISpaceController& controller,
|
||||
Toolbar::Position toolbarPos, unsigned tbUnits);
|
||||
View* setContentView(View* view);
|
||||
Toolbar* toolbar() {return m_toolbar.m_view.get();}
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
struct CornerView : View {
|
||||
Space& m_space;
|
||||
VertexBufferBindingSolid m_vertexBinding;
|
||||
bool m_flip;
|
||||
CornerView(ViewResources& res, Space& space, const zeus::CColor& triColor);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
using View::resized;
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, bool flip);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
friend struct CornerView;
|
||||
ViewChild<std::unique_ptr<CornerView>> m_cornerView;
|
||||
|
||||
SplitView* findSplitViewOnSide(SplitView::Axis axis, int side);
|
||||
public:
|
||||
Space(ViewResources& res, View& parentView, ISpaceController& controller, Toolbar::Position toolbarPos,
|
||||
unsigned tbUnits);
|
||||
View* setContentView(View* view);
|
||||
Toolbar* toolbar() { return m_toolbar.m_view.get(); }
|
||||
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& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
View::setMultiplyColor(color);
|
||||
if (m_contentView.m_view)
|
||||
m_contentView.m_view->setMultiplyColor(color);
|
||||
if (m_toolbar.m_view)
|
||||
m_toolbar.m_view->setMultiplyColor(color);
|
||||
}
|
||||
SplitView* findSplitViewOnSide(SplitView::Axis axis, int side);
|
||||
|
||||
bool isSpace() const { return true; }
|
||||
void setMultiplyColor(const zeus::CColor& color) {
|
||||
View::setMultiplyColor(color);
|
||||
if (m_contentView.m_view)
|
||||
m_contentView.m_view->setMultiplyColor(color);
|
||||
if (m_toolbar.m_view)
|
||||
m_toolbar.m_view->setMultiplyColor(color);
|
||||
}
|
||||
|
||||
bool isSpace() const { return true; }
|
||||
};
|
||||
inline Space* View::castToSpace() { return isSpace() ? static_cast<Space*>(this) : nullptr; }
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -2,119 +2,104 @@
|
|||
|
||||
#include "specter/View.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
struct ISplitSpaceController;
|
||||
|
||||
class SplitView : public View
|
||||
{
|
||||
friend class RootView;
|
||||
friend class Space;
|
||||
class SplitView : public View {
|
||||
friend class RootView;
|
||||
friend class Space;
|
||||
|
||||
public:
|
||||
class Resources
|
||||
{
|
||||
friend class ViewResources;
|
||||
friend class SplitView;
|
||||
boo::ObjToken<boo::ITextureS> m_shadingTex;
|
||||
class Resources {
|
||||
friend class ViewResources;
|
||||
friend class SplitView;
|
||||
boo::ObjToken<boo::ITextureS> m_shadingTex;
|
||||
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
|
||||
void destroy() { m_shadingTex.reset(); }
|
||||
};
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
|
||||
void destroy() { m_shadingTex.reset(); }
|
||||
};
|
||||
|
||||
enum class ArrowDir
|
||||
{
|
||||
Up,
|
||||
Down,
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
enum class ArrowDir { Up, Down, Left, Right };
|
||||
|
||||
enum class Axis { Horizontal, Vertical };
|
||||
|
||||
enum class Axis
|
||||
{
|
||||
Horizontal,
|
||||
Vertical
|
||||
};
|
||||
private:
|
||||
ISplitSpaceController* m_controller;
|
||||
Axis m_axis;
|
||||
float m_slide = 0.5;
|
||||
void _setSplit(float slide);
|
||||
bool m_dragging = false;
|
||||
ISplitSpaceController* m_controller;
|
||||
Axis m_axis;
|
||||
float m_slide = 0.5;
|
||||
void _setSplit(float slide);
|
||||
bool m_dragging = false;
|
||||
|
||||
ViewChild<View*> m_views[2];
|
||||
ViewBlock m_splitBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_splitBlockBuf;
|
||||
TexShaderVert m_splitVerts[4];
|
||||
ViewChild<View*> m_views[2];
|
||||
ViewBlock m_splitBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_splitBlockBuf;
|
||||
TexShaderVert m_splitVerts[4];
|
||||
|
||||
int m_clearanceA, m_clearanceB;
|
||||
int m_clearanceA, m_clearanceB;
|
||||
|
||||
void setHorizontalVerts(int width)
|
||||
{
|
||||
m_splitVerts[0].m_pos.assign(0, 2, 0);
|
||||
m_splitVerts[0].m_uv.assign(0, 0);
|
||||
m_splitVerts[1].m_pos.assign(0, -1, 0);
|
||||
m_splitVerts[1].m_uv.assign(1, 0);
|
||||
m_splitVerts[2].m_pos.assign(width, 2, 0);
|
||||
m_splitVerts[2].m_uv.assign(0, 0);
|
||||
m_splitVerts[3].m_pos.assign(width, -1, 0);
|
||||
m_splitVerts[3].m_uv.assign(1, 0);
|
||||
}
|
||||
void setHorizontalVerts(int width) {
|
||||
m_splitVerts[0].m_pos.assign(0, 2, 0);
|
||||
m_splitVerts[0].m_uv.assign(0, 0);
|
||||
m_splitVerts[1].m_pos.assign(0, -1, 0);
|
||||
m_splitVerts[1].m_uv.assign(1, 0);
|
||||
m_splitVerts[2].m_pos.assign(width, 2, 0);
|
||||
m_splitVerts[2].m_uv.assign(0, 0);
|
||||
m_splitVerts[3].m_pos.assign(width, -1, 0);
|
||||
m_splitVerts[3].m_uv.assign(1, 0);
|
||||
}
|
||||
|
||||
void setVerticalVerts(int height)
|
||||
{
|
||||
m_splitVerts[0].m_pos.assign(-1, height, 0);
|
||||
m_splitVerts[0].m_uv.assign(0, 0);
|
||||
m_splitVerts[1].m_pos.assign(-1, 0, 0);
|
||||
m_splitVerts[1].m_uv.assign(0, 0);
|
||||
m_splitVerts[2].m_pos.assign(2, height, 0);
|
||||
m_splitVerts[2].m_uv.assign(1, 0);
|
||||
m_splitVerts[3].m_pos.assign(2, 0, 0);
|
||||
m_splitVerts[3].m_uv.assign(1, 0);
|
||||
}
|
||||
void setVerticalVerts(int height) {
|
||||
m_splitVerts[0].m_pos.assign(-1, height, 0);
|
||||
m_splitVerts[0].m_uv.assign(0, 0);
|
||||
m_splitVerts[1].m_pos.assign(-1, 0, 0);
|
||||
m_splitVerts[1].m_uv.assign(0, 0);
|
||||
m_splitVerts[2].m_pos.assign(2, height, 0);
|
||||
m_splitVerts[2].m_uv.assign(1, 0);
|
||||
m_splitVerts[3].m_pos.assign(2, 0, 0);
|
||||
m_splitVerts[3].m_uv.assign(1, 0);
|
||||
}
|
||||
|
||||
VertexBufferBindingTex m_splitVertsBinding;
|
||||
VertexBufferBindingTex m_splitVertsBinding;
|
||||
|
||||
public:
|
||||
SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller,
|
||||
Axis axis, float split, int clearanceA=-1, int clearanceB=-1);
|
||||
View* setContentView(int slot, View* view);
|
||||
void setSplit(float split);
|
||||
void setAxis(Axis axis);
|
||||
Axis axis() const {return m_axis;}
|
||||
float split() const {return m_slide;}
|
||||
bool testSplitHover(const boo::SWindowCoord& coord);
|
||||
bool testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlotOut,
|
||||
SplitView*& splitOut, int& slotOut,
|
||||
boo::SWindowRect& rectOut, ArrowDir& dirOut, int forceSlot=-1);
|
||||
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 endDragSplit();
|
||||
void moveDragSplit(const boo::SWindowCoord& coord);
|
||||
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& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller, Axis axis, float split,
|
||||
int clearanceA = -1, int clearanceB = -1);
|
||||
View* setContentView(int slot, View* view);
|
||||
void setSplit(float split);
|
||||
void setAxis(Axis axis);
|
||||
Axis axis() const { return m_axis; }
|
||||
float split() const { return m_slide; }
|
||||
bool testSplitHover(const boo::SWindowCoord& coord);
|
||||
bool testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlotOut, SplitView*& splitOut, int& slotOut,
|
||||
boo::SWindowRect& rectOut, ArrowDir& dirOut, int forceSlot = -1);
|
||||
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 endDragSplit();
|
||||
void moveDragSplit(const boo::SWindowCoord& coord);
|
||||
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& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
View::setMultiplyColor(color);
|
||||
m_splitBlock.m_color = color;
|
||||
m_splitBlockBuf.access().finalAssign(m_splitBlock);
|
||||
void setMultiplyColor(const zeus::CColor& color) {
|
||||
View::setMultiplyColor(color);
|
||||
m_splitBlock.m_color = color;
|
||||
m_splitBlockBuf.access().finalAssign(m_splitBlock);
|
||||
|
||||
if (m_views[0].m_view)
|
||||
m_views[0].m_view->setMultiplyColor(color);
|
||||
if (m_views[1].m_view)
|
||||
m_views[1].m_view->setMultiplyColor(color);
|
||||
}
|
||||
if (m_views[0].m_view)
|
||||
m_views[0].m_view->setMultiplyColor(color);
|
||||
if (m_views[1].m_view)
|
||||
m_views[1].m_view->setMultiplyColor(color);
|
||||
}
|
||||
|
||||
bool isSplitView() const { return true; }
|
||||
bool isSplitView() const { return true; }
|
||||
};
|
||||
inline SplitView* View::castToSplitView() { return isSplitView() ? static_cast<SplitView*>(this) : nullptr; }
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -5,139 +5,128 @@
|
|||
#include "TextView.hpp"
|
||||
#include <array>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
#define SPECTER_TABLE_MAX_ROWS 128ul
|
||||
|
||||
enum class SortDirection
|
||||
{
|
||||
None,
|
||||
Ascending,
|
||||
Descending
|
||||
enum class SortDirection { None, Ascending, Descending };
|
||||
|
||||
struct ITableDataBinding {
|
||||
virtual size_t columnCount() const = 0;
|
||||
virtual size_t rowCount() const = 0;
|
||||
virtual std::string_view header(size_t cIdx) const { return {}; }
|
||||
virtual std::string_view cell(size_t cIdx, size_t rIdx) const { return {}; }
|
||||
};
|
||||
|
||||
struct ITableDataBinding
|
||||
{
|
||||
virtual size_t columnCount() const=0;
|
||||
virtual size_t rowCount() const=0;
|
||||
virtual std::string_view header(size_t cIdx) const { return {}; }
|
||||
virtual std::string_view cell(size_t cIdx, size_t rIdx) const { return {}; }
|
||||
struct ITableStateBinding {
|
||||
virtual float getColumnSplit(size_t cIdx) const { return -1.0; }
|
||||
virtual bool columnSplitResizeAllowed() const { return false; }
|
||||
virtual void setColumnSplit(size_t cIdx, float split) {}
|
||||
virtual SortDirection getSort(size_t& cIdx) const {
|
||||
cIdx = 0;
|
||||
return SortDirection::None;
|
||||
}
|
||||
virtual void setSort(size_t cIdx, SortDirection dir) {}
|
||||
virtual void setSelectedRow(size_t rIdx) {}
|
||||
virtual void rowActivated(size_t rIdx) {}
|
||||
};
|
||||
|
||||
struct ITableStateBinding
|
||||
{
|
||||
virtual float getColumnSplit(size_t cIdx) const {return -1.0;}
|
||||
virtual bool columnSplitResizeAllowed() const {return false;}
|
||||
virtual void setColumnSplit(size_t cIdx, float split) {}
|
||||
virtual SortDirection getSort(size_t& cIdx) const {cIdx = 0; return SortDirection::None;}
|
||||
virtual void setSort(size_t cIdx, SortDirection dir) {}
|
||||
virtual void setSelectedRow(size_t rIdx) {}
|
||||
virtual void rowActivated(size_t rIdx) {}
|
||||
};
|
||||
class Table : public View {
|
||||
ITableDataBinding* m_data;
|
||||
ITableStateBinding* m_state;
|
||||
|
||||
class Table : public View
|
||||
{
|
||||
ITableDataBinding* m_data;
|
||||
ITableStateBinding* m_state;
|
||||
size_t m_maxColumns;
|
||||
size_t m_rows = 0;
|
||||
size_t m_columns = 0;
|
||||
size_t m_selectedRow = -1;
|
||||
size_t m_deferredActivation = -1;
|
||||
size_t m_clickFrames = 15;
|
||||
|
||||
size_t m_maxColumns;
|
||||
size_t m_rows = 0;
|
||||
size_t m_columns = 0;
|
||||
size_t m_selectedRow = -1;
|
||||
size_t m_deferredActivation = -1;
|
||||
size_t m_clickFrames = 15;
|
||||
struct CellView : public View {
|
||||
Table& m_t;
|
||||
std::unique_ptr<TextView> m_text;
|
||||
size_t m_c, m_r;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
uint64_t m_textHash = 0;
|
||||
CellView(Table& t, ViewResources& res);
|
||||
|
||||
struct CellView : public View
|
||||
{
|
||||
Table& m_t;
|
||||
std::unique_ptr<TextView> m_text;
|
||||
size_t m_c, m_r;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
uint64_t m_textHash = 0;
|
||||
CellView(Table& t, ViewResources& res);
|
||||
|
||||
bool m_selected = false;
|
||||
void select();
|
||||
void deselect();
|
||||
void reset();
|
||||
bool reset(size_t c);
|
||||
bool reset(size_t c, size_t r);
|
||||
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseEnter(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub,
|
||||
const boo::SWindowRect& scissor);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
std::vector<ViewChild<std::unique_ptr<CellView>>> m_headerViews;
|
||||
using ColumnPool = std::array<std::array<ViewChild<std::unique_ptr<CellView>>, SPECTER_TABLE_MAX_ROWS>, 2>;
|
||||
std::vector<ColumnPool> m_cellPools;
|
||||
size_t m_ensuredRows = 0;
|
||||
std::vector<ColumnPool>& ensureCellPools(size_t rows, size_t cols, ViewResources& res);
|
||||
size_t m_activePool = -1;
|
||||
bool m_header = false;
|
||||
|
||||
std::vector<boo::SWindowRect> m_hCellRects;
|
||||
size_t m_hDraggingIdx = 0;
|
||||
|
||||
std::unique_ptr<SolidShaderVert[]> m_hVerts;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void _setHeaderVerts(const boo::SWindowRect& rect);
|
||||
|
||||
std::vector<boo::SWindowRect> getCellRects(const boo::SWindowRect& tableRect) const;
|
||||
|
||||
ViewChild<std::unique_ptr<ScrollView>> m_scroll;
|
||||
|
||||
struct RowsView : public View
|
||||
{
|
||||
Table& m_t;
|
||||
|
||||
std::unique_ptr<SolidShaderVert[]> m_verts;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
size_t m_visibleStart = 0;
|
||||
size_t m_visibleRows = 0;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
void _setRowVerts(const boo::SWindowRect& rowsRect, const boo::SWindowRect& scissor);
|
||||
|
||||
RowsView(Table& t, ViewResources& res);
|
||||
int nominalHeight() const;
|
||||
int nominalWidth() const {return m_t.m_scroll.m_view->nominalWidth();}
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub,
|
||||
const boo::SWindowRect& scissor);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
} m_rowsView;
|
||||
|
||||
bool m_headerNeedsUpdate = false;
|
||||
bool m_inSelectRow = false;
|
||||
|
||||
void _updateData();
|
||||
|
||||
public:
|
||||
Table(ViewResources& res, View& parentView, ITableDataBinding* data,
|
||||
ITableStateBinding* state=nullptr, size_t maxColumns=8);
|
||||
|
||||
void cycleSortColumn(size_t c);
|
||||
void selectRow(size_t r);
|
||||
void setMultiplyColor(const zeus::CColor& color);
|
||||
bool m_selected = false;
|
||||
void select();
|
||||
void deselect();
|
||||
void reset();
|
||||
bool reset(size_t c);
|
||||
bool reset(size_t c, size_t r);
|
||||
|
||||
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 scroll(const boo::SWindowCoord&, const boo::SScrollDelta&);
|
||||
|
||||
void think();
|
||||
void updateData();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
std::vector<ViewChild<std::unique_ptr<CellView>>> m_headerViews;
|
||||
using ColumnPool = std::array<std::array<ViewChild<std::unique_ptr<CellView>>, SPECTER_TABLE_MAX_ROWS>, 2>;
|
||||
std::vector<ColumnPool> m_cellPools;
|
||||
size_t m_ensuredRows = 0;
|
||||
std::vector<ColumnPool>& ensureCellPools(size_t rows, size_t cols, ViewResources& res);
|
||||
size_t m_activePool = -1;
|
||||
bool m_header = false;
|
||||
|
||||
std::vector<boo::SWindowRect> m_hCellRects;
|
||||
size_t m_hDraggingIdx = 0;
|
||||
|
||||
std::unique_ptr<SolidShaderVert[]> m_hVerts;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
void _setHeaderVerts(const boo::SWindowRect& rect);
|
||||
|
||||
std::vector<boo::SWindowRect> getCellRects(const boo::SWindowRect& tableRect) const;
|
||||
|
||||
ViewChild<std::unique_ptr<ScrollView>> m_scroll;
|
||||
|
||||
struct RowsView : public View {
|
||||
Table& m_t;
|
||||
|
||||
std::unique_ptr<SolidShaderVert[]> m_verts;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
size_t m_visibleStart = 0;
|
||||
size_t m_visibleRows = 0;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
void _setRowVerts(const boo::SWindowRect& rowsRect, const boo::SWindowRect& scissor);
|
||||
|
||||
RowsView(Table& t, ViewResources& res);
|
||||
int nominalHeight() const;
|
||||
int nominalWidth() const { return m_t.m_scroll.m_view->nominalWidth(); }
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
void mouseLeave(const boo::SWindowCoord&);
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
} m_rowsView;
|
||||
|
||||
bool m_headerNeedsUpdate = false;
|
||||
bool m_inSelectRow = false;
|
||||
|
||||
void _updateData();
|
||||
|
||||
public:
|
||||
Table(ViewResources& res, View& parentView, ITableDataBinding* data, ITableStateBinding* state = nullptr,
|
||||
size_t maxColumns = 8);
|
||||
|
||||
void cycleSortColumn(size_t c);
|
||||
void selectRow(size_t r);
|
||||
void setMultiplyColor(const zeus::CColor& color);
|
||||
|
||||
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 scroll(const boo::SWindowCoord&, const boo::SScrollDelta&);
|
||||
|
||||
void think();
|
||||
void updateData();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -4,135 +4,123 @@
|
|||
#include "TextView.hpp"
|
||||
#include <boo/IWindow.hpp>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class TextField : public ITextInputView
|
||||
{
|
||||
bool m_hasTextSet = false;
|
||||
bool m_hasMarkSet = false;
|
||||
std::string m_textStr;
|
||||
std::string m_deferredTextStr;
|
||||
std::string m_deferredMarkStr;
|
||||
std::unique_ptr<TextView> m_text;
|
||||
std::unique_ptr<TextView> m_errText;
|
||||
class TextField : public ITextInputView {
|
||||
bool m_hasTextSet = false;
|
||||
bool m_hasMarkSet = false;
|
||||
std::string m_textStr;
|
||||
std::string m_deferredTextStr;
|
||||
std::string m_deferredMarkStr;
|
||||
std::unique_ptr<TextView> m_text;
|
||||
std::unique_ptr<TextView> m_errText;
|
||||
|
||||
SolidShaderVert m_verts[41];
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
SolidShaderVert m_verts[41];
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
|
||||
int m_nomWidth = 0;
|
||||
int m_nomHeight = 0;
|
||||
int m_nomWidth = 0;
|
||||
int m_nomHeight = 0;
|
||||
|
||||
bool m_hasSelectionClear = false;
|
||||
bool m_hasSelectionSet = false;
|
||||
bool m_hasCursorSet = false;
|
||||
size_t m_selectionStart = 0;
|
||||
size_t m_deferredSelectionStart = 0;
|
||||
size_t m_selectionCount = 0;
|
||||
size_t m_deferredSelectionCount = 0;
|
||||
|
||||
size_t m_markReplStart = 0;
|
||||
size_t m_deferredMarkReplStart = 0;
|
||||
size_t m_markReplCount = 0;
|
||||
size_t m_deferredMarkReplCount = 0;
|
||||
|
||||
size_t m_markSelStart = 0;
|
||||
size_t m_deferredMarkSelStart = 0;
|
||||
size_t m_markSelCount = 0;
|
||||
size_t m_deferredMarkSelCount = 0;
|
||||
|
||||
size_t m_cursorPos = 0;
|
||||
size_t m_deferredCursorPos = SIZE_MAX;
|
||||
size_t m_cursorFrames = 0;
|
||||
size_t m_clickFrames = 15;
|
||||
size_t m_clickFrames2 = 15;
|
||||
size_t m_errorFrames = 360;
|
||||
bool m_hasSelectionClear = false;
|
||||
bool m_hasSelectionSet = false;
|
||||
bool m_hasCursorSet = false;
|
||||
size_t m_selectionStart = 0;
|
||||
size_t m_deferredSelectionStart = 0;
|
||||
size_t m_selectionCount = 0;
|
||||
size_t m_deferredSelectionCount = 0;
|
||||
|
||||
size_t m_dragStart = 0;
|
||||
size_t m_dragging = 0;
|
||||
size_t m_markReplStart = 0;
|
||||
size_t m_deferredMarkReplStart = 0;
|
||||
size_t m_markReplCount = 0;
|
||||
size_t m_deferredMarkReplCount = 0;
|
||||
|
||||
bool m_active = false;
|
||||
bool m_error = false;
|
||||
size_t m_markSelStart = 0;
|
||||
size_t m_deferredMarkSelStart = 0;
|
||||
size_t m_markSelCount = 0;
|
||||
size_t m_deferredMarkSelCount = 0;
|
||||
|
||||
enum class BGState
|
||||
{
|
||||
Inactive,
|
||||
Hover,
|
||||
Disabled
|
||||
} m_bgState = BGState::Inactive;
|
||||
void setInactive();
|
||||
void setHover();
|
||||
void setDisabled();
|
||||
void refreshBg();
|
||||
size_t m_cursorPos = 0;
|
||||
size_t m_deferredCursorPos = SIZE_MAX;
|
||||
size_t m_cursorFrames = 0;
|
||||
size_t m_clickFrames = 15;
|
||||
size_t m_clickFrames2 = 15;
|
||||
size_t m_errorFrames = 360;
|
||||
|
||||
size_t m_dragStart = 0;
|
||||
size_t m_dragging = 0;
|
||||
|
||||
bool m_active = false;
|
||||
bool m_error = false;
|
||||
|
||||
enum class BGState { Inactive, Hover, Disabled } m_bgState = BGState::Inactive;
|
||||
void setInactive();
|
||||
void setHover();
|
||||
void setDisabled();
|
||||
void refreshBg();
|
||||
|
||||
public:
|
||||
TextField(ViewResources& res, View& parentView, IStringBinding* strBind);
|
||||
TextField(ViewResources& res, View& parentView, IStringBinding* strBind);
|
||||
|
||||
std::string_view getText() const {return m_textStr;}
|
||||
void setText(std::string_view str);
|
||||
std::string_view getText() const { return m_textStr; }
|
||||
void setText(std::string_view str);
|
||||
|
||||
void clipboardCopy();
|
||||
void clipboardCut();
|
||||
void clipboardPaste();
|
||||
void clipboardCopy();
|
||||
void clipboardCut();
|
||||
void clipboardPaste();
|
||||
|
||||
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 specialKeyDown(boo::ESpecialKey, boo::EModifierKey, bool);
|
||||
|
||||
bool hasMarkedText() const;
|
||||
std::pair<int,int> markedRange() const;
|
||||
std::pair<int,int> selectedRange() const;
|
||||
void setMarkedText(std::string_view str,
|
||||
const std::pair<int,int>& selectedRange,
|
||||
const std::pair<int,int>& replacementRange);
|
||||
void unmarkText();
|
||||
|
||||
std::string substringForRange(const std::pair<int,int>& range,
|
||||
std::pair<int,int>& actualRange) const;
|
||||
void insertText(std::string_view str, const std::pair<int,int>& range);
|
||||
int characterIndexAtPoint(const boo::SWindowCoord& point) const;
|
||||
boo::SWindowRect rectForCharacterRange(const std::pair<int,int>& range,
|
||||
std::pair<int,int>& actualRange) const;
|
||||
|
||||
void think();
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
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 specialKeyDown(boo::ESpecialKey, boo::EModifierKey, bool);
|
||||
|
||||
int nominalWidth() const {return m_nomWidth;}
|
||||
int nominalHeight() const {return m_nomHeight;}
|
||||
bool hasMarkedText() const;
|
||||
std::pair<int, int> markedRange() const;
|
||||
std::pair<int, int> selectedRange() const;
|
||||
void setMarkedText(std::string_view str, const std::pair<int, int>& selectedRange,
|
||||
const std::pair<int, int>& replacementRange);
|
||||
void unmarkText();
|
||||
|
||||
void setActive(bool active);
|
||||
void setCursorPos(size_t pos);
|
||||
void setErrorState(std::string_view message);
|
||||
void clearErrorState();
|
||||
std::string substringForRange(const std::pair<int, int>& range, std::pair<int, int>& actualRange) const;
|
||||
void insertText(std::string_view str, const std::pair<int, int>& range);
|
||||
int characterIndexAtPoint(const boo::SWindowCoord& point) const;
|
||||
boo::SWindowRect rectForCharacterRange(const std::pair<int, int>& range, std::pair<int, int>& actualRange) const;
|
||||
|
||||
void setSelectionRange(size_t start, size_t count);
|
||||
void clearSelectionRange();
|
||||
void think();
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
View::setMultiplyColor(color);
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock);
|
||||
m_text->setMultiplyColor(color);
|
||||
if (m_errText)
|
||||
m_errText->setMultiplyColor(color);
|
||||
}
|
||||
int nominalWidth() const { return m_nomWidth; }
|
||||
int nominalHeight() const { return m_nomHeight; }
|
||||
|
||||
void setActive(bool active);
|
||||
void setCursorPos(size_t pos);
|
||||
void setErrorState(std::string_view message);
|
||||
void clearErrorState();
|
||||
|
||||
void setSelectionRange(size_t start, size_t count);
|
||||
void clearSelectionRange();
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color) {
|
||||
View::setMultiplyColor(color);
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock);
|
||||
m_text->setMultiplyColor(color);
|
||||
if (m_errText)
|
||||
m_errText->setMultiplyColor(color);
|
||||
}
|
||||
|
||||
private:
|
||||
void _setCursorPos();
|
||||
void _reallySetCursorPos(size_t pos);
|
||||
void _setSelectionRange();
|
||||
void _reallySetSelectionRange(size_t start, size_t len);
|
||||
void _reallySetMarkRange(size_t start, size_t len);
|
||||
void _clearSelectionRange();
|
||||
void _setText();
|
||||
void _setMarkedText();
|
||||
void _setCursorPos();
|
||||
void _reallySetCursorPos(size_t pos);
|
||||
void _setSelectionRange();
|
||||
void _reallySetSelectionRange(size_t start, size_t len);
|
||||
void _reallySetMarkRange(size_t start, size_t len);
|
||||
void _clearSelectionRange();
|
||||
void _setText();
|
||||
void _setMarkedText();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -5,128 +5,112 @@
|
|||
|
||||
#include "FontCache.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
class ViewResources;
|
||||
|
||||
class TextView : public View
|
||||
{
|
||||
class TextView : public View {
|
||||
public:
|
||||
enum class Alignment
|
||||
{
|
||||
Left,
|
||||
Center,
|
||||
Right
|
||||
};
|
||||
struct RenderGlyph
|
||||
{
|
||||
zeus::CVector3f m_pos[4];
|
||||
zeus::CMatrix4f m_mv;
|
||||
zeus::CVector3f m_uv[4];
|
||||
zeus::CColor m_color;
|
||||
//char _dummy[48];
|
||||
|
||||
RenderGlyph& operator=(const RenderGlyph& other)
|
||||
{
|
||||
m_pos[0] = other.m_pos[0];
|
||||
m_pos[1] = other.m_pos[1];
|
||||
m_pos[2] = other.m_pos[2];
|
||||
m_pos[3] = other.m_pos[3];
|
||||
m_mv = other.m_mv;
|
||||
m_uv[0] = other.m_uv[0];
|
||||
m_uv[1] = other.m_uv[1];
|
||||
m_uv[2] = other.m_uv[2];
|
||||
m_uv[3] = other.m_uv[3];
|
||||
m_color = other.m_color;
|
||||
return *this;
|
||||
}
|
||||
enum class Alignment { Left, Center, Right };
|
||||
struct RenderGlyph {
|
||||
zeus::CVector3f m_pos[4];
|
||||
zeus::CMatrix4f m_mv;
|
||||
zeus::CVector3f m_uv[4];
|
||||
zeus::CColor m_color;
|
||||
// char _dummy[48];
|
||||
|
||||
RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const zeus::CColor& defaultColor);
|
||||
};
|
||||
struct RenderGlyphInfo
|
||||
{
|
||||
uint32_t m_char;
|
||||
std::pair<int,int> m_dims;
|
||||
int m_adv;
|
||||
bool m_space = false;
|
||||
RenderGlyph& operator=(const RenderGlyph& other) {
|
||||
m_pos[0] = other.m_pos[0];
|
||||
m_pos[1] = other.m_pos[1];
|
||||
m_pos[2] = other.m_pos[2];
|
||||
m_pos[3] = other.m_pos[3];
|
||||
m_mv = other.m_mv;
|
||||
m_uv[0] = other.m_uv[0];
|
||||
m_uv[1] = other.m_uv[1];
|
||||
m_uv[2] = other.m_uv[2];
|
||||
m_uv[3] = other.m_uv[3];
|
||||
m_color = other.m_color;
|
||||
return *this;
|
||||
}
|
||||
|
||||
RenderGlyphInfo(uint32_t ch, int width, int height, int adv)
|
||||
: m_char(ch), m_dims(width, height), m_adv(adv), m_space(iswspace(ch) != 0) {}
|
||||
};
|
||||
RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const zeus::CColor& defaultColor);
|
||||
};
|
||||
struct RenderGlyphInfo {
|
||||
uint32_t m_char;
|
||||
std::pair<int, int> m_dims;
|
||||
int m_adv;
|
||||
bool m_space = false;
|
||||
|
||||
RenderGlyphInfo(uint32_t ch, int width, int height, int adv)
|
||||
: m_char(ch), m_dims(width, height), m_adv(adv), m_space(iswspace(ch) != 0) {}
|
||||
};
|
||||
|
||||
private:
|
||||
size_t m_capacity;
|
||||
size_t m_curSize = 0;
|
||||
hecl::VertexBufferPool<RenderGlyph>::Token m_glyphBuf;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_shaderBinding;
|
||||
const FontAtlas& m_fontAtlas;
|
||||
Alignment m_align;
|
||||
int m_width = 0;
|
||||
size_t m_capacity;
|
||||
size_t m_curSize = 0;
|
||||
hecl::VertexBufferPool<RenderGlyph>::Token m_glyphBuf;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_shaderBinding;
|
||||
const FontAtlas& m_fontAtlas;
|
||||
Alignment m_align;
|
||||
int m_width = 0;
|
||||
|
||||
friend class MultiLineTextView;
|
||||
static int DoKern(FT_Pos val, const FontAtlas& atlas);
|
||||
|
||||
void _commitResources(size_t capacity);
|
||||
|
||||
public:
|
||||
class Resources {
|
||||
friend class ViewResources;
|
||||
friend class TextView;
|
||||
friend class MultiLineTextView;
|
||||
static int DoKern(FT_Pos val, const FontAtlas& atlas);
|
||||
|
||||
void _commitResources(size_t capacity);
|
||||
hecl::VertexBufferPool<RenderGlyph> m_glyphPool;
|
||||
|
||||
public:
|
||||
class Resources
|
||||
{
|
||||
friend class ViewResources;
|
||||
friend class TextView;
|
||||
friend class MultiLineTextView;
|
||||
void updateBuffers() { m_glyphPool.updateBuffers(); }
|
||||
|
||||
hecl::VertexBufferPool<RenderGlyph> m_glyphPool;
|
||||
FontCache* m_fcache = nullptr;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_regular;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_subpixel;
|
||||
|
||||
void updateBuffers()
|
||||
{
|
||||
m_glyphPool.updateBuffers();
|
||||
}
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, FontCache* fcache);
|
||||
|
||||
FontCache* m_fcache = nullptr;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_regular;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_subpixel;
|
||||
void destroy() {
|
||||
m_glyphPool.doDestroy();
|
||||
m_regular.reset();
|
||||
m_subpixel.reset();
|
||||
}
|
||||
};
|
||||
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, FontCache* fcache);
|
||||
TextView(ViewResources& res, View& parentView, const FontAtlas& font, Alignment align = Alignment::Left,
|
||||
size_t capacity = 256);
|
||||
TextView(ViewResources& res, View& parentView, FontTag font, Alignment align = Alignment::Left,
|
||||
size_t capacity = 256);
|
||||
|
||||
void destroy()
|
||||
{
|
||||
m_glyphPool.doDestroy();
|
||||
m_regular.reset();
|
||||
m_subpixel.reset();
|
||||
}
|
||||
};
|
||||
std::vector<RenderGlyph>& accessGlyphs() { return m_glyphs; }
|
||||
const std::vector<RenderGlyph>& accessGlyphs() const { return m_glyphs; }
|
||||
|
||||
TextView(ViewResources& res, View& parentView, const FontAtlas& font, Alignment align=Alignment::Left, size_t capacity=256);
|
||||
TextView(ViewResources& res, View& parentView, FontTag font, Alignment align=Alignment::Left, size_t capacity=256);
|
||||
void typesetGlyphs(std::string_view str, const zeus::CColor& defaultColor = zeus::CColor::skWhite);
|
||||
void typesetGlyphs(std::wstring_view str, const zeus::CColor& defaultColor = zeus::CColor::skWhite);
|
||||
void invalidateGlyphs();
|
||||
|
||||
std::vector<RenderGlyph>& accessGlyphs() {return m_glyphs;}
|
||||
const std::vector<RenderGlyph>& accessGlyphs() const {return m_glyphs;}
|
||||
void colorGlyphs(const zeus::CColor& newColor);
|
||||
void colorGlyphsTypeOn(const zeus::CColor& newColor, float startInterval = 0.2, float fadeTime = 0.5);
|
||||
void think();
|
||||
|
||||
void typesetGlyphs(std::string_view str,
|
||||
const zeus::CColor& defaultColor=zeus::CColor::skWhite);
|
||||
void typesetGlyphs(std::wstring_view str,
|
||||
const zeus::CColor& defaultColor=zeus::CColor::skWhite);
|
||||
void invalidateGlyphs();
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
void colorGlyphs(const zeus::CColor& newColor);
|
||||
void colorGlyphsTypeOn(const zeus::CColor& newColor, float startInterval=0.2, float fadeTime=0.5);
|
||||
void think();
|
||||
int nominalWidth() const { return m_width; }
|
||||
int nominalHeight() const { return m_fontAtlas.FT_LineHeight() >> 6; }
|
||||
|
||||
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
int nominalWidth() const {return m_width;}
|
||||
int nominalHeight() const {return m_fontAtlas.FT_LineHeight() >> 6;}
|
||||
|
||||
std::pair<int,int> queryGlyphDimensions(size_t pos) const;
|
||||
size_t reverseSelectGlyph(int x) const;
|
||||
int queryReverseAdvance(size_t idx) const;
|
||||
std::pair<size_t,size_t> queryWholeWordRange(size_t idx) const;
|
||||
std::pair<int, int> queryGlyphDimensions(size_t pos) const;
|
||||
size_t reverseSelectGlyph(int x) const;
|
||||
int queryReverseAdvance(size_t idx) const;
|
||||
std::pair<size_t, size_t> queryWholeWordRange(size_t idx) const;
|
||||
|
||||
private:
|
||||
std::vector<RenderGlyph> m_glyphs;
|
||||
std::vector<RenderGlyphInfo> m_glyphInfo;
|
||||
std::vector<RenderGlyph> m_glyphs;
|
||||
std::vector<RenderGlyphInfo> m_glyphInfo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -2,75 +2,62 @@
|
|||
|
||||
#include "specter/View.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
#define SPECTER_TOOLBAR_GAUGE 28
|
||||
|
||||
class Toolbar : public View
|
||||
{
|
||||
class Toolbar : public View {
|
||||
public:
|
||||
class Resources
|
||||
{
|
||||
friend class ViewResources;
|
||||
friend class Toolbar;
|
||||
boo::ObjToken<boo::ITextureS> m_shadingTex;
|
||||
class Resources {
|
||||
friend class ViewResources;
|
||||
friend class Toolbar;
|
||||
boo::ObjToken<boo::ITextureS> m_shadingTex;
|
||||
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
|
||||
void destroy() { m_shadingTex.reset(); }
|
||||
};
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
|
||||
void destroy() { m_shadingTex.reset(); }
|
||||
};
|
||||
|
||||
enum class Position { None, Bottom, Top };
|
||||
|
||||
enum class Position
|
||||
{
|
||||
None,
|
||||
Bottom,
|
||||
Top
|
||||
};
|
||||
private:
|
||||
unsigned m_units;
|
||||
std::vector<std::vector<ViewChild<View*>>> m_children;
|
||||
unsigned m_units;
|
||||
std::vector<std::vector<ViewChild<View*>>> m_children;
|
||||
|
||||
ViewBlock m_tbBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_tbBlockBuf;
|
||||
TexShaderVert m_tbVerts[10];
|
||||
int m_nomGauge = 25;
|
||||
int m_padding = 10;
|
||||
ViewBlock m_tbBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_tbBlockBuf;
|
||||
TexShaderVert m_tbVerts[10];
|
||||
int m_nomGauge = 25;
|
||||
int m_padding = 10;
|
||||
|
||||
void setHorizontalVerts(int width);
|
||||
void setVerticalVerts(int height);
|
||||
void setHorizontalVerts(int width);
|
||||
void setVerticalVerts(int height);
|
||||
|
||||
VertexBufferBindingTex m_vertsBinding;
|
||||
VertexBufferBindingTex m_vertsBinding;
|
||||
|
||||
public:
|
||||
Toolbar(ViewResources& res, View& parentView, Position toolbarPos, unsigned units);
|
||||
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&coord);
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
Toolbar(ViewResources& res, View& parentView, Position toolbarPos, unsigned units);
|
||||
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& coord);
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
int nominalHeight() const
|
||||
{
|
||||
return m_nomGauge;
|
||||
}
|
||||
int nominalHeight() const { return m_nomGauge; }
|
||||
|
||||
void clear()
|
||||
{
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
u.clear();
|
||||
}
|
||||
void push_back(View* v, unsigned unit);
|
||||
void clear() {
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
u.clear();
|
||||
}
|
||||
void push_back(View* v, unsigned unit);
|
||||
|
||||
void setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
View::setMultiplyColor(color);
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
if (c.m_view)
|
||||
c.m_view->setMultiplyColor(color);
|
||||
}
|
||||
void setMultiplyColor(const zeus::CColor& color) {
|
||||
View::setMultiplyColor(color);
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
if (c.m_view)
|
||||
c.m_view->setMultiplyColor(color);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -3,37 +3,34 @@
|
|||
#include "specter/View.hpp"
|
||||
#include "specter/MultiLineTextView.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class Tooltip : public View
|
||||
{
|
||||
ViewBlock m_ttBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_ttBlockBuf;
|
||||
SolidShaderVert m_ttVerts[16];
|
||||
int m_nomWidth = 25;
|
||||
int m_nomHeight = 25;
|
||||
class Tooltip : public View {
|
||||
ViewBlock m_ttBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_ttBlockBuf;
|
||||
SolidShaderVert m_ttVerts[16];
|
||||
int m_nomWidth = 25;
|
||||
int m_nomHeight = 25;
|
||||
|
||||
void setVerts(int width, int height, float pf);
|
||||
void setVerts(int width, int height, float pf);
|
||||
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
VertexBufferBindingSolid m_vertsBinding;
|
||||
|
||||
std::string m_titleStr;
|
||||
std::unique_ptr<TextView> m_title;
|
||||
std::string m_messageStr;
|
||||
std::unique_ptr<MultiLineTextView> m_message;
|
||||
std::string m_titleStr;
|
||||
std::unique_ptr<TextView> m_title;
|
||||
std::string m_messageStr;
|
||||
std::unique_ptr<MultiLineTextView> m_message;
|
||||
|
||||
std::unique_ptr<TextView> m_cornersOutline[4];
|
||||
std::unique_ptr<TextView> m_cornersFilled[4];
|
||||
|
||||
std::unique_ptr<TextView> m_cornersOutline[4];
|
||||
std::unique_ptr<TextView> m_cornersFilled[4];
|
||||
public:
|
||||
Tooltip(ViewResources& res, View& parentView, std::string_view title,
|
||||
std::string_view message);
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
Tooltip(ViewResources& res, View& parentView, std::string_view title, std::string_view message);
|
||||
void resized(const boo::SWindowRect& rootView, const boo::SWindowRect& sub);
|
||||
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
int nominalWidth() const {return m_nomWidth;}
|
||||
int nominalHeight() const {return m_nomHeight;}
|
||||
int nominalWidth() const { return m_nomWidth; }
|
||||
int nominalHeight() const { return m_nomHeight; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -3,32 +3,29 @@
|
|||
#include <string>
|
||||
#include <athena/DNAYaml.hpp>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
class Locale {
|
||||
std::string_view m_name;
|
||||
std::string_view m_fullName;
|
||||
std::unique_ptr<athena::io::YAMLNode> m_rootNode;
|
||||
const athena::io::YAMLNode* m_langNode;
|
||||
|
||||
class Locale
|
||||
{
|
||||
std::string_view m_name;
|
||||
std::string_view m_fullName;
|
||||
std::unique_ptr<athena::io::YAMLNode> m_rootNode;
|
||||
const athena::io::YAMLNode* m_langNode;
|
||||
public:
|
||||
Locale(std::string_view name, std::string_view fullName,
|
||||
const unsigned char* yamlSource, size_t yamlLength);
|
||||
std::string_view name() const {return m_name;}
|
||||
std::string_view fullName() const {return m_fullName;}
|
||||
const athena::io::YAMLNode* rootNode() const {return m_langNode;}
|
||||
Locale(std::string_view name, std::string_view fullName, const unsigned char* yamlSource, size_t yamlLength);
|
||||
std::string_view name() const { return m_name; }
|
||||
std::string_view fullName() const { return m_fullName; }
|
||||
const athena::io::YAMLNode* rootNode() const { return m_langNode; }
|
||||
};
|
||||
|
||||
class Translator
|
||||
{
|
||||
const Locale* m_targetLocale;
|
||||
class Translator {
|
||||
const Locale* m_targetLocale;
|
||||
|
||||
public:
|
||||
Translator(const Locale* targetLocale) {setLocale(targetLocale);}
|
||||
void setLocale(const Locale* targetLocale);
|
||||
std::string_view translate(std::string_view key) const;
|
||||
std::string_view translateOr(std::string_view key, std::string_view vor) const;
|
||||
Translator(const Locale* targetLocale) { setLocale(targetLocale); }
|
||||
void setLocale(const Locale* targetLocale);
|
||||
std::string_view translate(std::string_view key) const;
|
||||
std::string_view translateOr(std::string_view key, std::string_view vor) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -10,393 +10,334 @@
|
|||
#include "hecl/UniformBufferPool.hpp"
|
||||
#include "hecl/VertexBufferPool.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
class IThemeData;
|
||||
class ViewResources;
|
||||
class RootView;
|
||||
|
||||
extern zeus::CMatrix4f g_PlatformMatrix;
|
||||
|
||||
class RectangleConstraint
|
||||
{
|
||||
class RectangleConstraint {
|
||||
public:
|
||||
enum class Test
|
||||
{
|
||||
Fixed,
|
||||
Minimum,
|
||||
Maximum
|
||||
};
|
||||
enum class Test { Fixed, Minimum, Maximum };
|
||||
|
||||
private:
|
||||
int m_x, m_y;
|
||||
Test m_xtest, m_ytest;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
class Space;
|
||||
class SplitView;
|
||||
class View
|
||||
{
|
||||
class View {
|
||||
public:
|
||||
struct SolidShaderVert
|
||||
{
|
||||
zeus::CVector3f m_pos;
|
||||
zeus::CColor m_color = zeus::CColor::skClear;
|
||||
};
|
||||
struct TexShaderVert
|
||||
{
|
||||
zeus::CVector3f m_pos;
|
||||
zeus::CVector2f m_uv;
|
||||
};
|
||||
struct ViewBlock
|
||||
{
|
||||
zeus::CMatrix4f m_mv;
|
||||
zeus::CColor m_color = zeus::CColor::skWhite;
|
||||
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;
|
||||
}
|
||||
void finalAssign(const ViewBlock& other)
|
||||
{
|
||||
m_mv = g_PlatformMatrix * other.m_mv;
|
||||
m_color = other.m_color;
|
||||
}
|
||||
};
|
||||
struct SolidShaderVert {
|
||||
zeus::CVector3f m_pos;
|
||||
zeus::CColor m_color = zeus::CColor::skClear;
|
||||
};
|
||||
struct TexShaderVert {
|
||||
zeus::CVector3f m_pos;
|
||||
zeus::CVector2f m_uv;
|
||||
};
|
||||
struct ViewBlock {
|
||||
zeus::CMatrix4f m_mv;
|
||||
zeus::CColor m_color = zeus::CColor::skWhite;
|
||||
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;
|
||||
}
|
||||
void finalAssign(const ViewBlock& other) {
|
||||
m_mv = g_PlatformMatrix * other.m_mv;
|
||||
m_color = other.m_color;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename VertStruct>
|
||||
struct VertexBufferBinding
|
||||
{
|
||||
typename hecl::VertexBufferPool<VertStruct>::Token m_vertsBuf;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_shaderBinding;
|
||||
template <typename VertStruct>
|
||||
struct VertexBufferBinding {
|
||||
typename hecl::VertexBufferPool<VertStruct>::Token m_vertsBuf;
|
||||
boo::ObjToken<boo::IShaderDataBinding> m_shaderBinding;
|
||||
|
||||
void load(const VertStruct* data, size_t count)
|
||||
{
|
||||
if (m_vertsBuf)
|
||||
{
|
||||
VertStruct* out = m_vertsBuf.access();
|
||||
for (size_t i=0; i<count; ++i)
|
||||
out[i] = data[i];
|
||||
}
|
||||
}
|
||||
template <typename VertArray>
|
||||
void load(const VertArray data)
|
||||
{
|
||||
static_assert(std::is_same<std::remove_all_extents_t<VertArray>,
|
||||
VertStruct>::value, "mismatched type");
|
||||
if (m_vertsBuf)
|
||||
{
|
||||
constexpr size_t count = sizeof(VertArray) / sizeof(VertStruct);
|
||||
VertStruct* out = m_vertsBuf.access();
|
||||
for (size_t i=0; i<count; ++i)
|
||||
out[i] = data[i];
|
||||
}
|
||||
}
|
||||
void load(const VertStruct* data, size_t count) {
|
||||
if (m_vertsBuf) {
|
||||
VertStruct* out = m_vertsBuf.access();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
out[i] = data[i];
|
||||
}
|
||||
}
|
||||
template <typename VertArray>
|
||||
void load(const VertArray data) {
|
||||
static_assert(std::is_same<std::remove_all_extents_t<VertArray>, VertStruct>::value, "mismatched type");
|
||||
if (m_vertsBuf) {
|
||||
constexpr size_t count = sizeof(VertArray) / sizeof(VertStruct);
|
||||
VertStruct* out = m_vertsBuf.access();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
out[i] = data[i];
|
||||
}
|
||||
}
|
||||
|
||||
operator const boo::ObjToken<boo::IShaderDataBinding>&() { return m_shaderBinding; }
|
||||
};
|
||||
struct VertexBufferBindingSolid : VertexBufferBinding<SolidShaderVert>
|
||||
{
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf);
|
||||
};
|
||||
struct VertexBufferBindingTex : VertexBufferBinding<TexShaderVert>
|
||||
{
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
const boo::ObjToken<boo::ITexture>& texture);
|
||||
};
|
||||
operator const boo::ObjToken<boo::IShaderDataBinding>&() { return m_shaderBinding; }
|
||||
};
|
||||
struct VertexBufferBindingSolid : VertexBufferBinding<SolidShaderVert> {
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res, size_t count,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf);
|
||||
};
|
||||
struct VertexBufferBindingTex : VertexBufferBinding<TexShaderVert> {
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res, size_t count,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
const boo::ObjToken<boo::ITexture>& texture);
|
||||
};
|
||||
|
||||
private:
|
||||
RootView& m_rootView;
|
||||
View& m_parentView;
|
||||
boo::SWindowRect m_subRect;
|
||||
VertexBufferBindingSolid m_bgVertsBinding;
|
||||
SolidShaderVert m_bgRect[4];
|
||||
RootView& m_rootView;
|
||||
View& m_parentView;
|
||||
boo::SWindowRect m_subRect;
|
||||
VertexBufferBindingSolid m_bgVertsBinding;
|
||||
SolidShaderVert m_bgRect[4];
|
||||
|
||||
friend class RootView;
|
||||
View(ViewResources& res);
|
||||
friend class RootView;
|
||||
View(ViewResources& res);
|
||||
|
||||
protected:
|
||||
ViewBlock m_viewVertBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_viewVertBlockBuf;
|
||||
ViewBlock m_viewVertBlock;
|
||||
hecl::UniformBufferPool<ViewBlock>::Token m_viewVertBlockBuf;
|
||||
|
||||
public:
|
||||
struct Resources
|
||||
{
|
||||
hecl::UniformBufferPool<ViewBlock> m_bufPool;
|
||||
hecl::VertexBufferPool<SolidShaderVert> m_solidPool;
|
||||
hecl::VertexBufferPool<TexShaderVert> m_texPool;
|
||||
struct Resources {
|
||||
hecl::UniformBufferPool<ViewBlock> m_bufPool;
|
||||
hecl::VertexBufferPool<SolidShaderVert> m_solidPool;
|
||||
hecl::VertexBufferPool<TexShaderVert> m_texPool;
|
||||
|
||||
void updateBuffers()
|
||||
{
|
||||
m_bufPool.updateBuffers();
|
||||
m_solidPool.updateBuffers();
|
||||
m_texPool.updateBuffers();
|
||||
}
|
||||
void updateBuffers() {
|
||||
m_bufPool.updateBuffers();
|
||||
m_solidPool.updateBuffers();
|
||||
m_texPool.updateBuffers();
|
||||
}
|
||||
|
||||
boo::ObjToken<boo::IShaderPipeline> m_solidShader;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_texShader;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_solidShader;
|
||||
boo::ObjToken<boo::IShaderPipeline> m_texShader;
|
||||
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
|
||||
void init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme);
|
||||
|
||||
void destroy()
|
||||
{
|
||||
m_bufPool.doDestroy();
|
||||
m_solidPool.doDestroy();
|
||||
m_texPool.doDestroy();
|
||||
void destroy() {
|
||||
m_bufPool.doDestroy();
|
||||
m_solidPool.doDestroy();
|
||||
m_texPool.doDestroy();
|
||||
|
||||
m_solidShader.reset();
|
||||
m_texShader.reset();
|
||||
}
|
||||
};
|
||||
m_solidShader.reset();
|
||||
m_texShader.reset();
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
View(ViewResources& res, View& parentView);
|
||||
void buildResources(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res);
|
||||
void commitResources(ViewResources& res, const boo::FactoryCommitFunc& commitFunc);
|
||||
View(ViewResources& res, View& parentView);
|
||||
void buildResources(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res);
|
||||
void commitResources(ViewResources& res, const boo::FactoryCommitFunc& commitFunc);
|
||||
|
||||
public:
|
||||
virtual ~View() {}
|
||||
View() = delete;
|
||||
View(const View& other) = delete;
|
||||
View& operator=(const View& other) = delete;
|
||||
virtual ~View() {}
|
||||
View() = delete;
|
||||
View(const View& other) = delete;
|
||||
View& operator=(const View& other) = delete;
|
||||
|
||||
View& parentView() {return m_parentView;}
|
||||
RootView& rootView() {return m_rootView;}
|
||||
const RootView& rootView() const {return m_rootView;}
|
||||
const boo::SWindowRect& subRect() const {return m_subRect;}
|
||||
int width() const {return m_subRect.size[0];}
|
||||
int height() const {return m_subRect.size[1];}
|
||||
void updateSize();
|
||||
View& parentView() { return m_parentView; }
|
||||
RootView& rootView() { return m_rootView; }
|
||||
const RootView& rootView() const { return m_rootView; }
|
||||
const boo::SWindowRect& subRect() const { return m_subRect; }
|
||||
int width() const { return m_subRect.size[0]; }
|
||||
int height() const { return m_subRect.size[1]; }
|
||||
void updateSize();
|
||||
|
||||
void setBackground(const zeus::CColor& color)
|
||||
{
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_bgRect[i].m_color = color;
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
}
|
||||
void setBackground(const zeus::CColor& color) {
|
||||
for (int i = 0; i < 4; ++i)
|
||||
m_bgRect[i].m_color = color;
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
}
|
||||
|
||||
virtual void setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock);
|
||||
}
|
||||
virtual void setMultiplyColor(const zeus::CColor& color) {
|
||||
m_viewVertBlock.m_color = color;
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock);
|
||||
}
|
||||
|
||||
virtual int nominalWidth() const {return 0;}
|
||||
virtual int nominalHeight() const {return 0;}
|
||||
virtual int nominalWidth() const { return 0; }
|
||||
virtual int nominalHeight() const { return 0; }
|
||||
|
||||
virtual void setActive(bool) {}
|
||||
virtual void setActive(bool) {}
|
||||
|
||||
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&) {}
|
||||
virtual void mouseEnter(const boo::SWindowCoord&) {}
|
||||
virtual void mouseLeave(const boo::SWindowCoord&) {}
|
||||
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) {}
|
||||
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&) {}
|
||||
virtual void mouseEnter(const boo::SWindowCoord&) {}
|
||||
virtual void mouseLeave(const boo::SWindowCoord&) {}
|
||||
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) {}
|
||||
|
||||
virtual void containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {}
|
||||
virtual void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
virtual void resized(const ViewBlock& vb, const boo::SWindowRect& sub);
|
||||
virtual void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub,
|
||||
const boo::SWindowRect& scissor) {resized(root, sub);}
|
||||
virtual void think() {}
|
||||
virtual void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
virtual void containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {}
|
||||
virtual void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||
virtual void resized(const ViewBlock& vb, const boo::SWindowRect& sub);
|
||||
virtual void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor) {
|
||||
resized(root, sub);
|
||||
}
|
||||
virtual void think() {}
|
||||
virtual void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||
|
||||
virtual bool isSpace() const { return false; }
|
||||
virtual bool isSplitView() const { return false; }
|
||||
Space* castToSpace();
|
||||
SplitView* castToSplitView();
|
||||
virtual bool isSpace() const { return false; }
|
||||
virtual bool isSplitView() const { return false; }
|
||||
Space* castToSpace();
|
||||
SplitView* castToSplitView();
|
||||
};
|
||||
|
||||
template <class ViewPtrType>
|
||||
struct ViewChild
|
||||
{
|
||||
ViewPtrType m_view = ViewPtrType();
|
||||
bool m_mouseIn = false;
|
||||
int m_mouseDown = 0;
|
||||
struct ViewChild {
|
||||
ViewPtrType m_view = ViewPtrType();
|
||||
bool m_mouseIn = false;
|
||||
int m_mouseDown = 0;
|
||||
|
||||
bool mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (!m_view)
|
||||
return false;
|
||||
if (m_view->subRect().coordInRect(coord))
|
||||
{
|
||||
if ((m_mouseDown & 1 << int(button)) == 0)
|
||||
{
|
||||
m_view->mouseDown(coord, button, mod);
|
||||
m_mouseDown |= 1 << int(button);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
bool mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (!m_view)
|
||||
return false;
|
||||
if (m_view->subRect().coordInRect(coord)) {
|
||||
if ((m_mouseDown & 1 << int(button)) == 0) {
|
||||
m_view->mouseDown(coord, button, mod);
|
||||
m_mouseDown |= 1 << int(button);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (!m_view)
|
||||
return;
|
||||
if ((m_mouseDown & 1 << int(button)) != 0)
|
||||
{
|
||||
m_view->mouseUp(coord, button, mod);
|
||||
m_mouseDown &= ~(1 << int(button));
|
||||
}
|
||||
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (!m_view)
|
||||
return;
|
||||
if ((m_mouseDown & 1 << int(button)) != 0) {
|
||||
m_view->mouseUp(coord, button, mod);
|
||||
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 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 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 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);
|
||||
}
|
||||
void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) {
|
||||
if (!m_view)
|
||||
return;
|
||||
if (m_mouseIn)
|
||||
m_view->scroll(coord, scroll);
|
||||
}
|
||||
};
|
||||
|
||||
template <class ViewPtrType>
|
||||
struct ScissorViewChild : ViewChild<ViewPtrType>
|
||||
{
|
||||
using base = ViewChild<ViewPtrType>;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
struct ScissorViewChild : ViewChild<ViewPtrType> {
|
||||
using base = ViewChild<ViewPtrType>;
|
||||
boo::SWindowRect m_scissorRect;
|
||||
|
||||
bool mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (!base::m_view)
|
||||
return false;
|
||||
if (base::m_view->subRect().coordInRect(coord) &&
|
||||
m_scissorRect.coordInRect(coord))
|
||||
{
|
||||
if ((base::m_mouseDown & 1 << int(button)) == 0)
|
||||
{
|
||||
base::m_view->mouseDown(coord, button, mod);
|
||||
base::m_mouseDown |= 1 << int(button);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
bool mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (!base::m_view)
|
||||
return false;
|
||||
if (base::m_view->subRect().coordInRect(coord) && m_scissorRect.coordInRect(coord)) {
|
||||
if ((base::m_mouseDown & 1 << int(button)) == 0) {
|
||||
base::m_view->mouseDown(coord, button, mod);
|
||||
base::m_mouseDown |= 1 << int(button);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (!base::m_view)
|
||||
return;
|
||||
if (base::m_view->subRect().coordInRect(coord) &&
|
||||
m_scissorRect.coordInRect(coord))
|
||||
{
|
||||
if (!base::m_mouseIn)
|
||||
{
|
||||
base::m_view->mouseEnter(coord);
|
||||
base::m_mouseIn = true;
|
||||
}
|
||||
base::m_view->mouseMove(coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (base::m_mouseIn)
|
||||
{
|
||||
base::m_view->mouseLeave(coord);
|
||||
base::m_mouseIn = false;
|
||||
}
|
||||
}
|
||||
void mouseMove(const boo::SWindowCoord& coord) {
|
||||
if (!base::m_view)
|
||||
return;
|
||||
if (base::m_view->subRect().coordInRect(coord) && m_scissorRect.coordInRect(coord)) {
|
||||
if (!base::m_mouseIn) {
|
||||
base::m_view->mouseEnter(coord);
|
||||
base::m_mouseIn = true;
|
||||
}
|
||||
base::m_view->mouseMove(coord);
|
||||
} else {
|
||||
if (base::m_mouseIn) {
|
||||
base::m_view->mouseLeave(coord);
|
||||
base::m_mouseIn = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -7,213 +7,204 @@
|
|||
|
||||
#include <thread>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
class IThemeData
|
||||
{
|
||||
namespace specter {
|
||||
class IThemeData {
|
||||
public:
|
||||
virtual const zeus::CColor& uiText() const = 0;
|
||||
virtual const zeus::CColor& uiAltText() const = 0;
|
||||
virtual const zeus::CColor& fieldText() const = 0;
|
||||
virtual const zeus::CColor& fieldMarkedText() const = 0;
|
||||
virtual const zeus::CColor& selectedFieldText() const = 0;
|
||||
virtual const zeus::CColor& uiText() const = 0;
|
||||
virtual const zeus::CColor& uiAltText() const = 0;
|
||||
virtual const zeus::CColor& fieldText() const = 0;
|
||||
virtual const zeus::CColor& fieldMarkedText() const = 0;
|
||||
virtual const zeus::CColor& selectedFieldText() const = 0;
|
||||
|
||||
virtual const zeus::CColor& viewportBackground() const = 0;
|
||||
virtual const zeus::CColor& toolbarBackground() const = 0;
|
||||
virtual const zeus::CColor& tooltipBackground() const = 0;
|
||||
virtual const zeus::CColor& spaceBackground() const = 0;
|
||||
virtual const zeus::CColor& splashBackground() const = 0;
|
||||
virtual const zeus::CColor& splashErrorBackground() const = 0;
|
||||
virtual const zeus::CColor& viewportBackground() const = 0;
|
||||
virtual const zeus::CColor& toolbarBackground() const = 0;
|
||||
virtual const zeus::CColor& tooltipBackground() const = 0;
|
||||
virtual const zeus::CColor& spaceBackground() const = 0;
|
||||
virtual const zeus::CColor& splashBackground() const = 0;
|
||||
virtual const zeus::CColor& splashErrorBackground() const = 0;
|
||||
|
||||
virtual const zeus::CColor& splash1() const = 0;
|
||||
virtual const zeus::CColor& splash2() const = 0;
|
||||
virtual const zeus::CColor& splash1() const = 0;
|
||||
virtual const zeus::CColor& splash2() const = 0;
|
||||
|
||||
virtual const zeus::CColor& button1Inactive() const = 0;
|
||||
virtual const zeus::CColor& button2Inactive() const = 0;
|
||||
virtual const zeus::CColor& button1Hover() const = 0;
|
||||
virtual const zeus::CColor& button2Hover() const = 0;
|
||||
virtual const zeus::CColor& button1Press() const = 0;
|
||||
virtual const zeus::CColor& button2Press() const = 0;
|
||||
virtual const zeus::CColor& button1Disabled() const = 0;
|
||||
virtual const zeus::CColor& button2Disabled() const = 0;
|
||||
virtual const zeus::CColor& button1Inactive() const = 0;
|
||||
virtual const zeus::CColor& button2Inactive() const = 0;
|
||||
virtual const zeus::CColor& button1Hover() const = 0;
|
||||
virtual const zeus::CColor& button2Hover() const = 0;
|
||||
virtual const zeus::CColor& button1Press() const = 0;
|
||||
virtual const zeus::CColor& button2Press() const = 0;
|
||||
virtual const zeus::CColor& button1Disabled() const = 0;
|
||||
virtual const zeus::CColor& button2Disabled() const = 0;
|
||||
|
||||
virtual const zeus::CColor& textfield1Inactive() const = 0;
|
||||
virtual const zeus::CColor& textfield2Inactive() const = 0;
|
||||
virtual const zeus::CColor& textfield1Hover() const = 0;
|
||||
virtual const zeus::CColor& textfield2Hover() const = 0;
|
||||
virtual const zeus::CColor& textfield1Disabled() const = 0;
|
||||
virtual const zeus::CColor& textfield2Disabled() const = 0;
|
||||
virtual const zeus::CColor& textfieldSelection() const = 0;
|
||||
virtual const zeus::CColor& textfieldMarkSelection() const = 0;
|
||||
virtual const zeus::CColor& textfield1Inactive() const = 0;
|
||||
virtual const zeus::CColor& textfield2Inactive() const = 0;
|
||||
virtual const zeus::CColor& textfield1Hover() const = 0;
|
||||
virtual const zeus::CColor& textfield2Hover() const = 0;
|
||||
virtual const zeus::CColor& textfield1Disabled() const = 0;
|
||||
virtual const zeus::CColor& textfield2Disabled() const = 0;
|
||||
virtual const zeus::CColor& textfieldSelection() const = 0;
|
||||
virtual const zeus::CColor& textfieldMarkSelection() const = 0;
|
||||
|
||||
virtual const zeus::CColor& tableCellBg1() const = 0;
|
||||
virtual const zeus::CColor& tableCellBg2() const = 0;
|
||||
virtual const zeus::CColor& tableCellBgSelected() const = 0;
|
||||
virtual const zeus::CColor& tableCellBg1() const = 0;
|
||||
virtual const zeus::CColor& tableCellBg2() const = 0;
|
||||
virtual const zeus::CColor& tableCellBgSelected() const = 0;
|
||||
|
||||
virtual const zeus::CColor& scrollIndicator() const = 0;
|
||||
virtual const zeus::CColor& scrollIndicator() const = 0;
|
||||
|
||||
virtual const zeus::CColor& spaceTriangleShading1() const = 0;
|
||||
virtual const zeus::CColor& spaceTriangleShading2() const = 0;
|
||||
virtual const zeus::CColor& spaceTriangleShading1() const = 0;
|
||||
virtual const zeus::CColor& spaceTriangleShading2() const = 0;
|
||||
};
|
||||
|
||||
class DefaultThemeData : public IThemeData
|
||||
{
|
||||
zeus::CColor m_uiText = zeus::CColor::skWhite;
|
||||
zeus::CColor m_uiAltText = zeus::CColor::skGrey;
|
||||
zeus::CColor m_fieldText = zeus::CColor::skBlack;
|
||||
zeus::CColor m_fieldMarkedText = {0.25, 0.25, 0.25, 1.0};
|
||||
zeus::CColor m_selectedFieldText = zeus::CColor::skWhite;
|
||||
class DefaultThemeData : public IThemeData {
|
||||
zeus::CColor m_uiText = zeus::CColor::skWhite;
|
||||
zeus::CColor m_uiAltText = zeus::CColor::skGrey;
|
||||
zeus::CColor m_fieldText = zeus::CColor::skBlack;
|
||||
zeus::CColor m_fieldMarkedText = {0.25, 0.25, 0.25, 1.0};
|
||||
zeus::CColor m_selectedFieldText = zeus::CColor::skWhite;
|
||||
|
||||
zeus::CColor m_vpBg = {0.2, 0.2, 0.2, 1.0};
|
||||
zeus::CColor m_tbBg = {0.2, 0.2, 0.2, 0.9};
|
||||
zeus::CColor m_tooltipBg = {0.1, 0.1, 0.1, 0.85};
|
||||
zeus::CColor m_spaceBg = {0.075, 0.075, 0.075, 0.85};
|
||||
zeus::CColor m_splashBg = {0.075, 0.075, 0.075, 0.85};
|
||||
zeus::CColor m_splashErrorBg = {0.1, 0.01, 0.01, 0.85};
|
||||
zeus::CColor m_vpBg = {0.2, 0.2, 0.2, 1.0};
|
||||
zeus::CColor m_tbBg = {0.2, 0.2, 0.2, 0.9};
|
||||
zeus::CColor m_tooltipBg = {0.1, 0.1, 0.1, 0.85};
|
||||
zeus::CColor m_spaceBg = {0.075, 0.075, 0.075, 0.85};
|
||||
zeus::CColor m_splashBg = {0.075, 0.075, 0.075, 0.85};
|
||||
zeus::CColor m_splashErrorBg = {0.1, 0.01, 0.01, 0.85};
|
||||
|
||||
zeus::CColor m_splash1 = {1.0, 1.0, 1.0, 1.0};
|
||||
zeus::CColor m_splash2 = {0.3, 0.3, 0.3, 1.0};
|
||||
zeus::CColor m_splash1 = {1.0, 1.0, 1.0, 1.0};
|
||||
zeus::CColor m_splash2 = {0.3, 0.3, 0.3, 1.0};
|
||||
|
||||
zeus::CColor m_button1Inactive = {0.2823, 0.2823, 0.2823, 1.0};
|
||||
zeus::CColor m_button2Inactive = {0.1725, 0.1725, 0.1725, 1.0};
|
||||
zeus::CColor m_button1Hover = {0.3523, 0.3523, 0.3523, 1.0};
|
||||
zeus::CColor m_button2Hover = {0.2425, 0.2425, 0.2425, 1.0};
|
||||
zeus::CColor m_button1Press = {0.1725, 0.1725, 0.1725, 1.0};
|
||||
zeus::CColor m_button2Press = {0.2823, 0.2823, 0.2823, 1.0};
|
||||
zeus::CColor m_button1Disabled = {0.2823, 0.2823, 0.2823, 0.5};
|
||||
zeus::CColor m_button2Disabled = {0.1725, 0.1725, 0.1725, 0.5};
|
||||
zeus::CColor m_button1Inactive = {0.2823, 0.2823, 0.2823, 1.0};
|
||||
zeus::CColor m_button2Inactive = {0.1725, 0.1725, 0.1725, 1.0};
|
||||
zeus::CColor m_button1Hover = {0.3523, 0.3523, 0.3523, 1.0};
|
||||
zeus::CColor m_button2Hover = {0.2425, 0.2425, 0.2425, 1.0};
|
||||
zeus::CColor m_button1Press = {0.1725, 0.1725, 0.1725, 1.0};
|
||||
zeus::CColor m_button2Press = {0.2823, 0.2823, 0.2823, 1.0};
|
||||
zeus::CColor m_button1Disabled = {0.2823, 0.2823, 0.2823, 0.5};
|
||||
zeus::CColor m_button2Disabled = {0.1725, 0.1725, 0.1725, 0.5};
|
||||
|
||||
zeus::CColor m_textfield2Inactive = {0.7823, 0.7823, 0.7823, 1.0};
|
||||
zeus::CColor m_textfield1Inactive = {0.5725, 0.5725, 0.5725, 1.0};
|
||||
zeus::CColor m_textfield2Hover = {0.8523, 0.8523, 0.8523, 1.0};
|
||||
zeus::CColor m_textfield1Hover = {0.6425, 0.6425, 0.6425, 1.0};
|
||||
zeus::CColor m_textfield2Disabled = {0.7823, 0.7823, 0.7823, 0.5};
|
||||
zeus::CColor m_textfield1Disabled = {0.5725, 0.5725, 0.5725, 0.5};
|
||||
zeus::CColor m_textfieldSelection = {0.2725, 0.2725, 0.2725, 1.0};
|
||||
zeus::CColor m_textfieldMarkSelection = {1.0, 1.0, 0.2725, 1.0};
|
||||
zeus::CColor m_textfield2Inactive = {0.7823, 0.7823, 0.7823, 1.0};
|
||||
zeus::CColor m_textfield1Inactive = {0.5725, 0.5725, 0.5725, 1.0};
|
||||
zeus::CColor m_textfield2Hover = {0.8523, 0.8523, 0.8523, 1.0};
|
||||
zeus::CColor m_textfield1Hover = {0.6425, 0.6425, 0.6425, 1.0};
|
||||
zeus::CColor m_textfield2Disabled = {0.7823, 0.7823, 0.7823, 0.5};
|
||||
zeus::CColor m_textfield1Disabled = {0.5725, 0.5725, 0.5725, 0.5};
|
||||
zeus::CColor m_textfieldSelection = {0.2725, 0.2725, 0.2725, 1.0};
|
||||
zeus::CColor m_textfieldMarkSelection = {1.0, 1.0, 0.2725, 1.0};
|
||||
|
||||
zeus::CColor m_tableCellBg1 = {0.1725, 0.1725, 0.1725, 0.75};
|
||||
zeus::CColor m_tableCellBg2 = {0.2425, 0.2425, 0.2425, 0.75};
|
||||
zeus::CColor m_tableCellBgSelected = {0.6425, 0.6425, 0.6425, 1.0};
|
||||
zeus::CColor m_tableCellBg1 = {0.1725, 0.1725, 0.1725, 0.75};
|
||||
zeus::CColor m_tableCellBg2 = {0.2425, 0.2425, 0.2425, 0.75};
|
||||
zeus::CColor m_tableCellBgSelected = {0.6425, 0.6425, 0.6425, 1.0};
|
||||
|
||||
zeus::CColor m_scrollIndicator = {0.2823, 0.2823, 0.2823, 1.0};
|
||||
zeus::CColor m_scrollIndicator = {0.2823, 0.2823, 0.2823, 1.0};
|
||||
|
||||
zeus::CColor m_spaceTriangleShading1 = {0.6425, 0.6425, 0.6425, 1.0};
|
||||
zeus::CColor m_spaceTriangleShading2 = {0.5725, 0.5725, 0.5725, 1.0};
|
||||
zeus::CColor m_spaceTriangleShading1 = {0.6425, 0.6425, 0.6425, 1.0};
|
||||
zeus::CColor m_spaceTriangleShading2 = {0.5725, 0.5725, 0.5725, 1.0};
|
||||
|
||||
public:
|
||||
virtual const zeus::CColor& uiText() const { return m_uiText; }
|
||||
virtual const zeus::CColor& uiAltText() const { return m_uiAltText; }
|
||||
virtual const zeus::CColor& fieldText() const { return m_fieldText; }
|
||||
virtual const zeus::CColor& fieldMarkedText() const { return m_fieldMarkedText; }
|
||||
virtual const zeus::CColor& selectedFieldText() const { return m_selectedFieldText; }
|
||||
virtual const zeus::CColor& uiText() const { return m_uiText; }
|
||||
virtual const zeus::CColor& uiAltText() const { return m_uiAltText; }
|
||||
virtual const zeus::CColor& fieldText() const { return m_fieldText; }
|
||||
virtual const zeus::CColor& fieldMarkedText() const { return m_fieldMarkedText; }
|
||||
virtual const zeus::CColor& selectedFieldText() const { return m_selectedFieldText; }
|
||||
|
||||
virtual const zeus::CColor& viewportBackground() const { return m_vpBg; }
|
||||
virtual const zeus::CColor& toolbarBackground() const { return m_tbBg; }
|
||||
virtual const zeus::CColor& tooltipBackground() const { return m_tooltipBg; }
|
||||
virtual const zeus::CColor& spaceBackground() const { return m_spaceBg; }
|
||||
virtual const zeus::CColor& splashBackground() const { return m_splashBg; }
|
||||
virtual const zeus::CColor& splashErrorBackground() const { return m_splashErrorBg; }
|
||||
virtual const zeus::CColor& viewportBackground() const { return m_vpBg; }
|
||||
virtual const zeus::CColor& toolbarBackground() const { return m_tbBg; }
|
||||
virtual const zeus::CColor& tooltipBackground() const { return m_tooltipBg; }
|
||||
virtual const zeus::CColor& spaceBackground() const { return m_spaceBg; }
|
||||
virtual const zeus::CColor& splashBackground() const { return m_splashBg; }
|
||||
virtual const zeus::CColor& splashErrorBackground() const { return m_splashErrorBg; }
|
||||
|
||||
virtual const zeus::CColor& splash1() const { return m_splash1; }
|
||||
virtual const zeus::CColor& splash2() const { return m_splash2; }
|
||||
virtual const zeus::CColor& splash1() const { return m_splash1; }
|
||||
virtual const zeus::CColor& splash2() const { return m_splash2; }
|
||||
|
||||
virtual const zeus::CColor& button1Inactive() const { return m_button1Inactive; }
|
||||
virtual const zeus::CColor& button2Inactive() const { return m_button2Inactive; }
|
||||
virtual const zeus::CColor& button1Hover() const { return m_button1Hover; }
|
||||
virtual const zeus::CColor& button2Hover() const { return m_button2Hover; }
|
||||
virtual const zeus::CColor& button1Press() const { return m_button1Press; }
|
||||
virtual const zeus::CColor& button2Press() const { return m_button2Press; }
|
||||
virtual const zeus::CColor& button1Disabled() const { return m_button1Disabled; }
|
||||
virtual const zeus::CColor& button2Disabled() const { return m_button2Disabled; }
|
||||
virtual const zeus::CColor& button1Inactive() const { return m_button1Inactive; }
|
||||
virtual const zeus::CColor& button2Inactive() const { return m_button2Inactive; }
|
||||
virtual const zeus::CColor& button1Hover() const { return m_button1Hover; }
|
||||
virtual const zeus::CColor& button2Hover() const { return m_button2Hover; }
|
||||
virtual const zeus::CColor& button1Press() const { return m_button1Press; }
|
||||
virtual const zeus::CColor& button2Press() const { return m_button2Press; }
|
||||
virtual const zeus::CColor& button1Disabled() const { return m_button1Disabled; }
|
||||
virtual const zeus::CColor& button2Disabled() const { return m_button2Disabled; }
|
||||
|
||||
virtual const zeus::CColor& textfield1Inactive() const { return m_textfield1Inactive; }
|
||||
virtual const zeus::CColor& textfield2Inactive() const { return m_textfield2Inactive; }
|
||||
virtual const zeus::CColor& textfield1Hover() const { return m_textfield1Hover; }
|
||||
virtual const zeus::CColor& textfield2Hover() const { return m_textfield2Hover; }
|
||||
virtual const zeus::CColor& textfield1Disabled() const { return m_textfield1Disabled; }
|
||||
virtual const zeus::CColor& textfield2Disabled() const { return m_textfield2Disabled; }
|
||||
virtual const zeus::CColor& textfieldSelection() const { return m_textfieldSelection; }
|
||||
virtual const zeus::CColor& textfieldMarkSelection() const { return m_textfieldMarkSelection; }
|
||||
virtual const zeus::CColor& textfield1Inactive() const { return m_textfield1Inactive; }
|
||||
virtual const zeus::CColor& textfield2Inactive() const { return m_textfield2Inactive; }
|
||||
virtual const zeus::CColor& textfield1Hover() const { return m_textfield1Hover; }
|
||||
virtual const zeus::CColor& textfield2Hover() const { return m_textfield2Hover; }
|
||||
virtual const zeus::CColor& textfield1Disabled() const { return m_textfield1Disabled; }
|
||||
virtual const zeus::CColor& textfield2Disabled() const { return m_textfield2Disabled; }
|
||||
virtual const zeus::CColor& textfieldSelection() const { return m_textfieldSelection; }
|
||||
virtual const zeus::CColor& textfieldMarkSelection() const { return m_textfieldMarkSelection; }
|
||||
|
||||
virtual const zeus::CColor& tableCellBg1() const { return m_tableCellBg1; }
|
||||
virtual const zeus::CColor& tableCellBg2() const { return m_tableCellBg2; }
|
||||
virtual const zeus::CColor& tableCellBgSelected() const { return m_tableCellBgSelected; }
|
||||
virtual const zeus::CColor& tableCellBg1() const { return m_tableCellBg1; }
|
||||
virtual const zeus::CColor& tableCellBg2() const { return m_tableCellBg2; }
|
||||
virtual const zeus::CColor& tableCellBgSelected() const { return m_tableCellBgSelected; }
|
||||
|
||||
virtual const zeus::CColor& scrollIndicator() const { return m_scrollIndicator; }
|
||||
virtual const zeus::CColor& scrollIndicator() const { return m_scrollIndicator; }
|
||||
|
||||
virtual const zeus::CColor& spaceTriangleShading1() const { return m_spaceTriangleShading1; }
|
||||
virtual const zeus::CColor& spaceTriangleShading2() const { return m_spaceTriangleShading2; }
|
||||
virtual const zeus::CColor& spaceTriangleShading1() const { return m_spaceTriangleShading1; }
|
||||
virtual const zeus::CColor& spaceTriangleShading2() const { return m_spaceTriangleShading2; }
|
||||
};
|
||||
|
||||
class ViewResources
|
||||
{
|
||||
void init(boo::IGraphicsDataFactory::Context& factory, const IThemeData& theme, FontCache* fcache)
|
||||
{
|
||||
m_viewRes.init(factory, theme);
|
||||
m_textRes.init(factory, fcache);
|
||||
m_splitRes.init(factory, theme);
|
||||
m_toolbarRes.init(factory, theme);
|
||||
m_buttonRes.init(factory, theme);
|
||||
}
|
||||
class ViewResources {
|
||||
void init(boo::IGraphicsDataFactory::Context& factory, const IThemeData& theme, FontCache* fcache) {
|
||||
m_viewRes.init(factory, theme);
|
||||
m_textRes.init(factory, fcache);
|
||||
m_splitRes.init(factory, theme);
|
||||
m_toolbarRes.init(factory, theme);
|
||||
m_buttonRes.init(factory, theme);
|
||||
}
|
||||
|
||||
public:
|
||||
boo::IGraphicsDataFactory* m_factory;
|
||||
FontCache* m_fcache = nullptr;
|
||||
View::Resources m_viewRes;
|
||||
TextView::Resources m_textRes;
|
||||
SplitView::Resources m_splitRes;
|
||||
Toolbar::Resources m_toolbarRes;
|
||||
Button::Resources m_buttonRes;
|
||||
boo::IGraphicsDataFactory* m_factory;
|
||||
FontCache* m_fcache = nullptr;
|
||||
View::Resources m_viewRes;
|
||||
TextView::Resources m_textRes;
|
||||
SplitView::Resources m_splitRes;
|
||||
Toolbar::Resources m_toolbarRes;
|
||||
Button::Resources m_buttonRes;
|
||||
|
||||
specter::FontTag m_mainFont;
|
||||
specter::FontTag m_monoFont10;
|
||||
specter::FontTag m_monoFont18;
|
||||
specter::FontTag m_mainFont;
|
||||
specter::FontTag m_monoFont10;
|
||||
specter::FontTag m_monoFont18;
|
||||
|
||||
specter::FontTag m_heading14;
|
||||
specter::FontTag m_heading18;
|
||||
specter::FontTag m_heading14;
|
||||
specter::FontTag m_heading18;
|
||||
|
||||
specter::FontTag m_titleFont;
|
||||
specter::FontTag m_curveFont;
|
||||
specter::FontTag m_titleFont;
|
||||
specter::FontTag m_curveFont;
|
||||
|
||||
std::thread m_fcacheThread;
|
||||
std::atomic_bool m_fcacheInterrupt = {false};
|
||||
std::atomic_bool m_fcacheReady = {false};
|
||||
std::thread m_fcacheThread;
|
||||
std::atomic_bool m_fcacheInterrupt = {false};
|
||||
std::atomic_bool m_fcacheReady = {false};
|
||||
|
||||
ViewResources() = default;
|
||||
ViewResources(const ViewResources& other) = delete;
|
||||
ViewResources(ViewResources&& other) = default;
|
||||
ViewResources& operator=(const ViewResources& other) = delete;
|
||||
ViewResources& operator=(ViewResources&& other) = default;
|
||||
ViewResources() = default;
|
||||
ViewResources(const ViewResources& other) = delete;
|
||||
ViewResources(ViewResources&& other) = default;
|
||||
ViewResources& operator=(const ViewResources& other) = delete;
|
||||
ViewResources& operator=(ViewResources&& other) = default;
|
||||
|
||||
void updateBuffers()
|
||||
{
|
||||
m_viewRes.updateBuffers();
|
||||
m_textRes.updateBuffers();
|
||||
void updateBuffers() {
|
||||
m_viewRes.updateBuffers();
|
||||
m_textRes.updateBuffers();
|
||||
}
|
||||
|
||||
~ViewResources() {
|
||||
if (m_fcacheThread.joinable()) {
|
||||
m_fcacheInterrupt.store(true);
|
||||
m_fcacheThread.join();
|
||||
}
|
||||
}
|
||||
|
||||
~ViewResources()
|
||||
{
|
||||
if (m_fcacheThread.joinable())
|
||||
{
|
||||
m_fcacheInterrupt.store(true);
|
||||
m_fcacheThread.join();
|
||||
}
|
||||
}
|
||||
void init(boo::IGraphicsDataFactory* factory, FontCache* fcache, const IThemeData* theme, float pixelFactor);
|
||||
void destroyResData();
|
||||
void prepFontCacheSync();
|
||||
void prepFontCacheAsync(boo::IWindow* window);
|
||||
bool fontCacheReady() const { return m_fcacheReady.load(); }
|
||||
void resetPixelFactor(float pixelFactor);
|
||||
void resetTheme(const IThemeData* theme);
|
||||
|
||||
void init(boo::IGraphicsDataFactory* factory, FontCache* fcache, const IThemeData* theme, float pixelFactor);
|
||||
void destroyResData();
|
||||
void prepFontCacheSync();
|
||||
void prepFontCacheAsync(boo::IWindow* window);
|
||||
bool fontCacheReady() const { return m_fcacheReady.load(); }
|
||||
void resetPixelFactor(float pixelFactor);
|
||||
void resetTheme(const IThemeData* theme);
|
||||
float m_pixelFactor = 0;
|
||||
float pixelFactor() const { return m_pixelFactor; }
|
||||
|
||||
float m_pixelFactor = 0;
|
||||
float pixelFactor() const { return m_pixelFactor; }
|
||||
|
||||
const IThemeData* m_theme;
|
||||
const IThemeData& themeData() const { return *m_theme; }
|
||||
const IThemeData* m_theme;
|
||||
const IThemeData& themeData() const { return *m_theme; }
|
||||
};
|
||||
} // namespace specter
|
||||
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#if __specter__
|
||||
#define SPECTER_PROPERTY(n, d) \
|
||||
[[using specter: name(n), description(d)]]
|
||||
#define SPECTER_ENUM(n, d, et) \
|
||||
[[using specter: name(n), description(d), enum_type(et)]]
|
||||
#define SPECTER_PROPERTY(n, d) [[using specter: name(n), description(d)]]
|
||||
#define SPECTER_ENUM(n, d, et) [[using specter: name(n), description(d), enum_type(et)]]
|
||||
#else
|
||||
#define SPECTER_PROPERTY(n, d)
|
||||
#define SPECTER_ENUM(n, d, et)
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -16,4 +16,3 @@
|
|||
#include "NodeSocket.hpp"
|
||||
#include "FontCache.hpp"
|
||||
#include "ViewResources.hpp"
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,12 +1,10 @@
|
|||
#include "specter/Control.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
Control::Control(ViewResources& res, View& parentView,
|
||||
IControlBinding* controlBinding)
|
||||
Control::Control(ViewResources& res, View& parentView, IControlBinding* controlBinding)
|
||||
: View(res, parentView), m_controlBinding(controlBinding) {}
|
||||
|
||||
|
||||
std::recursive_mutex ITextInputView::m_textInputLk;
|
||||
|
||||
}
|
||||
} // namespace specter
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,41 +1,34 @@
|
|||
#include "specter/Icon.hpp"
|
||||
#include "specter/RootView.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
IconView::IconView(ViewResources& res, View& parentView, Icon& icon)
|
||||
: View(res, parentView)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertexBinding.init(ctx, res, 4, m_viewVertBlockBuf, icon.m_tex);
|
||||
return true;
|
||||
});
|
||||
TexShaderVert verts[] =
|
||||
{
|
||||
{{0, 1, 0}, icon.m_uvCoords[0]},
|
||||
{{0, 0, 0}, icon.m_uvCoords[1]},
|
||||
{{1, 1, 0}, icon.m_uvCoords[2]},
|
||||
{{1, 0, 0}, icon.m_uvCoords[3]},
|
||||
};
|
||||
m_vertexBinding.load<decltype(verts)>(verts);
|
||||
setBackground(zeus::CColor::skBlue);
|
||||
IconView::IconView(ViewResources& res, View& parentView, Icon& icon) : View(res, parentView) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_vertexBinding.init(ctx, res, 4, m_viewVertBlockBuf, icon.m_tex);
|
||||
return true;
|
||||
});
|
||||
TexShaderVert verts[] = {
|
||||
{{0, 1, 0}, icon.m_uvCoords[0]},
|
||||
{{0, 0, 0}, icon.m_uvCoords[1]},
|
||||
{{1, 1, 0}, icon.m_uvCoords[2]},
|
||||
{{1, 0, 0}, icon.m_uvCoords[3]},
|
||||
};
|
||||
m_vertexBinding.load<decltype(verts)>(verts);
|
||||
setBackground(zeus::CColor::skBlue);
|
||||
}
|
||||
|
||||
void IconView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
m_viewVertBlock.setViewRect(root, sub);
|
||||
m_viewVertBlock.m_mv[0][0] *= sub.size[0];
|
||||
m_viewVertBlock.m_mv[1][1] *= sub.size[1];
|
||||
View::resized(m_viewVertBlock, sub);
|
||||
void IconView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
m_viewVertBlock.setViewRect(root, sub);
|
||||
m_viewVertBlock.m_mv[0][0] *= sub.size[0];
|
||||
m_viewVertBlock.m_mv[1][1] *= sub.size[1];
|
||||
View::resized(m_viewVertBlock, sub);
|
||||
}
|
||||
|
||||
void IconView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
gfxQ->setShaderDataBinding(m_vertexBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
void IconView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
gfxQ->setShaderDataBinding(m_vertexBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace specter
|
||||
|
|
|
@ -5,322 +5,264 @@
|
|||
#define ROW_HEIGHT 18
|
||||
#define ITEM_MARGIN 1
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode)
|
||||
: View(res, parentView)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.init(ctx, res, 8, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_headText.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator));
|
||||
m_content.reset(new ContentView(res, *this));
|
||||
m_scroll.m_view->setContentView(m_content.get());
|
||||
reset(rootNode);
|
||||
Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode) : View(res, parentView) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.init(ctx, res, 8, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_headText.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator));
|
||||
m_content.reset(new ContentView(res, *this));
|
||||
m_scroll.m_view->setContentView(m_content.get());
|
||||
reset(rootNode);
|
||||
}
|
||||
|
||||
void Menu::reset(IMenuNode* rootNode)
|
||||
{
|
||||
m_rootNode = rootNode;
|
||||
m_thisNode = rootNode;
|
||||
ViewResources& res = rootView().viewRes();
|
||||
void Menu::reset(IMenuNode* rootNode) {
|
||||
m_rootNode = rootNode;
|
||||
m_thisNode = rootNode;
|
||||
ViewResources& res = rootView().viewRes();
|
||||
|
||||
for (int i=0 ; i<8 ; ++i)
|
||||
m_verts[i].m_color = res.themeData().tooltipBackground();
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
for (int i = 0; i < 8; ++i)
|
||||
m_verts[i].m_color = res.themeData().tooltipBackground();
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
m_subMenu.reset();
|
||||
m_subMenu.reset();
|
||||
|
||||
const std::string* headText = rootNode->text();
|
||||
m_headText->typesetGlyphs(headText?*headText:"", rootView().themeData().uiAltText());
|
||||
const std::string* headText = rootNode->text();
|
||||
m_headText->typesetGlyphs(headText ? *headText : "", rootView().themeData().uiAltText());
|
||||
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
int itemAdv = (ROW_HEIGHT + ITEM_MARGIN*2) * pf;
|
||||
m_cWidth = m_headText->nominalWidth() + 10*pf;
|
||||
m_cHeight = headText ? itemAdv : 0;
|
||||
m_cTop = m_cHeight;
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
int itemAdv = (ROW_HEIGHT + ITEM_MARGIN * 2) * pf;
|
||||
m_cWidth = m_headText->nominalWidth() + 10 * pf;
|
||||
m_cHeight = headText ? itemAdv : 0;
|
||||
m_cTop = m_cHeight;
|
||||
|
||||
size_t subCount = rootNode->subNodeCount();
|
||||
m_items.clear();
|
||||
if (subCount)
|
||||
{
|
||||
m_items.reserve(subCount);
|
||||
for (size_t i=0 ; i<subCount ; ++i)
|
||||
{
|
||||
IMenuNode* node = rootNode->subNode(i);
|
||||
const std::string* nodeText = node->text();
|
||||
size_t subCount = rootNode->subNodeCount();
|
||||
m_items.clear();
|
||||
if (subCount) {
|
||||
m_items.reserve(subCount);
|
||||
for (size_t i = 0; i < subCount; ++i) {
|
||||
IMenuNode* node = rootNode->subNode(i);
|
||||
const std::string* nodeText = node->text();
|
||||
|
||||
m_items.emplace_back();
|
||||
ViewChild<std::unique_ptr<ItemView>>& item = m_items.back();
|
||||
m_items.emplace_back();
|
||||
ViewChild<std::unique_ptr<ItemView>>& item = m_items.back();
|
||||
|
||||
if (nodeText)
|
||||
{
|
||||
item.m_view.reset(new ItemView(res, *this, *nodeText, i, node));
|
||||
m_cWidth = std::max(m_cWidth, int(item.m_view->m_textView->nominalWidth() + 10*pf));
|
||||
}
|
||||
if (nodeText) {
|
||||
item.m_view.reset(new ItemView(res, *this, *nodeText, i, node));
|
||||
m_cWidth = std::max(m_cWidth, int(item.m_view->m_textView->nominalWidth() + 10 * pf));
|
||||
}
|
||||
|
||||
m_cHeight += itemAdv;
|
||||
}
|
||||
m_cHeight += itemAdv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode, IMenuNode* thisNode)
|
||||
: View(res, parentView), m_rootNode(rootNode), m_thisNode(thisNode)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.init(ctx, res, 8, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_headText.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator));
|
||||
m_content.reset(new ContentView(res, *this));
|
||||
m_scroll.m_view->setContentView(m_content.get());
|
||||
: View(res, parentView), m_rootNode(rootNode), m_thisNode(thisNode) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.init(ctx, res, 8, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_headText.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator));
|
||||
m_content.reset(new ContentView(res, *this));
|
||||
m_scroll.m_view->setContentView(m_content.get());
|
||||
}
|
||||
|
||||
Menu::ContentView::ContentView(ViewResources& res, Menu& menu)
|
||||
: View(res, menu), m_menu(menu)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_hlVertsBinding.init(ctx, res, 4, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
Menu::ContentView::ContentView(ViewResources& res, Menu& menu) : View(res, menu), m_menu(menu) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_hlVertsBinding.init(ctx, res, 4, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
m_hlVerts[0].m_color = res.themeData().button1Hover();
|
||||
m_hlVerts[1].m_color = res.themeData().button2Hover();
|
||||
m_hlVerts[2].m_color = res.themeData().button1Hover();
|
||||
m_hlVerts[3].m_color = res.themeData().button2Hover();
|
||||
m_hlVerts[0].m_color = res.themeData().button1Hover();
|
||||
m_hlVerts[1].m_color = res.themeData().button2Hover();
|
||||
m_hlVerts[2].m_color = res.themeData().button1Hover();
|
||||
m_hlVerts[3].m_color = res.themeData().button2Hover();
|
||||
}
|
||||
|
||||
Menu::ItemView::ItemView(ViewResources& res, Menu& menu, std::string_view text, size_t idx, IMenuNode* node)
|
||||
: View(res, menu), m_menu(menu), m_idx(idx), m_node(node)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
return true;
|
||||
});
|
||||
m_textView.reset(new specter::TextView(res, *this, res.m_mainFont));
|
||||
m_textView->typesetGlyphs(text, res.themeData().uiText());
|
||||
: View(res, menu), m_menu(menu), m_idx(idx), m_node(node) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
return true;
|
||||
});
|
||||
m_textView.reset(new specter::TextView(res, *this, res.m_mainFont));
|
||||
m_textView->typesetGlyphs(text, res.themeData().uiText());
|
||||
}
|
||||
|
||||
void Menu::setVerts(int width, int height, float pf)
|
||||
{
|
||||
m_verts[0].m_pos.assign(0, height-m_cTop-pf, 0);
|
||||
m_verts[1].m_pos.assign(0, 0, 0);
|
||||
m_verts[2].m_pos.assign(width, height-m_cTop-pf, 0);
|
||||
m_verts[3].m_pos.assign(width, 0, 0);
|
||||
void Menu::setVerts(int width, int height, float pf) {
|
||||
m_verts[0].m_pos.assign(0, height - m_cTop - pf, 0);
|
||||
m_verts[1].m_pos.assign(0, 0, 0);
|
||||
m_verts[2].m_pos.assign(width, height - m_cTop - pf, 0);
|
||||
m_verts[3].m_pos.assign(width, 0, 0);
|
||||
|
||||
m_verts[4].m_pos.assign(0, height, 0);
|
||||
m_verts[5].m_pos.assign(0, height-m_cTop+pf, 0);
|
||||
m_verts[6].m_pos.assign(width, height, 0);
|
||||
m_verts[7].m_pos.assign(width, height-m_cTop+pf, 0);
|
||||
m_verts[4].m_pos.assign(0, height, 0);
|
||||
m_verts[5].m_pos.assign(0, height - m_cTop + pf, 0);
|
||||
m_verts[6].m_pos.assign(width, height, 0);
|
||||
m_verts[7].m_pos.assign(width, height - m_cTop + pf, 0);
|
||||
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
}
|
||||
|
||||
void Menu::ContentView::setHighlightedItem(size_t idx)
|
||||
{
|
||||
if (idx == -1)
|
||||
{
|
||||
m_highlightedItem = -1;
|
||||
return;
|
||||
}
|
||||
ViewChild<std::unique_ptr<ItemView>>& vc = m_menu.m_items[idx];
|
||||
void Menu::ContentView::setHighlightedItem(size_t idx) {
|
||||
if (idx == -1) {
|
||||
m_highlightedItem = -1;
|
||||
return;
|
||||
}
|
||||
ViewChild<std::unique_ptr<ItemView>>& vc = m_menu.m_items[idx];
|
||||
|
||||
if (!vc.m_view)
|
||||
{
|
||||
m_highlightedItem = -1;
|
||||
return;
|
||||
}
|
||||
if (!vc.m_view) {
|
||||
m_highlightedItem = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
m_highlightedItem = idx;
|
||||
const boo::SWindowRect& bgRect = subRect();
|
||||
const boo::SWindowRect& itemRect = vc.m_view->subRect();
|
||||
int y = itemRect.location[1] - bgRect.location[1];
|
||||
m_highlightedItem = idx;
|
||||
const boo::SWindowRect& bgRect = subRect();
|
||||
const boo::SWindowRect& itemRect = vc.m_view->subRect();
|
||||
int y = itemRect.location[1] - bgRect.location[1];
|
||||
|
||||
m_hlVerts[0].m_pos.assign(0, y+itemRect.size[1], 0);
|
||||
m_hlVerts[1].m_pos.assign(0, y, 0);
|
||||
m_hlVerts[2].m_pos.assign(itemRect.size[0], y+itemRect.size[1], 0);
|
||||
m_hlVerts[3].m_pos.assign(itemRect.size[0], y, 0);
|
||||
m_hlVerts[0].m_pos.assign(0, y + itemRect.size[1], 0);
|
||||
m_hlVerts[1].m_pos.assign(0, y, 0);
|
||||
m_hlVerts[2].m_pos.assign(itemRect.size[0], y + itemRect.size[1], 0);
|
||||
m_hlVerts[3].m_pos.assign(itemRect.size[0], y, 0);
|
||||
|
||||
m_hlVertsBinding.load<decltype(m_hlVerts)>(m_hlVerts);
|
||||
m_hlVertsBinding.load<decltype(m_hlVerts)>(m_hlVerts);
|
||||
}
|
||||
|
||||
void Menu::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
m_scroll.mouseDown(coord, button, mod);
|
||||
void Menu::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
m_scroll.mouseDown(coord, button, mod);
|
||||
}
|
||||
|
||||
void Menu::ContentView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& v : m_menu.m_items)
|
||||
v.mouseDown(coord, button, mod);
|
||||
void Menu::ContentView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& v : m_menu.m_items)
|
||||
v.mouseDown(coord, button, mod);
|
||||
}
|
||||
|
||||
void Menu::ItemView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
void Menu::ItemView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {}
|
||||
|
||||
void Menu::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
m_scroll.mouseUp(coord, button, mod);
|
||||
if (m_deferredActivation) {
|
||||
IMenuNode* node = m_deferredActivation;
|
||||
m_deferredActivation = nullptr;
|
||||
node->activated(coord);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
m_scroll.mouseUp(coord, button, mod);
|
||||
if (m_deferredActivation)
|
||||
{
|
||||
IMenuNode* node = m_deferredActivation;
|
||||
m_deferredActivation = nullptr;
|
||||
node->activated(coord);
|
||||
}
|
||||
void Menu::ContentView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& v : m_menu.m_items)
|
||||
v.mouseUp(coord, button, mod);
|
||||
}
|
||||
|
||||
void Menu::ContentView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& v : m_menu.m_items)
|
||||
v.mouseUp(coord, button, mod);
|
||||
void Menu::ItemView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (m_menu.m_content->m_highlightedItem == m_idx)
|
||||
m_menu.m_deferredActivation = m_node;
|
||||
}
|
||||
|
||||
void Menu::ItemView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (m_menu.m_content->m_highlightedItem == m_idx)
|
||||
m_menu.m_deferredActivation = m_node;
|
||||
void Menu::mouseMove(const boo::SWindowCoord& coord) { m_scroll.mouseMove(coord); }
|
||||
|
||||
void Menu::ContentView::mouseMove(const boo::SWindowCoord& coord) {
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& v : m_menu.m_items)
|
||||
v.mouseMove(coord);
|
||||
}
|
||||
|
||||
void Menu::mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_scroll.mouseMove(coord);
|
||||
void Menu::ItemView::mouseEnter(const boo::SWindowCoord& coord) { m_menu.m_content->setHighlightedItem(m_idx); }
|
||||
|
||||
void Menu::mouseLeave(const boo::SWindowCoord& coord) { m_scroll.mouseLeave(coord); }
|
||||
|
||||
void Menu::ContentView::mouseLeave(const boo::SWindowCoord& coord) {
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& v : m_menu.m_items)
|
||||
v.mouseLeave(coord);
|
||||
}
|
||||
|
||||
void Menu::ContentView::mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& v : m_menu.m_items)
|
||||
v.mouseMove(coord);
|
||||
}
|
||||
void Menu::ItemView::mouseLeave(const boo::SWindowCoord& coord) { m_menu.m_content->unsetHighlightedItem(m_idx); }
|
||||
|
||||
void Menu::ItemView::mouseEnter(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_menu.m_content->setHighlightedItem(m_idx);
|
||||
}
|
||||
void Menu::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) { m_scroll.scroll(coord, scroll); }
|
||||
|
||||
void Menu::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_scroll.mouseLeave(coord);
|
||||
}
|
||||
void Menu::think() { m_scroll.m_view->think(); }
|
||||
|
||||
void Menu::ContentView::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& v : m_menu.m_items)
|
||||
v.mouseLeave(coord);
|
||||
}
|
||||
void Menu::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
boo::SWindowRect rect = sub;
|
||||
rect.size[0] = m_cWidth;
|
||||
if (rect.location[1] - m_cHeight < 0) {
|
||||
rect.location[1] += ROW_HEIGHT * pf;
|
||||
rect.size[1] = std::min(root.size[1] - rect.location[1], m_cHeight);
|
||||
} else {
|
||||
rect.location[1] -= m_cHeight;
|
||||
rect.size[1] = m_cHeight;
|
||||
}
|
||||
|
||||
void Menu::ItemView::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_menu.m_content->unsetHighlightedItem(m_idx);
|
||||
}
|
||||
View::resized(root, rect);
|
||||
m_scroll.m_view->resized(root, rect);
|
||||
setVerts(rect.size[0], rect.size[1], pf);
|
||||
|
||||
void Menu::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll)
|
||||
{
|
||||
m_scroll.scroll(coord, scroll);
|
||||
}
|
||||
|
||||
void Menu::think()
|
||||
{
|
||||
m_scroll.m_view->think();
|
||||
}
|
||||
|
||||
void Menu::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
boo::SWindowRect rect = sub;
|
||||
rect.size[0] = m_cWidth;
|
||||
if (rect.location[1] - m_cHeight < 0)
|
||||
{
|
||||
rect.location[1] += ROW_HEIGHT*pf;
|
||||
rect.size[1] = std::min(root.size[1] - rect.location[1], m_cHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
rect.location[1] -= m_cHeight;
|
||||
rect.size[1] = m_cHeight;
|
||||
}
|
||||
|
||||
View::resized(root, rect);
|
||||
m_scroll.m_view->resized(root, rect);
|
||||
setVerts(rect.size[0], rect.size[1], pf);
|
||||
|
||||
rect.location[0] += 5*pf;
|
||||
rect.location[1] += rect.size[1] - (ROW_HEIGHT + ITEM_MARGIN - 5)*pf;
|
||||
rect.size[0] = m_headText->nominalWidth();
|
||||
rect.size[1] = m_headText->nominalHeight();
|
||||
m_headText->resized(root, rect);
|
||||
rect.location[0] += 5 * pf;
|
||||
rect.location[1] += rect.size[1] - (ROW_HEIGHT + ITEM_MARGIN - 5) * pf;
|
||||
rect.size[0] = m_headText->nominalWidth();
|
||||
rect.size[1] = m_headText->nominalHeight();
|
||||
m_headText->resized(root, rect);
|
||||
}
|
||||
|
||||
void Menu::ContentView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub,
|
||||
const boo::SWindowRect& scissor)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
m_scissorRect = scissor;
|
||||
boo::SWindowRect itemRect = sub;
|
||||
itemRect.size[0] = m_menu.m_cWidth;
|
||||
itemRect.size[1] = ROW_HEIGHT*pf;
|
||||
itemRect.location[1] += sub.size[1] - m_menu.m_cTop + ITEM_MARGIN*pf;
|
||||
int itemAdv = (ROW_HEIGHT + ITEM_MARGIN*2) * pf;
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& c : m_menu.m_items)
|
||||
{
|
||||
itemRect.location[1] -= itemAdv;
|
||||
if (c.m_view)
|
||||
c.m_view->resized(root, itemRect);
|
||||
}
|
||||
const boo::SWindowRect& scissor) {
|
||||
View::resized(root, sub);
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
m_scissorRect = scissor;
|
||||
boo::SWindowRect itemRect = sub;
|
||||
itemRect.size[0] = m_menu.m_cWidth;
|
||||
itemRect.size[1] = ROW_HEIGHT * pf;
|
||||
itemRect.location[1] += sub.size[1] - m_menu.m_cTop + ITEM_MARGIN * pf;
|
||||
int itemAdv = (ROW_HEIGHT + ITEM_MARGIN * 2) * pf;
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& c : m_menu.m_items) {
|
||||
itemRect.location[1] -= itemAdv;
|
||||
if (c.m_view)
|
||||
c.m_view->resized(root, itemRect);
|
||||
}
|
||||
}
|
||||
|
||||
void Menu::ItemView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
boo::SWindowRect textRect = sub;
|
||||
textRect.location[0] += 5*pf;
|
||||
textRect.location[1] += 5*pf;
|
||||
m_textView->resized(root, textRect);
|
||||
void Menu::ItemView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
View::resized(root, sub);
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
boo::SWindowRect textRect = sub;
|
||||
textRect.location[0] += 5 * pf;
|
||||
textRect.location[1] += 5 * pf;
|
||||
m_textView->resized(root, textRect);
|
||||
}
|
||||
|
||||
void Menu::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
void Menu::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
View::draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
m_scroll.m_view->draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(4, 4);
|
||||
m_headText->draw(gfxQ);
|
||||
}
|
||||
|
||||
void Menu::ContentView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
View::draw(gfxQ);
|
||||
gfxQ->setScissor(m_scissorRect);
|
||||
if (m_highlightedItem != -1) {
|
||||
gfxQ->setShaderDataBinding(m_hlVertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
m_scroll.m_view->draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(4, 4);
|
||||
m_headText->draw(gfxQ);
|
||||
}
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& c : m_menu.m_items)
|
||||
if (c.m_view)
|
||||
c.m_view->draw(gfxQ);
|
||||
gfxQ->setScissor(rootView().subRect());
|
||||
}
|
||||
|
||||
void Menu::ContentView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
gfxQ->setScissor(m_scissorRect);
|
||||
if (m_highlightedItem != -1)
|
||||
{
|
||||
gfxQ->setShaderDataBinding(m_hlVertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
}
|
||||
for (ViewChild<std::unique_ptr<ItemView>>& c : m_menu.m_items)
|
||||
if (c.m_view)
|
||||
c.m_view->draw(gfxQ);
|
||||
gfxQ->setScissor(rootView().subRect());
|
||||
void Menu::ItemView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
View::draw(gfxQ);
|
||||
m_textView->draw(gfxQ);
|
||||
}
|
||||
|
||||
void Menu::ItemView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
m_textView->draw(gfxQ);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace specter
|
||||
|
|
|
@ -3,107 +3,93 @@
|
|||
#include "specter/RootView.hpp"
|
||||
#include "specter/Menu.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
MessageWindow::MessageWindow(ViewResources& res, View& parentView,
|
||||
Type type, std::string_view message,
|
||||
std::function<void (bool)> func)
|
||||
MessageWindow::MessageWindow(ViewResources& res, View& parentView, Type type, std::string_view message,
|
||||
std::function<void(bool)> func)
|
||||
: ModalWindow(res, parentView, RectangleConstraint(),
|
||||
type==Type::ErrorOk ? res.themeData().splashErrorBackground() : res.themeData().splashBackground()),
|
||||
m_type(type), m_func(func),
|
||||
m_okBind(*this, rootView().viewManager().translateOr("ok", "OK")),
|
||||
m_cancelBind(*this, rootView().viewManager().translateOr("cancel", "Cancel"))
|
||||
{
|
||||
m_text.reset(new MultiLineTextView(res, *this, res.m_mainFont, TextView::Alignment::Center));
|
||||
m_text->typesetGlyphs(message, res.themeData().uiText(), 380 * res.pixelFactor());
|
||||
constraint() = RectangleConstraint(400 * res.pixelFactor(), 80 * res.pixelFactor() + m_text->nominalHeight());
|
||||
type == Type::ErrorOk ? res.themeData().splashErrorBackground() : res.themeData().splashBackground())
|
||||
, m_type(type)
|
||||
, m_func(func)
|
||||
, m_okBind(*this, rootView().viewManager().translateOr("ok", "OK"))
|
||||
, m_cancelBind(*this, rootView().viewManager().translateOr("cancel", "Cancel")) {
|
||||
m_text.reset(new MultiLineTextView(res, *this, res.m_mainFont, TextView::Alignment::Center));
|
||||
m_text->typesetGlyphs(message, res.themeData().uiText(), 380 * res.pixelFactor());
|
||||
constraint() = RectangleConstraint(400 * res.pixelFactor(), 80 * res.pixelFactor() + m_text->nominalHeight());
|
||||
|
||||
m_ok.m_view.reset(new Button(res, *this, &m_okBind, m_okBind.m_name, nullptr,
|
||||
Button::Style::Block, zeus::CColor::skWhite,
|
||||
RectangleConstraint(150 * res.pixelFactor())));
|
||||
if (type == Type::ConfirmOkCancel)
|
||||
m_cancel.m_view.reset(new Button(res, *this, &m_cancelBind, m_cancelBind.m_name, nullptr,
|
||||
Button::Style::Block, zeus::CColor::skWhite,
|
||||
RectangleConstraint(150 * res.pixelFactor())));
|
||||
m_ok.m_view.reset(new Button(res, *this, &m_okBind, m_okBind.m_name, nullptr, Button::Style::Block,
|
||||
zeus::CColor::skWhite, RectangleConstraint(150 * res.pixelFactor())));
|
||||
if (type == Type::ConfirmOkCancel)
|
||||
m_cancel.m_view.reset(new Button(res, *this, &m_cancelBind, m_cancelBind.m_name, nullptr, Button::Style::Block,
|
||||
zeus::CColor::skWhite, RectangleConstraint(150 * res.pixelFactor())));
|
||||
|
||||
updateContentOpacity(0.0);
|
||||
updateContentOpacity(0.0);
|
||||
}
|
||||
|
||||
void MessageWindow::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
|
||||
{
|
||||
if (closed() || skipBuildInAnimation())
|
||||
return;
|
||||
m_ok.mouseDown(coord, button, mods);
|
||||
m_cancel.mouseDown(coord, button, mods);
|
||||
void MessageWindow::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) {
|
||||
if (closed() || skipBuildInAnimation())
|
||||
return;
|
||||
m_ok.mouseDown(coord, button, mods);
|
||||
m_cancel.mouseDown(coord, button, mods);
|
||||
}
|
||||
|
||||
void MessageWindow::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods)
|
||||
{
|
||||
if (closed())
|
||||
return;
|
||||
m_ok.mouseUp(coord, button, mods);
|
||||
m_cancel.mouseUp(coord, button, mods);
|
||||
void MessageWindow::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) {
|
||||
if (closed())
|
||||
return;
|
||||
m_ok.mouseUp(coord, button, mods);
|
||||
m_cancel.mouseUp(coord, button, mods);
|
||||
}
|
||||
|
||||
void MessageWindow::mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (closed())
|
||||
return;
|
||||
m_ok.mouseMove(coord);
|
||||
m_cancel.mouseMove(coord);
|
||||
void MessageWindow::mouseMove(const boo::SWindowCoord& coord) {
|
||||
if (closed())
|
||||
return;
|
||||
m_ok.mouseMove(coord);
|
||||
m_cancel.mouseMove(coord);
|
||||
}
|
||||
|
||||
void MessageWindow::mouseEnter(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (closed())
|
||||
return;
|
||||
m_ok.mouseEnter(coord);
|
||||
m_cancel.mouseEnter(coord);
|
||||
void MessageWindow::mouseEnter(const boo::SWindowCoord& coord) {
|
||||
if (closed())
|
||||
return;
|
||||
m_ok.mouseEnter(coord);
|
||||
m_cancel.mouseEnter(coord);
|
||||
}
|
||||
|
||||
void MessageWindow::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (closed())
|
||||
return;
|
||||
m_ok.mouseLeave(coord);
|
||||
m_cancel.mouseLeave(coord);
|
||||
void MessageWindow::mouseLeave(const boo::SWindowCoord& coord) {
|
||||
if (closed())
|
||||
return;
|
||||
m_ok.mouseLeave(coord);
|
||||
m_cancel.mouseLeave(coord);
|
||||
}
|
||||
|
||||
void MessageWindow::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
ModalWindow::resized(root, sub);
|
||||
boo::SWindowRect buttonRect = subRect();
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
buttonRect.location[1] += 20 * pf;
|
||||
buttonRect.size[0] = m_ok.m_view->nominalWidth();
|
||||
buttonRect.size[1] = m_ok.m_view->nominalHeight();
|
||||
if (m_type == Type::ConfirmOkCancel)
|
||||
{
|
||||
buttonRect.location[0] += 45 * pf;
|
||||
m_ok.m_view->resized(root, buttonRect);
|
||||
buttonRect.location[0] += 160 * pf;
|
||||
m_cancel.m_view->resized(root, buttonRect);
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonRect.location[0] += 125 * pf;
|
||||
m_ok.m_view->resized(root, buttonRect);
|
||||
}
|
||||
void MessageWindow::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
ModalWindow::resized(root, sub);
|
||||
boo::SWindowRect buttonRect = subRect();
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
buttonRect.location[1] += 20 * pf;
|
||||
buttonRect.size[0] = m_ok.m_view->nominalWidth();
|
||||
buttonRect.size[1] = m_ok.m_view->nominalHeight();
|
||||
if (m_type == Type::ConfirmOkCancel) {
|
||||
buttonRect.location[0] += 45 * pf;
|
||||
m_ok.m_view->resized(root, buttonRect);
|
||||
buttonRect.location[0] += 160 * pf;
|
||||
m_cancel.m_view->resized(root, buttonRect);
|
||||
} else {
|
||||
buttonRect.location[0] += 125 * pf;
|
||||
m_ok.m_view->resized(root, buttonRect);
|
||||
}
|
||||
|
||||
boo::SWindowRect textRect = subRect();
|
||||
textRect.location[0] += 200 * pf;
|
||||
textRect.location[1] += 65 * pf;
|
||||
m_text->resized(root, textRect);
|
||||
boo::SWindowRect textRect = subRect();
|
||||
textRect.location[0] += 200 * pf;
|
||||
textRect.location[1] += 65 * pf;
|
||||
m_text->resized(root, textRect);
|
||||
}
|
||||
|
||||
void MessageWindow::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
ModalWindow::draw(gfxQ);
|
||||
m_text->draw(gfxQ);
|
||||
m_ok.m_view->draw(gfxQ);
|
||||
if (m_type == Type::ConfirmOkCancel)
|
||||
m_cancel.m_view->draw(gfxQ);
|
||||
void MessageWindow::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
ModalWindow::draw(gfxQ);
|
||||
m_text->draw(gfxQ);
|
||||
m_ok.m_view->draw(gfxQ);
|
||||
if (m_type == Type::ConfirmOkCancel)
|
||||
m_cancel.m_view->draw(gfxQ);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace specter
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
#include "specter/ViewResources.hpp"
|
||||
#include "specter/RootView.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
#define WIRE_START 0
|
||||
#define WIRE_FRAMES 40
|
||||
|
@ -16,483 +15,451 @@ namespace specter
|
|||
#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::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
void ModalWindow::setLineVerts(int width, int height, float pf, float t) {
|
||||
std::pair<int, int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
float t1 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::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;
|
||||
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 = 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 = 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);
|
||||
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::setLineVertsOut(int width, int height, float pf, float t)
|
||||
{
|
||||
std::pair<int,int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
float t1 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
void ModalWindow::setLineVertsOut(int width, int height, float pf, float t) {
|
||||
std::pair<int, int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
float t1 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.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 = zeus::CVector3f::lerp({lineLeft, lineBottom, 0}, {lineLeft, lineTop, 0}, t1);
|
||||
m_verts.lineVerts[1].m_pos.assign(lineLeft, lineBottom, 0);
|
||||
m_verts.lineVerts[2].m_pos = zeus::CVector3f::lerp({lineRight, lineBottom, 0}, {lineRight, lineTop, 0}, t1);
|
||||
m_verts.lineVerts[3].m_pos.assign(lineRight, lineBottom, 0);
|
||||
m_verts.lineVerts[4].m_pos = m_verts.lineVerts[3].m_pos;
|
||||
float lineLeft = 0;
|
||||
float lineRight = pf * LINE_WIDTH;
|
||||
float lineTop = height - margin.second;
|
||||
float lineBottom = margin.second;
|
||||
m_verts.lineVerts[0].m_pos = zeus::CVector3f::lerp({lineLeft, lineBottom, 0}, {lineLeft, lineTop, 0}, t1);
|
||||
m_verts.lineVerts[1].m_pos.assign(lineLeft, lineBottom, 0);
|
||||
m_verts.lineVerts[2].m_pos = zeus::CVector3f::lerp({lineRight, lineBottom, 0}, {lineRight, lineTop, 0}, t1);
|
||||
m_verts.lineVerts[3].m_pos.assign(lineRight, lineBottom, 0);
|
||||
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 = zeus::CVector3f::lerp({lineRight, lineTop, 0}, {lineLeft, lineTop, 0}, t1);
|
||||
m_verts.lineVerts[6].m_pos = m_verts.lineVerts[5].m_pos;
|
||||
m_verts.lineVerts[7].m_pos = zeus::CVector3f::lerp({lineRight, lineBottom, 0}, {lineLeft, lineBottom, 0}, t1);
|
||||
m_verts.lineVerts[8].m_pos.assign(lineRight, lineTop, 0);
|
||||
m_verts.lineVerts[9].m_pos.assign(lineRight, lineBottom, 0);
|
||||
m_verts.lineVerts[10].m_pos = m_verts.lineVerts[9].m_pos;
|
||||
lineLeft = margin.first;
|
||||
lineRight = width - margin.first;
|
||||
lineTop = height;
|
||||
lineBottom = height - pf * LINE_WIDTH;
|
||||
m_verts.lineVerts[5].m_pos = zeus::CVector3f::lerp({lineRight, lineTop, 0}, {lineLeft, lineTop, 0}, t1);
|
||||
m_verts.lineVerts[6].m_pos = m_verts.lineVerts[5].m_pos;
|
||||
m_verts.lineVerts[7].m_pos = zeus::CVector3f::lerp({lineRight, lineBottom, 0}, {lineLeft, lineBottom, 0}, t1);
|
||||
m_verts.lineVerts[8].m_pos.assign(lineRight, lineTop, 0);
|
||||
m_verts.lineVerts[9].m_pos.assign(lineRight, lineBottom, 0);
|
||||
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 = zeus::CVector3f::lerp({lineLeft, lineBottom, 0}, {lineLeft, lineTop, 0}, t2);
|
||||
m_verts.lineVerts[12].m_pos = m_verts.lineVerts[11].m_pos;
|
||||
m_verts.lineVerts[13].m_pos.assign(lineLeft, lineBottom, 0);
|
||||
m_verts.lineVerts[14].m_pos = zeus::CVector3f::lerp({lineRight, lineBottom, 0}, {lineRight, lineTop, 0}, t2);
|
||||
m_verts.lineVerts[15].m_pos.assign(lineRight, lineBottom, 0);
|
||||
m_verts.lineVerts[16].m_pos = m_verts.lineVerts[15].m_pos;
|
||||
lineLeft = width - pf * LINE_WIDTH;
|
||||
lineRight = width;
|
||||
lineTop = height - margin.second;
|
||||
lineBottom = margin.second;
|
||||
m_verts.lineVerts[11].m_pos = zeus::CVector3f::lerp({lineLeft, lineBottom, 0}, {lineLeft, lineTop, 0}, t2);
|
||||
m_verts.lineVerts[12].m_pos = m_verts.lineVerts[11].m_pos;
|
||||
m_verts.lineVerts[13].m_pos.assign(lineLeft, lineBottom, 0);
|
||||
m_verts.lineVerts[14].m_pos = zeus::CVector3f::lerp({lineRight, lineBottom, 0}, {lineRight, lineTop, 0}, t2);
|
||||
m_verts.lineVerts[15].m_pos.assign(lineRight, lineBottom, 0);
|
||||
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 = zeus::CVector3f::lerp({lineRight, lineTop, 0}, {lineLeft, lineTop, 0}, t2);
|
||||
m_verts.lineVerts[18].m_pos = m_verts.lineVerts[17].m_pos;
|
||||
m_verts.lineVerts[19].m_pos = zeus::CVector3f::lerp({lineRight, lineBottom, 0}, {lineLeft, lineBottom, 0}, t2);
|
||||
m_verts.lineVerts[20].m_pos.assign(lineRight, lineTop, 0);
|
||||
m_verts.lineVerts[21].m_pos.assign(lineRight, lineBottom, 0);
|
||||
lineLeft = margin.first;
|
||||
lineRight = width - margin.first;
|
||||
lineTop = pf * LINE_WIDTH;
|
||||
lineBottom = 0;
|
||||
m_verts.lineVerts[17].m_pos = zeus::CVector3f::lerp({lineRight, lineTop, 0}, {lineLeft, lineTop, 0}, t2);
|
||||
m_verts.lineVerts[18].m_pos = m_verts.lineVerts[17].m_pos;
|
||||
m_verts.lineVerts[19].m_pos = zeus::CVector3f::lerp({lineRight, lineBottom, 0}, {lineLeft, lineBottom, 0}, t2);
|
||||
m_verts.lineVerts[20].m_pos.assign(lineRight, lineTop, 0);
|
||||
m_verts.lineVerts[21].m_pos.assign(lineRight, lineBottom, 0);
|
||||
}
|
||||
|
||||
void ModalWindow::setLineColors(float t)
|
||||
{
|
||||
float t1 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t3 = zeus::clamp(0.f, t * 2.f - 2.f, 1.f);
|
||||
void ModalWindow::setLineColors(float t) {
|
||||
float t1 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t3 = zeus::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);
|
||||
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[2]->colorGlyphs(zeus::CColor::skClear);
|
||||
m_cornersOutline[3]->colorGlyphs(c2);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cornersOutline[1]->colorGlyphs(c2);
|
||||
m_cornersOutline[2]->colorGlyphs(c3);
|
||||
m_cornersOutline[3]->colorGlyphs(c2);
|
||||
}
|
||||
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[2]->colorGlyphs(zeus::CColor::skClear);
|
||||
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[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[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[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;
|
||||
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::setLineColorsOut(float t)
|
||||
{
|
||||
float t1 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t3 = zeus::clamp(0.f, t * 2.f - 2.f, 1.f);
|
||||
void ModalWindow::setLineColorsOut(float t) {
|
||||
float t1 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t3 = zeus::clamp(0.f, t * 2.f - 2.f, 1.f);
|
||||
|
||||
zeus::CColor c1 = zeus::CColor::lerp(m_line2Clear, m_line2, t1);
|
||||
zeus::CColor c2 = zeus::CColor::lerp(m_line2Clear, m_line2, t2);
|
||||
zeus::CColor c3 = zeus::CColor::lerp(m_line2Clear, m_line2, t3);
|
||||
zeus::CColor c1 = zeus::CColor::lerp(m_line2Clear, m_line2, t1);
|
||||
zeus::CColor c2 = zeus::CColor::lerp(m_line2Clear, m_line2, t2);
|
||||
zeus::CColor c3 = zeus::CColor::lerp(m_line2Clear, m_line2, t3);
|
||||
|
||||
m_cornersOutline[2]->colorGlyphs(c1);
|
||||
if (t < 0.5)
|
||||
{
|
||||
m_cornersOutline[1]->colorGlyphs(zeus::CColor::skClear);
|
||||
m_cornersOutline[0]->colorGlyphs(zeus::CColor::skClear);
|
||||
m_cornersOutline[3]->colorGlyphs(zeus::CColor::skClear);
|
||||
}
|
||||
else if (t < 1.0)
|
||||
{
|
||||
m_cornersOutline[1]->colorGlyphs(c2);
|
||||
m_cornersOutline[0]->colorGlyphs(zeus::CColor::skClear);
|
||||
m_cornersOutline[3]->colorGlyphs(c2);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cornersOutline[1]->colorGlyphs(c2);
|
||||
m_cornersOutline[0]->colorGlyphs(c3);
|
||||
m_cornersOutline[3]->colorGlyphs(c2);
|
||||
}
|
||||
m_cornersOutline[2]->colorGlyphs(c1);
|
||||
if (t < 0.5) {
|
||||
m_cornersOutline[1]->colorGlyphs(zeus::CColor::skClear);
|
||||
m_cornersOutline[0]->colorGlyphs(zeus::CColor::skClear);
|
||||
m_cornersOutline[3]->colorGlyphs(zeus::CColor::skClear);
|
||||
} else if (t < 1.0) {
|
||||
m_cornersOutline[1]->colorGlyphs(c2);
|
||||
m_cornersOutline[0]->colorGlyphs(zeus::CColor::skClear);
|
||||
m_cornersOutline[3]->colorGlyphs(c2);
|
||||
} else {
|
||||
m_cornersOutline[1]->colorGlyphs(c2);
|
||||
m_cornersOutline[0]->colorGlyphs(c3);
|
||||
m_cornersOutline[3]->colorGlyphs(c2);
|
||||
}
|
||||
|
||||
m_verts.lineVerts[0].m_color = c3;
|
||||
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[0].m_color = c3;
|
||||
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 = c3;
|
||||
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[5].m_color = c3;
|
||||
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 = c1;
|
||||
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[11].m_color = c2;
|
||||
m_verts.lineVerts[12].m_color = m_verts.lineVerts[11].m_color;
|
||||
m_verts.lineVerts[13].m_color = c1;
|
||||
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 = c1;
|
||||
m_verts.lineVerts[21].m_color = m_verts.lineVerts[20].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 = c1;
|
||||
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);
|
||||
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;
|
||||
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 = 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);
|
||||
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::clamp(0.f, t, 1.f);
|
||||
zeus::CColor color = zeus::CColor::lerp(m_windowBgClear, m_windowBg, t);
|
||||
void ModalWindow::setFillColors(float t) {
|
||||
t = zeus::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);
|
||||
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, const RectangleConstraint& constraint)
|
||||
: ModalWindow(res, parentView, constraint, res.themeData().splashBackground()) {}
|
||||
|
||||
ModalWindow::ModalWindow(ViewResources& res, View& parentView,
|
||||
const RectangleConstraint& constraint,
|
||||
ModalWindow::ModalWindow(ViewResources& res, View& parentView, const RectangleConstraint& constraint,
|
||||
const zeus::CColor& bgColor)
|
||||
: View(res, parentView),
|
||||
m_constraint(constraint),
|
||||
m_windowBg(bgColor),
|
||||
m_windowBgClear(m_windowBg),
|
||||
m_line1(res.themeData().splash1()),
|
||||
m_line2(res.themeData().splash2()),
|
||||
m_line2Clear(m_line2)
|
||||
{
|
||||
m_windowBgClear[3] = 0.0;
|
||||
m_line2Clear[3] = 0.0;
|
||||
: View(res, parentView)
|
||||
, m_constraint(constraint)
|
||||
, m_windowBg(bgColor)
|
||||
, m_windowBgClear(m_windowBg)
|
||||
, m_line1(res.themeData().splash1())
|
||||
, m_line2(res.themeData().splash2())
|
||||
, m_line2Clear(m_line2) {
|
||||
m_windowBgClear[3] = 0.0;
|
||||
m_line2Clear[3] = 0.0;
|
||||
|
||||
res.m_factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_viewBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_vertsBinding.init(ctx, res, 38, m_viewBlockBuf);
|
||||
return true;
|
||||
} BooTrace);
|
||||
|
||||
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);
|
||||
|
||||
_loadVerts();
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
switch (m_phase)
|
||||
{
|
||||
case Phase::BuildIn:
|
||||
{
|
||||
bool loadVerts = false;
|
||||
int doneCount = 0;
|
||||
if (m_frame > WIRE_START)
|
||||
{
|
||||
float wt = (m_frame-WIRE_START) / float(WIRE_FRAMES);
|
||||
wt = zeus::clamp(0.f, wt, 2.f);
|
||||
m_lineTime = CubicEase(wt);
|
||||
setLineVerts(m_width, m_height, pf, m_lineTime);
|
||||
setLineColors(wt);
|
||||
if (wt == 2.f)
|
||||
++doneCount;
|
||||
loadVerts = true;
|
||||
}
|
||||
if (m_frame > SOLID_START)
|
||||
{
|
||||
float ft = (m_frame-SOLID_START) / float(SOLID_FRAMES);
|
||||
ft = zeus::clamp(0.f, ft, 2.f);
|
||||
setFillColors(ft);
|
||||
if (ft == 2.f)
|
||||
++doneCount;
|
||||
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::clamp(0.f, tt, 1.f);
|
||||
updateContentOpacity(tt);
|
||||
if (tt == 1.f)
|
||||
++doneCount;
|
||||
}
|
||||
if (doneCount == 3)
|
||||
m_phase = Phase::Showing;
|
||||
if (loadVerts)
|
||||
_loadVerts();
|
||||
++m_frame;
|
||||
break;
|
||||
}
|
||||
case Phase::ResWait:
|
||||
{
|
||||
if (res.fontCacheReady())
|
||||
{
|
||||
updateContentOpacity(1.0);
|
||||
m_phase = Phase::Showing;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Phase::BuildOut:
|
||||
{
|
||||
{
|
||||
float wt = (WIRE_FRAMES - m_frame) / float(WIRE_FRAMES);
|
||||
wt = zeus::clamp(0.f, wt, 1.f);
|
||||
m_lineTime = CubicEase(wt);
|
||||
setLineVertsOut(m_width, m_height, pf, m_lineTime);
|
||||
setLineColorsOut(wt);
|
||||
if (wt == 0.f)
|
||||
m_phase = Phase::Done;
|
||||
}
|
||||
{
|
||||
float ft = (SOLID_FRAMES - m_frame) / float(SOLID_FRAMES);
|
||||
ft = zeus::clamp(0.f, ft, 1.f);
|
||||
setFillColors(ft);
|
||||
}
|
||||
if (res.fontCacheReady())
|
||||
{
|
||||
float tt = (CONTENT_FRAMES - m_frame) / float(CONTENT_FRAMES);
|
||||
tt = zeus::clamp(0.f, tt, 1.f);
|
||||
updateContentOpacity(tt);
|
||||
}
|
||||
_loadVerts();
|
||||
++m_frame;
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
_loadVerts();
|
||||
m_phase = Phase::ResWait;
|
||||
res.m_factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
buildResources(ctx, res);
|
||||
m_viewBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_vertsBinding.init(ctx, res, 38, m_viewBlockBuf);
|
||||
return true;
|
||||
} BooTrace);
|
||||
|
||||
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);
|
||||
|
||||
_loadVerts();
|
||||
}
|
||||
|
||||
void ModalWindow::close(bool skipAnimation)
|
||||
{
|
||||
m_phase = skipAnimation ? Phase::Done : Phase::BuildOut;
|
||||
m_frame = 0;
|
||||
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::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
void ModalWindow::think() {
|
||||
specter::ViewResources& res = rootView().viewRes();
|
||||
float pf = res.pixelFactor();
|
||||
|
||||
boo::SWindowRect centerRect = sub;
|
||||
std::pair<int,int> constrained = m_constraint.solve(root.size[0] - CONTENT_MARGIN * pf * 2,
|
||||
root.size[1] - CONTENT_MARGIN * pf * 2);
|
||||
m_width = std::max(constrained.first, int(WINDOW_MIN_DIM * pf));
|
||||
m_height = std::max(constrained.second, 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.access().finalAssign(m_viewBlock);
|
||||
|
||||
setLineVerts(m_width, m_height, pf, m_lineTime);
|
||||
setFillVerts(m_width, m_height, pf);
|
||||
switch (m_phase) {
|
||||
case Phase::BuildIn: {
|
||||
bool loadVerts = false;
|
||||
int doneCount = 0;
|
||||
if (m_frame > WIRE_START) {
|
||||
float wt = (m_frame - WIRE_START) / float(WIRE_FRAMES);
|
||||
wt = zeus::clamp(0.f, wt, 2.f);
|
||||
m_lineTime = CubicEase(wt);
|
||||
setLineVerts(m_width, m_height, pf, m_lineTime);
|
||||
setLineColors(wt);
|
||||
if (wt == 2.f)
|
||||
++doneCount;
|
||||
loadVerts = true;
|
||||
}
|
||||
if (m_frame > SOLID_START) {
|
||||
float ft = (m_frame - SOLID_START) / float(SOLID_FRAMES);
|
||||
ft = zeus::clamp(0.f, ft, 2.f);
|
||||
setFillColors(ft);
|
||||
if (ft == 2.f)
|
||||
++doneCount;
|
||||
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::clamp(0.f, tt, 1.f);
|
||||
updateContentOpacity(tt);
|
||||
if (tt == 1.f)
|
||||
++doneCount;
|
||||
}
|
||||
if (doneCount == 3)
|
||||
m_phase = Phase::Showing;
|
||||
if (loadVerts)
|
||||
_loadVerts();
|
||||
++m_frame;
|
||||
break;
|
||||
}
|
||||
case Phase::ResWait: {
|
||||
if (res.fontCacheReady()) {
|
||||
updateContentOpacity(1.0);
|
||||
m_phase = Phase::Showing;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Phase::BuildOut: {
|
||||
{
|
||||
float wt = (WIRE_FRAMES - m_frame) / float(WIRE_FRAMES);
|
||||
wt = zeus::clamp(0.f, wt, 1.f);
|
||||
m_lineTime = CubicEase(wt);
|
||||
setLineVertsOut(m_width, m_height, pf, m_lineTime);
|
||||
setLineColorsOut(wt);
|
||||
if (wt == 0.f)
|
||||
m_phase = Phase::Done;
|
||||
}
|
||||
{
|
||||
float ft = (SOLID_FRAMES - m_frame) / float(SOLID_FRAMES);
|
||||
ft = zeus::clamp(0.f, ft, 1.f);
|
||||
setFillColors(ft);
|
||||
}
|
||||
if (res.fontCacheReady()) {
|
||||
float tt = (CONTENT_FRAMES - m_frame) / float(CONTENT_FRAMES);
|
||||
tt = zeus::clamp(0.f, tt, 1.f);
|
||||
updateContentOpacity(tt);
|
||||
}
|
||||
_loadVerts();
|
||||
|
||||
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);
|
||||
++m_frame;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ModalWindow::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
if (m_phase == Phase::Done)
|
||||
return;
|
||||
bool ModalWindow::skipBuildInAnimation() {
|
||||
if (m_phase != Phase::BuildIn)
|
||||
return false;
|
||||
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 22);
|
||||
gfxQ->draw(22, 16);
|
||||
specter::ViewResources& res = rootView().viewRes();
|
||||
float pf = res.pixelFactor();
|
||||
|
||||
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);
|
||||
m_lineTime = 1.0;
|
||||
setLineVerts(m_width, m_height, pf, 1.0);
|
||||
setLineColors(2.0);
|
||||
setFillColors(2.0);
|
||||
_loadVerts();
|
||||
m_phase = Phase::ResWait;
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModalWindow::close(bool skipAnimation) {
|
||||
m_phase = skipAnimation ? Phase::Done : Phase::BuildOut;
|
||||
m_frame = 0;
|
||||
}
|
||||
|
||||
void ModalWindow::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
|
||||
boo::SWindowRect centerRect = sub;
|
||||
std::pair<int, int> constrained =
|
||||
m_constraint.solve(root.size[0] - CONTENT_MARGIN * pf * 2, root.size[1] - CONTENT_MARGIN * pf * 2);
|
||||
m_width = std::max(constrained.first, int(WINDOW_MIN_DIM * pf));
|
||||
m_height = std::max(constrained.second, 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.access().finalAssign(m_viewBlock);
|
||||
|
||||
setLineVerts(m_width, m_height, pf, m_lineTime);
|
||||
setFillVerts(m_width, m_height, pf);
|
||||
_loadVerts();
|
||||
|
||||
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) {
|
||||
if (m_phase == Phase::Done)
|
||||
return;
|
||||
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 22);
|
||||
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);
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -1,290 +1,249 @@
|
|||
#include "specter/MultiLineTextView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::MultiLineTextView");
|
||||
|
||||
std::string MultiLineTextView::LineWrap(std::string_view str, int wrap)
|
||||
{
|
||||
size_t rem = str.size();
|
||||
const utf8proc_uint8_t* it = reinterpret_cast<const utf8proc_uint8_t*>(str.data());
|
||||
uint32_t lCh = -1;
|
||||
int adv = 0;
|
||||
std::string MultiLineTextView::LineWrap(std::string_view str, int wrap) {
|
||||
size_t rem = str.size();
|
||||
const utf8proc_uint8_t* it = reinterpret_cast<const utf8proc_uint8_t*>(str.data());
|
||||
uint32_t lCh = -1;
|
||||
int adv = 0;
|
||||
|
||||
std::string ret;
|
||||
ret.reserve(str.size());
|
||||
size_t lastSpaceRem;
|
||||
const utf8proc_uint8_t* lastSpaceIt = nullptr;
|
||||
size_t rollbackPos;
|
||||
while (rem)
|
||||
{
|
||||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (sz < 0)
|
||||
Log.report(logvisor::Fatal, "invalid UTF-8 char");
|
||||
if (ch == '\n')
|
||||
{
|
||||
ret += '\n';
|
||||
lCh = -1;
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
lastSpaceIt = nullptr;
|
||||
adv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
const FontAtlas::Glyph* glyph = m_fontAtlas.lookupGlyph(ch);
|
||||
if (!glyph)
|
||||
{
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lCh != -1)
|
||||
adv += TextView::DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas);
|
||||
adv += glyph->m_advance;
|
||||
|
||||
if (adv > wrap && lastSpaceIt)
|
||||
{
|
||||
ret.assign(ret.cbegin(), ret.cbegin() + rollbackPos);
|
||||
ret += '\n';
|
||||
lCh = -1;
|
||||
rem = lastSpaceRem;
|
||||
it = lastSpaceIt;
|
||||
lastSpaceIt = nullptr;
|
||||
adv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sz == 1 && (it[0] == ' ' || it[0] == '-' || it[0] == '/' || it[0] == '\\'))
|
||||
{
|
||||
lastSpaceIt = it + 1;
|
||||
lastSpaceRem = rem - 1;
|
||||
rollbackPos = ret.size() + 1;
|
||||
}
|
||||
for (utf8proc_ssize_t i=0 ; i<sz ; ++i)
|
||||
ret += it[i];
|
||||
lCh = glyph->m_glyphIdx;
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
std::string ret;
|
||||
ret.reserve(str.size());
|
||||
size_t lastSpaceRem;
|
||||
const utf8proc_uint8_t* lastSpaceIt = nullptr;
|
||||
size_t rollbackPos;
|
||||
while (rem) {
|
||||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (sz < 0)
|
||||
Log.report(logvisor::Fatal, "invalid UTF-8 char");
|
||||
if (ch == '\n') {
|
||||
ret += '\n';
|
||||
lCh = -1;
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
lastSpaceIt = nullptr;
|
||||
adv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::wstring MultiLineTextView::LineWrap(std::wstring_view str, int wrap)
|
||||
{
|
||||
uint32_t lCh = -1;
|
||||
int adv = 0;
|
||||
|
||||
std::wstring ret;
|
||||
ret.reserve(str.size());
|
||||
std::wstring_view::const_iterator lastSpaceIt = str.cend();
|
||||
size_t rollbackPos;
|
||||
for (std::wstring_view::const_iterator it = str.cbegin() ; it != str.cend() ; ++it)
|
||||
{
|
||||
wchar_t ch = *it;
|
||||
if (ch == L'\n')
|
||||
{
|
||||
ret += L'\n';
|
||||
lCh = -1;
|
||||
lastSpaceIt = str.cend();
|
||||
adv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
const FontAtlas::Glyph* glyph = m_fontAtlas.lookupGlyph(ch);
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
if (lCh != -1)
|
||||
adv += TextView::DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas);
|
||||
adv += glyph->m_advance;
|
||||
|
||||
if (adv > wrap && lastSpaceIt != str.cend())
|
||||
{
|
||||
ret.assign(ret.cbegin(), ret.cbegin() + rollbackPos);
|
||||
ret += L'\n';
|
||||
lCh = -1;
|
||||
it = lastSpaceIt;
|
||||
lastSpaceIt = str.cend();
|
||||
adv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch == L' ' || ch == L'-')
|
||||
{
|
||||
lastSpaceIt = it + 1;
|
||||
rollbackPos = ret.size() + 1;
|
||||
}
|
||||
ret += ch;
|
||||
lCh = glyph->m_glyphIdx;
|
||||
const FontAtlas::Glyph* glyph = m_fontAtlas.lookupGlyph(ch);
|
||||
if (!glyph) {
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
continue;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
if (lCh != -1)
|
||||
adv += TextView::DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas);
|
||||
adv += glyph->m_advance;
|
||||
|
||||
MultiLineTextView::MultiLineTextView(ViewResources& res,
|
||||
View& parentView,
|
||||
const FontAtlas& font,
|
||||
TextView::Alignment align,
|
||||
size_t lineCapacity,
|
||||
float lineHeight)
|
||||
: View(res, parentView),
|
||||
m_viewSystem(res),
|
||||
m_fontAtlas(font),
|
||||
m_align(align),
|
||||
m_lineCapacity(lineCapacity),
|
||||
m_lineHeight(lineHeight)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
MultiLineTextView::MultiLineTextView(ViewResources& res,
|
||||
View& parentView,
|
||||
FontTag font,
|
||||
TextView::Alignment align,
|
||||
size_t lineCapacity,
|
||||
float lineHeight)
|
||||
: MultiLineTextView(res,
|
||||
parentView,
|
||||
res.m_textRes.m_fcache->lookupAtlas(font),
|
||||
align,
|
||||
lineCapacity,
|
||||
lineHeight) {}
|
||||
|
||||
void MultiLineTextView::typesetGlyphs(std::string_view str,
|
||||
const zeus::CColor& defaultColor,
|
||||
unsigned wrap)
|
||||
{
|
||||
if (wrap)
|
||||
{
|
||||
typesetGlyphs(LineWrap(str, wrap), defaultColor);
|
||||
return;
|
||||
if (adv > wrap && lastSpaceIt) {
|
||||
ret.assign(ret.cbegin(), ret.cbegin() + rollbackPos);
|
||||
ret += '\n';
|
||||
lCh = -1;
|
||||
rem = lastSpaceRem;
|
||||
it = lastSpaceIt;
|
||||
lastSpaceIt = nullptr;
|
||||
adv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_width = 0;
|
||||
size_t rem = str.size() + 1;
|
||||
const utf8proc_uint8_t* it = reinterpret_cast<const utf8proc_uint8_t*>(str.data());
|
||||
|
||||
size_t lineCount = 0;
|
||||
while (rem)
|
||||
{
|
||||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (sz < 0)
|
||||
Log.report(logvisor::Fatal, "invalid UTF-8 char");
|
||||
if (ch == '\n' || ch == '\0')
|
||||
++lineCount;
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
if (sz == 1 && (it[0] == ' ' || it[0] == '-' || it[0] == '/' || it[0] == '\\')) {
|
||||
lastSpaceIt = it + 1;
|
||||
lastSpaceRem = rem - 1;
|
||||
rollbackPos = ret.size() + 1;
|
||||
}
|
||||
for (utf8proc_ssize_t i = 0; i < sz; ++i)
|
||||
ret += it[i];
|
||||
lCh = glyph->m_glyphIdx;
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
}
|
||||
|
||||
m_lines.reserve(lineCount);
|
||||
rem = str.size() + 1;
|
||||
it = reinterpret_cast<const utf8proc_uint8_t*>(str.data());
|
||||
const utf8proc_uint8_t* beginIt = it;
|
||||
size_t lineIt = 0;
|
||||
|
||||
while (rem)
|
||||
{
|
||||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (ch == '\n' || ch == '\0')
|
||||
{
|
||||
TextView& tv = (lineIt < m_lines.size()) ? *m_lines[lineIt] :
|
||||
*m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity));
|
||||
tv.typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor);
|
||||
m_width = std::max(m_width, tv.nominalWidth());
|
||||
beginIt = it + 1;
|
||||
++lineIt;
|
||||
}
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
}
|
||||
|
||||
updateSize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MultiLineTextView::typesetGlyphs(std::wstring_view str,
|
||||
const zeus::CColor& defaultColor,
|
||||
unsigned wrap)
|
||||
{
|
||||
if (wrap)
|
||||
{
|
||||
typesetGlyphs(LineWrap(str, wrap), defaultColor);
|
||||
return;
|
||||
std::wstring MultiLineTextView::LineWrap(std::wstring_view str, int wrap) {
|
||||
uint32_t lCh = -1;
|
||||
int adv = 0;
|
||||
|
||||
std::wstring ret;
|
||||
ret.reserve(str.size());
|
||||
std::wstring_view::const_iterator lastSpaceIt = str.cend();
|
||||
size_t rollbackPos;
|
||||
for (std::wstring_view::const_iterator it = str.cbegin(); it != str.cend(); ++it) {
|
||||
wchar_t ch = *it;
|
||||
if (ch == L'\n') {
|
||||
ret += L'\n';
|
||||
lCh = -1;
|
||||
lastSpaceIt = str.cend();
|
||||
adv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_width = 0;
|
||||
size_t rem = str.size() + 1;
|
||||
auto it = str.cbegin();
|
||||
const FontAtlas::Glyph* glyph = m_fontAtlas.lookupGlyph(ch);
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
size_t lineCount = 0;
|
||||
while (rem)
|
||||
{
|
||||
if (*it == L'\n' || *it == L'\0')
|
||||
++lineCount;
|
||||
--rem;
|
||||
++it;
|
||||
if (lCh != -1)
|
||||
adv += TextView::DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas);
|
||||
adv += glyph->m_advance;
|
||||
|
||||
if (adv > wrap && lastSpaceIt != str.cend()) {
|
||||
ret.assign(ret.cbegin(), ret.cbegin() + rollbackPos);
|
||||
ret += L'\n';
|
||||
lCh = -1;
|
||||
it = lastSpaceIt;
|
||||
lastSpaceIt = str.cend();
|
||||
adv = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_lines.reserve(lineCount);
|
||||
rem = str.size() + 1;
|
||||
it = str.cbegin();
|
||||
auto beginIt = it;
|
||||
size_t lineIt = 0;
|
||||
|
||||
while (rem)
|
||||
{
|
||||
if (*it == L'\n' || *it == L'\0')
|
||||
{
|
||||
TextView& tv = (lineIt < m_lines.size()) ? *m_lines[lineIt] :
|
||||
*m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity));
|
||||
tv.typesetGlyphs(std::wstring(beginIt, it), defaultColor);
|
||||
m_width = std::max(m_width, tv.nominalWidth());
|
||||
beginIt = it + 1;
|
||||
++lineIt;
|
||||
}
|
||||
--rem;
|
||||
++it;
|
||||
if (ch == L' ' || ch == L'-') {
|
||||
lastSpaceIt = it + 1;
|
||||
rollbackPos = ret.size() + 1;
|
||||
}
|
||||
ret += ch;
|
||||
lCh = glyph->m_glyphIdx;
|
||||
}
|
||||
|
||||
updateSize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void MultiLineTextView::colorGlyphs(const zeus::CColor& newColor)
|
||||
{
|
||||
for (std::unique_ptr<TextView>& tv : m_lines)
|
||||
tv->colorGlyphs(newColor);
|
||||
MultiLineTextView::MultiLineTextView(ViewResources& res, View& parentView, const FontAtlas& font,
|
||||
TextView::Alignment align, size_t lineCapacity, float lineHeight)
|
||||
: View(res, parentView)
|
||||
, m_viewSystem(res)
|
||||
, m_fontAtlas(font)
|
||||
, m_align(align)
|
||||
, m_lineCapacity(lineCapacity)
|
||||
, m_lineHeight(lineHeight) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void MultiLineTextView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
unsigned lHeight = unsigned(m_lineHeight * m_fontAtlas.FT_LineHeight()) >> 6;
|
||||
unsigned decumHeight = lHeight * m_lines.size();
|
||||
boo::SWindowRect tsub = sub;
|
||||
tsub.location[1] += decumHeight;
|
||||
tsub.size[1] = 10;
|
||||
for (std::unique_ptr<TextView>& tv : m_lines)
|
||||
{
|
||||
tsub.location[1] -= lHeight;
|
||||
tv->resized(root, tsub);
|
||||
MultiLineTextView::MultiLineTextView(ViewResources& res, View& parentView, FontTag font, TextView::Alignment align,
|
||||
size_t lineCapacity, float lineHeight)
|
||||
: MultiLineTextView(res, parentView, res.m_textRes.m_fcache->lookupAtlas(font), align, lineCapacity, lineHeight) {}
|
||||
|
||||
void MultiLineTextView::typesetGlyphs(std::string_view str, const zeus::CColor& defaultColor, unsigned wrap) {
|
||||
if (wrap) {
|
||||
typesetGlyphs(LineWrap(str, wrap), defaultColor);
|
||||
return;
|
||||
}
|
||||
|
||||
m_width = 0;
|
||||
size_t rem = str.size() + 1;
|
||||
const utf8proc_uint8_t* it = reinterpret_cast<const utf8proc_uint8_t*>(str.data());
|
||||
|
||||
size_t lineCount = 0;
|
||||
while (rem) {
|
||||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (sz < 0)
|
||||
Log.report(logvisor::Fatal, "invalid UTF-8 char");
|
||||
if (ch == '\n' || ch == '\0')
|
||||
++lineCount;
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
}
|
||||
|
||||
m_lines.reserve(lineCount);
|
||||
rem = str.size() + 1;
|
||||
it = reinterpret_cast<const utf8proc_uint8_t*>(str.data());
|
||||
const utf8proc_uint8_t* beginIt = it;
|
||||
size_t lineIt = 0;
|
||||
|
||||
while (rem) {
|
||||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (ch == '\n' || ch == '\0') {
|
||||
TextView& tv =
|
||||
(lineIt < m_lines.size())
|
||||
? *m_lines[lineIt]
|
||||
: *m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity));
|
||||
tv.typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor);
|
||||
m_width = std::max(m_width, tv.nominalWidth());
|
||||
beginIt = it + 1;
|
||||
++lineIt;
|
||||
}
|
||||
rem -= sz;
|
||||
it += sz;
|
||||
}
|
||||
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void MultiLineTextView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
for (std::unique_ptr<TextView>& tv : m_lines)
|
||||
tv->draw(gfxQ);
|
||||
void MultiLineTextView::typesetGlyphs(std::wstring_view str, const zeus::CColor& defaultColor, unsigned wrap) {
|
||||
if (wrap) {
|
||||
typesetGlyphs(LineWrap(str, wrap), defaultColor);
|
||||
return;
|
||||
}
|
||||
|
||||
m_width = 0;
|
||||
size_t rem = str.size() + 1;
|
||||
auto it = str.cbegin();
|
||||
|
||||
size_t lineCount = 0;
|
||||
while (rem) {
|
||||
if (*it == L'\n' || *it == L'\0')
|
||||
++lineCount;
|
||||
--rem;
|
||||
++it;
|
||||
}
|
||||
|
||||
m_lines.reserve(lineCount);
|
||||
rem = str.size() + 1;
|
||||
it = str.cbegin();
|
||||
auto beginIt = it;
|
||||
size_t lineIt = 0;
|
||||
|
||||
while (rem) {
|
||||
if (*it == L'\n' || *it == L'\0') {
|
||||
TextView& tv =
|
||||
(lineIt < m_lines.size())
|
||||
? *m_lines[lineIt]
|
||||
: *m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity));
|
||||
tv.typesetGlyphs(std::wstring(beginIt, it), defaultColor);
|
||||
m_width = std::max(m_width, tv.nominalWidth());
|
||||
beginIt = it + 1;
|
||||
++lineIt;
|
||||
}
|
||||
--rem;
|
||||
++it;
|
||||
}
|
||||
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void MultiLineTextView::colorGlyphs(const zeus::CColor& newColor) {
|
||||
for (std::unique_ptr<TextView>& tv : m_lines)
|
||||
tv->colorGlyphs(newColor);
|
||||
}
|
||||
|
||||
void MultiLineTextView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
View::resized(root, sub);
|
||||
unsigned lHeight = unsigned(m_lineHeight * m_fontAtlas.FT_LineHeight()) >> 6;
|
||||
unsigned decumHeight = lHeight * m_lines.size();
|
||||
boo::SWindowRect tsub = sub;
|
||||
tsub.location[1] += decumHeight;
|
||||
tsub.size[1] = 10;
|
||||
for (std::unique_ptr<TextView>& tv : m_lines) {
|
||||
tsub.location[1] -= lHeight;
|
||||
tv->resized(root, tsub);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiLineTextView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
View::draw(gfxQ);
|
||||
for (std::unique_ptr<TextView>& tv : m_lines)
|
||||
tv->draw(gfxQ);
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -2,94 +2,82 @@
|
|||
#include "specter/RootView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
PathButtons::PathButtons(ViewResources& res, View& parentView, IPathButtonsBinding& binding, bool fillContainer)
|
||||
: ScrollView(res, parentView, ScrollView::Style::SideButtons), m_binding(binding), m_fillContainer(fillContainer)
|
||||
{
|
||||
m_contentView.m_view.reset(new ContentView(res, *this));
|
||||
setContentView(m_contentView.m_view.get());
|
||||
: ScrollView(res, parentView, ScrollView::Style::SideButtons), m_binding(binding), m_fillContainer(fillContainer) {
|
||||
m_contentView.m_view.reset(new ContentView(res, *this));
|
||||
setContentView(m_contentView.m_view.get());
|
||||
}
|
||||
|
||||
void PathButtons::setButtons(const std::vector<hecl::SystemString>& comps)
|
||||
{
|
||||
m_pathButtons.clear();
|
||||
m_pathButtons.reserve(comps.size());
|
||||
size_t idx = 0;
|
||||
ViewResources& res = rootView().viewRes();
|
||||
for (const hecl::SystemString& c : comps)
|
||||
m_pathButtons.emplace_back(*this, res, idx++, c);
|
||||
void PathButtons::setButtons(const std::vector<hecl::SystemString>& comps) {
|
||||
m_pathButtons.clear();
|
||||
m_pathButtons.reserve(comps.size());
|
||||
size_t idx = 0;
|
||||
ViewResources& res = rootView().viewRes();
|
||||
for (const hecl::SystemString& c : comps)
|
||||
m_pathButtons.emplace_back(*this, res, idx++, c);
|
||||
}
|
||||
|
||||
void PathButtons::setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
ScrollView::setMultiplyColor(color);
|
||||
for (PathButton& b : m_pathButtons)
|
||||
b.m_button.m_view->setMultiplyColor(color);
|
||||
void PathButtons::setMultiplyColor(const zeus::CColor& color) {
|
||||
ScrollView::setMultiplyColor(color);
|
||||
for (PathButton& b : m_pathButtons)
|
||||
b.m_button.m_view->setMultiplyColor(color);
|
||||
}
|
||||
|
||||
void PathButtons::ContentView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.mouseDown(coord, button, mod);
|
||||
void PathButtons::ContentView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button,
|
||||
boo::EModifierKey mod) {
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.mouseDown(coord, button, mod);
|
||||
}
|
||||
|
||||
void PathButtons::ContentView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.mouseUp(coord, button, mod);
|
||||
if (m_pb.m_pathButtonPending >= 0)
|
||||
{
|
||||
m_pb.m_binding.pathButtonActivated(m_pb.m_pathButtonPending);
|
||||
m_pb.m_pathButtonPending = -1;
|
||||
}
|
||||
void PathButtons::ContentView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button,
|
||||
boo::EModifierKey mod) {
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.mouseUp(coord, button, mod);
|
||||
if (m_pb.m_pathButtonPending >= 0) {
|
||||
m_pb.m_binding.pathButtonActivated(m_pb.m_pathButtonPending);
|
||||
m_pb.m_pathButtonPending = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void PathButtons::ContentView::mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.mouseMove(coord);
|
||||
void PathButtons::ContentView::mouseMove(const boo::SWindowCoord& coord) {
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.mouseMove(coord);
|
||||
}
|
||||
|
||||
void PathButtons::ContentView::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.mouseLeave(coord);
|
||||
void PathButtons::ContentView::mouseLeave(const boo::SWindowCoord& coord) {
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.mouseLeave(coord);
|
||||
}
|
||||
|
||||
void PathButtons::ContentView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub,
|
||||
const boo::SWindowRect& scissor)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
m_scissorRect = scissor;
|
||||
m_scissorRect.size[1] += 2;
|
||||
boo::SWindowRect pathRect = sub;
|
||||
for (PathButton& b : m_pb.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] + 2;
|
||||
}
|
||||
const boo::SWindowRect& scissor) {
|
||||
View::resized(root, sub);
|
||||
m_scissorRect = scissor;
|
||||
m_scissorRect.size[1] += 2;
|
||||
boo::SWindowRect pathRect = sub;
|
||||
for (PathButton& b : m_pb.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] + 2;
|
||||
}
|
||||
}
|
||||
|
||||
void PathButtons::containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
if (m_fillContainer)
|
||||
{
|
||||
boo::SWindowRect fillRect = sub;
|
||||
fillRect.size[1] = 20 * rootView().viewRes().pixelFactor();
|
||||
View::resized(root, fillRect);
|
||||
}
|
||||
void PathButtons::containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
if (m_fillContainer) {
|
||||
boo::SWindowRect fillRect = sub;
|
||||
fillRect.size[1] = 20 * rootView().viewRes().pixelFactor();
|
||||
View::resized(root, fillRect);
|
||||
}
|
||||
}
|
||||
|
||||
void PathButtons::ContentView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
gfxQ->setScissor(m_scissorRect);
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.m_view->draw(gfxQ);
|
||||
gfxQ->setScissor(rootView().subRect());
|
||||
void PathButtons::ContentView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
gfxQ->setScissor(m_scissorRect);
|
||||
for (PathButton& b : m_pb.m_pathButtons)
|
||||
b.m_button.m_view->draw(gfxQ);
|
||||
gfxQ->setScissor(rootView().subRect());
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace specter
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,315 +3,261 @@
|
|||
#include "specter/RootView.hpp"
|
||||
#include "specter/Button.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
#define MAX_SCROLL_SPEED 100
|
||||
|
||||
ScrollView::ScrollView(ViewResources& res, View& parentView, Style style)
|
||||
: View(res, parentView), m_style(style), m_sideButtonBind(*this, rootView().viewManager())
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.init(ctx, res, 4, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
: View(res, parentView), m_style(style), m_sideButtonBind(*this, rootView().viewManager()) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.init(ctx, res, 4, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (style == Style::SideButtons)
|
||||
{
|
||||
m_sideButtons[0].m_view.reset(new Button(res, *this, &m_sideButtonBind, "<"));
|
||||
m_sideButtons[1].m_view.reset(new Button(res, *this, &m_sideButtonBind, ">"));
|
||||
}
|
||||
if (style == Style::SideButtons) {
|
||||
m_sideButtons[0].m_view.reset(new Button(res, *this, &m_sideButtonBind, "<"));
|
||||
m_sideButtons[1].m_view.reset(new Button(res, *this, &m_sideButtonBind, ">"));
|
||||
}
|
||||
}
|
||||
|
||||
bool ScrollView::_scroll(const boo::SScrollDelta& scroll)
|
||||
{
|
||||
if (m_contentView.m_view)
|
||||
{
|
||||
float ratioX = subRect().size[0] / float(m_contentView.m_view->nominalWidth());
|
||||
float ratioY = subRect().size[1] / float(m_contentView.m_view->nominalHeight());
|
||||
bool ScrollView::_scroll(const boo::SScrollDelta& scroll) {
|
||||
if (m_contentView.m_view) {
|
||||
float ratioX = subRect().size[0] / float(m_contentView.m_view->nominalWidth());
|
||||
float ratioY = subRect().size[1] / float(m_contentView.m_view->nominalHeight());
|
||||
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
double mult = 20.0 * pf;
|
||||
if (scroll.isFine)
|
||||
mult = 1.0 * pf;
|
||||
|
||||
bool ret = false;
|
||||
|
||||
if (ratioX >= 1.f)
|
||||
{
|
||||
m_scroll[0] = 0;
|
||||
m_targetScroll[0] = 0;
|
||||
m_drawSideButtons = false;
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_drawSideButtons = true;
|
||||
m_targetScroll[0] += scroll.delta[0] * mult;
|
||||
m_targetScroll[0] = std::min(m_targetScroll[0], 0);
|
||||
int scrollWidth = m_contentView.m_view->nominalWidth() - scrollAreaWidth();
|
||||
m_targetScroll[0] = std::max(m_targetScroll[0], -scrollWidth);
|
||||
}
|
||||
|
||||
if (ratioY >= 1.f)
|
||||
{
|
||||
m_scroll[1] = 0;
|
||||
m_targetScroll[1] = 0;
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_targetScroll[1] -= scroll.delta[1] * mult;
|
||||
m_targetScroll[1] = std::max(m_targetScroll[1], 0);
|
||||
int scrollHeight = m_contentView.m_view->nominalHeight() - subRect().size[1];
|
||||
m_targetScroll[1] = std::min(m_targetScroll[1], scrollHeight);
|
||||
}
|
||||
|
||||
if (scroll.isFine)
|
||||
{
|
||||
m_scroll[0] = m_targetScroll[0];
|
||||
m_scroll[1] = m_targetScroll[1];
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_scroll[0] = 0;
|
||||
m_scroll[1] = 0;
|
||||
m_targetScroll[0] = 0;
|
||||
m_targetScroll[1] = 0;
|
||||
m_drawSideButtons = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int ScrollView::scrollAreaWidth() const
|
||||
{
|
||||
int ret = subRect().size[0];
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons)
|
||||
{
|
||||
ret -= m_sideButtons[0].m_view->nominalWidth();
|
||||
ret -= m_sideButtons[1].m_view->nominalWidth();
|
||||
}
|
||||
return std::max(0, ret);
|
||||
}
|
||||
|
||||
void ScrollView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons)
|
||||
{
|
||||
if (m_sideButtons[0].mouseDown(coord, button, mod) ||
|
||||
m_sideButtons[1].mouseDown(coord, button, mod))
|
||||
return;
|
||||
}
|
||||
m_contentView.mouseDown(coord, button, mod);
|
||||
}
|
||||
|
||||
void ScrollView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (m_style == Style::SideButtons)
|
||||
{
|
||||
m_sideButtons[0].mouseUp(coord, button, mod);
|
||||
m_sideButtons[1].mouseUp(coord, button, mod);
|
||||
}
|
||||
m_contentView.mouseUp(coord, button, mod);
|
||||
}
|
||||
|
||||
void ScrollView::mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons)
|
||||
{
|
||||
m_sideButtons[0].mouseMove(coord);
|
||||
m_sideButtons[1].mouseMove(coord);
|
||||
}
|
||||
m_contentView.mouseMove(coord);
|
||||
}
|
||||
|
||||
void ScrollView::mouseEnter(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons)
|
||||
{
|
||||
m_sideButtons[0].mouseEnter(coord);
|
||||
m_sideButtons[1].mouseEnter(coord);
|
||||
}
|
||||
m_contentView.mouseEnter(coord);
|
||||
}
|
||||
|
||||
void ScrollView::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (m_style == Style::SideButtons)
|
||||
{
|
||||
m_sideButtons[0].mouseLeave(coord);
|
||||
m_sideButtons[1].mouseLeave(coord);
|
||||
}
|
||||
m_contentView.mouseLeave(coord);
|
||||
}
|
||||
|
||||
void ScrollView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll)
|
||||
{
|
||||
if (!scroll.isAccelerated)
|
||||
{
|
||||
boo::SScrollDelta newScroll = scroll;
|
||||
m_consecutiveScroll[m_consecutiveIdx][0] += scroll.delta[0];
|
||||
m_consecutiveScroll[m_consecutiveIdx][1] += scroll.delta[1];
|
||||
newScroll.delta[0] = 0;
|
||||
newScroll.delta[1] = 0;
|
||||
for (size_t i=0 ; i<16 ; ++i)
|
||||
{
|
||||
newScroll.delta[0] += m_consecutiveScroll[i][0];
|
||||
newScroll.delta[1] += m_consecutiveScroll[i][1];
|
||||
}
|
||||
if (_scroll(newScroll))
|
||||
updateSize();
|
||||
return;
|
||||
}
|
||||
if (_scroll(scroll))
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void ScrollView::setMultiplyColor(const zeus::CColor& color)
|
||||
{
|
||||
View::setMultiplyColor(color);
|
||||
if (m_style == Style::SideButtons)
|
||||
{
|
||||
m_sideButtons[0].m_view->setMultiplyColor(color);
|
||||
m_sideButtons[1].m_view->setMultiplyColor(color);
|
||||
}
|
||||
if (m_contentView.m_view)
|
||||
m_contentView.m_view->setMultiplyColor(color);
|
||||
}
|
||||
|
||||
void ScrollView::think()
|
||||
{
|
||||
m_consecutiveIdx = (m_consecutiveIdx+1) % 16;
|
||||
m_consecutiveScroll[m_consecutiveIdx][0] = 0.0;
|
||||
m_consecutiveScroll[m_consecutiveIdx][1] = 0.0;
|
||||
|
||||
if (m_sideButtonState != SideButtonState::None)
|
||||
{
|
||||
if (m_sideButtonState == SideButtonState::ScrollLeft)
|
||||
m_targetScroll[0] -= 3;
|
||||
else if (m_sideButtonState == SideButtonState::ScrollRight)
|
||||
m_targetScroll[0] += 3;
|
||||
m_targetScroll[0] = std::min(m_targetScroll[0], 0);
|
||||
int scrollWidth = m_contentView.m_view->nominalWidth() - scrollAreaWidth();
|
||||
m_targetScroll[0] = std::max(m_targetScroll[0], -scrollWidth);
|
||||
}
|
||||
|
||||
bool update = false;
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
double mult = 20.0 * pf;
|
||||
if (scroll.isFine)
|
||||
mult = 1.0 * pf;
|
||||
|
||||
int xSpeed = std::max(1, std::min(abs(m_targetScroll[0] - m_scroll[0]) / int(5*pf), int(pf*MAX_SCROLL_SPEED)));
|
||||
if (m_scroll[0] < m_targetScroll[0])
|
||||
{
|
||||
m_scroll[0] += xSpeed;
|
||||
update = true;
|
||||
}
|
||||
else if (m_scroll[0] > m_targetScroll[0])
|
||||
{
|
||||
m_scroll[0] -= xSpeed;
|
||||
update = true;
|
||||
bool ret = false;
|
||||
|
||||
if (ratioX >= 1.f) {
|
||||
m_scroll[0] = 0;
|
||||
m_targetScroll[0] = 0;
|
||||
m_drawSideButtons = false;
|
||||
ret = true;
|
||||
} else {
|
||||
m_drawSideButtons = true;
|
||||
m_targetScroll[0] += scroll.delta[0] * mult;
|
||||
m_targetScroll[0] = std::min(m_targetScroll[0], 0);
|
||||
int scrollWidth = m_contentView.m_view->nominalWidth() - scrollAreaWidth();
|
||||
m_targetScroll[0] = std::max(m_targetScroll[0], -scrollWidth);
|
||||
}
|
||||
|
||||
int ySpeed = std::max(1, std::min(abs(m_targetScroll[1] - m_scroll[1]) / int(5*pf), int(pf*MAX_SCROLL_SPEED)));
|
||||
if (m_scroll[1] < m_targetScroll[1])
|
||||
{
|
||||
m_scroll[1] += ySpeed;
|
||||
update = true;
|
||||
}
|
||||
else if (m_scroll[1] > m_targetScroll[1])
|
||||
{
|
||||
m_scroll[1] -= ySpeed;
|
||||
update = true;
|
||||
if (ratioY >= 1.f) {
|
||||
m_scroll[1] = 0;
|
||||
m_targetScroll[1] = 0;
|
||||
ret = true;
|
||||
} else {
|
||||
m_targetScroll[1] -= scroll.delta[1] * mult;
|
||||
m_targetScroll[1] = std::max(m_targetScroll[1], 0);
|
||||
int scrollHeight = m_contentView.m_view->nominalHeight() - subRect().size[1];
|
||||
m_targetScroll[1] = std::min(m_targetScroll[1], scrollHeight);
|
||||
}
|
||||
|
||||
if (update)
|
||||
updateSize();
|
||||
if (scroll.isFine) {
|
||||
m_scroll[0] = m_targetScroll[0];
|
||||
m_scroll[1] = m_targetScroll[1];
|
||||
ret = true;
|
||||
}
|
||||
|
||||
return ret;
|
||||
} else {
|
||||
m_scroll[0] = 0;
|
||||
m_scroll[1] = 0;
|
||||
m_targetScroll[0] = 0;
|
||||
m_targetScroll[1] = 0;
|
||||
m_drawSideButtons = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScrollView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
_scroll({});
|
||||
if (m_contentView.m_view)
|
||||
{
|
||||
boo::SWindowRect cRect = sub;
|
||||
cRect.location[0] += m_scroll[0];
|
||||
cRect.location[1] += sub.size[1] - m_contentView.m_view->nominalHeight() + m_scroll[1];
|
||||
cRect.size[0] = m_contentView.m_view->nominalWidth();
|
||||
cRect.size[1] = m_contentView.m_view->nominalHeight();
|
||||
m_contentView.m_scissorRect = sub;
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons)
|
||||
{
|
||||
int width0 = m_sideButtons[0].m_view->nominalWidth() + 2;
|
||||
int width1 = m_sideButtons[1].m_view->nominalWidth();
|
||||
cRect.location[0] += width0;
|
||||
cRect.size[0] -= (width0 + width1);
|
||||
int ScrollView::scrollAreaWidth() const {
|
||||
int ret = subRect().size[0];
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons) {
|
||||
ret -= m_sideButtons[0].m_view->nominalWidth();
|
||||
ret -= m_sideButtons[1].m_view->nominalWidth();
|
||||
}
|
||||
return std::max(0, ret);
|
||||
}
|
||||
|
||||
m_contentView.m_scissorRect.location[0] += width0;
|
||||
m_contentView.m_scissorRect.size[0] -= (width0 + width1);
|
||||
}
|
||||
m_contentView.m_view->resized(root, cRect, m_contentView.m_scissorRect);
|
||||
void ScrollView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons) {
|
||||
if (m_sideButtons[0].mouseDown(coord, button, mod) || m_sideButtons[1].mouseDown(coord, button, mod))
|
||||
return;
|
||||
}
|
||||
m_contentView.mouseDown(coord, button, mod);
|
||||
}
|
||||
|
||||
void ScrollView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (m_style == Style::SideButtons) {
|
||||
m_sideButtons[0].mouseUp(coord, button, mod);
|
||||
m_sideButtons[1].mouseUp(coord, button, mod);
|
||||
}
|
||||
m_contentView.mouseUp(coord, button, mod);
|
||||
}
|
||||
|
||||
if (m_style == Style::ThinIndicator)
|
||||
{
|
||||
float ratio = sub.size[1] / float(cRect.size[1]);
|
||||
m_drawInd = ratio < 1.f;
|
||||
if (m_drawInd)
|
||||
{
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
int barHeight = sub.size[1] * ratio;
|
||||
int scrollHeight = sub.size[1] - barHeight;
|
||||
float prog = m_scroll[1] / float(cRect.size[1] - sub.size[1]);
|
||||
int x = sub.size[0];
|
||||
int y = sub.size[1] - scrollHeight * prog;
|
||||
m_verts[0].m_pos.assign(x, y, 0);
|
||||
m_verts[1].m_pos.assign(x, y-barHeight, 0);
|
||||
m_verts[2].m_pos.assign(x+2*pf, y, 0);
|
||||
m_verts[3].m_pos.assign(x+2*pf, y-barHeight, 0);
|
||||
const zeus::CColor& color = rootView().themeData().scrollIndicator();
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_verts[i].m_color = color;
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
}
|
||||
}
|
||||
else if (m_style == Style::SideButtons && m_drawSideButtons)
|
||||
{
|
||||
boo::SWindowRect bRect = sub;
|
||||
bRect.size[0] = m_sideButtons[0].m_view->nominalWidth();
|
||||
bRect.size[1] = m_sideButtons[0].m_view->nominalHeight();
|
||||
m_sideButtons[0].m_view->resized(root, bRect);
|
||||
void ScrollView::mouseMove(const boo::SWindowCoord& coord) {
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons) {
|
||||
m_sideButtons[0].mouseMove(coord);
|
||||
m_sideButtons[1].mouseMove(coord);
|
||||
}
|
||||
m_contentView.mouseMove(coord);
|
||||
}
|
||||
|
||||
bRect.size[0] = m_sideButtons[1].m_view->nominalWidth();
|
||||
bRect.size[1] = m_sideButtons[1].m_view->nominalHeight();
|
||||
bRect.location[0] += sub.size[0] - bRect.size[0];
|
||||
m_sideButtons[1].m_view->resized(root, bRect);
|
||||
}
|
||||
void ScrollView::mouseEnter(const boo::SWindowCoord& coord) {
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons) {
|
||||
m_sideButtons[0].mouseEnter(coord);
|
||||
m_sideButtons[1].mouseEnter(coord);
|
||||
}
|
||||
m_contentView.mouseEnter(coord);
|
||||
}
|
||||
|
||||
void ScrollView::mouseLeave(const boo::SWindowCoord& coord) {
|
||||
if (m_style == Style::SideButtons) {
|
||||
m_sideButtons[0].mouseLeave(coord);
|
||||
m_sideButtons[1].mouseLeave(coord);
|
||||
}
|
||||
m_contentView.mouseLeave(coord);
|
||||
}
|
||||
|
||||
void ScrollView::scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) {
|
||||
if (!scroll.isAccelerated) {
|
||||
boo::SScrollDelta newScroll = scroll;
|
||||
m_consecutiveScroll[m_consecutiveIdx][0] += scroll.delta[0];
|
||||
m_consecutiveScroll[m_consecutiveIdx][1] += scroll.delta[1];
|
||||
newScroll.delta[0] = 0;
|
||||
newScroll.delta[1] = 0;
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
newScroll.delta[0] += m_consecutiveScroll[i][0];
|
||||
newScroll.delta[1] += m_consecutiveScroll[i][1];
|
||||
}
|
||||
if (_scroll(newScroll))
|
||||
updateSize();
|
||||
return;
|
||||
}
|
||||
if (_scroll(scroll))
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void ScrollView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
if (m_contentView.m_view)
|
||||
{
|
||||
m_contentView.m_view->draw(gfxQ);
|
||||
void ScrollView::setMultiplyColor(const zeus::CColor& color) {
|
||||
View::setMultiplyColor(color);
|
||||
if (m_style == Style::SideButtons) {
|
||||
m_sideButtons[0].m_view->setMultiplyColor(color);
|
||||
m_sideButtons[1].m_view->setMultiplyColor(color);
|
||||
}
|
||||
if (m_contentView.m_view)
|
||||
m_contentView.m_view->setMultiplyColor(color);
|
||||
}
|
||||
|
||||
if (m_style == Style::ThinIndicator && m_drawInd)
|
||||
{
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
}
|
||||
else if (m_style == Style::SideButtons && m_drawSideButtons)
|
||||
{
|
||||
m_sideButtons[0].m_view->draw(gfxQ);
|
||||
m_sideButtons[1].m_view->draw(gfxQ);
|
||||
}
|
||||
void ScrollView::think() {
|
||||
m_consecutiveIdx = (m_consecutiveIdx + 1) % 16;
|
||||
m_consecutiveScroll[m_consecutiveIdx][0] = 0.0;
|
||||
m_consecutiveScroll[m_consecutiveIdx][1] = 0.0;
|
||||
|
||||
if (m_sideButtonState != SideButtonState::None) {
|
||||
if (m_sideButtonState == SideButtonState::ScrollLeft)
|
||||
m_targetScroll[0] -= 3;
|
||||
else if (m_sideButtonState == SideButtonState::ScrollRight)
|
||||
m_targetScroll[0] += 3;
|
||||
m_targetScroll[0] = std::min(m_targetScroll[0], 0);
|
||||
int scrollWidth = m_contentView.m_view->nominalWidth() - scrollAreaWidth();
|
||||
m_targetScroll[0] = std::max(m_targetScroll[0], -scrollWidth);
|
||||
}
|
||||
|
||||
bool update = false;
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
|
||||
int xSpeed = std::max(1, std::min(abs(m_targetScroll[0] - m_scroll[0]) / int(5 * pf), int(pf * MAX_SCROLL_SPEED)));
|
||||
if (m_scroll[0] < m_targetScroll[0]) {
|
||||
m_scroll[0] += xSpeed;
|
||||
update = true;
|
||||
} else if (m_scroll[0] > m_targetScroll[0]) {
|
||||
m_scroll[0] -= xSpeed;
|
||||
update = true;
|
||||
}
|
||||
|
||||
int ySpeed = std::max(1, std::min(abs(m_targetScroll[1] - m_scroll[1]) / int(5 * pf), int(pf * MAX_SCROLL_SPEED)));
|
||||
if (m_scroll[1] < m_targetScroll[1]) {
|
||||
m_scroll[1] += ySpeed;
|
||||
update = true;
|
||||
} else if (m_scroll[1] > m_targetScroll[1]) {
|
||||
m_scroll[1] -= ySpeed;
|
||||
update = true;
|
||||
}
|
||||
|
||||
if (update)
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void ScrollView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
View::resized(root, sub);
|
||||
_scroll({});
|
||||
if (m_contentView.m_view) {
|
||||
boo::SWindowRect cRect = sub;
|
||||
cRect.location[0] += m_scroll[0];
|
||||
cRect.location[1] += sub.size[1] - m_contentView.m_view->nominalHeight() + m_scroll[1];
|
||||
cRect.size[0] = m_contentView.m_view->nominalWidth();
|
||||
cRect.size[1] = m_contentView.m_view->nominalHeight();
|
||||
m_contentView.m_scissorRect = sub;
|
||||
if (m_style == Style::SideButtons && m_drawSideButtons) {
|
||||
int width0 = m_sideButtons[0].m_view->nominalWidth() + 2;
|
||||
int width1 = m_sideButtons[1].m_view->nominalWidth();
|
||||
cRect.location[0] += width0;
|
||||
cRect.size[0] -= (width0 + width1);
|
||||
|
||||
m_contentView.m_scissorRect.location[0] += width0;
|
||||
m_contentView.m_scissorRect.size[0] -= (width0 + width1);
|
||||
}
|
||||
m_contentView.m_view->resized(root, cRect, m_contentView.m_scissorRect);
|
||||
|
||||
if (m_style == Style::ThinIndicator) {
|
||||
float ratio = sub.size[1] / float(cRect.size[1]);
|
||||
m_drawInd = ratio < 1.f;
|
||||
if (m_drawInd) {
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
int barHeight = sub.size[1] * ratio;
|
||||
int scrollHeight = sub.size[1] - barHeight;
|
||||
float prog = m_scroll[1] / float(cRect.size[1] - sub.size[1]);
|
||||
int x = sub.size[0];
|
||||
int y = sub.size[1] - scrollHeight * prog;
|
||||
m_verts[0].m_pos.assign(x, y, 0);
|
||||
m_verts[1].m_pos.assign(x, y - barHeight, 0);
|
||||
m_verts[2].m_pos.assign(x + 2 * pf, y, 0);
|
||||
m_verts[3].m_pos.assign(x + 2 * pf, y - barHeight, 0);
|
||||
const zeus::CColor& color = rootView().themeData().scrollIndicator();
|
||||
for (int i = 0; i < 4; ++i)
|
||||
m_verts[i].m_color = color;
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
}
|
||||
} else if (m_style == Style::SideButtons && m_drawSideButtons) {
|
||||
boo::SWindowRect bRect = sub;
|
||||
bRect.size[0] = m_sideButtons[0].m_view->nominalWidth();
|
||||
bRect.size[1] = m_sideButtons[0].m_view->nominalHeight();
|
||||
m_sideButtons[0].m_view->resized(root, bRect);
|
||||
|
||||
bRect.size[0] = m_sideButtons[1].m_view->nominalWidth();
|
||||
bRect.size[1] = m_sideButtons[1].m_view->nominalHeight();
|
||||
bRect.location[0] += sub.size[0] - bRect.size[0];
|
||||
m_sideButtons[1].m_view->resized(root, bRect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
if (m_contentView.m_view) {
|
||||
m_contentView.m_view->draw(gfxQ);
|
||||
|
||||
if (m_style == Style::ThinIndicator && m_drawInd) {
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
} else if (m_style == Style::SideButtons && m_drawSideButtons) {
|
||||
m_sideButtons[0].m_view->draw(gfxQ);
|
||||
m_sideButtons[1].m_view->draw(gfxQ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
#include "specter/ViewResources.hpp"
|
||||
#include "specter/RootView.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::Space");
|
||||
|
||||
#define TRIANGLE_DIM 12
|
||||
|
@ -18,343 +17,282 @@ static logvisor::Module Log("specter::Space");
|
|||
|
||||
static const zeus::CColor TriColor = {0.75, 0.75, 0.75, 1.0};
|
||||
|
||||
Space::Space(ViewResources& res, View& parentView, ISpaceController& controller,
|
||||
Toolbar::Position tbPos, unsigned tbUnits)
|
||||
: View(res, parentView), m_controller(controller), m_tbPos(tbPos)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
return true;
|
||||
});
|
||||
setBackground(res.themeData().spaceBackground());
|
||||
if (controller.spaceSplitAllowed())
|
||||
m_cornerView.m_view.reset(new CornerView(res, *this, TriColor));
|
||||
if (tbPos != Toolbar::Position::None)
|
||||
m_toolbar.m_view.reset(new Toolbar(res, *this, tbPos, tbUnits));
|
||||
Space::Space(ViewResources& res, View& parentView, ISpaceController& controller, Toolbar::Position tbPos,
|
||||
unsigned tbUnits)
|
||||
: View(res, parentView), m_controller(controller), m_tbPos(tbPos) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
return true;
|
||||
});
|
||||
setBackground(res.themeData().spaceBackground());
|
||||
if (controller.spaceSplitAllowed())
|
||||
m_cornerView.m_view.reset(new CornerView(res, *this, TriColor));
|
||||
if (tbPos != Toolbar::Position::None)
|
||||
m_toolbar.m_view.reset(new Toolbar(res, *this, tbPos, tbUnits));
|
||||
}
|
||||
|
||||
Space::CornerView::CornerView(ViewResources& res, Space& space, const zeus::CColor& triColor)
|
||||
: View(res, space), m_space(space)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_vertexBinding.init(ctx, res, 34, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
float pf = res.pixelFactor();
|
||||
: View(res, space), m_space(space) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_vertexBinding.init(ctx, res, 34, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
float pf = res.pixelFactor();
|
||||
|
||||
zeus::CColor edgeColor1 = triColor * res.themeData().spaceTriangleShading1();
|
||||
zeus::CColor edgeColor2 = triColor * res.themeData().spaceTriangleShading2();
|
||||
View::SolidShaderVert verts[34];
|
||||
zeus::CColor edgeColor1 = triColor * res.themeData().spaceTriangleShading1();
|
||||
zeus::CColor edgeColor2 = triColor * res.themeData().spaceTriangleShading2();
|
||||
View::SolidShaderVert verts[34];
|
||||
|
||||
verts[0].m_pos.assign(0, TRIANGLE_DIM * pf, 0);
|
||||
verts[0].m_color = edgeColor1;
|
||||
verts[1].m_pos.assign(TRIANGLE_DIM * pf, 0, 0);
|
||||
verts[1].m_color = edgeColor1;
|
||||
verts[2].m_pos.assign(0, (TRIANGLE_DIM + 1) * pf, 0);
|
||||
verts[2].m_color = edgeColor1;
|
||||
verts[3].m_pos.assign((TRIANGLE_DIM + 1) * pf, 0, 0);
|
||||
verts[3].m_color = edgeColor1;
|
||||
verts[4] = verts[3];
|
||||
verts[0].m_pos.assign(0, TRIANGLE_DIM * pf, 0);
|
||||
verts[0].m_color = edgeColor1;
|
||||
verts[1].m_pos.assign(TRIANGLE_DIM * pf, 0, 0);
|
||||
verts[1].m_color = edgeColor1;
|
||||
verts[2].m_pos.assign(0, (TRIANGLE_DIM + 1) * pf, 0);
|
||||
verts[2].m_color = edgeColor1;
|
||||
verts[3].m_pos.assign((TRIANGLE_DIM + 1) * pf, 0, 0);
|
||||
verts[3].m_color = edgeColor1;
|
||||
verts[4] = verts[3];
|
||||
|
||||
verts[5].m_pos.assign(0, TRIANGLE_DIM1 * pf, 0);
|
||||
verts[5].m_color = edgeColor2;
|
||||
verts[6] = verts[5];
|
||||
verts[7].m_pos.assign(TRIANGLE_DIM1 * pf, 0, 0);
|
||||
verts[7].m_color = edgeColor2;
|
||||
verts[8].m_pos.assign(0, (TRIANGLE_DIM1 + 1) * pf, 0);
|
||||
verts[8].m_color = edgeColor2;
|
||||
verts[9].m_pos.assign((TRIANGLE_DIM1 + 1) * pf, 0, 0);
|
||||
verts[9].m_color = edgeColor2;
|
||||
verts[10] = verts[9];
|
||||
verts[5].m_pos.assign(0, TRIANGLE_DIM1 * pf, 0);
|
||||
verts[5].m_color = edgeColor2;
|
||||
verts[6] = verts[5];
|
||||
verts[7].m_pos.assign(TRIANGLE_DIM1 * pf, 0, 0);
|
||||
verts[7].m_color = edgeColor2;
|
||||
verts[8].m_pos.assign(0, (TRIANGLE_DIM1 + 1) * pf, 0);
|
||||
verts[8].m_color = edgeColor2;
|
||||
verts[9].m_pos.assign((TRIANGLE_DIM1 + 1) * pf, 0, 0);
|
||||
verts[9].m_color = edgeColor2;
|
||||
verts[10] = verts[9];
|
||||
|
||||
verts[11].m_pos.assign(0, TRIANGLE_DIM2 * pf, 0);
|
||||
verts[11].m_color = edgeColor2;
|
||||
verts[12] = verts[11];
|
||||
verts[13].m_pos.assign(TRIANGLE_DIM2 * pf, 0, 0);
|
||||
verts[13].m_color = edgeColor2;
|
||||
verts[14].m_pos.assign(0, (TRIANGLE_DIM2 + 1) * pf, 0);
|
||||
verts[14].m_color = edgeColor2;
|
||||
verts[15].m_pos.assign((TRIANGLE_DIM2 + 1) * pf, 0, 0);
|
||||
verts[15].m_color = edgeColor2;
|
||||
verts[16] = verts[15];
|
||||
verts[11].m_pos.assign(0, TRIANGLE_DIM2 * pf, 0);
|
||||
verts[11].m_color = edgeColor2;
|
||||
verts[12] = verts[11];
|
||||
verts[13].m_pos.assign(TRIANGLE_DIM2 * pf, 0, 0);
|
||||
verts[13].m_color = edgeColor2;
|
||||
verts[14].m_pos.assign(0, (TRIANGLE_DIM2 + 1) * pf, 0);
|
||||
verts[14].m_color = edgeColor2;
|
||||
verts[15].m_pos.assign((TRIANGLE_DIM2 + 1) * pf, 0, 0);
|
||||
verts[15].m_color = edgeColor2;
|
||||
verts[16] = verts[15];
|
||||
|
||||
verts[17].m_pos.assign(0, TRIANGLE_DIM3 * pf, 0);
|
||||
verts[17].m_color = edgeColor2;
|
||||
verts[18] = verts[17];
|
||||
verts[19].m_pos.assign(TRIANGLE_DIM3 * pf, 0, 0);
|
||||
verts[19].m_color = edgeColor2;
|
||||
verts[20].m_pos.assign(0, (TRIANGLE_DIM3 + 1) * pf, 0);
|
||||
verts[20].m_color = edgeColor2;
|
||||
verts[21].m_pos.assign((TRIANGLE_DIM3 + 1) * pf, 0, 0);
|
||||
verts[21].m_color = edgeColor2;
|
||||
verts[22] = verts[21];
|
||||
verts[17].m_pos.assign(0, TRIANGLE_DIM3 * pf, 0);
|
||||
verts[17].m_color = edgeColor2;
|
||||
verts[18] = verts[17];
|
||||
verts[19].m_pos.assign(TRIANGLE_DIM3 * pf, 0, 0);
|
||||
verts[19].m_color = edgeColor2;
|
||||
verts[20].m_pos.assign(0, (TRIANGLE_DIM3 + 1) * pf, 0);
|
||||
verts[20].m_color = edgeColor2;
|
||||
verts[21].m_pos.assign((TRIANGLE_DIM3 + 1) * pf, 0, 0);
|
||||
verts[21].m_color = edgeColor2;
|
||||
verts[22] = verts[21];
|
||||
|
||||
verts[23].m_pos.assign(0, TRIANGLE_DIM4 * pf, 0);
|
||||
verts[23].m_color = edgeColor2;
|
||||
verts[24] = verts[23];
|
||||
verts[25].m_pos.assign(TRIANGLE_DIM4 * pf, 0, 0);
|
||||
verts[25].m_color = edgeColor2;
|
||||
verts[26].m_pos.assign(0, (TRIANGLE_DIM4 + 1) * pf, 0);
|
||||
verts[26].m_color = edgeColor2;
|
||||
verts[27].m_pos.assign((TRIANGLE_DIM4 + 1) * pf, 0, 0);
|
||||
verts[27].m_color = edgeColor2;
|
||||
verts[28] = verts[27];
|
||||
verts[23].m_pos.assign(0, TRIANGLE_DIM4 * pf, 0);
|
||||
verts[23].m_color = edgeColor2;
|
||||
verts[24] = verts[23];
|
||||
verts[25].m_pos.assign(TRIANGLE_DIM4 * pf, 0, 0);
|
||||
verts[25].m_color = edgeColor2;
|
||||
verts[26].m_pos.assign(0, (TRIANGLE_DIM4 + 1) * pf, 0);
|
||||
verts[26].m_color = edgeColor2;
|
||||
verts[27].m_pos.assign((TRIANGLE_DIM4 + 1) * pf, 0, 0);
|
||||
verts[27].m_color = edgeColor2;
|
||||
verts[28] = verts[27];
|
||||
|
||||
verts[29].m_pos.assign(0, TRIANGLE_DIM5 * pf, 0);
|
||||
verts[29].m_color = edgeColor2;
|
||||
verts[30] = verts[29];
|
||||
verts[31].m_pos.assign(TRIANGLE_DIM5 * pf, 0, 0);
|
||||
verts[31].m_color = edgeColor2;
|
||||
verts[32].m_pos.assign(0, (TRIANGLE_DIM5 + 1) * pf, 0);
|
||||
verts[32].m_color = edgeColor2;
|
||||
verts[33].m_pos.assign((TRIANGLE_DIM5 + 1) * pf, 0, 0);
|
||||
verts[33].m_color = edgeColor2;
|
||||
verts[29].m_pos.assign(0, TRIANGLE_DIM5 * pf, 0);
|
||||
verts[29].m_color = edgeColor2;
|
||||
verts[30] = verts[29];
|
||||
verts[31].m_pos.assign(TRIANGLE_DIM5 * pf, 0, 0);
|
||||
verts[31].m_color = edgeColor2;
|
||||
verts[32].m_pos.assign(0, (TRIANGLE_DIM5 + 1) * pf, 0);
|
||||
verts[32].m_color = edgeColor2;
|
||||
verts[33].m_pos.assign((TRIANGLE_DIM5 + 1) * pf, 0, 0);
|
||||
verts[33].m_color = edgeColor2;
|
||||
|
||||
m_vertexBinding.load<decltype(verts)>(verts);
|
||||
m_vertexBinding.load<decltype(verts)>(verts);
|
||||
}
|
||||
|
||||
View* Space::setContentView(View* view)
|
||||
{
|
||||
View* ret = m_contentView.m_view;
|
||||
m_contentView.m_view = view;
|
||||
updateSize();
|
||||
return ret;
|
||||
View* Space::setContentView(View* view) {
|
||||
View* ret = m_contentView.m_view;
|
||||
m_contentView.m_view = view;
|
||||
updateSize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Space::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (m_cornerView.mouseDown(coord, button, mod))
|
||||
return;
|
||||
m_contentView.mouseDown(coord, button, mod);
|
||||
m_toolbar.mouseDown(coord, button, mod);
|
||||
void Space::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (m_cornerView.mouseDown(coord, button, mod))
|
||||
return;
|
||||
m_contentView.mouseDown(coord, button, mod);
|
||||
m_toolbar.mouseDown(coord, button, mod);
|
||||
}
|
||||
|
||||
void Space::CornerView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (button == boo::EMouseButton::Primary)
|
||||
{
|
||||
m_space.m_cornerDrag = true;
|
||||
m_space.m_cornerDragPoint[0] = coord.pixel[0];
|
||||
m_space.m_cornerDragPoint[1] = coord.pixel[1];
|
||||
rootView().setActiveDragView(&m_space);
|
||||
}
|
||||
void Space::CornerView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (button == boo::EMouseButton::Primary) {
|
||||
m_space.m_cornerDrag = true;
|
||||
m_space.m_cornerDragPoint[0] = coord.pixel[0];
|
||||
m_space.m_cornerDragPoint[1] = coord.pixel[1];
|
||||
rootView().setActiveDragView(&m_space);
|
||||
}
|
||||
}
|
||||
|
||||
void Space::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
m_cornerView.mouseUp(coord, button, mod);
|
||||
m_contentView.mouseUp(coord, button, mod);
|
||||
m_toolbar.mouseUp(coord, button, mod);
|
||||
void Space::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
m_cornerView.mouseUp(coord, button, mod);
|
||||
m_contentView.mouseUp(coord, button, mod);
|
||||
m_toolbar.mouseUp(coord, button, mod);
|
||||
}
|
||||
|
||||
void Space::CornerView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
if (button == boo::EMouseButton::Primary)
|
||||
{
|
||||
m_space.m_cornerDrag = false;
|
||||
rootView().unsetActiveDragView(&m_space);
|
||||
}
|
||||
void Space::CornerView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
if (button == boo::EMouseButton::Primary) {
|
||||
m_space.m_cornerDrag = false;
|
||||
rootView().unsetActiveDragView(&m_space);
|
||||
}
|
||||
}
|
||||
|
||||
void Space::mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (m_cornerDrag)
|
||||
{
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
if (coord.pixel[0] < m_cornerDragPoint[0] - CORNER_DRAG_THRESHOLD * pf)
|
||||
{
|
||||
if (m_cornerView.m_view->m_flip)
|
||||
{
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 1, coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Vertical, 0);
|
||||
if (sv)
|
||||
{
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().beginInteractiveJoin(sv, coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (coord.pixel[1] < m_cornerDragPoint[1] - CORNER_DRAG_THRESHOLD * pf)
|
||||
{
|
||||
if (m_cornerView.m_view->m_flip)
|
||||
{
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 1, coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Horizontal, 0);
|
||||
if (sv)
|
||||
{
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().beginInteractiveJoin(sv, coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (coord.pixel[0] > m_cornerDragPoint[0] + CORNER_DRAG_THRESHOLD * pf)
|
||||
{
|
||||
if (!m_cornerView.m_view->m_flip)
|
||||
{
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 0, coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Vertical, 1);
|
||||
if (sv)
|
||||
{
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().beginInteractiveJoin(sv, coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (coord.pixel[1] > m_cornerDragPoint[1] + CORNER_DRAG_THRESHOLD * pf)
|
||||
{
|
||||
if (!m_cornerView.m_view->m_flip)
|
||||
{
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 0, coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Horizontal, 1);
|
||||
if (sv)
|
||||
{
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().beginInteractiveJoin(sv, coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cornerView.mouseMove(coord);
|
||||
m_contentView.mouseMove(coord);
|
||||
m_toolbar.mouseMove(coord);
|
||||
}
|
||||
}
|
||||
|
||||
void Space::mouseEnter(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_cornerView.mouseEnter(coord);
|
||||
m_contentView.mouseEnter(coord);
|
||||
m_toolbar.mouseEnter(coord);
|
||||
}
|
||||
|
||||
void Space::CornerView::mouseEnter(const boo::SWindowCoord& coord)
|
||||
{
|
||||
rootView().setSpaceCornerHover(true);
|
||||
}
|
||||
|
||||
void Space::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_cornerView.mouseLeave(coord);
|
||||
m_contentView.mouseLeave(coord);
|
||||
m_toolbar.mouseLeave(coord);
|
||||
}
|
||||
|
||||
void Space::CornerView::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
rootView().setSpaceCornerHover(false);
|
||||
}
|
||||
|
||||
SplitView* Space::findSplitViewOnSide(SplitView::Axis axis, int side)
|
||||
{
|
||||
SplitView* ret = parentView().castToSplitView();
|
||||
View* test = this;
|
||||
while (ret)
|
||||
{
|
||||
if (ret->axis() != axis)
|
||||
return nullptr;
|
||||
if (ret->m_views[side ^ 1].m_view == test)
|
||||
return ret;
|
||||
else if (ret->m_views[side].m_view == test)
|
||||
test = ret;
|
||||
ret = ret->parentView().castToSplitView();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Space::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
|
||||
void Space::mouseMove(const boo::SWindowCoord& coord) {
|
||||
if (m_cornerDrag) {
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
if (m_cornerView.m_view)
|
||||
{
|
||||
boo::SWindowRect cornerRect = sub;
|
||||
int triDim = TRIANGLE_DIM * pf;
|
||||
cornerRect.size[0] = cornerRect.size[1] = triDim;
|
||||
if (cornerRect.location[0] < triDim && cornerRect.location[1] < triDim)
|
||||
{
|
||||
cornerRect.location[0] += sub.size[0] - triDim;
|
||||
cornerRect.location[1] += sub.size[1] - triDim;
|
||||
m_cornerView.m_view->resized(root, cornerRect, true);
|
||||
if (coord.pixel[0] < m_cornerDragPoint[0] - CORNER_DRAG_THRESHOLD * pf) {
|
||||
if (m_cornerView.m_view->m_flip) {
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 1, coord);
|
||||
} else {
|
||||
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Vertical, 0);
|
||||
if (sv) {
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().beginInteractiveJoin(sv, coord);
|
||||
}
|
||||
else
|
||||
m_cornerView.m_view->resized(root, cornerRect, false);
|
||||
}
|
||||
|
||||
boo::SWindowRect tbRect = sub;
|
||||
if (m_toolbar.m_view)
|
||||
{
|
||||
tbRect.size[1] = m_toolbar.m_view->nominalHeight();
|
||||
if (m_tbPos == Toolbar::Position::Top)
|
||||
tbRect.location[1] += sub.size[1] - tbRect.size[1];
|
||||
m_toolbar.m_view->resized(root, tbRect);
|
||||
}
|
||||
else
|
||||
tbRect.size[1] = 0;
|
||||
|
||||
if (m_contentView.m_view)
|
||||
{
|
||||
boo::SWindowRect contentRect = sub;
|
||||
if (m_tbPos == Toolbar::Position::Bottom)
|
||||
contentRect.location[1] += tbRect.size[1];
|
||||
contentRect.size[1] = sub.size[1] - tbRect.size[1];
|
||||
contentRect.size[1] = std::max(contentRect.size[1], 0);
|
||||
m_contentView.m_view->resized(root, contentRect);
|
||||
}
|
||||
} else if (coord.pixel[1] < m_cornerDragPoint[1] - CORNER_DRAG_THRESHOLD * pf) {
|
||||
if (m_cornerView.m_view->m_flip) {
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 1, coord);
|
||||
} else {
|
||||
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Horizontal, 0);
|
||||
if (sv) {
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().beginInteractiveJoin(sv, coord);
|
||||
}
|
||||
}
|
||||
} else if (coord.pixel[0] > m_cornerDragPoint[0] + CORNER_DRAG_THRESHOLD * pf) {
|
||||
if (!m_cornerView.m_view->m_flip) {
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Vertical, 0, coord);
|
||||
} else {
|
||||
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Vertical, 1);
|
||||
if (sv) {
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().beginInteractiveJoin(sv, coord);
|
||||
}
|
||||
}
|
||||
} else if (coord.pixel[1] > m_cornerDragPoint[1] + CORNER_DRAG_THRESHOLD * pf) {
|
||||
if (!m_cornerView.m_view->m_flip) {
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().viewManager().deferSpaceSplit(&m_controller, SplitView::Axis::Horizontal, 0, coord);
|
||||
} else {
|
||||
SplitView* sv = findSplitViewOnSide(SplitView::Axis::Horizontal, 1);
|
||||
if (sv) {
|
||||
rootView().mouseUp(coord, boo::EMouseButton::Primary, boo::EModifierKey::None);
|
||||
rootView().beginInteractiveJoin(sv, coord);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_cornerView.mouseMove(coord);
|
||||
m_contentView.mouseMove(coord);
|
||||
m_toolbar.mouseMove(coord);
|
||||
}
|
||||
}
|
||||
|
||||
void Space::CornerView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, bool flip)
|
||||
{
|
||||
m_flip = flip;
|
||||
if (flip)
|
||||
{
|
||||
m_viewVertBlock.m_mv[0][0] = -2.0f / root.size[0];
|
||||
m_viewVertBlock.m_mv[1][1] = -2.0f / root.size[1];
|
||||
m_viewVertBlock.m_mv[3][0] = (sub.location[0] + sub.size[0]) * -m_viewVertBlock.m_mv[0][0] - 1.0f;
|
||||
m_viewVertBlock.m_mv[3][1] = (sub.location[1] + sub.size[1]) * -m_viewVertBlock.m_mv[1][1] - 1.0f;
|
||||
View::resized(m_viewVertBlock, sub);
|
||||
}
|
||||
else
|
||||
View::resized(root, sub);
|
||||
void Space::mouseEnter(const boo::SWindowCoord& coord) {
|
||||
m_cornerView.mouseEnter(coord);
|
||||
m_contentView.mouseEnter(coord);
|
||||
m_toolbar.mouseEnter(coord);
|
||||
}
|
||||
|
||||
void Space::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
if (m_contentView.m_view)
|
||||
m_contentView.m_view->draw(gfxQ);
|
||||
if (m_toolbar.m_view)
|
||||
m_toolbar.m_view->draw(gfxQ);
|
||||
if (m_cornerView.m_view)
|
||||
m_cornerView.m_view->draw(gfxQ);
|
||||
void Space::CornerView::mouseEnter(const boo::SWindowCoord& coord) { rootView().setSpaceCornerHover(true); }
|
||||
|
||||
void Space::mouseLeave(const boo::SWindowCoord& coord) {
|
||||
m_cornerView.mouseLeave(coord);
|
||||
m_contentView.mouseLeave(coord);
|
||||
m_toolbar.mouseLeave(coord);
|
||||
}
|
||||
|
||||
void Space::CornerView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
gfxQ->setShaderDataBinding(m_vertexBinding);
|
||||
gfxQ->draw(0, 34);
|
||||
void Space::CornerView::mouseLeave(const boo::SWindowCoord& coord) { rootView().setSpaceCornerHover(false); }
|
||||
|
||||
SplitView* Space::findSplitViewOnSide(SplitView::Axis axis, int side) {
|
||||
SplitView* ret = parentView().castToSplitView();
|
||||
View* test = this;
|
||||
while (ret) {
|
||||
if (ret->axis() != axis)
|
||||
return nullptr;
|
||||
if (ret->m_views[side ^ 1].m_view == test)
|
||||
return ret;
|
||||
else if (ret->m_views[side].m_view == test)
|
||||
test = ret;
|
||||
ret = ret->parentView().castToSplitView();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Space::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
View::resized(root, sub);
|
||||
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
if (m_cornerView.m_view) {
|
||||
boo::SWindowRect cornerRect = sub;
|
||||
int triDim = TRIANGLE_DIM * pf;
|
||||
cornerRect.size[0] = cornerRect.size[1] = triDim;
|
||||
if (cornerRect.location[0] < triDim && cornerRect.location[1] < triDim) {
|
||||
cornerRect.location[0] += sub.size[0] - triDim;
|
||||
cornerRect.location[1] += sub.size[1] - triDim;
|
||||
m_cornerView.m_view->resized(root, cornerRect, true);
|
||||
} else
|
||||
m_cornerView.m_view->resized(root, cornerRect, false);
|
||||
}
|
||||
|
||||
boo::SWindowRect tbRect = sub;
|
||||
if (m_toolbar.m_view) {
|
||||
tbRect.size[1] = m_toolbar.m_view->nominalHeight();
|
||||
if (m_tbPos == Toolbar::Position::Top)
|
||||
tbRect.location[1] += sub.size[1] - tbRect.size[1];
|
||||
m_toolbar.m_view->resized(root, tbRect);
|
||||
} else
|
||||
tbRect.size[1] = 0;
|
||||
|
||||
if (m_contentView.m_view) {
|
||||
boo::SWindowRect contentRect = sub;
|
||||
if (m_tbPos == Toolbar::Position::Bottom)
|
||||
contentRect.location[1] += tbRect.size[1];
|
||||
contentRect.size[1] = sub.size[1] - tbRect.size[1];
|
||||
contentRect.size[1] = std::max(contentRect.size[1], 0);
|
||||
m_contentView.m_view->resized(root, contentRect);
|
||||
}
|
||||
}
|
||||
|
||||
void Space::CornerView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, bool flip) {
|
||||
m_flip = flip;
|
||||
if (flip) {
|
||||
m_viewVertBlock.m_mv[0][0] = -2.0f / root.size[0];
|
||||
m_viewVertBlock.m_mv[1][1] = -2.0f / root.size[1];
|
||||
m_viewVertBlock.m_mv[3][0] = (sub.location[0] + sub.size[0]) * -m_viewVertBlock.m_mv[0][0] - 1.0f;
|
||||
m_viewVertBlock.m_mv[3][1] = (sub.location[1] + sub.size[1]) * -m_viewVertBlock.m_mv[1][1] - 1.0f;
|
||||
View::resized(m_viewVertBlock, sub);
|
||||
} else
|
||||
View::resized(root, sub);
|
||||
}
|
||||
|
||||
void Space::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
View::draw(gfxQ);
|
||||
if (m_contentView.m_view)
|
||||
m_contentView.m_view->draw(gfxQ);
|
||||
if (m_toolbar.m_view)
|
||||
m_toolbar.m_view->draw(gfxQ);
|
||||
if (m_cornerView.m_view)
|
||||
m_cornerView.m_view->draw(gfxQ);
|
||||
}
|
||||
|
||||
void Space::CornerView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
gfxQ->setShaderDataBinding(m_vertexBinding);
|
||||
gfxQ->draw(0, 34);
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -4,492 +4,401 @@
|
|||
#include "specter/ViewResources.hpp"
|
||||
#include "specter/Space.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::SplitView");
|
||||
|
||||
static const zeus::RGBA32 Tex[3] =
|
||||
{
|
||||
{{0,0,0,64}},
|
||||
{{0,0,0,255}},
|
||||
{{255,255,255,64}}
|
||||
};
|
||||
static const zeus::RGBA32 Tex[3] = {{{0, 0, 0, 64}}, {{0, 0, 0, 255}}, {{255, 255, 255, 64}}};
|
||||
|
||||
void SplitView::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme)
|
||||
{
|
||||
m_shadingTex = ctx.newStaticTexture(3, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, Tex, 12);
|
||||
void SplitView::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme) {
|
||||
m_shadingTex = ctx.newStaticTexture(3, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, Tex, 12);
|
||||
}
|
||||
|
||||
SplitView::SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller,
|
||||
Axis axis, float split, int clearanceA, int clearanceB)
|
||||
: View(res, parentView), m_controller(controller), m_axis(axis), m_slide(split),
|
||||
m_clearanceA(clearanceA), m_clearanceB(clearanceB)
|
||||
{
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_splitBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_splitVertsBinding.init(ctx, res, 4, m_splitBlockBuf, res.m_splitRes.m_shadingTex.get());
|
||||
return true;
|
||||
});
|
||||
SplitView::SplitView(ViewResources& res, View& parentView, ISplitSpaceController* controller, Axis axis, float split,
|
||||
int clearanceA, int clearanceB)
|
||||
: View(res, parentView)
|
||||
, m_controller(controller)
|
||||
, m_axis(axis)
|
||||
, m_slide(split)
|
||||
, m_clearanceA(clearanceA)
|
||||
, m_clearanceB(clearanceB) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_splitBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_splitVertsBinding.init(ctx, res, 4, m_splitBlockBuf, res.m_splitRes.m_shadingTex.get());
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
View* SplitView::setContentView(int slot, View* view)
|
||||
{
|
||||
if (slot < 0 || slot > 1)
|
||||
Log.report(logvisor::Fatal, "out-of-range slot to RootView::SplitView::setContentView");
|
||||
View* ret = m_views[slot].m_view;
|
||||
m_views[slot].m_view = view;
|
||||
m_views[slot].m_mouseDown = 0;
|
||||
m_views[slot].m_mouseIn = false;
|
||||
updateSize();
|
||||
return ret;
|
||||
View* SplitView::setContentView(int slot, View* view) {
|
||||
if (slot < 0 || slot > 1)
|
||||
Log.report(logvisor::Fatal, "out-of-range slot to RootView::SplitView::setContentView");
|
||||
View* ret = m_views[slot].m_view;
|
||||
m_views[slot].m_view = view;
|
||||
m_views[slot].m_mouseDown = 0;
|
||||
m_views[slot].m_mouseIn = false;
|
||||
updateSize();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SplitView::_setSplit(float slide)
|
||||
{
|
||||
m_slide = std::min(std::max(slide, 0.0f), 1.0f);
|
||||
const boo::SWindowRect& rect = subRect();
|
||||
if (rect.size[0] && rect.size[1] &&
|
||||
(m_clearanceA >= 0 || m_clearanceB >= 0))
|
||||
{
|
||||
if (m_axis == Axis::Horizontal)
|
||||
{
|
||||
int slidePx = rect.size[1] * m_slide;
|
||||
if (m_clearanceA >= 0 && slidePx < m_clearanceA)
|
||||
m_slide = m_clearanceA / float(rect.size[1]);
|
||||
if (m_clearanceB >= 0 && (rect.size[1] - slidePx) < m_clearanceB)
|
||||
m_slide = 1.0 - m_clearanceB / float(rect.size[1]);
|
||||
}
|
||||
else if (m_axis == Axis::Vertical)
|
||||
{
|
||||
int slidePx = rect.size[0] * m_slide;
|
||||
if (m_clearanceA >= 0 && slidePx < m_clearanceA)
|
||||
m_slide = m_clearanceA / float(rect.size[0]);
|
||||
if (m_clearanceB >= 0 && (rect.size[0] - slidePx) < m_clearanceB)
|
||||
m_slide = 1.0 - m_clearanceB / float(rect.size[0]);
|
||||
}
|
||||
m_slide = std::min(std::max(m_slide, 0.0f), 1.0f);
|
||||
void SplitView::_setSplit(float slide) {
|
||||
m_slide = std::min(std::max(slide, 0.0f), 1.0f);
|
||||
const boo::SWindowRect& rect = subRect();
|
||||
if (rect.size[0] && rect.size[1] && (m_clearanceA >= 0 || m_clearanceB >= 0)) {
|
||||
if (m_axis == Axis::Horizontal) {
|
||||
int slidePx = rect.size[1] * m_slide;
|
||||
if (m_clearanceA >= 0 && slidePx < m_clearanceA)
|
||||
m_slide = m_clearanceA / float(rect.size[1]);
|
||||
if (m_clearanceB >= 0 && (rect.size[1] - slidePx) < m_clearanceB)
|
||||
m_slide = 1.0 - m_clearanceB / float(rect.size[1]);
|
||||
} else if (m_axis == Axis::Vertical) {
|
||||
int slidePx = rect.size[0] * m_slide;
|
||||
if (m_clearanceA >= 0 && slidePx < m_clearanceA)
|
||||
m_slide = m_clearanceA / float(rect.size[0]);
|
||||
if (m_clearanceB >= 0 && (rect.size[0] - slidePx) < m_clearanceB)
|
||||
m_slide = 1.0 - m_clearanceB / float(rect.size[0]);
|
||||
}
|
||||
if (m_controller)
|
||||
m_controller->updateSplit(m_slide);
|
||||
m_slide = std::min(std::max(m_slide, 0.0f), 1.0f);
|
||||
}
|
||||
if (m_controller)
|
||||
m_controller->updateSplit(m_slide);
|
||||
}
|
||||
|
||||
void SplitView::setSplit(float slide)
|
||||
{
|
||||
_setSplit(slide);
|
||||
updateSize();
|
||||
void SplitView::setSplit(float slide) {
|
||||
_setSplit(slide);
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void SplitView::setAxis(Axis axis)
|
||||
{
|
||||
m_axis = axis;
|
||||
setSplit(m_slide);
|
||||
void SplitView::setAxis(Axis axis) {
|
||||
m_axis = axis;
|
||||
setSplit(m_slide);
|
||||
}
|
||||
|
||||
bool SplitView::testSplitHover(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (m_axis == Axis::Horizontal)
|
||||
{
|
||||
int slidePx = subRect().size[1] * m_slide;
|
||||
if (abs(int(coord.pixel[1] - subRect().location[1]) - slidePx) < 4)
|
||||
return true;
|
||||
}
|
||||
else if (m_axis == Axis::Vertical)
|
||||
{
|
||||
int slidePx = subRect().size[0] * m_slide;
|
||||
if (abs(int(coord.pixel[0] - subRect().location[0]) - slidePx) < 4)
|
||||
return true;
|
||||
}
|
||||
bool SplitView::testSplitHover(const boo::SWindowCoord& coord) {
|
||||
if (m_axis == Axis::Horizontal) {
|
||||
int slidePx = subRect().size[1] * m_slide;
|
||||
if (abs(int(coord.pixel[1] - subRect().location[1]) - slidePx) < 4)
|
||||
return true;
|
||||
} else if (m_axis == Axis::Vertical) {
|
||||
int slidePx = subRect().size[0] * m_slide;
|
||||
if (abs(int(coord.pixel[0] - subRect().location[0]) - slidePx) < 4)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlotOut, SplitView*& splitOut, int& slotOut,
|
||||
boo::SWindowRect& rectOut, ArrowDir& dirOut, int forceSlot) {
|
||||
if (!subRect().coordInRect(coord))
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SplitView::testJoinArrowHover(const boo::SWindowCoord& coord, int& origSlotOut,
|
||||
SplitView*& splitOut, int& slotOut,
|
||||
boo::SWindowRect& rectOut, ArrowDir& dirOut, int forceSlot)
|
||||
{
|
||||
if (!subRect().coordInRect(coord))
|
||||
return false;
|
||||
int origDummy;
|
||||
ArrowDir dirDummy;
|
||||
|
||||
int origDummy;
|
||||
ArrowDir dirDummy;
|
||||
|
||||
if (m_axis == Axis::Horizontal)
|
||||
{
|
||||
int slidePx = subRect().size[1] * m_slide;
|
||||
if ((forceSlot == -1 && coord.pixel[1] - subRect().location[1] - slidePx >= 0) || forceSlot == 1)
|
||||
{
|
||||
origSlotOut = 0;
|
||||
dirOut = ArrowDir::Up;
|
||||
if (m_views[1].m_view)
|
||||
{
|
||||
SplitView* chSplit = m_views[1].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Horizontal)
|
||||
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0);
|
||||
}
|
||||
splitOut = this;
|
||||
slotOut = 1;
|
||||
rectOut = subRect();
|
||||
rectOut.location[1] += slidePx;
|
||||
rectOut.size[1] -= slidePx;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
origSlotOut = 1;
|
||||
dirOut = ArrowDir::Down;
|
||||
if (m_views[0].m_view)
|
||||
{
|
||||
SplitView* chSplit = m_views[0].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Horizontal)
|
||||
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1);
|
||||
}
|
||||
splitOut = this;
|
||||
slotOut = 0;
|
||||
rectOut = subRect();
|
||||
rectOut.size[1] = slidePx;
|
||||
return true;
|
||||
}
|
||||
if (m_axis == Axis::Horizontal) {
|
||||
int slidePx = subRect().size[1] * m_slide;
|
||||
if ((forceSlot == -1 && coord.pixel[1] - subRect().location[1] - slidePx >= 0) || forceSlot == 1) {
|
||||
origSlotOut = 0;
|
||||
dirOut = ArrowDir::Up;
|
||||
if (m_views[1].m_view) {
|
||||
SplitView* chSplit = m_views[1].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Horizontal)
|
||||
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0);
|
||||
}
|
||||
splitOut = this;
|
||||
slotOut = 1;
|
||||
rectOut = subRect();
|
||||
rectOut.location[1] += slidePx;
|
||||
rectOut.size[1] -= slidePx;
|
||||
return true;
|
||||
} else {
|
||||
origSlotOut = 1;
|
||||
dirOut = ArrowDir::Down;
|
||||
if (m_views[0].m_view) {
|
||||
SplitView* chSplit = m_views[0].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Horizontal)
|
||||
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1);
|
||||
}
|
||||
splitOut = this;
|
||||
slotOut = 0;
|
||||
rectOut = subRect();
|
||||
rectOut.size[1] = slidePx;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int slidePx = subRect().size[0] * m_slide;
|
||||
if ((forceSlot == -1 && coord.pixel[0] - subRect().location[0] - slidePx >= 0) || forceSlot == 1)
|
||||
{
|
||||
origSlotOut = 0;
|
||||
dirOut = ArrowDir::Right;
|
||||
if (m_views[1].m_view)
|
||||
{
|
||||
SplitView* chSplit = m_views[1].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Vertical)
|
||||
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0);
|
||||
}
|
||||
splitOut = this;
|
||||
slotOut = 1;
|
||||
rectOut = subRect();
|
||||
rectOut.location[0] += slidePx;
|
||||
rectOut.size[0] -= slidePx;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
origSlotOut = 1;
|
||||
dirOut = ArrowDir::Left;
|
||||
if (m_views[0].m_view)
|
||||
{
|
||||
SplitView* chSplit = m_views[0].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Vertical)
|
||||
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1);
|
||||
}
|
||||
splitOut = this;
|
||||
slotOut = 0;
|
||||
rectOut = subRect();
|
||||
rectOut.size[0] = slidePx;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
int slidePx = subRect().size[0] * m_slide;
|
||||
if ((forceSlot == -1 && coord.pixel[0] - subRect().location[0] - slidePx >= 0) || forceSlot == 1) {
|
||||
origSlotOut = 0;
|
||||
dirOut = ArrowDir::Right;
|
||||
if (m_views[1].m_view) {
|
||||
SplitView* chSplit = m_views[1].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Vertical)
|
||||
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 0);
|
||||
}
|
||||
splitOut = this;
|
||||
slotOut = 1;
|
||||
rectOut = subRect();
|
||||
rectOut.location[0] += slidePx;
|
||||
rectOut.size[0] -= slidePx;
|
||||
return true;
|
||||
} else {
|
||||
origSlotOut = 1;
|
||||
dirOut = ArrowDir::Left;
|
||||
if (m_views[0].m_view) {
|
||||
SplitView* chSplit = m_views[0].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Vertical)
|
||||
return chSplit->testJoinArrowHover(coord, origDummy, splitOut, slotOut, rectOut, dirDummy, 1);
|
||||
}
|
||||
splitOut = this;
|
||||
slotOut = 0;
|
||||
rectOut = subRect();
|
||||
rectOut.size[0] = slidePx;
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Horizontal)
|
||||
return chSplit->getJoinArrowHover(1, rectOut, dirOut);
|
||||
}
|
||||
rectOut = subRect();
|
||||
rectOut.size[1] = slidePx;
|
||||
dirOut = ArrowDir::Down;
|
||||
}
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Vertical)
|
||||
return chSplit->getJoinArrowHover(1, rectOut, dirOut);
|
||||
}
|
||||
rectOut = subRect();
|
||||
rectOut.size[0] = slidePx;
|
||||
dirOut = ArrowDir::Left;
|
||||
}
|
||||
} else {
|
||||
int slidePx = subRect().size[0] * m_slide;
|
||||
if (slot == 1) {
|
||||
if (m_views[1].m_view) {
|
||||
SplitView* chSplit = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
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;
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
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;
|
||||
}
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
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;
|
||||
}
|
||||
} 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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Horizontal)
|
||||
return chSplit->getSplitLineHover(1, rectOut, axisOut);
|
||||
}
|
||||
rectOut = subRect();
|
||||
rectOut.size[1] = slidePx;
|
||||
axisOut = Axis::Vertical;
|
||||
}
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
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 = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
if (chSplit && chSplit->m_axis == Axis::Vertical)
|
||||
return chSplit->getSplitLineHover(1, rectOut, axisOut);
|
||||
}
|
||||
rectOut = subRect();
|
||||
rectOut.size[0] = slidePx;
|
||||
axisOut = Axis::Horizontal;
|
||||
}
|
||||
} else {
|
||||
int slidePx = subRect().size[0] * m_slide;
|
||||
if (slot == 1) {
|
||||
if (m_views[1].m_view) {
|
||||
SplitView* chSplit = m_views[1].m_view->castToSplitView();
|
||||
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 = m_views[0].m_view->castToSplitView();
|
||||
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)
|
||||
{
|
||||
m_dragging = true;
|
||||
if (m_axis == Axis::Horizontal)
|
||||
setSplit((coord.pixel[1] - subRect().location[1]) / float(subRect().size[1]));
|
||||
else if (m_axis == Axis::Vertical)
|
||||
setSplit((coord.pixel[0] - subRect().location[0]) / float(subRect().size[0]));
|
||||
void SplitView::startDragSplit(const boo::SWindowCoord& coord) {
|
||||
m_dragging = true;
|
||||
if (m_axis == Axis::Horizontal)
|
||||
setSplit((coord.pixel[1] - subRect().location[1]) / float(subRect().size[1]));
|
||||
else if (m_axis == Axis::Vertical)
|
||||
setSplit((coord.pixel[0] - subRect().location[0]) / float(subRect().size[0]));
|
||||
}
|
||||
|
||||
void SplitView::endDragSplit()
|
||||
{
|
||||
m_dragging = false;
|
||||
void SplitView::endDragSplit() { m_dragging = false; }
|
||||
|
||||
void SplitView::moveDragSplit(const boo::SWindowCoord& coord) {
|
||||
if (m_axis == Axis::Horizontal)
|
||||
setSplit((coord.pixel[1] - subRect().location[1]) / float(subRect().size[1]));
|
||||
else if (m_axis == Axis::Vertical)
|
||||
setSplit((coord.pixel[0] - subRect().location[0]) / float(subRect().size[0]));
|
||||
}
|
||||
|
||||
void SplitView::moveDragSplit(const boo::SWindowCoord& coord)
|
||||
{
|
||||
if (m_axis == Axis::Horizontal)
|
||||
setSplit((coord.pixel[1] - subRect().location[1]) / float(subRect().size[1]));
|
||||
else if (m_axis == Axis::Vertical)
|
||||
setSplit((coord.pixel[0] - subRect().location[0]) / float(subRect().size[0]));
|
||||
void SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
m_views[0].mouseDown(coord, button, mod);
|
||||
m_views[1].mouseDown(coord, button, mod);
|
||||
}
|
||||
|
||||
void SplitView::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
m_views[0].mouseDown(coord, button, mod);
|
||||
m_views[1].mouseDown(coord, button, mod);
|
||||
void SplitView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
m_views[0].mouseUp(coord, button, mod);
|
||||
m_views[1].mouseUp(coord, button, mod);
|
||||
}
|
||||
|
||||
void SplitView::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
m_views[0].mouseUp(coord, button, mod);
|
||||
m_views[1].mouseUp(coord, button, mod);
|
||||
void SplitView::mouseMove(const boo::SWindowCoord& coord) {
|
||||
m_views[0].mouseMove(coord);
|
||||
m_views[1].mouseMove(coord);
|
||||
}
|
||||
|
||||
void SplitView::mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_views[0].mouseMove(coord);
|
||||
m_views[1].mouseMove(coord);
|
||||
void SplitView::mouseEnter(const boo::SWindowCoord& coord) {
|
||||
m_views[0].mouseEnter(coord);
|
||||
m_views[1].mouseEnter(coord);
|
||||
}
|
||||
|
||||
void SplitView::mouseEnter(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_views[0].mouseEnter(coord);
|
||||
m_views[1].mouseEnter(coord);
|
||||
void SplitView::mouseLeave(const boo::SWindowCoord& coord) {
|
||||
m_views[0].mouseLeave(coord);
|
||||
m_views[1].mouseLeave(coord);
|
||||
}
|
||||
|
||||
void SplitView::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_views[0].mouseLeave(coord);
|
||||
m_views[1].mouseLeave(coord);
|
||||
}
|
||||
|
||||
void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
_setSplit(m_slide);
|
||||
if (m_axis == Axis::Horizontal)
|
||||
{
|
||||
boo::SWindowRect ssub = sub;
|
||||
ssub.size[1] *= m_slide;
|
||||
if (m_views[0].m_view)
|
||||
m_views[0].m_view->resized(root, ssub);
|
||||
ssub.location[1] += ssub.size[1];
|
||||
ssub.size[1] = sub.size[1] - ssub.size[1];
|
||||
if (m_views[1].m_view)
|
||||
m_views[1].m_view->resized(root, ssub);
|
||||
ssub.location[1] -= 1;
|
||||
m_splitBlock.setViewRect(root, ssub);
|
||||
setHorizontalVerts(ssub.size[0]);
|
||||
}
|
||||
else if (m_axis == Axis::Vertical)
|
||||
{
|
||||
boo::SWindowRect ssub = sub;
|
||||
ssub.size[0] *= m_slide;
|
||||
if (m_views[0].m_view)
|
||||
m_views[0].m_view->resized(root, ssub);
|
||||
ssub.location[0] += ssub.size[0];
|
||||
ssub.size[0] = sub.size[0] - ssub.size[0];
|
||||
if (m_views[1].m_view)
|
||||
m_views[1].m_view->resized(root, ssub);
|
||||
ssub.location[0] -= 1;
|
||||
m_splitBlock.setViewRect(root, ssub);
|
||||
setVerticalVerts(ssub.size[1]);
|
||||
}
|
||||
m_splitBlockBuf.access().finalAssign(m_splitBlock);
|
||||
m_splitVertsBinding.load<decltype(m_splitVerts)>(m_splitVerts);
|
||||
}
|
||||
|
||||
void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
void SplitView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
View::resized(root, sub);
|
||||
_setSplit(m_slide);
|
||||
if (m_axis == Axis::Horizontal) {
|
||||
boo::SWindowRect ssub = sub;
|
||||
ssub.size[1] *= m_slide;
|
||||
if (m_views[0].m_view)
|
||||
m_views[0].m_view->draw(gfxQ);
|
||||
m_views[0].m_view->resized(root, ssub);
|
||||
ssub.location[1] += ssub.size[1];
|
||||
ssub.size[1] = sub.size[1] - ssub.size[1];
|
||||
if (m_views[1].m_view)
|
||||
m_views[1].m_view->draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_splitVertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
m_views[1].m_view->resized(root, ssub);
|
||||
ssub.location[1] -= 1;
|
||||
m_splitBlock.setViewRect(root, ssub);
|
||||
setHorizontalVerts(ssub.size[0]);
|
||||
} else if (m_axis == Axis::Vertical) {
|
||||
boo::SWindowRect ssub = sub;
|
||||
ssub.size[0] *= m_slide;
|
||||
if (m_views[0].m_view)
|
||||
m_views[0].m_view->resized(root, ssub);
|
||||
ssub.location[0] += ssub.size[0];
|
||||
ssub.size[0] = sub.size[0] - ssub.size[0];
|
||||
if (m_views[1].m_view)
|
||||
m_views[1].m_view->resized(root, ssub);
|
||||
ssub.location[0] -= 1;
|
||||
m_splitBlock.setViewRect(root, ssub);
|
||||
setVerticalVerts(ssub.size[1]);
|
||||
}
|
||||
m_splitBlockBuf.access().finalAssign(m_splitBlock);
|
||||
m_splitVertsBinding.load<decltype(m_splitVerts)>(m_splitVerts);
|
||||
}
|
||||
|
||||
void SplitView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
View::draw(gfxQ);
|
||||
if (m_views[0].m_view)
|
||||
m_views[0].m_view->draw(gfxQ);
|
||||
if (m_views[1].m_view)
|
||||
m_views[1].m_view->draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_splitVertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -7,336 +7,285 @@
|
|||
#include <freetype/internal/internal.h>
|
||||
#include <freetype/internal/ftobjs.h>
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::TextView");
|
||||
|
||||
void TextView::Resources::init(boo::IGraphicsDataFactory::Context& ctx, FontCache* fcache)
|
||||
{
|
||||
m_fcache = fcache;
|
||||
m_regular = hecl::conv->convert(ctx, Shader_SpecterTextViewShader{});
|
||||
m_subpixel = hecl::conv->convert(ctx, Shader_SpecterTextViewShaderSubpixel{});
|
||||
void TextView::Resources::init(boo::IGraphicsDataFactory::Context& ctx, FontCache* fcache) {
|
||||
m_fcache = fcache;
|
||||
m_regular = hecl::conv->convert(ctx, Shader_SpecterTextViewShader{});
|
||||
m_subpixel = hecl::conv->convert(ctx, Shader_SpecterTextViewShaderSubpixel{});
|
||||
}
|
||||
|
||||
void TextView::_commitResources(size_t capacity)
|
||||
{
|
||||
auto& res = rootView().viewRes();
|
||||
auto fontTex = m_fontAtlas.texture(res.m_factory);
|
||||
View::commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
void TextView::_commitResources(size_t capacity) {
|
||||
auto& res = rootView().viewRes();
|
||||
auto fontTex = m_fontAtlas.texture(res.m_factory);
|
||||
View::commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
buildResources(ctx, res);
|
||||
|
||||
if (capacity)
|
||||
{
|
||||
m_glyphBuf = res.m_textRes.m_glyphPool.allocateBlock(res.m_factory, capacity);
|
||||
if (capacity) {
|
||||
m_glyphBuf = res.m_textRes.m_glyphPool.allocateBlock(res.m_factory, capacity);
|
||||
|
||||
boo::ObjToken<boo::IShaderPipeline> shader;
|
||||
if (m_fontAtlas.subpixel())
|
||||
shader = res.m_textRes.m_subpixel;
|
||||
else
|
||||
shader = res.m_textRes.m_regular;
|
||||
boo::ObjToken<boo::IShaderPipeline> shader;
|
||||
if (m_fontAtlas.subpixel())
|
||||
shader = res.m_textRes.m_subpixel;
|
||||
else
|
||||
shader = res.m_textRes.m_regular;
|
||||
|
||||
auto vBufInfo = m_glyphBuf.getBufferInfo();
|
||||
auto uBufInfo = m_viewVertBlockBuf.getBufferInfo();
|
||||
boo::ObjToken<boo::IGraphicsBuffer> uBufs[] = {uBufInfo.first.get()};
|
||||
size_t uBufOffs[] = {size_t(uBufInfo.second)};
|
||||
size_t uBufSizes[] = {sizeof(ViewBlock)};
|
||||
boo::ObjToken<boo::ITexture> texs[] = {fontTex.get()};
|
||||
auto vBufInfo = m_glyphBuf.getBufferInfo();
|
||||
auto uBufInfo = m_viewVertBlockBuf.getBufferInfo();
|
||||
boo::ObjToken<boo::IGraphicsBuffer> uBufs[] = {uBufInfo.first.get()};
|
||||
size_t uBufOffs[] = {size_t(uBufInfo.second)};
|
||||
size_t uBufSizes[] = {sizeof(ViewBlock)};
|
||||
boo::ObjToken<boo::ITexture> texs[] = {fontTex.get()};
|
||||
|
||||
m_shaderBinding = ctx.newShaderDataBinding(shader, {}, vBufInfo.first.get(), nullptr, 1,
|
||||
uBufs, nullptr, uBufOffs, uBufSizes,
|
||||
1, texs, nullptr, nullptr, 0, vBufInfo.second);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
m_shaderBinding = ctx.newShaderDataBinding(shader, {}, vBufInfo.first.get(), nullptr, 1, uBufs, nullptr, uBufOffs,
|
||||
uBufSizes, 1, texs, nullptr, nullptr, 0, vBufInfo.second);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
TextView::TextView(ViewResources& res,
|
||||
View& parentView, const FontAtlas& font,
|
||||
Alignment align, size_t capacity)
|
||||
: View(res, parentView),
|
||||
m_capacity(capacity),
|
||||
m_fontAtlas(font),
|
||||
m_align(align)
|
||||
{
|
||||
if (size_t(hecl::VertexBufferPool<RenderGlyph>::bucketCapacity()) < capacity)
|
||||
Log.report(logvisor::Fatal, "bucket overflow [%" PRISize "/%" PRISize "]",
|
||||
capacity, hecl::VertexBufferPool<RenderGlyph>::bucketCapacity());
|
||||
TextView::TextView(ViewResources& res, View& parentView, const FontAtlas& font, Alignment align, size_t capacity)
|
||||
: View(res, parentView), m_capacity(capacity), m_fontAtlas(font), m_align(align) {
|
||||
if (size_t(hecl::VertexBufferPool<RenderGlyph>::bucketCapacity()) < capacity)
|
||||
Log.report(logvisor::Fatal, "bucket overflow [%" PRISize "/%" PRISize "]", capacity,
|
||||
hecl::VertexBufferPool<RenderGlyph>::bucketCapacity());
|
||||
|
||||
_commitResources(0);
|
||||
_commitResources(0);
|
||||
}
|
||||
|
||||
TextView::TextView(ViewResources& res, View& parentView, FontTag font, Alignment align, size_t capacity)
|
||||
: TextView(res, parentView, res.m_textRes.m_fcache->lookupAtlas(font), align, capacity) {}
|
||||
|
||||
TextView::RenderGlyph::RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const zeus::CColor& defaultColor)
|
||||
{
|
||||
m_pos[0].assign(adv + glyph.m_leftPadding, glyph.m_verticalOffset + glyph.m_height, 0.f);
|
||||
m_pos[1].assign(adv + glyph.m_leftPadding, glyph.m_verticalOffset, 0.f);
|
||||
m_pos[2].assign(adv + glyph.m_leftPadding + glyph.m_width, glyph.m_verticalOffset + glyph.m_height, 0.f);
|
||||
m_pos[3].assign(adv + glyph.m_leftPadding + glyph.m_width, glyph.m_verticalOffset, 0.f);
|
||||
m_uv[0].assign(glyph.m_uv[0], glyph.m_uv[1], glyph.m_layerFloat);
|
||||
m_uv[1].assign(glyph.m_uv[0], glyph.m_uv[3], glyph.m_layerFloat);
|
||||
m_uv[2].assign(glyph.m_uv[2], glyph.m_uv[1], glyph.m_layerFloat);
|
||||
m_uv[3].assign(glyph.m_uv[2], glyph.m_uv[3], glyph.m_layerFloat);
|
||||
m_color = defaultColor;
|
||||
adv += glyph.m_advance;
|
||||
TextView::RenderGlyph::RenderGlyph(int& adv, const FontAtlas::Glyph& glyph, const zeus::CColor& defaultColor) {
|
||||
m_pos[0].assign(adv + glyph.m_leftPadding, glyph.m_verticalOffset + glyph.m_height, 0.f);
|
||||
m_pos[1].assign(adv + glyph.m_leftPadding, glyph.m_verticalOffset, 0.f);
|
||||
m_pos[2].assign(adv + glyph.m_leftPadding + glyph.m_width, glyph.m_verticalOffset + glyph.m_height, 0.f);
|
||||
m_pos[3].assign(adv + glyph.m_leftPadding + glyph.m_width, glyph.m_verticalOffset, 0.f);
|
||||
m_uv[0].assign(glyph.m_uv[0], glyph.m_uv[1], glyph.m_layerFloat);
|
||||
m_uv[1].assign(glyph.m_uv[0], glyph.m_uv[3], glyph.m_layerFloat);
|
||||
m_uv[2].assign(glyph.m_uv[2], glyph.m_uv[1], glyph.m_layerFloat);
|
||||
m_uv[3].assign(glyph.m_uv[2], glyph.m_uv[3], glyph.m_layerFloat);
|
||||
m_color = defaultColor;
|
||||
adv += glyph.m_advance;
|
||||
}
|
||||
|
||||
int TextView::DoKern(FT_Pos val, const FontAtlas& atlas)
|
||||
{
|
||||
if (!val) return 0;
|
||||
val = FT_MulFix(val, atlas.FT_Xscale());
|
||||
int TextView::DoKern(FT_Pos val, const FontAtlas& atlas) {
|
||||
if (!val)
|
||||
return 0;
|
||||
val = FT_MulFix(val, atlas.FT_Xscale());
|
||||
|
||||
FT_Pos orig_x = val;
|
||||
FT_Pos orig_x = val;
|
||||
|
||||
/* we scale down kerning values for small ppem values */
|
||||
/* to avoid that rounding makes them too big. */
|
||||
/* `25' has been determined heuristically. */
|
||||
if (atlas.FT_XPPem() < 25)
|
||||
val = FT_MulDiv(orig_x, atlas.FT_XPPem(), 25);
|
||||
/* we scale down kerning values for small ppem values */
|
||||
/* to avoid that rounding makes them too big. */
|
||||
/* `25' has been determined heuristically. */
|
||||
if (atlas.FT_XPPem() < 25)
|
||||
val = FT_MulDiv(orig_x, atlas.FT_XPPem(), 25);
|
||||
|
||||
return FT_PIX_ROUND(val) >> 6;
|
||||
return FT_PIX_ROUND(val) >> 6;
|
||||
}
|
||||
|
||||
void TextView::typesetGlyphs(std::string_view str, const zeus::CColor& defaultColor)
|
||||
{
|
||||
UTF8Iterator it(str.begin());
|
||||
size_t charLen = str.size() ? std::min(it.countTo(str.end()), m_capacity) : 0;
|
||||
if (charLen > m_curSize)
|
||||
{
|
||||
m_curSize = charLen;
|
||||
_commitResources(charLen);
|
||||
void TextView::typesetGlyphs(std::string_view str, const zeus::CColor& defaultColor) {
|
||||
UTF8Iterator it(str.begin());
|
||||
size_t charLen = str.size() ? std::min(it.countTo(str.end()), m_capacity) : 0;
|
||||
if (charLen > m_curSize) {
|
||||
m_curSize = charLen;
|
||||
_commitResources(charLen);
|
||||
}
|
||||
|
||||
uint32_t lCh = -1;
|
||||
m_glyphs.clear();
|
||||
m_glyphs.reserve(charLen);
|
||||
m_glyphInfo.clear();
|
||||
m_glyphInfo.reserve(charLen);
|
||||
int adv = 0;
|
||||
|
||||
if (charLen) {
|
||||
for (; it.iter() < str.end(); ++it) {
|
||||
utf8proc_int32_t ch = *it;
|
||||
if (ch == -1) {
|
||||
Log.report(logvisor::Warning, "invalid UTF-8 char");
|
||||
break;
|
||||
}
|
||||
if (ch == '\n' || ch == '\0')
|
||||
break;
|
||||
|
||||
const FontAtlas::Glyph* glyph = m_fontAtlas.lookupGlyph(ch);
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
if (lCh != -1)
|
||||
adv += DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas);
|
||||
m_glyphs.emplace_back(adv, *glyph, defaultColor);
|
||||
m_glyphInfo.emplace_back(ch, glyph->m_width, glyph->m_height, adv);
|
||||
|
||||
lCh = glyph->m_glyphIdx;
|
||||
|
||||
if (m_glyphs.size() == m_capacity)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t lCh = -1;
|
||||
m_glyphs.clear();
|
||||
m_glyphs.reserve(charLen);
|
||||
m_glyphInfo.clear();
|
||||
m_glyphInfo.reserve(charLen);
|
||||
int adv = 0;
|
||||
|
||||
if (charLen)
|
||||
{
|
||||
for (; it.iter() < str.end() ; ++it)
|
||||
{
|
||||
utf8proc_int32_t ch = *it;
|
||||
if (ch == -1)
|
||||
{
|
||||
Log.report(logvisor::Warning, "invalid UTF-8 char");
|
||||
break;
|
||||
}
|
||||
if (ch == '\n' || ch == '\0')
|
||||
break;
|
||||
|
||||
const FontAtlas::Glyph* glyph = m_fontAtlas.lookupGlyph(ch);
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
if (lCh != -1)
|
||||
adv += DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas);
|
||||
m_glyphs.emplace_back(adv, *glyph, defaultColor);
|
||||
m_glyphInfo.emplace_back(ch, glyph->m_width, glyph->m_height, adv);
|
||||
|
||||
lCh = glyph->m_glyphIdx;
|
||||
|
||||
if (m_glyphs.size() == m_capacity)
|
||||
break;
|
||||
}
|
||||
if (m_align == Alignment::Right) {
|
||||
int adj = -adv;
|
||||
for (RenderGlyph& g : m_glyphs) {
|
||||
g.m_pos[0][0] += adj;
|
||||
g.m_pos[1][0] += adj;
|
||||
g.m_pos[2][0] += adj;
|
||||
g.m_pos[3][0] += adj;
|
||||
}
|
||||
|
||||
if (m_align == Alignment::Right)
|
||||
{
|
||||
int adj = -adv;
|
||||
for (RenderGlyph& g : m_glyphs)
|
||||
{
|
||||
g.m_pos[0][0] += adj;
|
||||
g.m_pos[1][0] += adj;
|
||||
g.m_pos[2][0] += adj;
|
||||
g.m_pos[3][0] += adj;
|
||||
}
|
||||
}
|
||||
else if (m_align == Alignment::Center)
|
||||
{
|
||||
int adj = -adv / 2;
|
||||
for (RenderGlyph& g : m_glyphs)
|
||||
{
|
||||
g.m_pos[0][0] += adj;
|
||||
g.m_pos[1][0] += adj;
|
||||
g.m_pos[2][0] += adj;
|
||||
g.m_pos[3][0] += adj;
|
||||
}
|
||||
} else if (m_align == Alignment::Center) {
|
||||
int adj = -adv / 2;
|
||||
for (RenderGlyph& g : m_glyphs) {
|
||||
g.m_pos[0][0] += adj;
|
||||
g.m_pos[1][0] += adj;
|
||||
g.m_pos[2][0] += adj;
|
||||
g.m_pos[3][0] += adj;
|
||||
}
|
||||
}
|
||||
|
||||
m_width = adv;
|
||||
invalidateGlyphs();
|
||||
updateSize();
|
||||
m_width = adv;
|
||||
invalidateGlyphs();
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void TextView::typesetGlyphs(std::wstring_view str, const zeus::CColor& defaultColor)
|
||||
{
|
||||
size_t charLen = std::min(str.size(), m_capacity);
|
||||
if (charLen > m_curSize)
|
||||
{
|
||||
m_curSize = charLen;
|
||||
_commitResources(charLen);
|
||||
void TextView::typesetGlyphs(std::wstring_view str, const zeus::CColor& defaultColor) {
|
||||
size_t charLen = std::min(str.size(), m_capacity);
|
||||
if (charLen > m_curSize) {
|
||||
m_curSize = charLen;
|
||||
_commitResources(charLen);
|
||||
}
|
||||
|
||||
uint32_t lCh = -1;
|
||||
m_glyphs.clear();
|
||||
m_glyphs.reserve(charLen);
|
||||
m_glyphInfo.clear();
|
||||
m_glyphInfo.reserve(charLen);
|
||||
int adv = 0;
|
||||
|
||||
for (wchar_t ch : str) {
|
||||
if (ch == L'\n')
|
||||
break;
|
||||
|
||||
const FontAtlas::Glyph* glyph = m_fontAtlas.lookupGlyph(ch);
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
if (lCh != -1)
|
||||
adv += DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas);
|
||||
m_glyphs.emplace_back(adv, *glyph, defaultColor);
|
||||
m_glyphInfo.emplace_back(ch, glyph->m_width, glyph->m_height, adv);
|
||||
|
||||
lCh = glyph->m_glyphIdx;
|
||||
|
||||
if (m_glyphs.size() == m_capacity)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_align == Alignment::Right) {
|
||||
int adj = -adv;
|
||||
for (RenderGlyph& g : m_glyphs) {
|
||||
g.m_pos[0][0] += adj;
|
||||
g.m_pos[1][0] += adj;
|
||||
g.m_pos[2][0] += adj;
|
||||
g.m_pos[3][0] += adj;
|
||||
}
|
||||
|
||||
uint32_t lCh = -1;
|
||||
m_glyphs.clear();
|
||||
m_glyphs.reserve(charLen);
|
||||
m_glyphInfo.clear();
|
||||
m_glyphInfo.reserve(charLen);
|
||||
int adv = 0;
|
||||
|
||||
for (wchar_t ch : str)
|
||||
{
|
||||
if (ch == L'\n')
|
||||
break;
|
||||
|
||||
const FontAtlas::Glyph* glyph = m_fontAtlas.lookupGlyph(ch);
|
||||
if (!glyph)
|
||||
continue;
|
||||
|
||||
if (lCh != -1)
|
||||
adv += DoKern(m_fontAtlas.lookupKern(lCh, glyph->m_glyphIdx), m_fontAtlas);
|
||||
m_glyphs.emplace_back(adv, *glyph, defaultColor);
|
||||
m_glyphInfo.emplace_back(ch, glyph->m_width, glyph->m_height, adv);
|
||||
|
||||
lCh = glyph->m_glyphIdx;
|
||||
|
||||
if (m_glyphs.size() == m_capacity)
|
||||
break;
|
||||
} else if (m_align == Alignment::Center) {
|
||||
int adj = -adv / 2;
|
||||
for (RenderGlyph& g : m_glyphs) {
|
||||
g.m_pos[0][0] += adj;
|
||||
g.m_pos[1][0] += adj;
|
||||
g.m_pos[2][0] += adj;
|
||||
g.m_pos[3][0] += adj;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_align == Alignment::Right)
|
||||
{
|
||||
int adj = -adv;
|
||||
for (RenderGlyph& g : m_glyphs)
|
||||
{
|
||||
g.m_pos[0][0] += adj;
|
||||
g.m_pos[1][0] += adj;
|
||||
g.m_pos[2][0] += adj;
|
||||
g.m_pos[3][0] += adj;
|
||||
}
|
||||
}
|
||||
else if (m_align == Alignment::Center)
|
||||
{
|
||||
int adj = -adv / 2;
|
||||
for (RenderGlyph& g : m_glyphs)
|
||||
{
|
||||
g.m_pos[0][0] += adj;
|
||||
g.m_pos[1][0] += adj;
|
||||
g.m_pos[2][0] += adj;
|
||||
g.m_pos[3][0] += adj;
|
||||
}
|
||||
}
|
||||
|
||||
m_width = adv;
|
||||
invalidateGlyphs();
|
||||
updateSize();
|
||||
m_width = adv;
|
||||
invalidateGlyphs();
|
||||
updateSize();
|
||||
}
|
||||
|
||||
void TextView::colorGlyphs(const zeus::CColor& newColor)
|
||||
{
|
||||
void TextView::colorGlyphs(const zeus::CColor& newColor) {
|
||||
for (RenderGlyph& glyph : m_glyphs)
|
||||
glyph.m_color = newColor;
|
||||
invalidateGlyphs();
|
||||
}
|
||||
|
||||
void TextView::colorGlyphsTypeOn(const zeus::CColor& newColor, float startInterval, float fadeTime) {}
|
||||
|
||||
void TextView::invalidateGlyphs() {
|
||||
if (m_glyphBuf) {
|
||||
RenderGlyph* out = m_glyphBuf.access();
|
||||
size_t i = 0;
|
||||
for (RenderGlyph& glyph : m_glyphs)
|
||||
glyph.m_color = newColor;
|
||||
invalidateGlyphs();
|
||||
out[i++] = glyph;
|
||||
}
|
||||
}
|
||||
|
||||
void TextView::colorGlyphsTypeOn(const zeus::CColor& newColor, float startInterval, float fadeTime)
|
||||
{
|
||||
void TextView::think() {}
|
||||
|
||||
void TextView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { View::resized(root, sub); }
|
||||
|
||||
void TextView::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
View::draw(gfxQ);
|
||||
if (m_glyphs.size()) {
|
||||
gfxQ->setShaderDataBinding(m_shaderBinding);
|
||||
gfxQ->drawInstances(0, 4, m_glyphs.size());
|
||||
}
|
||||
}
|
||||
|
||||
void TextView::invalidateGlyphs()
|
||||
{
|
||||
if (m_glyphBuf)
|
||||
{
|
||||
RenderGlyph* out = m_glyphBuf.access();
|
||||
size_t i = 0;
|
||||
for (RenderGlyph& glyph : m_glyphs)
|
||||
out[i++] = glyph;
|
||||
std::pair<int, int> TextView::queryGlyphDimensions(size_t pos) const {
|
||||
if (pos >= m_glyphInfo.size())
|
||||
Log.report(logvisor::Fatal, "TextView::queryGlyphWidth(%" PRISize ") out of bounds: %" PRISize, pos,
|
||||
m_glyphInfo.size());
|
||||
|
||||
return m_glyphInfo[pos].m_dims;
|
||||
}
|
||||
|
||||
size_t TextView::reverseSelectGlyph(int x) const {
|
||||
size_t ret = 0;
|
||||
size_t idx = 1;
|
||||
int minDelta = abs(x);
|
||||
for (const RenderGlyphInfo& info : m_glyphInfo) {
|
||||
int thisDelta = abs(info.m_adv - x);
|
||||
if (thisDelta < minDelta) {
|
||||
minDelta = thisDelta;
|
||||
ret = idx;
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TextView::think()
|
||||
{
|
||||
int TextView::queryReverseAdvance(size_t idx) const {
|
||||
if (idx > m_glyphInfo.size())
|
||||
Log.report(logvisor::Fatal, "TextView::queryReverseGlyph(%" PRISize ") out of inclusive bounds: %" PRISize, idx,
|
||||
m_glyphInfo.size());
|
||||
if (!idx)
|
||||
return 0;
|
||||
return m_glyphInfo[idx - 1].m_adv;
|
||||
}
|
||||
|
||||
void TextView::resized(const boo::SWindowRect &root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
std::pair<size_t, size_t> TextView::queryWholeWordRange(size_t idx) const {
|
||||
if (idx > m_glyphInfo.size())
|
||||
Log.report(logvisor::Fatal, "TextView::queryWholeWordRange(%" PRISize ") out of inclusive bounds: %" PRISize, idx,
|
||||
m_glyphInfo.size());
|
||||
if (m_glyphInfo.empty())
|
||||
return {0, 0};
|
||||
|
||||
if (idx == m_glyphInfo.size())
|
||||
--idx;
|
||||
|
||||
size_t begin = idx;
|
||||
while (begin > 0 && !m_glyphInfo[begin - 1].m_space)
|
||||
--begin;
|
||||
|
||||
size_t end = idx;
|
||||
while (end < m_glyphInfo.size() && !m_glyphInfo[end].m_space)
|
||||
++end;
|
||||
|
||||
return {begin, end - begin};
|
||||
}
|
||||
|
||||
void TextView::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
if (m_glyphs.size())
|
||||
{
|
||||
gfxQ->setShaderDataBinding(m_shaderBinding);
|
||||
gfxQ->drawInstances(0, 4, m_glyphs.size());
|
||||
}
|
||||
}
|
||||
|
||||
std::pair<int,int> TextView::queryGlyphDimensions(size_t pos) const
|
||||
{
|
||||
if (pos >= m_glyphInfo.size())
|
||||
Log.report(logvisor::Fatal,
|
||||
"TextView::queryGlyphWidth(%" PRISize ") out of bounds: %" PRISize,
|
||||
pos, m_glyphInfo.size());
|
||||
|
||||
return m_glyphInfo[pos].m_dims;
|
||||
}
|
||||
|
||||
size_t TextView::reverseSelectGlyph(int x) const
|
||||
{
|
||||
size_t ret = 0;
|
||||
size_t idx = 1;
|
||||
int minDelta = abs(x);
|
||||
for (const RenderGlyphInfo& info : m_glyphInfo)
|
||||
{
|
||||
int thisDelta = abs(info.m_adv-x);
|
||||
if (thisDelta < minDelta)
|
||||
{
|
||||
minDelta = thisDelta;
|
||||
ret = idx;
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int TextView::queryReverseAdvance(size_t idx) const
|
||||
{
|
||||
if (idx > m_glyphInfo.size())
|
||||
Log.report(logvisor::Fatal,
|
||||
"TextView::queryReverseGlyph(%" PRISize ") out of inclusive bounds: %" PRISize,
|
||||
idx, m_glyphInfo.size());
|
||||
if (!idx) return 0;
|
||||
return m_glyphInfo[idx-1].m_adv;
|
||||
}
|
||||
|
||||
std::pair<size_t,size_t> TextView::queryWholeWordRange(size_t idx) const
|
||||
{
|
||||
if (idx > m_glyphInfo.size())
|
||||
Log.report(logvisor::Fatal,
|
||||
"TextView::queryWholeWordRange(%" PRISize ") out of inclusive bounds: %" PRISize,
|
||||
idx, m_glyphInfo.size());
|
||||
if (m_glyphInfo.empty())
|
||||
return {0,0};
|
||||
|
||||
if (idx == m_glyphInfo.size())
|
||||
--idx;
|
||||
|
||||
size_t begin = idx;
|
||||
while (begin > 0 && !m_glyphInfo[begin-1].m_space)
|
||||
--begin;
|
||||
|
||||
size_t end = idx;
|
||||
while (end < m_glyphInfo.size() && !m_glyphInfo[end].m_space)
|
||||
++end;
|
||||
|
||||
return {begin, end-begin};
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace specter
|
||||
|
|
|
@ -5,180 +5,158 @@
|
|||
|
||||
#define TOOLBAR_PADDING 10
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::Space");
|
||||
|
||||
static const zeus::RGBA32 Tex[] =
|
||||
{
|
||||
{{255,255,255,64}},
|
||||
{{255,255,255,64}},
|
||||
{{0,0,0,64}},
|
||||
{{0,0,0,64}}
|
||||
};
|
||||
static const zeus::RGBA32 Tex[] = {{{255, 255, 255, 64}}, {{255, 255, 255, 64}}, {{0, 0, 0, 64}}, {{0, 0, 0, 64}}};
|
||||
|
||||
void Toolbar::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme)
|
||||
{
|
||||
m_shadingTex = ctx.newStaticTexture(4, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, Tex, 16);
|
||||
void Toolbar::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme) {
|
||||
m_shadingTex = ctx.newStaticTexture(4, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, Tex, 16);
|
||||
}
|
||||
|
||||
Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos, unsigned units)
|
||||
: View(res, parentView), m_units(units),
|
||||
m_nomGauge(res.pixelFactor() * SPECTER_TOOLBAR_GAUGE * units),
|
||||
m_padding(res.pixelFactor() * TOOLBAR_PADDING)
|
||||
{
|
||||
m_children.reserve(units);
|
||||
for (unsigned u=0 ; u<units ; ++u)
|
||||
m_children.emplace_back();
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_tbBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_vertsBinding.init(ctx, res, 10, m_tbBlockBuf, res.m_toolbarRes.m_shadingTex.get());
|
||||
return true;
|
||||
});
|
||||
setBackground(res.themeData().toolbarBackground());
|
||||
: View(res, parentView)
|
||||
, m_units(units)
|
||||
, m_nomGauge(res.pixelFactor() * SPECTER_TOOLBAR_GAUGE * units)
|
||||
, m_padding(res.pixelFactor() * TOOLBAR_PADDING) {
|
||||
m_children.reserve(units);
|
||||
for (unsigned u = 0; u < units; ++u)
|
||||
m_children.emplace_back();
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_tbBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_vertsBinding.init(ctx, res, 10, m_tbBlockBuf, res.m_toolbarRes.m_shadingTex.get());
|
||||
return true;
|
||||
});
|
||||
setBackground(res.themeData().toolbarBackground());
|
||||
}
|
||||
|
||||
void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseDown(coord, button, mod);
|
||||
void Toolbar::mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseDown(coord, button, mod);
|
||||
}
|
||||
|
||||
void Toolbar::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod)
|
||||
{
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseUp(coord, button, mod);
|
||||
void Toolbar::mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mod) {
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseUp(coord, button, mod);
|
||||
}
|
||||
|
||||
void Toolbar::mouseMove(const boo::SWindowCoord& coord)
|
||||
{
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseMove(coord);
|
||||
void Toolbar::mouseMove(const boo::SWindowCoord& coord) {
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseMove(coord);
|
||||
}
|
||||
|
||||
void Toolbar::mouseEnter(const boo::SWindowCoord& coord)
|
||||
{
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseEnter(coord);
|
||||
void Toolbar::mouseEnter(const boo::SWindowCoord& coord) {
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseEnter(coord);
|
||||
}
|
||||
|
||||
void Toolbar::mouseLeave(const boo::SWindowCoord& coord)
|
||||
{
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseLeave(coord);
|
||||
void Toolbar::mouseLeave(const boo::SWindowCoord& coord) {
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.mouseLeave(coord);
|
||||
}
|
||||
|
||||
void Toolbar::setHorizontalVerts(int width)
|
||||
{
|
||||
m_tbVerts[0].m_pos.assign(0, 1 + m_nomGauge, 0);
|
||||
m_tbVerts[0].m_uv.assign(0, 0);
|
||||
m_tbVerts[1].m_pos.assign(0, -1 + m_nomGauge, 0);
|
||||
m_tbVerts[1].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[2].m_pos.assign(width, 1 + m_nomGauge, 0);
|
||||
m_tbVerts[2].m_uv.assign(0, 0);
|
||||
m_tbVerts[3].m_pos.assign(width, -1 + m_nomGauge, 0);
|
||||
m_tbVerts[3].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[4].m_pos.assign(width, -1 + m_nomGauge, 0);
|
||||
m_tbVerts[4].m_uv.assign(0.5, 0);
|
||||
void Toolbar::setHorizontalVerts(int width) {
|
||||
m_tbVerts[0].m_pos.assign(0, 1 + m_nomGauge, 0);
|
||||
m_tbVerts[0].m_uv.assign(0, 0);
|
||||
m_tbVerts[1].m_pos.assign(0, -1 + m_nomGauge, 0);
|
||||
m_tbVerts[1].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[2].m_pos.assign(width, 1 + m_nomGauge, 0);
|
||||
m_tbVerts[2].m_uv.assign(0, 0);
|
||||
m_tbVerts[3].m_pos.assign(width, -1 + m_nomGauge, 0);
|
||||
m_tbVerts[3].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[4].m_pos.assign(width, -1 + m_nomGauge, 0);
|
||||
m_tbVerts[4].m_uv.assign(0.5, 0);
|
||||
|
||||
m_tbVerts[5].m_pos.assign(0, 1, 0);
|
||||
m_tbVerts[5].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[6].m_pos.assign(0, 1, 0);
|
||||
m_tbVerts[6].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[7].m_pos.assign(0, -1, 0);
|
||||
m_tbVerts[7].m_uv.assign(1, 0);
|
||||
m_tbVerts[8].m_pos.assign(width, 1, 0);
|
||||
m_tbVerts[8].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[9].m_pos.assign(width, -1, 0);
|
||||
m_tbVerts[9].m_uv.assign(1, 0);
|
||||
m_tbVerts[5].m_pos.assign(0, 1, 0);
|
||||
m_tbVerts[5].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[6].m_pos.assign(0, 1, 0);
|
||||
m_tbVerts[6].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[7].m_pos.assign(0, -1, 0);
|
||||
m_tbVerts[7].m_uv.assign(1, 0);
|
||||
m_tbVerts[8].m_pos.assign(width, 1, 0);
|
||||
m_tbVerts[8].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[9].m_pos.assign(width, -1, 0);
|
||||
m_tbVerts[9].m_uv.assign(1, 0);
|
||||
}
|
||||
|
||||
void Toolbar::setVerticalVerts(int height)
|
||||
{
|
||||
m_tbVerts[0].m_pos.assign(-1, height, 0);
|
||||
m_tbVerts[0].m_uv.assign(0, 0);
|
||||
m_tbVerts[1].m_pos.assign(-1, 0, 0);
|
||||
m_tbVerts[1].m_uv.assign(0, 0);
|
||||
m_tbVerts[2].m_pos.assign(1, height, 0);
|
||||
m_tbVerts[2].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[3].m_pos.assign(1, 0, 0);
|
||||
m_tbVerts[3].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[4].m_pos.assign(1, 0, 0);
|
||||
m_tbVerts[4].m_uv.assign(0.5, 0);
|
||||
void Toolbar::setVerticalVerts(int height) {
|
||||
m_tbVerts[0].m_pos.assign(-1, height, 0);
|
||||
m_tbVerts[0].m_uv.assign(0, 0);
|
||||
m_tbVerts[1].m_pos.assign(-1, 0, 0);
|
||||
m_tbVerts[1].m_uv.assign(0, 0);
|
||||
m_tbVerts[2].m_pos.assign(1, height, 0);
|
||||
m_tbVerts[2].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[3].m_pos.assign(1, 0, 0);
|
||||
m_tbVerts[3].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[4].m_pos.assign(1, 0, 0);
|
||||
m_tbVerts[4].m_uv.assign(0.5, 0);
|
||||
|
||||
m_tbVerts[5].m_pos.assign(-1 + m_nomGauge, height, 0);
|
||||
m_tbVerts[5].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[6].m_pos.assign(-1 + m_nomGauge, height, 0);
|
||||
m_tbVerts[6].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[7].m_pos.assign(-1 + m_nomGauge, 0, 0);
|
||||
m_tbVerts[7].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[8].m_pos.assign(1 + m_nomGauge, height, 0);
|
||||
m_tbVerts[8].m_uv.assign(1, 0);
|
||||
m_tbVerts[9].m_pos.assign(1 + m_nomGauge, 0, 0);
|
||||
m_tbVerts[9].m_uv.assign(1, 0);
|
||||
m_tbVerts[5].m_pos.assign(-1 + m_nomGauge, height, 0);
|
||||
m_tbVerts[5].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[6].m_pos.assign(-1 + m_nomGauge, height, 0);
|
||||
m_tbVerts[6].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[7].m_pos.assign(-1 + m_nomGauge, 0, 0);
|
||||
m_tbVerts[7].m_uv.assign(0.5, 0);
|
||||
m_tbVerts[8].m_pos.assign(1 + m_nomGauge, height, 0);
|
||||
m_tbVerts[8].m_uv.assign(1, 0);
|
||||
m_tbVerts[9].m_pos.assign(1 + m_nomGauge, 0, 0);
|
||||
m_tbVerts[9].m_uv.assign(1, 0);
|
||||
}
|
||||
|
||||
void Toolbar::push_back(View* v, unsigned unit)
|
||||
{
|
||||
if (unit >= m_units)
|
||||
Log.report(logvisor::Fatal, "unit %u out of range %u", unit, m_units);
|
||||
std::vector<ViewChild<View*>>& u = m_children[unit];
|
||||
u.emplace_back();
|
||||
u.back().m_view = v;
|
||||
void Toolbar::push_back(View* v, unsigned unit) {
|
||||
if (unit >= m_units)
|
||||
Log.report(logvisor::Fatal, "unit %u out of range %u", unit, m_units);
|
||||
std::vector<ViewChild<View*>>& u = m_children[unit];
|
||||
u.emplace_back();
|
||||
u.back().m_view = v;
|
||||
}
|
||||
|
||||
void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
setHorizontalVerts(sub.size[0]);
|
||||
m_vertsBinding.load<decltype(m_tbVerts)>(m_tbVerts);
|
||||
m_tbBlock.setViewRect(root, sub);
|
||||
m_tbBlockBuf.access().finalAssign(m_tbBlock);
|
||||
void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
View::resized(root, sub);
|
||||
setHorizontalVerts(sub.size[0]);
|
||||
m_vertsBinding.load<decltype(m_tbVerts)>(m_tbVerts);
|
||||
m_tbBlock.setViewRect(root, sub);
|
||||
m_tbBlockBuf.access().finalAssign(m_tbBlock);
|
||||
|
||||
float gaugeUnit = rootView().viewRes().pixelFactor() * SPECTER_TOOLBAR_GAUGE;
|
||||
float yOff = 0.0;
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
{
|
||||
boo::SWindowRect childRect = sub;
|
||||
boo::SWindowRect containRect = sub;
|
||||
containRect.location[0] += m_padding;
|
||||
containRect.size[0] -= m_padding * 2;
|
||||
containRect.size[1] = gaugeUnit;
|
||||
for (ViewChild<View*>& c : u)
|
||||
{
|
||||
c.m_view->containerResized(root, containRect);
|
||||
childRect.size[0] = c.m_view->nominalWidth();
|
||||
childRect.size[1] = c.m_view->nominalHeight();
|
||||
childRect.location[0] += m_padding;
|
||||
childRect.location[1] = sub.location[1] + (gaugeUnit - childRect.size[1]) / 2 - 1 + yOff;
|
||||
c.m_view->resized(root, childRect);
|
||||
childRect.location[0] += childRect.size[0];
|
||||
float gaugeUnit = rootView().viewRes().pixelFactor() * SPECTER_TOOLBAR_GAUGE;
|
||||
float yOff = 0.0;
|
||||
for (std::vector<ViewChild<View*>>& u : m_children) {
|
||||
boo::SWindowRect childRect = sub;
|
||||
boo::SWindowRect containRect = sub;
|
||||
containRect.location[0] += m_padding;
|
||||
containRect.size[0] -= m_padding * 2;
|
||||
containRect.size[1] = gaugeUnit;
|
||||
for (ViewChild<View*>& c : u) {
|
||||
c.m_view->containerResized(root, containRect);
|
||||
childRect.size[0] = c.m_view->nominalWidth();
|
||||
childRect.size[1] = c.m_view->nominalHeight();
|
||||
childRect.location[0] += m_padding;
|
||||
childRect.location[1] = sub.location[1] + (gaugeUnit - childRect.size[1]) / 2 - 1 + yOff;
|
||||
c.m_view->resized(root, childRect);
|
||||
childRect.location[0] += childRect.size[0];
|
||||
|
||||
containRect.location[0] += m_padding + childRect.size[0];
|
||||
containRect.size[0] -= m_padding + childRect.size[0];
|
||||
containRect.size[1] = gaugeUnit;
|
||||
}
|
||||
yOff += gaugeUnit;
|
||||
containRect.location[0] += m_padding + childRect.size[0];
|
||||
containRect.size[0] -= m_padding + childRect.size[0];
|
||||
containRect.size[1] = gaugeUnit;
|
||||
}
|
||||
yOff += gaugeUnit;
|
||||
}
|
||||
}
|
||||
|
||||
void Toolbar::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
View::draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 10);
|
||||
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.m_view->draw(gfxQ);
|
||||
}
|
||||
void Toolbar::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
View::draw(gfxQ);
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 10);
|
||||
|
||||
for (std::vector<ViewChild<View*>>& u : m_children)
|
||||
for (ViewChild<View*>& c : u)
|
||||
c.m_view->draw(gfxQ);
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -2,125 +2,116 @@
|
|||
#include "specter/ViewResources.hpp"
|
||||
#include "specter/RootView.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
|
||||
#define TOOLTIP_MAX_WIDTH 316
|
||||
#define TOOLTIP_MAX_TEXT_WIDTH 300
|
||||
|
||||
Tooltip::Tooltip(ViewResources& res, View& parentView, std::string_view title,
|
||||
std::string_view message)
|
||||
: View(res, parentView), m_titleStr(title), m_messageStr(message)
|
||||
{
|
||||
for (int i=0 ; i<16 ; ++i)
|
||||
m_ttVerts[i].m_color = res.themeData().tooltipBackground();
|
||||
Tooltip::Tooltip(ViewResources& res, View& parentView, std::string_view title, std::string_view message)
|
||||
: View(res, parentView), m_titleStr(title), m_messageStr(message) {
|
||||
for (int i = 0; i < 16; ++i)
|
||||
m_ttVerts[i].m_color = res.themeData().tooltipBackground();
|
||||
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
|
||||
{
|
||||
buildResources(ctx, res);
|
||||
m_ttBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_vertsBinding.init(ctx, res, 16, m_ttBlockBuf);
|
||||
return true;
|
||||
});
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_ttBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_vertsBinding.init(ctx, res, 16, m_ttBlockBuf);
|
||||
return true;
|
||||
});
|
||||
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
{
|
||||
m_cornersOutline[i].reset(new TextView(res, *this, res.m_curveFont, TextView::Alignment::Left, 1));
|
||||
m_cornersFilled[i].reset(new TextView(res, *this, res.m_curveFont, TextView::Alignment::Left, 1));
|
||||
}
|
||||
m_cornersOutline[0]->typesetGlyphs(L"\xF4F0");
|
||||
m_cornersFilled[0]->typesetGlyphs(L"\xF4F1", res.themeData().tooltipBackground());
|
||||
m_cornersOutline[1]->typesetGlyphs(L"\xF4F2");
|
||||
m_cornersFilled[1]->typesetGlyphs(L"\xF4F3", res.themeData().tooltipBackground());
|
||||
m_cornersOutline[2]->typesetGlyphs(L"\xF4F4");
|
||||
m_cornersFilled[2]->typesetGlyphs(L"\xF4F5", res.themeData().tooltipBackground());
|
||||
m_cornersOutline[3]->typesetGlyphs(L"\xF4F6");
|
||||
m_cornersFilled[3]->typesetGlyphs(L"\xF4F7", res.themeData().tooltipBackground());
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
m_cornersOutline[i].reset(new TextView(res, *this, res.m_curveFont, TextView::Alignment::Left, 1));
|
||||
m_cornersFilled[i].reset(new TextView(res, *this, res.m_curveFont, TextView::Alignment::Left, 1));
|
||||
}
|
||||
m_cornersOutline[0]->typesetGlyphs(L"\xF4F0");
|
||||
m_cornersFilled[0]->typesetGlyphs(L"\xF4F1", res.themeData().tooltipBackground());
|
||||
m_cornersOutline[1]->typesetGlyphs(L"\xF4F2");
|
||||
m_cornersFilled[1]->typesetGlyphs(L"\xF4F3", res.themeData().tooltipBackground());
|
||||
m_cornersOutline[2]->typesetGlyphs(L"\xF4F4");
|
||||
m_cornersFilled[2]->typesetGlyphs(L"\xF4F5", res.themeData().tooltipBackground());
|
||||
m_cornersOutline[3]->typesetGlyphs(L"\xF4F6");
|
||||
m_cornersFilled[3]->typesetGlyphs(L"\xF4F7", res.themeData().tooltipBackground());
|
||||
|
||||
m_title.reset(new TextView(res, *this, res.m_heading14));
|
||||
m_title->typesetGlyphs(m_titleStr);
|
||||
m_message.reset(new MultiLineTextView(res, *this, res.m_mainFont));
|
||||
m_message->typesetGlyphs(m_messageStr, zeus::CColor::skWhite,
|
||||
int(TOOLTIP_MAX_TEXT_WIDTH * res.pixelFactor()));
|
||||
m_title.reset(new TextView(res, *this, res.m_heading14));
|
||||
m_title->typesetGlyphs(m_titleStr);
|
||||
m_message.reset(new MultiLineTextView(res, *this, res.m_mainFont));
|
||||
m_message->typesetGlyphs(m_messageStr, zeus::CColor::skWhite, int(TOOLTIP_MAX_TEXT_WIDTH * res.pixelFactor()));
|
||||
|
||||
float pf = res.pixelFactor();
|
||||
std::pair<int,int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
m_nomWidth = std::min(int(TOOLTIP_MAX_WIDTH * pf),
|
||||
int(std::max(m_title->nominalWidth(), m_message->nominalWidth()) + margin.first * 2));
|
||||
m_nomHeight = m_title->nominalHeight() + m_message->nominalHeight() + margin.second * 3;
|
||||
float pf = res.pixelFactor();
|
||||
std::pair<int, int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
m_nomWidth = std::min(int(TOOLTIP_MAX_WIDTH * pf),
|
||||
int(std::max(m_title->nominalWidth(), m_message->nominalWidth()) + margin.first * 2));
|
||||
m_nomHeight = m_title->nominalHeight() + m_message->nominalHeight() + margin.second * 3;
|
||||
}
|
||||
|
||||
void Tooltip::setVerts(int width, int height, float pf)
|
||||
{
|
||||
std::pair<int,int> margin = m_cornersFilled[0]->queryGlyphDimensions(0);
|
||||
width = std::max(width, margin.first*2);
|
||||
height = std::max(height, margin.second*2);
|
||||
void Tooltip::setVerts(int width, int height, float pf) {
|
||||
std::pair<int, int> margin = m_cornersFilled[0]->queryGlyphDimensions(0);
|
||||
width = std::max(width, margin.first * 2);
|
||||
height = std::max(height, margin.second * 2);
|
||||
|
||||
m_ttVerts[0].m_pos.assign(0, height-margin.second, 0);
|
||||
m_ttVerts[1].m_pos.assign(0, margin.second, 0);
|
||||
m_ttVerts[2].m_pos.assign(width, height-margin.second, 0);
|
||||
m_ttVerts[3].m_pos.assign(width, margin.second, 0);
|
||||
m_ttVerts[4].m_pos.assign(width, margin.second, 0);
|
||||
m_ttVerts[0].m_pos.assign(0, height - margin.second, 0);
|
||||
m_ttVerts[1].m_pos.assign(0, margin.second, 0);
|
||||
m_ttVerts[2].m_pos.assign(width, height - margin.second, 0);
|
||||
m_ttVerts[3].m_pos.assign(width, margin.second, 0);
|
||||
m_ttVerts[4].m_pos.assign(width, margin.second, 0);
|
||||
|
||||
m_ttVerts[5].m_pos.assign(margin.first, height, 0);
|
||||
m_ttVerts[6].m_pos.assign(margin.first, height, 0);
|
||||
m_ttVerts[7].m_pos.assign(margin.first, height-margin.second, 0);
|
||||
m_ttVerts[8].m_pos.assign(width-margin.first, height, 0);
|
||||
m_ttVerts[9].m_pos.assign(width-margin.first, height-margin.second, 0);
|
||||
m_ttVerts[10].m_pos.assign(width-margin.first, height-margin.second, 0);
|
||||
m_ttVerts[5].m_pos.assign(margin.first, height, 0);
|
||||
m_ttVerts[6].m_pos.assign(margin.first, height, 0);
|
||||
m_ttVerts[7].m_pos.assign(margin.first, height - margin.second, 0);
|
||||
m_ttVerts[8].m_pos.assign(width - margin.first, height, 0);
|
||||
m_ttVerts[9].m_pos.assign(width - margin.first, height - margin.second, 0);
|
||||
m_ttVerts[10].m_pos.assign(width - margin.first, height - margin.second, 0);
|
||||
|
||||
m_ttVerts[11].m_pos.assign(margin.first, margin.second, 0);
|
||||
m_ttVerts[12].m_pos.assign(margin.first, margin.second, 0);
|
||||
m_ttVerts[13].m_pos.assign(margin.first, 0, 0);
|
||||
m_ttVerts[14].m_pos.assign(width-margin.first, margin.second, 0);
|
||||
m_ttVerts[15].m_pos.assign(width-margin.first, 0, 0);
|
||||
m_ttVerts[11].m_pos.assign(margin.first, margin.second, 0);
|
||||
m_ttVerts[12].m_pos.assign(margin.first, margin.second, 0);
|
||||
m_ttVerts[13].m_pos.assign(margin.first, 0, 0);
|
||||
m_ttVerts[14].m_pos.assign(width - margin.first, margin.second, 0);
|
||||
m_ttVerts[15].m_pos.assign(width - margin.first, 0, 0);
|
||||
|
||||
m_vertsBinding.load<decltype(m_ttVerts)>(m_ttVerts);
|
||||
m_vertsBinding.load<decltype(m_ttVerts)>(m_ttVerts);
|
||||
}
|
||||
|
||||
void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
View::resized(root, sub);
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
setVerts(m_nomWidth, m_nomHeight, pf);
|
||||
m_ttBlock.setViewRect(root, sub);
|
||||
m_ttBlockBuf.access().finalAssign(m_ttBlock);
|
||||
void Tooltip::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
View::resized(root, sub);
|
||||
float pf = rootView().viewRes().pixelFactor();
|
||||
setVerts(m_nomWidth, m_nomHeight, pf);
|
||||
m_ttBlock.setViewRect(root, sub);
|
||||
m_ttBlockBuf.access().finalAssign(m_ttBlock);
|
||||
|
||||
std::pair<int,int> margin = m_cornersFilled[0]->queryGlyphDimensions(0);
|
||||
std::pair<int, int> margin = m_cornersFilled[0]->queryGlyphDimensions(0);
|
||||
|
||||
boo::SWindowRect textRect = sub;
|
||||
textRect.location[0] += margin.first;
|
||||
textRect.location[1] += margin.second * 1.5;
|
||||
m_message->resized(root, textRect);
|
||||
boo::SWindowRect textRect = sub;
|
||||
textRect.location[0] += margin.first;
|
||||
textRect.location[1] += margin.second * 1.5;
|
||||
m_message->resized(root, textRect);
|
||||
|
||||
textRect.location[1] += m_message->nominalHeight() + margin.second;
|
||||
m_title->resized(root, textRect);
|
||||
textRect.location[1] += m_message->nominalHeight() + margin.second;
|
||||
m_title->resized(root, textRect);
|
||||
|
||||
boo::SWindowRect cornerRect = sub;
|
||||
cornerRect.location[1] += m_nomHeight - margin.second; // Upper left
|
||||
m_cornersOutline[0]->resized(root, cornerRect);
|
||||
m_cornersFilled[0]->resized(root, cornerRect);
|
||||
cornerRect.location[0] += m_nomWidth - margin.first; // Upper right
|
||||
m_cornersOutline[1]->resized(root, cornerRect);
|
||||
m_cornersFilled[1]->resized(root, cornerRect);
|
||||
cornerRect.location[1] = sub.location[1]; // Lower right
|
||||
m_cornersOutline[2]->resized(root, cornerRect);
|
||||
m_cornersFilled[2]->resized(root, cornerRect);
|
||||
cornerRect.location[0] = sub.location[0]; // Lower left
|
||||
m_cornersOutline[3]->resized(root, cornerRect);
|
||||
m_cornersFilled[3]->resized(root, cornerRect);
|
||||
boo::SWindowRect cornerRect = sub;
|
||||
cornerRect.location[1] += m_nomHeight - margin.second; // Upper left
|
||||
m_cornersOutline[0]->resized(root, cornerRect);
|
||||
m_cornersFilled[0]->resized(root, cornerRect);
|
||||
cornerRect.location[0] += m_nomWidth - margin.first; // Upper right
|
||||
m_cornersOutline[1]->resized(root, cornerRect);
|
||||
m_cornersFilled[1]->resized(root, cornerRect);
|
||||
cornerRect.location[1] = sub.location[1]; // Lower right
|
||||
m_cornersOutline[2]->resized(root, cornerRect);
|
||||
m_cornersFilled[2]->resized(root, cornerRect);
|
||||
cornerRect.location[0] = sub.location[0]; // Lower left
|
||||
m_cornersOutline[3]->resized(root, cornerRect);
|
||||
m_cornersFilled[3]->resized(root, cornerRect);
|
||||
}
|
||||
|
||||
void Tooltip::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 16);
|
||||
void Tooltip::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
gfxQ->setShaderDataBinding(m_vertsBinding);
|
||||
gfxQ->draw(0, 16);
|
||||
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
m_cornersFilled[i]->draw(gfxQ);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
m_cornersFilled[i]->draw(gfxQ);
|
||||
|
||||
m_title->draw(gfxQ);
|
||||
m_message->draw(gfxQ);
|
||||
m_title->draw(gfxQ);
|
||||
m_message->draw(gfxQ);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace specter
|
||||
|
|
|
@ -1,69 +1,57 @@
|
|||
#include "specter/Translator.hpp"
|
||||
#include "logvisor/logvisor.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::Translator");
|
||||
|
||||
Locale::Locale(std::string_view name, std::string_view fullName,
|
||||
const unsigned char* yamlSource, size_t yamlLength)
|
||||
: m_name(name), m_fullName(fullName)
|
||||
{
|
||||
athena::io::YAMLDocReader reader;
|
||||
yaml_parser_set_input_string(reader.getParser(), yamlSource, yamlLength);
|
||||
reader.parse(nullptr);
|
||||
m_rootNode = reader.releaseRootNode();
|
||||
if (m_rootNode)
|
||||
{
|
||||
m_langNode = m_rootNode->findMapChild(name.data());
|
||||
if (!m_langNode)
|
||||
Log.report(logvisor::Fatal, "no root node '%s' found in locale", name.data());
|
||||
}
|
||||
else
|
||||
Log.report(logvisor::Warning, "locale empty");
|
||||
Locale::Locale(std::string_view name, std::string_view fullName, const unsigned char* yamlSource, size_t yamlLength)
|
||||
: m_name(name), m_fullName(fullName) {
|
||||
athena::io::YAMLDocReader reader;
|
||||
yaml_parser_set_input_string(reader.getParser(), yamlSource, yamlLength);
|
||||
reader.parse(nullptr);
|
||||
m_rootNode = reader.releaseRootNode();
|
||||
if (m_rootNode) {
|
||||
m_langNode = m_rootNode->findMapChild(name.data());
|
||||
if (!m_langNode)
|
||||
Log.report(logvisor::Fatal, "no root node '%s' found in locale", name.data());
|
||||
} else
|
||||
Log.report(logvisor::Warning, "locale empty");
|
||||
}
|
||||
|
||||
void Translator::setLocale(const Locale* targetLocale)
|
||||
{
|
||||
if (!targetLocale)
|
||||
Log.report(logvisor::Fatal, "null locale");
|
||||
m_targetLocale = targetLocale;
|
||||
void Translator::setLocale(const Locale* targetLocale) {
|
||||
if (!targetLocale)
|
||||
Log.report(logvisor::Fatal, "null locale");
|
||||
m_targetLocale = targetLocale;
|
||||
}
|
||||
|
||||
static std::string_view RecursiveLookup(const athena::io::YAMLNode* node,
|
||||
std::string_view::const_iterator start,
|
||||
std::string_view::const_iterator end)
|
||||
{
|
||||
for (std::string_view::const_iterator it = start ; it != end ; ++it)
|
||||
{
|
||||
if (*it == '/')
|
||||
{
|
||||
const athena::io::YAMLNode* ch = node->findMapChild(std::string(start, it));
|
||||
if (!ch)
|
||||
return nullptr;
|
||||
return RecursiveLookup(ch, it+1, end);
|
||||
}
|
||||
}
|
||||
const athena::io::YAMLNode* ch = node->findMapChild(std::string(start, end));
|
||||
if (!ch)
|
||||
return {};
|
||||
return ch->m_scalarString;
|
||||
}
|
||||
|
||||
std::string_view Translator::translate(std::string_view key) const
|
||||
{
|
||||
if (!m_targetLocale->rootNode())
|
||||
static std::string_view RecursiveLookup(const athena::io::YAMLNode* node, std::string_view::const_iterator start,
|
||||
std::string_view::const_iterator end) {
|
||||
for (std::string_view::const_iterator it = start; it != end; ++it) {
|
||||
if (*it == '/') {
|
||||
const athena::io::YAMLNode* ch = node->findMapChild(std::string(start, it));
|
||||
if (!ch)
|
||||
return nullptr;
|
||||
|
||||
return RecursiveLookup(m_targetLocale->rootNode(), key.cbegin(), key.cend());
|
||||
return RecursiveLookup(ch, it + 1, end);
|
||||
}
|
||||
}
|
||||
const athena::io::YAMLNode* ch = node->findMapChild(std::string(start, end));
|
||||
if (!ch)
|
||||
return {};
|
||||
return ch->m_scalarString;
|
||||
}
|
||||
|
||||
std::string_view Translator::translateOr(std::string_view key, std::string_view vor) const
|
||||
{
|
||||
std::string_view find = translate(key);
|
||||
if (!find.empty())
|
||||
return find;
|
||||
return vor;
|
||||
std::string_view Translator::translate(std::string_view key) const {
|
||||
if (!m_targetLocale->rootNode())
|
||||
return nullptr;
|
||||
|
||||
return RecursiveLookup(m_targetLocale->rootNode(), key.cbegin(), key.cend());
|
||||
}
|
||||
|
||||
std::string_view Translator::translateOr(std::string_view key, std::string_view vor) const {
|
||||
std::string_view find = translate(key);
|
||||
if (!find.empty())
|
||||
return find;
|
||||
return vor;
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -3,121 +3,98 @@
|
|||
#include "specter/RootView.hpp"
|
||||
#include "hecl/Pipeline.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::View");
|
||||
|
||||
zeus::CMatrix4f g_PlatformMatrix;
|
||||
|
||||
void View::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme)
|
||||
{
|
||||
switch (ctx.platform())
|
||||
{
|
||||
case boo::IGraphicsDataFactory::Platform::Vulkan:
|
||||
g_PlatformMatrix.m[1][1] = -1.f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_solidShader = hecl::conv->convert(ctx, Shader_SpecterViewShaderSolid{});
|
||||
m_texShader = hecl::conv->convert(ctx, Shader_SpecterViewShaderTex{});
|
||||
void View::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme) {
|
||||
switch (ctx.platform()) {
|
||||
case boo::IGraphicsDataFactory::Platform::Vulkan:
|
||||
g_PlatformMatrix.m[1][1] = -1.f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
m_solidShader = hecl::conv->convert(ctx, Shader_SpecterViewShaderSolid{});
|
||||
m_texShader = hecl::conv->convert(ctx, Shader_SpecterViewShaderTex{});
|
||||
}
|
||||
|
||||
void View::buildResources(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res)
|
||||
{
|
||||
m_viewVertBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_bgVertsBinding.init(ctx, res, 4, m_viewVertBlockBuf);
|
||||
void View::buildResources(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res) {
|
||||
m_viewVertBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
m_bgVertsBinding.init(ctx, res, 4, m_viewVertBlockBuf);
|
||||
}
|
||||
|
||||
View::View(ViewResources& res)
|
||||
: m_rootView(*static_cast<RootView*>(this)),
|
||||
m_parentView(*static_cast<RootView*>(this)) {}
|
||||
: m_rootView(*static_cast<RootView*>(this)), m_parentView(*static_cast<RootView*>(this)) {}
|
||||
|
||||
View::View(ViewResources& res, View& parentView)
|
||||
: m_rootView(parentView.rootView()),
|
||||
m_parentView(parentView) {}
|
||||
View::View(ViewResources& res, View& parentView) : m_rootView(parentView.rootView()), m_parentView(parentView) {}
|
||||
|
||||
void View::updateSize()
|
||||
{
|
||||
resized(m_rootView.rootRect(), m_subRect);
|
||||
void View::updateSize() { resized(m_rootView.rootRect(), m_subRect); }
|
||||
|
||||
void View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
m_subRect = sub;
|
||||
m_viewVertBlock.setViewRect(root, sub);
|
||||
m_bgRect[0].m_pos.assign(0.f, sub.size[1], 0.f);
|
||||
m_bgRect[1].m_pos.assign(0.f, 0.f, 0.f);
|
||||
m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
|
||||
m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock);
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
}
|
||||
|
||||
void View::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||
{
|
||||
m_subRect = sub;
|
||||
m_viewVertBlock.setViewRect(root, sub);
|
||||
m_bgRect[0].m_pos.assign(0.f, sub.size[1], 0.f);
|
||||
m_bgRect[1].m_pos.assign(0.f, 0.f, 0.f);
|
||||
m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
|
||||
m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(m_viewVertBlock);
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
void View::resized(const ViewBlock& vb, const boo::SWindowRect& sub) {
|
||||
m_subRect = sub;
|
||||
m_bgRect[0].m_pos.assign(0.f, sub.size[1], 0.f);
|
||||
m_bgRect[1].m_pos.assign(0.f, 0.f, 0.f);
|
||||
m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
|
||||
m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(vb);
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
}
|
||||
|
||||
void View::resized(const ViewBlock& vb, const boo::SWindowRect& sub)
|
||||
{
|
||||
m_subRect = sub;
|
||||
m_bgRect[0].m_pos.assign(0.f, sub.size[1], 0.f);
|
||||
m_bgRect[1].m_pos.assign(0.f, 0.f, 0.f);
|
||||
m_bgRect[2].m_pos.assign(sub.size[0], sub.size[1], 0.f);
|
||||
m_bgRect[3].m_pos.assign(sub.size[0], 0.f, 0.f);
|
||||
if (m_viewVertBlockBuf)
|
||||
m_viewVertBlockBuf.access().finalAssign(vb);
|
||||
m_bgVertsBinding.load<decltype(m_bgRect)>(m_bgRect);
|
||||
void View::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
||||
if (m_bgVertsBinding.m_shaderBinding) {
|
||||
gfxQ->setShaderDataBinding(m_bgVertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
void View::draw(boo::IGraphicsCommandQueue* gfxQ)
|
||||
{
|
||||
if (m_bgVertsBinding.m_shaderBinding)
|
||||
{
|
||||
gfxQ->setShaderDataBinding(m_bgVertsBinding);
|
||||
gfxQ->draw(0, 4);
|
||||
}
|
||||
void View::commitResources(ViewResources& res, const boo::FactoryCommitFunc& commitFunc) {
|
||||
res.m_factory->commitTransaction(commitFunc BooTrace);
|
||||
}
|
||||
|
||||
void View::commitResources(ViewResources& res, const boo::FactoryCommitFunc& commitFunc)
|
||||
{
|
||||
res.m_factory->commitTransaction(commitFunc BooTrace);
|
||||
void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res, size_t count,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf) {
|
||||
m_vertsBuf = res.m_viewRes.m_solidPool.allocateBlock(res.m_factory, count);
|
||||
auto vBufInfo = m_vertsBuf.getBufferInfo();
|
||||
auto uBufInfo = viewBlockBuf.getBufferInfo();
|
||||
|
||||
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {uBufInfo.first.get()};
|
||||
size_t bufOffs[] = {size_t(uBufInfo.second)};
|
||||
size_t bufSizes[] = {sizeof(ViewBlock)};
|
||||
|
||||
m_shaderBinding =
|
||||
ctx.newShaderDataBinding(res.m_viewRes.m_solidShader, vBufInfo.first.get(), nullptr, nullptr, 1, bufs, nullptr,
|
||||
bufOffs, bufSizes, 0, nullptr, nullptr, nullptr, vBufInfo.second);
|
||||
}
|
||||
|
||||
void View::VertexBufferBindingSolid::init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf)
|
||||
{
|
||||
m_vertsBuf = res.m_viewRes.m_solidPool.allocateBlock(res.m_factory, count);
|
||||
auto vBufInfo = m_vertsBuf.getBufferInfo();
|
||||
auto uBufInfo = viewBlockBuf.getBufferInfo();
|
||||
|
||||
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {uBufInfo.first.get()};
|
||||
size_t bufOffs[] = {size_t(uBufInfo.second)};
|
||||
size_t bufSizes[] = {sizeof(ViewBlock)};
|
||||
|
||||
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_solidShader,
|
||||
vBufInfo.first.get(), nullptr,
|
||||
nullptr, 1, bufs, nullptr, bufOffs,
|
||||
bufSizes, 0, nullptr, nullptr, nullptr, vBufInfo.second);
|
||||
}
|
||||
|
||||
void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx,
|
||||
ViewResources& res, size_t count,
|
||||
void View::VertexBufferBindingTex::init(boo::IGraphicsDataFactory::Context& ctx, ViewResources& res, size_t count,
|
||||
const hecl::UniformBufferPool<ViewBlock>::Token& viewBlockBuf,
|
||||
const boo::ObjToken<boo::ITexture>& texture)
|
||||
{
|
||||
m_vertsBuf = res.m_viewRes.m_texPool.allocateBlock(res.m_factory, count);
|
||||
auto vBufInfo = m_vertsBuf.getBufferInfo();
|
||||
auto uBufInfo = viewBlockBuf.getBufferInfo();
|
||||
const boo::ObjToken<boo::ITexture>& texture) {
|
||||
m_vertsBuf = res.m_viewRes.m_texPool.allocateBlock(res.m_factory, count);
|
||||
auto vBufInfo = m_vertsBuf.getBufferInfo();
|
||||
auto uBufInfo = viewBlockBuf.getBufferInfo();
|
||||
|
||||
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {uBufInfo.first.get()};
|
||||
size_t bufOffs[] = {size_t(uBufInfo.second)};
|
||||
size_t bufSizes[] = {sizeof(ViewBlock)};
|
||||
boo::ObjToken<boo::ITexture> tex[] = {texture};
|
||||
boo::ObjToken<boo::IGraphicsBuffer> bufs[] = {uBufInfo.first.get()};
|
||||
size_t bufOffs[] = {size_t(uBufInfo.second)};
|
||||
size_t bufSizes[] = {sizeof(ViewBlock)};
|
||||
boo::ObjToken<boo::ITexture> tex[] = {texture};
|
||||
|
||||
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader,
|
||||
vBufInfo.first.get(), nullptr,
|
||||
nullptr, 1, bufs, nullptr, bufOffs,
|
||||
bufSizes, 1, tex, nullptr, nullptr, vBufInfo.second);
|
||||
m_shaderBinding = ctx.newShaderDataBinding(res.m_viewRes.m_texShader, vBufInfo.first.get(), nullptr, nullptr, 1, bufs,
|
||||
nullptr, bufOffs, bufSizes, 1, tex, nullptr, nullptr, vBufInfo.second);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
} // namespace specter
|
||||
|
|
|
@ -1,75 +1,69 @@
|
|||
#include "specter/ViewResources.hpp"
|
||||
|
||||
namespace specter
|
||||
{
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::ViewResources");
|
||||
|
||||
void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, const IThemeData* theme, float pf)
|
||||
{
|
||||
if (!factory || !fcache || !theme)
|
||||
Log.report(logvisor::Fatal, "all arguments of ViewResources::init() must be non-null");
|
||||
m_pixelFactor = pf;
|
||||
m_factory = factory;
|
||||
m_theme = theme;
|
||||
m_fcache = fcache;
|
||||
unsigned dpi = 72.f * m_pixelFactor;
|
||||
void ViewResources::init(boo::IGraphicsDataFactory* factory, FontCache* fcache, const IThemeData* theme, float pf) {
|
||||
if (!factory || !fcache || !theme)
|
||||
Log.report(logvisor::Fatal, "all arguments of ViewResources::init() must be non-null");
|
||||
m_pixelFactor = pf;
|
||||
m_factory = factory;
|
||||
m_theme = theme;
|
||||
m_fcache = fcache;
|
||||
unsigned dpi = 72.f * m_pixelFactor;
|
||||
|
||||
m_curveFont = fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi);
|
||||
m_curveFont = fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi);
|
||||
|
||||
factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
init(ctx, *theme, fcache);
|
||||
return true;
|
||||
} BooTrace);
|
||||
factory->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) {
|
||||
init(ctx, *theme, fcache);
|
||||
return true;
|
||||
} BooTrace);
|
||||
}
|
||||
|
||||
void ViewResources::destroyResData()
|
||||
{
|
||||
m_viewRes.destroy();
|
||||
m_textRes.destroy();
|
||||
m_splitRes.destroy();
|
||||
m_toolbarRes.destroy();
|
||||
m_buttonRes.destroy();
|
||||
void ViewResources::destroyResData() {
|
||||
m_viewRes.destroy();
|
||||
m_textRes.destroy();
|
||||
m_splitRes.destroy();
|
||||
m_toolbarRes.destroy();
|
||||
m_buttonRes.destroy();
|
||||
}
|
||||
|
||||
void ViewResources::prepFontCacheSync()
|
||||
{
|
||||
unsigned dpi = 72.f * m_pixelFactor;
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_mainFont = m_fcache->prepMainFont(AllCharFilter, false, 10.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_monoFont10 = m_fcache->prepMonoFont(AllCharFilter, false, 10.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_monoFont18 = m_fcache->prepMonoFont(AllCharFilter, false, 18.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_heading14 = m_fcache->prepMainFont(LatinAndJapaneseCharFilter, false, 14.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_heading18 = m_fcache->prepMainFont(LatinAndJapaneseCharFilter, false, 18.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_titleFont = m_fcache->prepMainFont(LatinCharFilter, false, 36.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_fcache->closeBuiltinFonts();
|
||||
m_fcacheReady.store(true);
|
||||
void ViewResources::prepFontCacheSync() {
|
||||
unsigned dpi = 72.f * m_pixelFactor;
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_mainFont = m_fcache->prepMainFont(AllCharFilter, false, 10.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_monoFont10 = m_fcache->prepMonoFont(AllCharFilter, false, 10.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_monoFont18 = m_fcache->prepMonoFont(AllCharFilter, false, 18.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_heading14 = m_fcache->prepMainFont(LatinAndJapaneseCharFilter, false, 14.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_heading18 = m_fcache->prepMainFont(LatinAndJapaneseCharFilter, false, 18.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_titleFont = m_fcache->prepMainFont(LatinCharFilter, false, 36.f, dpi);
|
||||
if (m_fcacheInterrupt.load())
|
||||
return;
|
||||
m_fcache->closeBuiltinFonts();
|
||||
m_fcacheReady.store(true);
|
||||
}
|
||||
|
||||
void ViewResources::prepFontCacheAsync(boo::IWindow* window)
|
||||
{
|
||||
m_fcacheReady.store(false);
|
||||
m_fcacheThread = std::thread([this]() { prepFontCacheSync(); });
|
||||
void ViewResources::prepFontCacheAsync(boo::IWindow* window) {
|
||||
m_fcacheReady.store(false);
|
||||
m_fcacheThread = std::thread([this]() { prepFontCacheSync(); });
|
||||
}
|
||||
|
||||
void ViewResources::resetPixelFactor(float pf)
|
||||
{
|
||||
m_pixelFactor = pf;
|
||||
unsigned dpi = 72.f * m_pixelFactor;
|
||||
m_curveFont = m_fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi);
|
||||
prepFontCacheSync();
|
||||
void ViewResources::resetPixelFactor(float pf) {
|
||||
m_pixelFactor = pf;
|
||||
unsigned dpi = 72.f * m_pixelFactor;
|
||||
m_curveFont = m_fcache->prepCurvesFont(AllCharFilter, false, 8.f, dpi);
|
||||
prepFontCacheSync();
|
||||
}
|
||||
|
||||
void ViewResources::resetTheme(const IThemeData* theme) { m_theme = theme; }
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e8dfecbb6e60dd79e01b62645ac8cf967cfd0a59
|
||||
Subproject commit e172225845f7e683e40d809f60c6677b289adc64
|
Loading…
Reference in New Issue