commit
553ee8b1f2
@ -192,7 +192,7 @@ Hud::Hud(Engine& engine, LevelFrontend& frontend, Player& player)
|
|||||||
gui.add(contentAccessPanel);
|
gui.add(contentAccessPanel);
|
||||||
|
|
||||||
auto dplotter = std::make_shared<Plotter>(gui, 350, 250, 2000, 16);
|
auto dplotter = std::make_shared<Plotter>(gui, 350, 250, 2000, 16);
|
||||||
dplotter->setGravity(Gravity::bottom_right);
|
dplotter->setGravity(Gravity::BOTTOM_RIGHT);
|
||||||
dplotter->setInteractive(false);
|
dplotter->setInteractive(false);
|
||||||
add(HudElement(HudElementMode::PERMANENT, nullptr, dplotter, true));
|
add(HudElement(HudElementMode::PERMANENT, nullptr, dplotter, true));
|
||||||
|
|
||||||
|
|||||||
@ -30,14 +30,14 @@ namespace gui {
|
|||||||
glm::vec2 size,
|
glm::vec2 size,
|
||||||
glm::vec4 padding = glm::vec4(0.0f),
|
glm::vec4 padding = glm::vec4(0.0f),
|
||||||
float interval = 2.0f,
|
float interval = 2.0f,
|
||||||
Orientation orientation = Orientation::vertical
|
Orientation orientation = Orientation::VERTICAL
|
||||||
)
|
)
|
||||||
: Container(gui, std::move(size)),
|
: Container(gui, std::move(size)),
|
||||||
padding(std::move(padding)),
|
padding(std::move(padding)),
|
||||||
interval(interval) {
|
interval(interval) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Orientation orientation = Orientation::vertical;
|
Orientation orientation = Orientation::VERTICAL;
|
||||||
glm::vec4 padding;
|
glm::vec4 padding;
|
||||||
float interval = 2.0f;
|
float interval = 2.0f;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -31,7 +31,7 @@ Button::Button(
|
|||||||
GUI& gui,
|
GUI& gui,
|
||||||
const std::wstring& text,
|
const std::wstring& text,
|
||||||
glm::vec4 padding,
|
glm::vec4 padding,
|
||||||
const onaction& action,
|
const OnAction& action,
|
||||||
glm::vec2 size
|
glm::vec2 size
|
||||||
)
|
)
|
||||||
: Panel(gui, size, padding, 0.0f) {
|
: Panel(gui, size, padding, 0.0f) {
|
||||||
@ -42,12 +42,12 @@ Button::Button(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action) {
|
if (action) {
|
||||||
listenAction(action);
|
listenClick(action);
|
||||||
}
|
}
|
||||||
setScrollable(false);
|
setScrollable(false);
|
||||||
|
|
||||||
label = std::make_shared<Label>(gui, text);
|
label = std::make_shared<Label>(gui, text);
|
||||||
label->setAlign(Align::center);
|
label->setAlign(Align::CENTER);
|
||||||
label->setSize(getContentSize());
|
label->setSize(getContentSize());
|
||||||
label->setInteractive(false);
|
label->setInteractive(false);
|
||||||
add(label);
|
add(label);
|
||||||
@ -95,5 +95,5 @@ Align Button::getTextAlign() const {
|
|||||||
if (label) {
|
if (label) {
|
||||||
return label->getAlign();
|
return label->getAlign();
|
||||||
}
|
}
|
||||||
return Align::left;
|
return Align::LEFT;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,7 @@ namespace gui {
|
|||||||
GUI& gui,
|
GUI& gui,
|
||||||
const std::wstring& text,
|
const std::wstring& text,
|
||||||
glm::vec4 padding,
|
glm::vec4 padding,
|
||||||
const onaction& action,
|
const OnAction& action,
|
||||||
glm::vec2 size = glm::vec2(-1)
|
glm::vec2 size = glm::vec2(-1)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ void gui::Canvas::draw(const DrawContext& pctx, const Assets& assets) {
|
|||||||
batch->rect(pos.x, pos.y, size.x, size.y, 0, 0, 0, {}, false, false, col);
|
batch->rect(pos.x, pos.y, size.x, size.y, 0, 0, 0, {}, false, false, col);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui::Canvas::setSize(glm::vec2 size) {
|
void gui::Canvas::setSize(const glm::vec2& size) {
|
||||||
UINode::setSize(size);
|
UINode::setSize(size);
|
||||||
data->extend(size.x, size.y);
|
data->extend(size.x, size.y);
|
||||||
texture->reload(*data);
|
texture->reload(*data);
|
||||||
|
|||||||
@ -15,7 +15,7 @@ namespace gui {
|
|||||||
|
|
||||||
void draw(const DrawContext& pctx, const Assets& assets) override;
|
void draw(const DrawContext& pctx, const Assets& assets) override;
|
||||||
|
|
||||||
void setSize(glm::vec2 size) override;
|
void setSize(const glm::vec2& size) override;
|
||||||
|
|
||||||
[[nodiscard]] auto getTexture() const {
|
[[nodiscard]] auto getTexture() const {
|
||||||
return texture;
|
return texture;
|
||||||
|
|||||||
@ -52,7 +52,7 @@ FullCheckBox::FullCheckBox(
|
|||||||
checkbox(std::make_shared<CheckBox>(gui, checked)),
|
checkbox(std::make_shared<CheckBox>(gui, checked)),
|
||||||
label(std::make_shared<Label>(gui, text)) {
|
label(std::make_shared<Label>(gui, text)) {
|
||||||
setColor(glm::vec4(0.0f));
|
setColor(glm::vec4(0.0f));
|
||||||
setOrientation(Orientation::horizontal);
|
setOrientation(Orientation::HORIZONTAL);
|
||||||
|
|
||||||
add(checkbox);
|
add(checkbox);
|
||||||
|
|
||||||
|
|||||||
@ -64,7 +64,7 @@ namespace gui {
|
|||||||
checkbox->setTooltip(text);
|
checkbox->setTooltip(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setSize(glm::vec2 new_size) override {
|
virtual void setSize(const glm::vec2& new_size) override {
|
||||||
Panel::setSize(new_size);
|
Panel::setSize(new_size);
|
||||||
checkbox->setSize(glm::vec2(size.y, size.y));
|
checkbox->setSize(glm::vec2(size.y, size.y));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -210,11 +210,11 @@ void Container::clear() {
|
|||||||
refresh();
|
refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::listenInterval(float interval, ontimeout callback, int repeat) {
|
void Container::listenInterval(float interval, OnTimeOut callback, int repeat) {
|
||||||
intervalEvents.push_back({std::move(callback), interval, 0.0f, repeat});
|
intervalEvents.push_back({std::move(callback), interval, 0.0f, repeat});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Container::setSize(glm::vec2 size) {
|
void Container::setSize(const glm::vec2& size) {
|
||||||
if (size == getSize()) {
|
if (size == getSize()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,9 +36,9 @@ namespace gui {
|
|||||||
virtual void remove(const std::string& id);
|
virtual void remove(const std::string& id);
|
||||||
virtual void scrolled(int value) override;
|
virtual void scrolled(int value) override;
|
||||||
virtual void setScrollable(bool flag);
|
virtual void setScrollable(bool flag);
|
||||||
void listenInterval(float interval, ontimeout callback, int repeat=-1);
|
void listenInterval(float interval, OnTimeOut callback, int repeat=-1);
|
||||||
virtual glm::vec2 getContentOffset() override {return glm::vec2(0.0f, scroll);};
|
virtual glm::vec2 getContentOffset() override {return glm::vec2(0.0f, scroll);};
|
||||||
virtual void setSize(glm::vec2 size) override;
|
virtual void setSize(const glm::vec2& size) override;
|
||||||
virtual int getScrollStep() const;
|
virtual int getScrollStep() const;
|
||||||
virtual void setScrollStep(int step);
|
virtual void setScrollStep(int step);
|
||||||
virtual void refresh() override;
|
virtual void refresh() override;
|
||||||
|
|||||||
@ -44,7 +44,7 @@ void InlineFrame::act(float delta) {
|
|||||||
setDocument(assets.getShared<UiDocument>(src));
|
setDocument(assets.getShared<UiDocument>(src));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InlineFrame::setSize(glm::vec2 size) {
|
void InlineFrame::setSize(const glm::vec2& size) {
|
||||||
Container::setSize(size);
|
Container::setSize(size);
|
||||||
if (root) {
|
if (root) {
|
||||||
root->setSize(size);
|
root->setSize(size);
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
class UiDocument;
|
class UiDocument;
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
class InlineFrame : public Container {
|
class InlineFrame final : public Container {
|
||||||
public:
|
public:
|
||||||
explicit InlineFrame(GUI& gui);
|
explicit InlineFrame(GUI& gui);
|
||||||
virtual ~InlineFrame();
|
virtual ~InlineFrame();
|
||||||
@ -14,7 +14,7 @@ namespace gui {
|
|||||||
void setDocument(const std::shared_ptr<UiDocument>& document);
|
void setDocument(const std::shared_ptr<UiDocument>& document);
|
||||||
|
|
||||||
void act(float delta) override;
|
void act(float delta) override;
|
||||||
void setSize(glm::vec2 size) override;
|
void setSize(const glm::vec2& size) override;
|
||||||
|
|
||||||
const std::string& getSrc() const;
|
const std::string& getSrc() const;
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
namespace gui {
|
namespace gui {
|
||||||
class Label;
|
class Label;
|
||||||
|
|
||||||
class InputBindBox : public Panel {
|
class InputBindBox final : public Panel {
|
||||||
protected:
|
protected:
|
||||||
Binding& binding;
|
Binding& binding;
|
||||||
glm::vec4 focusedColor {0.1f, 0.15f, 0.35f, 0.75f};
|
glm::vec4 focusedColor {0.1f, 0.15f, 0.35f, 0.75f};
|
||||||
@ -15,13 +15,13 @@ namespace gui {
|
|||||||
GUI& gui, Binding& binding, glm::vec4 padding = glm::vec4(6.0f)
|
GUI& gui, Binding& binding, glm::vec4 padding = glm::vec4(6.0f)
|
||||||
);
|
);
|
||||||
|
|
||||||
virtual void drawBackground(
|
void drawBackground(
|
||||||
const DrawContext& pctx, const Assets& assets
|
const DrawContext& pctx, const Assets& assets
|
||||||
) override;
|
) override;
|
||||||
|
|
||||||
virtual void clicked(Mousecode button) override;
|
void clicked(Mousecode button) override;
|
||||||
virtual void keyPressed(Keycode key) override;
|
void keyPressed(Keycode key) override;
|
||||||
virtual bool isFocuskeeper() const override {
|
bool isFocuskeeper() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -528,14 +528,14 @@ void InventoryView::setSelected(int index) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryView::setPos(glm::vec2 pos) {
|
void InventoryView::setPos(const glm::vec2& pos) {
|
||||||
Container::setPos(pos - origin);
|
Container::setPos(pos - origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryView::setOrigin(glm::vec2 origin) {
|
void InventoryView::setOrigin(const glm::vec2& origin) {
|
||||||
this->origin = origin;
|
this->origin = origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 InventoryView::getOrigin() const {
|
const glm::vec2& InventoryView::getOrigin() const {
|
||||||
return origin;
|
return origin;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,7 +109,7 @@ namespace gui {
|
|||||||
static inline std::string EXCHANGE_SLOT_NAME = "exchange-slot";
|
static inline std::string EXCHANGE_SLOT_NAME = "exchange-slot";
|
||||||
};
|
};
|
||||||
|
|
||||||
class InventoryView : public gui::Container {
|
class InventoryView final : public gui::Container {
|
||||||
const Content* content = nullptr;
|
const Content* content = nullptr;
|
||||||
|
|
||||||
std::shared_ptr<Inventory> inventory;
|
std::shared_ptr<Inventory> inventory;
|
||||||
@ -120,10 +120,10 @@ namespace gui {
|
|||||||
InventoryView(GUI& gui);
|
InventoryView(GUI& gui);
|
||||||
virtual ~InventoryView();
|
virtual ~InventoryView();
|
||||||
|
|
||||||
virtual void setPos(glm::vec2 pos) override;
|
void setPos(const glm::vec2& pos) override;
|
||||||
|
|
||||||
void setOrigin(glm::vec2 origin);
|
void setOrigin(const glm::vec2& origin);
|
||||||
glm::vec2 getOrigin() const;
|
const glm::vec2& getOrigin() const;
|
||||||
|
|
||||||
void setSelected(int index);
|
void setSelected(int index);
|
||||||
|
|
||||||
|
|||||||
@ -230,14 +230,14 @@ void Label::draw(const DrawContext& pctx, const Assets& assets) {
|
|||||||
|
|
||||||
glm::vec2 pos = calcPos();
|
glm::vec2 pos = calcPos();
|
||||||
switch (align) {
|
switch (align) {
|
||||||
case Align::left: break;
|
case Align::LEFT: break;
|
||||||
case Align::center: pos.x += (size.x-newsize.x)*0.5f; break;
|
case Align::CENTER: pos.x += (size.x-newsize.x)*0.5f; break;
|
||||||
case Align::right: pos.x += size.x-newsize.x; break;
|
case Align::RIGHT: pos.x += size.x-newsize.x; break;
|
||||||
}
|
}
|
||||||
switch (valign) {
|
switch (valign) {
|
||||||
case Align::top: break;
|
case Align::TOP: break;
|
||||||
case Align::center: pos.y += (size.y-newsize.y)*0.5f; break;
|
case Align::CENTER: pos.y += (size.y-newsize.y)*0.5f; break;
|
||||||
case Align::bottom: pos.y += size.y-newsize.y; break;
|
case Align::BOTTOM: pos.y += size.y-newsize.y; break;
|
||||||
}
|
}
|
||||||
textYOffset = pos.y-calcPos().y;
|
textYOffset = pos.y-calcPos().y;
|
||||||
totalLineHeight = lineHeight;
|
totalLineHeight = lineHeight;
|
||||||
|
|||||||
@ -44,7 +44,7 @@ namespace gui {
|
|||||||
float lineInterval = 1.5f;
|
float lineInterval = 1.5f;
|
||||||
|
|
||||||
/// @brief Vertical alignment (only when multiline is set to false)
|
/// @brief Vertical alignment (only when multiline is set to false)
|
||||||
Align valign = Align::center;
|
Align valign = Align::CENTER;
|
||||||
|
|
||||||
/// @brief Line separators and wrapping will be ignored if set to false
|
/// @brief Line separators and wrapping will be ignored if set to false
|
||||||
bool multiline = false;
|
bool multiline = false;
|
||||||
|
|||||||
@ -72,7 +72,7 @@ void Panel::refresh() {
|
|||||||
float x = padding.x;
|
float x = padding.x;
|
||||||
float y = padding.y;
|
float y = padding.y;
|
||||||
glm::vec2 size = getSize();
|
glm::vec2 size = getSize();
|
||||||
if (orientation == Orientation::vertical) {
|
if (orientation == Orientation::VERTICAL) {
|
||||||
float maxw = size.x;
|
float maxw = size.x;
|
||||||
for (auto& node : nodes) {
|
for (auto& node : nodes) {
|
||||||
const glm::vec4 margin = node->getMargin();
|
const glm::vec4 margin = node->getMargin();
|
||||||
|
|||||||
@ -19,7 +19,7 @@ SelectBox::SelectBox(
|
|||||||
: Button(gui, selected.text, padding, nullptr, glm::vec2(contentWidth, -1)),
|
: Button(gui, selected.text, padding, nullptr, glm::vec2(contentWidth, -1)),
|
||||||
options(std::move(options)) {
|
options(std::move(options)) {
|
||||||
|
|
||||||
listenAction([this](GUI& gui) {
|
listenClick([this](GUI& gui) {
|
||||||
auto panel = std::make_shared<Panel>(gui, getSize());
|
auto panel = std::make_shared<Panel>(gui, getSize());
|
||||||
panel->setPos(calcPos() + glm::vec2(0, size.y));
|
panel->setPos(calcPos() + glm::vec2(0, size.y));
|
||||||
for (const auto& option : this->options) {
|
for (const auto& option : this->options) {
|
||||||
@ -41,7 +41,7 @@ SelectBox::SelectBox(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void SelectBox::listenChange(onstringchange&& callback) {
|
void SelectBox::listenChange(OnStringChange&& callback) {
|
||||||
changeCallbacks.listen(std::move(callback));
|
changeCallbacks.listen(std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ namespace gui {
|
|||||||
const glm::vec4& padding
|
const glm::vec4& padding
|
||||||
);
|
);
|
||||||
|
|
||||||
void listenChange(onstringchange&& callback);
|
void listenChange(OnStringChange&& callback);
|
||||||
|
|
||||||
void setSelected(const Option& selected);
|
void setSelected(const Option& selected);
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ using namespace gui;
|
|||||||
SplitBox::SplitBox(GUI& gui, const glm::vec2& size, float splitPos, Orientation orientation)
|
SplitBox::SplitBox(GUI& gui, const glm::vec2& size, float splitPos, Orientation orientation)
|
||||||
: BasePanel(gui, size, glm::vec4(), 4.0f, orientation), splitPos(splitPos) {
|
: BasePanel(gui, size, glm::vec4(), 4.0f, orientation), splitPos(splitPos) {
|
||||||
setCursor(
|
setCursor(
|
||||||
orientation == Orientation::vertical ? CursorShape::NS_RESIZE
|
orientation == Orientation::VERTICAL ? CursorShape::NS_RESIZE
|
||||||
: CursorShape::EW_RESIZE
|
: CursorShape::EW_RESIZE
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -17,7 +17,7 @@ void SplitBox::mouseMove(int x, int y) {
|
|||||||
auto size = getSize();
|
auto size = getSize();
|
||||||
|
|
||||||
glm::ivec2 cursor(x - pos.x, y - pos.y);
|
glm::ivec2 cursor(x - pos.x, y - pos.y);
|
||||||
int axis = orientation == Orientation::vertical;
|
int axis = orientation == Orientation::VERTICAL;
|
||||||
|
|
||||||
int v = cursor[axis];
|
int v = cursor[axis];
|
||||||
v = std::max(std::min(static_cast<int>(size[axis]) - 10, v), 10);
|
v = std::max(std::min(static_cast<int>(size[axis]) - 10, v), 10);
|
||||||
@ -61,7 +61,7 @@ void SplitBox::refresh() {
|
|||||||
nodeA->setPos(glm::vec2(padding));
|
nodeA->setPos(glm::vec2(padding));
|
||||||
|
|
||||||
const auto& p = padding;
|
const auto& p = padding;
|
||||||
if (orientation == Orientation::vertical) {
|
if (orientation == Orientation::VERTICAL) {
|
||||||
float splitPos = this->splitPos * size.y;
|
float splitPos = this->splitPos * size.y;
|
||||||
nodeA->setSize({size.x-p.x-p.z, splitPos - sepRadius - p.y});
|
nodeA->setSize({size.x-p.x-p.z, splitPos - sepRadius - p.y});
|
||||||
nodeB->setSize({size.x-p.x-p.z, size.y - splitPos - sepRadius - p.w});
|
nodeB->setSize({size.x-p.x-p.z, size.y - splitPos - sepRadius - p.w});
|
||||||
|
|||||||
@ -216,7 +216,7 @@ TextBox::TextBox(GUI& gui, std::wstring placeholder, glm::vec4 padding)
|
|||||||
lineNumbersLabel->setSize(
|
lineNumbersLabel->setSize(
|
||||||
size - glm::vec2(padding.z + padding.x, padding.w + padding.y)
|
size - glm::vec2(padding.z + padding.x, padding.w + padding.y)
|
||||||
);
|
);
|
||||||
lineNumbersLabel->setVerticalAlign(Align::top);
|
lineNumbersLabel->setVerticalAlign(Align::TOP);
|
||||||
add(lineNumbersLabel);
|
add(lineNumbersLabel);
|
||||||
|
|
||||||
setHoverColor(glm::vec4(0.05f, 0.1f, 0.2f, 0.75f));
|
setHoverColor(glm::vec4(0.05f, 0.1f, 0.2f, 0.75f));
|
||||||
@ -565,7 +565,7 @@ bool TextBox::isValid() const {
|
|||||||
void TextBox::setMultiline(bool multiline) {
|
void TextBox::setMultiline(bool multiline) {
|
||||||
this->multiline = multiline;
|
this->multiline = multiline;
|
||||||
label->setMultiline(multiline);
|
label->setMultiline(multiline);
|
||||||
label->setVerticalAlign(multiline ? Align::top : Align::center);
|
label->setVerticalAlign(multiline ? Align::TOP : Align::CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TextBox::isMultiline() const {
|
bool TextBox::isMultiline() const {
|
||||||
|
|||||||
@ -64,24 +64,20 @@ UINode* UINode::getParent() const {
|
|||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINode* UINode::listenAction(const onaction& action) {
|
void UINode::listenClick(OnAction action) {
|
||||||
actions.listen(action);
|
actions.listen(UIAction::CLICK, std::move(action));
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINode* UINode::listenDoubleClick(const onaction& action) {
|
void UINode::listenDoubleClick(OnAction action) {
|
||||||
doubleClickCallbacks.listen(action);
|
actions.listen(UIAction::DOUBLE_CLICK, std::move(action));
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINode* UINode::listenFocus(const onaction& action) {
|
void UINode::listenFocus(OnAction action) {
|
||||||
focusCallbacks.listen(action);
|
actions.listen(UIAction::FOCUS, std::move(action));
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINode* UINode::listenDefocus(const onaction& action) {
|
void UINode::listenDefocus(OnAction action) {
|
||||||
defocusCallbacks.listen(action);
|
actions.listen(UIAction::DEFOCUS, std::move(action));
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::click(int, int) {
|
void UINode::click(int, int) {
|
||||||
@ -91,14 +87,14 @@ void UINode::click(int, int) {
|
|||||||
void UINode::doubleClick(int x, int y) {
|
void UINode::doubleClick(int x, int y) {
|
||||||
pressed = true;
|
pressed = true;
|
||||||
if (isInside(glm::vec2(x, y))) {
|
if (isInside(glm::vec2(x, y))) {
|
||||||
doubleClickCallbacks.notify(gui);
|
actions.notify(UIAction::DOUBLE_CLICK, gui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::mouseRelease(int x, int y) {
|
void UINode::mouseRelease(int x, int y) {
|
||||||
pressed = false;
|
pressed = false;
|
||||||
if (isInside(glm::vec2(x, y))) {
|
if (isInside(glm::vec2(x, y))) {
|
||||||
actions.notify(gui);
|
actions.notify(UIAction::CLICK, gui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,12 +104,12 @@ bool UINode::isPressed() const {
|
|||||||
|
|
||||||
void UINode::onFocus() {
|
void UINode::onFocus() {
|
||||||
focused = true;
|
focused = true;
|
||||||
focusCallbacks.notify(gui);
|
actions.notify(UIAction::FOCUS, gui);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::defocus() {
|
void UINode::defocus() {
|
||||||
focused = false;
|
focused = false;
|
||||||
defocusCallbacks.notify(gui);
|
actions.notify(UIAction::DEFOCUS, gui);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UINode::isFocused() const {
|
bool UINode::isFocused() const {
|
||||||
@ -197,7 +193,7 @@ glm::vec4 UINode::calcColor() const {
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::setPos(glm::vec2 pos) {
|
void UINode::setPos(const glm::vec2& pos) {
|
||||||
this->pos = pos;
|
this->pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +205,7 @@ glm::vec2 UINode::getSize() const {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::setSize(glm::vec2 size) {
|
void UINode::setSize(const glm::vec2& size) {
|
||||||
this->size = glm::vec2(
|
this->size = glm::vec2(
|
||||||
glm::max(minSize.x, glm::min(maxSize.x, size.x)),
|
glm::max(minSize.x, glm::min(maxSize.x, size.x)),
|
||||||
glm::max(minSize.y, glm::min(maxSize.y, size.y))
|
glm::max(minSize.y, glm::min(maxSize.y, size.y))
|
||||||
@ -220,7 +216,7 @@ glm::vec2 UINode::getMinSize() const {
|
|||||||
return minSize;
|
return minSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::setMinSize(glm::vec2 minSize) {
|
void UINode::setMinSize(const glm::vec2& minSize) {
|
||||||
this->minSize = minSize;
|
this->minSize = minSize;
|
||||||
setSize(getSize());
|
setSize(getSize());
|
||||||
}
|
}
|
||||||
@ -229,7 +225,7 @@ glm::vec2 UINode::getMaxSize() const {
|
|||||||
return maxSize;
|
return maxSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UINode::setMaxSize(glm::vec2 maxSize) {
|
void UINode::setMaxSize(const glm::vec2& maxSize) {
|
||||||
this->maxSize = maxSize;
|
this->maxSize = maxSize;
|
||||||
setSize(getSize());
|
setSize(getSize());
|
||||||
}
|
}
|
||||||
@ -334,7 +330,7 @@ void UINode::reposition() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UINode::setGravity(Gravity gravity) {
|
void UINode::setGravity(Gravity gravity) {
|
||||||
if (gravity == Gravity::none) {
|
if (gravity == Gravity::NONE) {
|
||||||
setPositionFunc(nullptr);
|
setPositionFunc(nullptr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -349,27 +345,27 @@ void UINode::setGravity(Gravity gravity) {
|
|||||||
|
|
||||||
float x = 0.0f, y = 0.0f;
|
float x = 0.0f, y = 0.0f;
|
||||||
switch (gravity) {
|
switch (gravity) {
|
||||||
case Gravity::top_left:
|
case Gravity::TOP_LEFT:
|
||||||
case Gravity::center_left:
|
case Gravity::CENTER_LEFT:
|
||||||
case Gravity::bottom_left: x = margin.x; break;
|
case Gravity::BOTTOM_LEFT: x = margin.x; break;
|
||||||
case Gravity::top_center:
|
case Gravity::TOP_CENTER:
|
||||||
case Gravity::center_center:
|
case Gravity::CENTER_CENTER:
|
||||||
case Gravity::bottom_center: x = (parentSize.x-size.x)/2.0f; break;
|
case Gravity::BOTTOM_CENTER: x = (parentSize.x-size.x)/2.0f; break;
|
||||||
case Gravity::top_right:
|
case Gravity::TOP_RIGHT:
|
||||||
case Gravity::center_right:
|
case Gravity::CENTER_RIGHT:
|
||||||
case Gravity::bottom_right: x = parentSize.x-size.x-margin.z; break;
|
case Gravity::BOTTOM_RIGHT: x = parentSize.x-size.x-margin.z; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
switch (gravity) {
|
switch (gravity) {
|
||||||
case Gravity::top_left:
|
case Gravity::TOP_LEFT:
|
||||||
case Gravity::top_center:
|
case Gravity::TOP_CENTER:
|
||||||
case Gravity::top_right: y = margin.y; break;
|
case Gravity::TOP_RIGHT: y = margin.y; break;
|
||||||
case Gravity::center_left:
|
case Gravity::CENTER_LEFT:
|
||||||
case Gravity::center_center:
|
case Gravity::CENTER_CENTER:
|
||||||
case Gravity::center_right: y = (parentSize.y-size.y)/2.0f; break;
|
case Gravity::CENTER_RIGHT: y = (parentSize.y-size.y)/2.0f; break;
|
||||||
case Gravity::bottom_left:
|
case Gravity::BOTTOM_LEFT:
|
||||||
case Gravity::bottom_center:
|
case Gravity::BOTTOM_CENTER:
|
||||||
case Gravity::bottom_right: y = parentSize.y-size.y-margin.w; break;
|
case Gravity::BOTTOM_RIGHT: y = parentSize.y-size.y-margin.w; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return glm::vec2(x, y);
|
return glm::vec2(x, y);
|
||||||
|
|||||||
@ -19,9 +19,9 @@ namespace gui {
|
|||||||
class GUI;
|
class GUI;
|
||||||
class Container;
|
class Container;
|
||||||
|
|
||||||
using onaction = std::function<void(GUI&)>;
|
using OnAction = std::function<void(GUI&)>;
|
||||||
using onnumberchange = std::function<void(GUI&, double)>;
|
using OnNumberChange = std::function<void(GUI&, double)>;
|
||||||
using onstringchange = std::function<void(GUI&, const std::string&)>;
|
using OnStringChange = std::function<void(GUI&, const std::string&)>;
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
class CallbacksSet {
|
class CallbacksSet {
|
||||||
@ -46,28 +46,60 @@ namespace gui {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
using ActionsSet = CallbacksSet<GUI&>;
|
template<class TagT, typename... Args>
|
||||||
|
class TaggedCallbacksSet {
|
||||||
|
public:
|
||||||
|
using Func = std::function<void(Args...)>;
|
||||||
|
private:
|
||||||
|
std::unique_ptr<std::vector<std::pair<TagT, Func>>> callbacks;
|
||||||
|
public:
|
||||||
|
void listen(TagT tag, Func&& callback) {
|
||||||
|
if (callbacks == nullptr) {
|
||||||
|
callbacks =
|
||||||
|
std::make_unique<std::vector<std::pair<TagT, Func>>>();
|
||||||
|
}
|
||||||
|
callbacks->push_back({tag, std::move(callback)});
|
||||||
|
}
|
||||||
|
|
||||||
|
void notify(TagT notifyTag, Args&&... args) {
|
||||||
|
if (callbacks == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const auto& [tag, callback] : * callbacks) {
|
||||||
|
if (tag != notifyTag) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
callback(args...);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class UIAction {
|
||||||
|
CLICK, DOUBLE_CLICK, FOCUS, DEFOCUS
|
||||||
|
};
|
||||||
|
|
||||||
|
using ActionsSet = TaggedCallbacksSet<UIAction, GUI&>;
|
||||||
using StringCallbacksSet = CallbacksSet<GUI&, const std::string&>;
|
using StringCallbacksSet = CallbacksSet<GUI&, const std::string&>;
|
||||||
|
|
||||||
enum class Align {
|
enum class Align {
|
||||||
left, center, right,
|
LEFT, CENTER, RIGHT,
|
||||||
top=left, bottom=right,
|
TOP=LEFT, BOTTOM=RIGHT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Gravity {
|
enum class Gravity {
|
||||||
none,
|
NONE,
|
||||||
|
|
||||||
top_left,
|
TOP_LEFT,
|
||||||
top_center,
|
TOP_CENTER,
|
||||||
top_right,
|
TOP_RIGHT,
|
||||||
|
|
||||||
center_left,
|
CENTER_LEFT,
|
||||||
center_center,
|
CENTER_CENTER,
|
||||||
center_right,
|
CENTER_RIGHT,
|
||||||
|
|
||||||
bottom_left,
|
BOTTOM_LEFT,
|
||||||
bottom_center,
|
BOTTOM_CENTER,
|
||||||
bottom_right
|
BOTTOM_RIGHT
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Base abstract class for all UI elements
|
/// @brief Base abstract class for all UI elements
|
||||||
@ -112,21 +144,15 @@ namespace gui {
|
|||||||
/// @brief z-index property specifies the stack order of an element
|
/// @brief z-index property specifies the stack order of an element
|
||||||
int zindex = 0;
|
int zindex = 0;
|
||||||
/// @brief element content alignment (supported by Label only)
|
/// @brief element content alignment (supported by Label only)
|
||||||
Align align = Align::left;
|
Align align = Align::LEFT;
|
||||||
/// @brief parent element
|
/// @brief parent element
|
||||||
UINode* parent = nullptr;
|
UINode* parent = nullptr;
|
||||||
/// @brief position supplier for the element (called on parent element size update)
|
/// @brief position supplier for the element (called on parent element size update)
|
||||||
vec2supplier positionfunc = nullptr;
|
vec2supplier positionfunc = nullptr;
|
||||||
/// @brief size supplier for the element (called on parent element size update)
|
/// @brief size supplier for the element (called on parent element size update)
|
||||||
vec2supplier sizefunc = nullptr;
|
vec2supplier sizefunc = nullptr;
|
||||||
/// @brief 'onclick' callbacks
|
/// @brief parameterless callbacks
|
||||||
ActionsSet actions;
|
ActionsSet actions;
|
||||||
/// @brief 'ondoubleclick' callbacks
|
|
||||||
ActionsSet doubleClickCallbacks;
|
|
||||||
/// @brief 'onfocus' callbacks
|
|
||||||
ActionsSet focusCallbacks;
|
|
||||||
/// @brief 'ondefocus' callbacks
|
|
||||||
ActionsSet defocusCallbacks;
|
|
||||||
/// @brief element tooltip text
|
/// @brief element tooltip text
|
||||||
std::wstring tooltip;
|
std::wstring tooltip;
|
||||||
/// @brief element tooltip delay
|
/// @brief element tooltip delay
|
||||||
@ -187,10 +213,10 @@ namespace gui {
|
|||||||
/// @brief Get element z-index
|
/// @brief Get element z-index
|
||||||
int getZIndex() const;
|
int getZIndex() const;
|
||||||
|
|
||||||
virtual UINode* listenAction(const onaction& action);
|
virtual void listenClick(OnAction action);
|
||||||
virtual UINode* listenDoubleClick(const onaction& action);
|
virtual void listenDoubleClick(OnAction action);
|
||||||
virtual UINode* listenFocus(const onaction& action);
|
virtual void listenFocus(OnAction action);
|
||||||
virtual UINode* listenDefocus(const onaction& action);
|
virtual void listenDefocus(OnAction action);
|
||||||
|
|
||||||
virtual void onFocus();
|
virtual void onFocus();
|
||||||
virtual void doubleClick(int x, int y);
|
virtual void doubleClick(int x, int y);
|
||||||
@ -243,14 +269,14 @@ namespace gui {
|
|||||||
virtual glm::vec2 getContentOffset() {return glm::vec2(0.0f);};
|
virtual glm::vec2 getContentOffset() {return glm::vec2(0.0f);};
|
||||||
/// @brief Calculate screen position of the element
|
/// @brief Calculate screen position of the element
|
||||||
virtual glm::vec2 calcPos() const;
|
virtual glm::vec2 calcPos() const;
|
||||||
virtual void setPos(glm::vec2 pos);
|
virtual void setPos(const glm::vec2& pos);
|
||||||
virtual glm::vec2 getPos() const;
|
virtual glm::vec2 getPos() const;
|
||||||
glm::vec2 getSize() const;
|
glm::vec2 getSize() const;
|
||||||
virtual void setSize(glm::vec2 size);
|
virtual void setSize(const glm::vec2& size);
|
||||||
glm::vec2 getMinSize() const;
|
glm::vec2 getMinSize() const;
|
||||||
virtual void setMinSize(glm::vec2 size);
|
virtual void setMinSize(const glm::vec2& size);
|
||||||
glm::vec2 getMaxSize() const;
|
glm::vec2 getMaxSize() const;
|
||||||
virtual void setMaxSize(glm::vec2 size);
|
virtual void setMaxSize(const glm::vec2& size);
|
||||||
/// @brief Called in containers when new element added
|
/// @brief Called in containers when new element added
|
||||||
virtual void refresh() {};
|
virtual void refresh() {};
|
||||||
virtual void fullRefresh() {
|
virtual void fullRefresh() {
|
||||||
|
|||||||
@ -3,12 +3,12 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace gui {
|
namespace gui {
|
||||||
enum class Orientation { vertical, horizontal };
|
enum class Orientation { VERTICAL, HORIZONTAL };
|
||||||
|
|
||||||
using ontimeout = std::function<void()>;
|
using OnTimeOut = std::function<void()>;
|
||||||
|
|
||||||
struct IntervalEvent {
|
struct IntervalEvent {
|
||||||
ontimeout callback;
|
OnTimeOut callback;
|
||||||
float interval;
|
float interval;
|
||||||
float timer;
|
float timer;
|
||||||
// -1 - infinity, 1 - one time event
|
// -1 - infinity, 1 - one time event
|
||||||
|
|||||||
@ -101,7 +101,7 @@ void guiutil::confirm(
|
|||||||
gui, glm::vec2(600, 200), glm::vec4(8.0f), 8.0f
|
gui, glm::vec2(600, 200), glm::vec4(8.0f), 8.0f
|
||||||
);
|
);
|
||||||
|
|
||||||
panel->setGravity(Gravity::center_center);
|
panel->setGravity(Gravity::CENTER_CENTER);
|
||||||
container->add(panel);
|
container->add(panel);
|
||||||
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
panel->setColor(glm::vec4(0.0f, 0.0f, 0.0f, 0.5f));
|
||||||
|
|
||||||
|
|||||||
@ -30,31 +30,31 @@
|
|||||||
using namespace gui;
|
using namespace gui;
|
||||||
|
|
||||||
static Align align_from_string(std::string_view str, Align def) {
|
static Align align_from_string(std::string_view str, Align def) {
|
||||||
if (str == "left") return Align::left;
|
if (str == "left") return Align::LEFT;
|
||||||
if (str == "center") return Align::center;
|
if (str == "center") return Align::CENTER;
|
||||||
if (str == "right") return Align::right;
|
if (str == "right") return Align::RIGHT;
|
||||||
if (str == "top") return Align::top;
|
if (str == "top") return Align::TOP;
|
||||||
if (str == "bottom") return Align::bottom;
|
if (str == "bottom") return Align::BOTTOM;
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Gravity gravity_from_string(const std::string& str) {
|
static Gravity gravity_from_string(const std::string& str) {
|
||||||
static const std::unordered_map<std::string, Gravity> gravity_names {
|
static const std::unordered_map<std::string, Gravity> gravity_names {
|
||||||
{"top-left", Gravity::top_left},
|
{"top-left", Gravity::TOP_LEFT},
|
||||||
{"top-center", Gravity::top_center},
|
{"top-center", Gravity::TOP_CENTER},
|
||||||
{"top-right", Gravity::top_right},
|
{"top-right", Gravity::TOP_RIGHT},
|
||||||
{"center-left", Gravity::center_left},
|
{"center-left", Gravity::CENTER_LEFT},
|
||||||
{"center-center", Gravity::center_center},
|
{"center-center", Gravity::CENTER_CENTER},
|
||||||
{"center-right", Gravity::center_right},
|
{"center-right", Gravity::CENTER_RIGHT},
|
||||||
{"bottom-left", Gravity::bottom_left},
|
{"bottom-left", Gravity::BOTTOM_LEFT},
|
||||||
{"bottom-center", Gravity::bottom_center},
|
{"bottom-center", Gravity::BOTTOM_CENTER},
|
||||||
{"bottom-right", Gravity::bottom_right},
|
{"bottom-right", Gravity::BOTTOM_RIGHT},
|
||||||
};
|
};
|
||||||
auto found = gravity_names.find(str);
|
auto found = gravity_names.find(str);
|
||||||
if (found != gravity_names.end()) {
|
if (found != gravity_names.end()) {
|
||||||
return found->second;
|
return found->second;
|
||||||
}
|
}
|
||||||
return Gravity::none;
|
return Gravity::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static runnable create_runnable(
|
static runnable create_runnable(
|
||||||
@ -73,7 +73,7 @@ static runnable create_runnable(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static onaction create_action(
|
static OnAction create_action(
|
||||||
const UiXmlReader& reader,
|
const UiXmlReader& reader,
|
||||||
const xml::xmlelement& element,
|
const xml::xmlelement& element,
|
||||||
const std::string& name
|
const std::string& name
|
||||||
@ -178,7 +178,7 @@ static void read_uinode(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (auto onclick = create_action(reader, element, "onclick")) {
|
if (auto onclick = create_action(reader, element, "onclick")) {
|
||||||
node.listenAction(onclick);
|
node.listenClick(onclick);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto onfocus = create_action(reader, element, "onfocus")) {
|
if (auto onfocus = create_action(reader, element, "onfocus")) {
|
||||||
@ -248,7 +248,7 @@ static void read_base_panel_impl(
|
|||||||
if (element.has("orientation")) {
|
if (element.has("orientation")) {
|
||||||
auto& oname = element.attr("orientation").getText();
|
auto& oname = element.attr("orientation").getText();
|
||||||
if (oname == "horizontal") {
|
if (oname == "horizontal") {
|
||||||
panel.setOrientation(Orientation::horizontal);
|
panel.setOrientation(Orientation::HORIZONTAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -273,7 +273,7 @@ static void read_panel_impl(
|
|||||||
if (element.has("orientation")) {
|
if (element.has("orientation")) {
|
||||||
auto& oname = element.attr("orientation").getText();
|
auto& oname = element.attr("orientation").getText();
|
||||||
if (oname == "horizontal") {
|
if (oname == "horizontal") {
|
||||||
panel.setOrientation(Orientation::horizontal);
|
panel.setOrientation(Orientation::HORIZONTAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (subnodes) {
|
if (subnodes) {
|
||||||
@ -334,7 +334,7 @@ static std::shared_ptr<UINode> read_label(
|
|||||||
if (element.has("multiline")) {
|
if (element.has("multiline")) {
|
||||||
label->setMultiline(element.attr("multiline").asBool());
|
label->setMultiline(element.attr("multiline").asBool());
|
||||||
if (!element.has("valign")) {
|
if (!element.has("valign")) {
|
||||||
label->setVerticalAlign(Align::top);
|
label->setVerticalAlign(Align::TOP);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (element.has("text-wrap")) {
|
if (element.has("text-wrap")) {
|
||||||
@ -360,8 +360,8 @@ static std::shared_ptr<UINode> read_split_box(
|
|||||||
float splitPos = element.attr("split-pos", "0.5").asFloat();
|
float splitPos = element.attr("split-pos", "0.5").asFloat();
|
||||||
Orientation orientation =
|
Orientation orientation =
|
||||||
element.attr("orientation", "vertical").getText() == "horizontal"
|
element.attr("orientation", "vertical").getText() == "horizontal"
|
||||||
? Orientation::horizontal
|
? Orientation::HORIZONTAL
|
||||||
: Orientation::vertical;
|
: Orientation::VERTICAL;
|
||||||
auto splitBox = std::make_shared<SplitBox>(
|
auto splitBox = std::make_shared<SplitBox>(
|
||||||
reader.getGUI(), glm::vec2(), splitPos, orientation
|
reader.getGUI(), glm::vec2(), splitPos, orientation
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user