Add menu stuff
This commit is contained in:
parent
3e284af672
commit
b6f6b28c98
@ -199,6 +199,12 @@ void gui::Context::DrawText(std::string_view text, const glm::vec2& pos, uint32_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gui::Context::DrawTextAligned(std::string_view text, const glm::vec2& pos, const glm::vec2& align, uint32_t color, float scale)
|
||||||
|
{
|
||||||
|
auto size = MeasureText(text) * scale;
|
||||||
|
DrawText(text, pos + size * align, color, scale);
|
||||||
|
}
|
||||||
|
|
||||||
void gui::Context::Render()
|
void gui::Context::Render()
|
||||||
{
|
{
|
||||||
va_.SetVBOData(vertices_.data(), vertices_.size() * sizeof(vertices_[0]));
|
va_.SetVBOData(vertices_.data(), vertices_.size() * sizeof(vertices_[0]));
|
||||||
|
|||||||
@ -36,6 +36,7 @@ public:
|
|||||||
|
|
||||||
glm::vec2 MeasureText(std::string_view text);
|
glm::vec2 MeasureText(std::string_view text);
|
||||||
void DrawText(std::string_view text, const glm::vec2& pos, uint32_t color = 0xFFFFFFFF, float scale = 1.0f);
|
void DrawText(std::string_view text, const glm::vec2& pos, uint32_t color = 0xFFFFFFFF, float scale = 1.0f);
|
||||||
|
void DrawTextAligned(std::string_view text, const glm::vec2& pos, const glm::vec2& align, uint32_t color = 0xFFFFFFFF, float scale = 1.0f);
|
||||||
|
|
||||||
void Render();
|
void Render();
|
||||||
|
|
||||||
|
|||||||
120
src/gui/menu.cpp
Normal file
120
src/gui/menu.cpp
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#include "menu.hpp"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
// Menu
|
||||||
|
|
||||||
|
void gui::Menu::Draw(Context& ctx, const glm::vec2& pos) const
|
||||||
|
{
|
||||||
|
// TODO: draw bg
|
||||||
|
|
||||||
|
glm::vec2 cursor = pos;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < items_.size(); ++i)
|
||||||
|
{
|
||||||
|
items_[i]->Draw(DrawMenuItemArgs(ctx, cursor, focus_ == i));
|
||||||
|
cursor.y += items_[i]->GetSize().y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui::Menu::Input(MenuInput in)
|
||||||
|
{
|
||||||
|
switch (in)
|
||||||
|
{
|
||||||
|
case MI_UP:
|
||||||
|
SwitchFocus(-1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MI_DOWN:
|
||||||
|
SwitchFocus(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (!items_.empty())
|
||||||
|
items_[focus_]->Input(in);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec2 gui::Menu::MeasureSize() const
|
||||||
|
{
|
||||||
|
glm::vec2 size(0.0f);
|
||||||
|
|
||||||
|
for (const auto& item : items_)
|
||||||
|
{
|
||||||
|
const auto& itemsize = item->GetSize();
|
||||||
|
size.x = glm::max(size.x, itemsize.x);
|
||||||
|
size.y += itemsize.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui::Menu::SwitchFocus(int dir)
|
||||||
|
{
|
||||||
|
if (items_.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
focus_ = (focus_ + items_.size() + dir) % items_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ButtonMenuItem
|
||||||
|
|
||||||
|
gui::ButtonMenuItem::ButtonMenuItem(std::string text, std::function<void()> click_cb)
|
||||||
|
: text_(std::move(text)), click_cb_(std::move(click_cb))
|
||||||
|
{
|
||||||
|
size_ = glm::vec2(500.0f, 30.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui::ButtonMenuItem::Draw(const DrawMenuItemArgs& args) const
|
||||||
|
{
|
||||||
|
Super::Draw(args);
|
||||||
|
glm::vec2 center = args.pos + glm::vec2(0.0f, size_.y * 0.5f);
|
||||||
|
args.ctx.DrawTextAligned(text_, center, glm::vec2(0.0f, -0.5f), args.focused ? COLOR_FOCUSED : COLOR_INACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui::ButtonMenuItem::Input(MenuInput in)
|
||||||
|
{
|
||||||
|
if (in == MI_ENTER && click_cb_)
|
||||||
|
click_cb_();
|
||||||
|
}
|
||||||
|
|
||||||
|
// SelectMenuItem
|
||||||
|
|
||||||
|
gui::SelectMenuItem::SelectMenuItem(std::string text, std::function<void()> click_cb,
|
||||||
|
std::function<void(int)> switch_cb)
|
||||||
|
: ButtonMenuItem(std::move(text), std::move(click_cb)), switch_cb_(std::move(switch_cb))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui::SelectMenuItem::Draw(const DrawMenuItemArgs& args) const
|
||||||
|
{
|
||||||
|
Super::Draw(args);
|
||||||
|
|
||||||
|
char buffer[128];
|
||||||
|
size_t len = snprintf(buffer, sizeof(buffer), "< %s >", select_text_.c_str());
|
||||||
|
|
||||||
|
glm::vec2 center_right = args.pos + glm::vec2(size_.x, size_.y * 0.5f);
|
||||||
|
args.ctx.DrawTextAligned(std::string_view(buffer, len), center_right, glm::vec2(-1.0f, -0.5f),
|
||||||
|
args.focused ? COLOR_FOCUSED : COLOR_INACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gui::SelectMenuItem::Input(MenuInput in)
|
||||||
|
{
|
||||||
|
switch (in)
|
||||||
|
{
|
||||||
|
case MI_LEFT:
|
||||||
|
if (switch_cb_)
|
||||||
|
switch_cb_(-1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MI_RIGHT:
|
||||||
|
if (switch_cb_)
|
||||||
|
switch_cb_(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
Super::Input(in);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
119
src/gui/menu.hpp
Normal file
119
src/gui/menu.hpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <concepts>
|
||||||
|
|
||||||
|
#include "context.hpp"
|
||||||
|
|
||||||
|
namespace gui
|
||||||
|
{
|
||||||
|
|
||||||
|
enum MenuInput
|
||||||
|
{
|
||||||
|
MI_UP,
|
||||||
|
MI_DOWN,
|
||||||
|
MI_LEFT,
|
||||||
|
MI_RIGHT,
|
||||||
|
MI_BACK,
|
||||||
|
MI_ENTER,
|
||||||
|
};
|
||||||
|
|
||||||
|
class MenuItem;
|
||||||
|
|
||||||
|
struct DrawMenuItemArgs
|
||||||
|
{
|
||||||
|
Context& ctx;
|
||||||
|
glm::vec2 pos;
|
||||||
|
bool focused;
|
||||||
|
|
||||||
|
DrawMenuItemArgs(Context& ctx, const glm::vec2& pos, bool focused) : ctx(ctx), pos(pos), focused(focused) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class Menu
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Menu() = default;
|
||||||
|
|
||||||
|
template <std::derived_from<MenuItem> T, typename... TArgs>
|
||||||
|
T& Add(TArgs&&... args)
|
||||||
|
{
|
||||||
|
auto item = std::make_unique<T>(std::forward<TArgs>(args)...);
|
||||||
|
auto& item_ref = *item;
|
||||||
|
items_.emplace_back(std::move(item));
|
||||||
|
return item_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Draw(Context& ctx, const glm::vec2& pos) const;
|
||||||
|
void Input(MenuInput in);
|
||||||
|
|
||||||
|
glm::vec2 MeasureSize() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SwitchFocus(int dir);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::unique_ptr<MenuItem>> items_;
|
||||||
|
size_t focus_ = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class MenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr static uint32_t COLOR_INACTIVE = 0xFFFFFFFF;
|
||||||
|
constexpr static uint32_t COLOR_FOCUSED = 0xFF00FFFF;
|
||||||
|
|
||||||
|
MenuItem() = default;
|
||||||
|
|
||||||
|
virtual void Draw(const DrawMenuItemArgs& args) const {}
|
||||||
|
virtual void Input(MenuInput in) {}
|
||||||
|
|
||||||
|
const glm::vec2& GetSize() const { return size_; }
|
||||||
|
|
||||||
|
virtual ~MenuItem() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
glm::vec2 size_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class ButtonMenuItem : public MenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Super = MenuItem;
|
||||||
|
|
||||||
|
ButtonMenuItem(std::string text, std::function<void()> click_cb);
|
||||||
|
|
||||||
|
virtual void Draw(const DrawMenuItemArgs& args) const override;
|
||||||
|
virtual void Input(MenuInput in) override;
|
||||||
|
|
||||||
|
virtual ~ButtonMenuItem() = default;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string text_;
|
||||||
|
std::function<void()> click_cb_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SelectMenuItem : public ButtonMenuItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using Super = ButtonMenuItem;
|
||||||
|
|
||||||
|
SelectMenuItem(std::string text, std::function<void()> click_cb, std::function<void(int)> switch_cb);
|
||||||
|
|
||||||
|
virtual void Draw(const DrawMenuItemArgs& args) const override;
|
||||||
|
virtual void Input(MenuInput in) override;
|
||||||
|
|
||||||
|
void SetSelectionText(std::string select_text) { select_text_ = std::move(select_text); }
|
||||||
|
|
||||||
|
virtual ~SelectMenuItem() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string select_text_;
|
||||||
|
std::function<void(int)> switch_cb_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user