mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-17 22:45:23 +00:00
Dedicated PathButtons class and horizontal ScrollView
This commit is contained in:
@@ -6,38 +6,46 @@
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
class Control;
|
||||
class Button;
|
||||
|
||||
struct IControlBinding
|
||||
{
|
||||
virtual const char* name() const=0;
|
||||
virtual const char* help() const {return nullptr;}
|
||||
virtual const char* name(const Control* control) const=0;
|
||||
virtual const char* help(const Control* control) const {return nullptr;}
|
||||
};
|
||||
|
||||
struct IButtonBinding : IControlBinding
|
||||
{
|
||||
/** Pressed/Released while Hovering action,
|
||||
* cancellable by holding the button and releasing outside */
|
||||
virtual void activated(const boo::SWindowCoord& coord)=0;
|
||||
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) {}
|
||||
};
|
||||
|
||||
struct IFloatBinding : IControlBinding
|
||||
{
|
||||
virtual float getDefault() const {return 0.0;}
|
||||
virtual std::pair<float,float> getBounds() const {return std::make_pair(FLT_MIN, FLT_MAX);}
|
||||
virtual void changed(float val)=0;
|
||||
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
|
||||
{
|
||||
virtual int getDefault() const {return 0;}
|
||||
virtual std::pair<int,int> getBounds() const {return std::make_pair(INT_MIN, INT_MAX);}
|
||||
virtual void changed(int val)=0;
|
||||
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
|
||||
{
|
||||
virtual std::string getDefault() const {return "";}
|
||||
virtual void changed(const std::string& val)=0;
|
||||
virtual std::string getDefault(const Control* control) const {return "";}
|
||||
virtual void changed(const Control* control, const std::string& val)=0;
|
||||
};
|
||||
|
||||
struct CVarControlBinding : IControlBinding
|
||||
@@ -45,8 +53,8 @@ struct CVarControlBinding : IControlBinding
|
||||
HECL::CVar* m_cvar;
|
||||
CVarControlBinding(HECL::CVar* cvar)
|
||||
: m_cvar(cvar) {}
|
||||
const char* name() const {return m_cvar->name().c_str();}
|
||||
const char* help() const {return m_cvar->rawHelp().c_str();}
|
||||
const char* name(const Control* control) const {return m_cvar->name().c_str();}
|
||||
const char* help(const Control* control) const {return m_cvar->rawHelp().c_str();}
|
||||
};
|
||||
|
||||
class Control : public View
|
||||
|
||||
@@ -10,12 +10,13 @@
|
||||
#include "ViewResources.hpp"
|
||||
#include "IViewManager.hpp"
|
||||
#include "MessageWindow.hpp"
|
||||
#include "PathButtons.hpp"
|
||||
#include <HECL/HECL.hpp>
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
|
||||
class FileBrowser : public ModalWindow
|
||||
class FileBrowser : public ModalWindow, public IPathButtonsBinding
|
||||
{
|
||||
public:
|
||||
enum class Type
|
||||
@@ -64,8 +65,8 @@ private:
|
||||
m_button.m_view.reset(new Button(res, fb, this, text, Button::Style::Block,
|
||||
RectangleConstraint(100 * res.pixelFactor(), -1, RectangleConstraint::Test::Minimum)));
|
||||
}
|
||||
const char* name() const {return m_text.c_str();}
|
||||
void activated(const boo::SWindowCoord&) {m_fb.okActivated(true);}
|
||||
const char* name(const Control* control) const {return m_text.c_str();}
|
||||
void activated(const Button* button, const boo::SWindowCoord&) {m_fb.okActivated(true);}
|
||||
} m_ok;
|
||||
|
||||
void cancelActivated();
|
||||
@@ -80,28 +81,12 @@ private:
|
||||
m_button.m_view.reset(new Button(res, fb, this, text, Button::Style::Block,
|
||||
RectangleConstraint(m_fb.m_ok.m_button.m_view->nominalWidth(), -1, RectangleConstraint::Test::Minimum)));
|
||||
}
|
||||
const char* name() const {return m_text.c_str();}
|
||||
void activated(const boo::SWindowCoord&) {m_fb.cancelActivated();}
|
||||
const char* name(const Control* control) const {return m_text.c_str();}
|
||||
void activated(const Button* button, const boo::SWindowCoord&) {m_fb.cancelActivated();}
|
||||
} m_cancel;
|
||||
|
||||
int m_pathButtonPending = -1;
|
||||
void pathButtonActivated(size_t idx);
|
||||
struct PathButton : IButtonBinding
|
||||
{
|
||||
FileBrowser& m_fb;
|
||||
size_t m_idx;
|
||||
ViewChild<std::unique_ptr<Button>> m_button;
|
||||
PathButton(FileBrowser& fb, ViewResources& res, size_t idx, const HECL::SystemString& str)
|
||||
: m_fb(fb), m_idx(idx)
|
||||
{
|
||||
HECL::SystemUTF8View utf8View(str);
|
||||
m_button.m_view.reset(new Button(res, fb, this, utf8View));
|
||||
}
|
||||
const char* name() const {return m_button.m_view->getText().c_str();}
|
||||
void activated(const boo::SWindowCoord&) {m_fb.m_pathButtonPending = m_idx;}
|
||||
};
|
||||
friend struct PathButton;
|
||||
std::vector<PathButton> m_pathButtons;
|
||||
ViewChild<std::unique_ptr<PathButtons>> m_pathButtons;
|
||||
|
||||
ViewChild<std::unique_ptr<TextField>> m_fileField;
|
||||
struct FileFieldBind : IStringBinding
|
||||
@@ -110,8 +95,8 @@ private:
|
||||
std::string m_name;
|
||||
FileFieldBind(FileBrowser& browser, const IViewManager& vm)
|
||||
: m_browser(browser), m_name(vm.translateOr("file_name", "File Name")) {}
|
||||
const char* name() const {return m_name.c_str();}
|
||||
void changed(const std::string& val)
|
||||
const char* name(const Control* control) const {return m_name.c_str();}
|
||||
void changed(const Control* control, const std::string& val)
|
||||
{
|
||||
}
|
||||
} m_fileFieldBind;
|
||||
@@ -345,7 +330,6 @@ public:
|
||||
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 touchDown(const boo::STouchCoord&, uintptr_t);
|
||||
|
||||
@@ -29,8 +29,8 @@ private:
|
||||
MessageWindow& m_mw;
|
||||
std::string m_name;
|
||||
OKBinding(MessageWindow& mw, std::string&& name) : m_mw(mw), m_name(std::move(name)) {}
|
||||
const char* name() const {return m_name.c_str();}
|
||||
void activated(const boo::SWindowCoord& coord)
|
||||
const char* name(const Control* control) const {return m_name.c_str();}
|
||||
void activated(const Button* button, const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_mw.m_func(true);
|
||||
}
|
||||
@@ -42,8 +42,8 @@ private:
|
||||
MessageWindow& m_mw;
|
||||
std::string m_name;
|
||||
CancelBinding(MessageWindow& mw, std::string&& name) : m_mw(mw), m_name(std::move(name)) {}
|
||||
const char* name() const {return m_name.c_str();}
|
||||
void activated(const boo::SWindowCoord& coord)
|
||||
const char* name(const Control* control) const {return m_name.c_str();}
|
||||
void activated(const Button* button, const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_mw.m_func(false);
|
||||
}
|
||||
|
||||
74
specter/include/Specter/PathButtons.hpp
Normal file
74
specter/include/Specter/PathButtons.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef SPECTER_PATHBUTTONS_HPP
|
||||
#define SPECTER_PATHBUTTONS_HPP
|
||||
|
||||
#include "Button.hpp"
|
||||
#include "ScrollView.hpp"
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
|
||||
struct IPathButtonsBinding
|
||||
{
|
||||
virtual void pathButtonActivated(size_t idx)=0;
|
||||
};
|
||||
|
||||
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&);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
struct PathButton : 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::SystemUTF8View(str).str()));
|
||||
}
|
||||
const char* name(const Control* control) const {return m_button.m_view->getText().c_str();}
|
||||
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);
|
||||
|
||||
void setButtons(const std::vector<HECL::SystemString>& comps);
|
||||
void setMultiplyColor(const Zeus::CColor& color);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPECTER_PATHBUTTONS_HPP
|
||||
@@ -2,6 +2,8 @@
|
||||
#define SPECTER_SCROLLVIEW_HPP
|
||||
|
||||
#include "View.hpp"
|
||||
#include "Button.hpp"
|
||||
#include "IViewManager.hpp"
|
||||
|
||||
namespace Specter
|
||||
{
|
||||
@@ -13,12 +15,13 @@ public:
|
||||
enum class Style
|
||||
{
|
||||
Plain,
|
||||
ThinIndicator
|
||||
ThinIndicator,
|
||||
SideButtons
|
||||
};
|
||||
|
||||
private:
|
||||
Style m_style;
|
||||
View* m_contentView = nullptr;
|
||||
ScissorViewChild<View*> m_contentView;
|
||||
int m_scroll[2] = {};
|
||||
int m_targetScroll[2] = {};
|
||||
|
||||
@@ -26,18 +29,61 @@ private:
|
||||
double m_consecutiveScroll[16][2] = {};
|
||||
|
||||
bool m_drawInd = false;
|
||||
bool m_drawSideButtons = false;
|
||||
|
||||
SolidShaderVert m_verts[4];
|
||||
boo::IGraphicsBufferD* m_vertsBuf = nullptr;
|
||||
boo::IVertexFormat* m_vtxFmt = nullptr; /* OpenGL only */
|
||||
boo::IShaderDataBinding* m_shaderBinding = nullptr;
|
||||
|
||||
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")) {}
|
||||
const char* name(const Control* control) const
|
||||
{return (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
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
public:
|
||||
ScrollView(ViewResources& res, View& parentView, Style style);
|
||||
void setContentView(View* v)
|
||||
{
|
||||
m_contentView = v;
|
||||
m_contentView.m_view = v;
|
||||
updateSize();
|
||||
}
|
||||
|
||||
@@ -56,8 +102,13 @@ public:
|
||||
void setMultiplyColor(const Zeus::CColor& color)
|
||||
{
|
||||
View::setMultiplyColor(color);
|
||||
if (m_contentView)
|
||||
m_contentView->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 think();
|
||||
|
||||
@@ -19,7 +19,7 @@ class Space : public View
|
||||
public:
|
||||
Space(ViewResources& res, View& parentView, Toolbar::Position toolbarPos);
|
||||
View* setContentView(View* view);
|
||||
Toolbar& toolbar() {return *m_toolbar;}
|
||||
Toolbar* toolbar() {return m_toolbar.get();}
|
||||
void mouseDown(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseUp(const boo::SWindowCoord&, boo::EMouseButton, boo::EModifierKey);
|
||||
void mouseMove(const boo::SWindowCoord&);
|
||||
|
||||
@@ -20,6 +20,7 @@ public:
|
||||
|
||||
enum class Position
|
||||
{
|
||||
None,
|
||||
Bottom,
|
||||
Top
|
||||
};
|
||||
|
||||
@@ -296,6 +296,54 @@ struct ViewChild
|
||||
}
|
||||
};
|
||||
|
||||
template <class ViewPtrType>
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SPECTER_VIEW_HPP
|
||||
|
||||
@@ -18,8 +18,9 @@ class ThemeData
|
||||
Zeus::CColor m_selectedFieldText = Zeus::CColor::skWhite;
|
||||
|
||||
Zeus::CColor m_vpBg = {0.2, 0.2, 0.2, 1.0};
|
||||
Zeus::CColor m_tbBg = {0.4, 0.4, 0.4, 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};
|
||||
|
||||
@@ -59,6 +60,7 @@ public:
|
||||
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;}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user