summaryrefslogtreecommitdiffstats
path: root/src/game/client/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/client/gui')
-rw-r--r--src/game/client/gui/CMakeLists.txt8
-rw-r--r--src/game/client/gui/background.cc14
-rw-r--r--src/game/client/gui/background.hh4
-rw-r--r--src/game/client/gui/bother.cc12
-rw-r--r--src/game/client/gui/bother.hh7
-rw-r--r--src/game/client/gui/chat.cc30
-rw-r--r--src/game/client/gui/chat.hh8
-rw-r--r--src/game/client/gui/crosshair.cc6
-rw-r--r--src/game/client/gui/crosshair.hh4
-rw-r--r--src/game/client/gui/direct_connection.cc20
-rw-r--r--src/game/client/gui/direct_connection.hh4
-rw-r--r--src/game/client/gui/hotbar.cc54
-rw-r--r--src/game/client/gui/hotbar.hh17
-rw-r--r--src/game/client/gui/imdraw_ext.cc34
-rw-r--r--src/game/client/gui/imdraw_ext.hh17
-rw-r--r--src/game/client/gui/imutils_button.cc95
-rw-r--r--src/game/client/gui/imutils_button.hh14
-rw-r--r--src/game/client/gui/imutils_popup.cc56
-rw-r--r--src/game/client/gui/imutils_popup.hh11
-rw-r--r--src/game/client/gui/imutils_text.cc46
-rw-r--r--src/game/client/gui/imutils_text.hh9
-rw-r--r--src/game/client/gui/language.cc38
-rw-r--r--src/game/client/gui/language.hh19
-rw-r--r--src/game/client/gui/main_menu.cc190
-rw-r--r--src/game/client/gui/main_menu.hh4
-rw-r--r--src/game/client/gui/message_box.cc20
-rw-r--r--src/game/client/gui/message_box.hh11
-rw-r--r--src/game/client/gui/metrics.cc28
-rw-r--r--src/game/client/gui/metrics.hh4
-rw-r--r--src/game/client/gui/play_menu.cc65
-rw-r--r--src/game/client/gui/play_menu.hh4
-rw-r--r--src/game/client/gui/progress_bar.cc16
-rw-r--r--src/game/client/gui/progress_bar.hh11
-rw-r--r--src/game/client/gui/scoreboard.cc4
-rw-r--r--src/game/client/gui/scoreboard.hh4
-rw-r--r--src/game/client/gui/settings.cc434
-rw-r--r--src/game/client/gui/splash.cc32
-rw-r--r--src/game/client/gui/splash.hh4
-rw-r--r--src/game/client/gui/status_lines.cc38
-rw-r--r--src/game/client/gui/status_lines.hh11
-rw-r--r--src/game/client/gui/window_title.cc2
-rw-r--r--src/game/client/gui/window_title.hh4
42 files changed, 763 insertions, 650 deletions
diff --git a/src/game/client/gui/CMakeLists.txt b/src/game/client/gui/CMakeLists.txt
index 46d64a1..e3d8b7a 100644
--- a/src/game/client/gui/CMakeLists.txt
+++ b/src/game/client/gui/CMakeLists.txt
@@ -12,8 +12,12 @@ target_sources(vclient PRIVATE
"${CMAKE_CURRENT_LIST_DIR}/gui_screen.hh"
"${CMAKE_CURRENT_LIST_DIR}/hotbar.cc"
"${CMAKE_CURRENT_LIST_DIR}/hotbar.hh"
- "${CMAKE_CURRENT_LIST_DIR}/imdraw_ext.cc"
- "${CMAKE_CURRENT_LIST_DIR}/imdraw_ext.hh"
+ "${CMAKE_CURRENT_LIST_DIR}/imutils_button.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/imutils_button.hh"
+ "${CMAKE_CURRENT_LIST_DIR}/imutils_popup.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/imutils_popup.hh"
+ "${CMAKE_CURRENT_LIST_DIR}/imutils_text.cc"
+ "${CMAKE_CURRENT_LIST_DIR}/imutils_text.hh"
"${CMAKE_CURRENT_LIST_DIR}/language.cc"
"${CMAKE_CURRENT_LIST_DIR}/language.hh"
"${CMAKE_CURRENT_LIST_DIR}/main_menu.cc"
diff --git a/src/game/client/gui/background.cc b/src/game/client/gui/background.cc
index 50fef01..81fb764 100644
--- a/src/game/client/gui/background.cc
+++ b/src/game/client/gui/background.cc
@@ -12,9 +12,9 @@
static resource_ptr<TextureGUI> texture;
-void gui::background::init(void)
+void background::init(void)
{
- texture = resource::load<TextureGUI>("textures/gui/background.png", TEXTURE_GUI_LOAD_VFLIP);
+ texture = resource::load<TextureGUI>("textures/gui/background.png");
if(texture == nullptr) {
spdlog::critical("background: texture load failed");
@@ -22,18 +22,14 @@ void gui::background::init(void)
}
}
-void gui::background::shutdown(void)
+void background::shutdown(void)
{
texture = nullptr;
}
-void gui::background::layout(void)
+void background::layout(void)
{
auto viewport = ImGui::GetMainViewport();
auto draw_list = ImGui::GetBackgroundDrawList();
-
- auto scaled_width = 0.75f * static_cast<float>(globals::width / globals::gui_scale);
- auto scaled_height = 0.75f * static_cast<float>(globals::height / globals::gui_scale);
- auto scale_uv = ImVec2(scaled_width / static_cast<float>(texture->size.x), scaled_height / static_cast<float>(texture->size.y));
- draw_list->AddImage(texture->handle, ImVec2(0.0f, 0.0f), viewport->Size, ImVec2(0.0f, 0.0f), scale_uv);
+ draw_list->AddImage(texture->handle, {}, viewport->Size);
}
diff --git a/src/game/client/gui/background.hh b/src/game/client/gui/background.hh
index 5c72a3f..51497d1 100644
--- a/src/game/client/gui/background.hh
+++ b/src/game/client/gui/background.hh
@@ -1,8 +1,8 @@
#pragma once
-namespace gui::background
+namespace background
{
void init(void);
void shutdown(void);
void layout(void);
-} // namespace gui::background
+} // namespace background
diff --git a/src/game/client/gui/bother.cc b/src/game/client/gui/bother.cc
index a045284..7309bbc 100644
--- a/src/game/client/gui/bother.cc
+++ b/src/game/client/gui/bother.cc
@@ -28,7 +28,7 @@ static void on_status_response_packet(const protocol::StatusResponse& packet)
bother_set.erase(identity);
- gui::BotherResponseEvent event;
+ BotherResponseEvent event;
event.identity = identity;
event.is_server_unreachable = false;
event.num_players = packet.num_players;
@@ -42,7 +42,7 @@ static void on_status_response_packet(const protocol::StatusResponse& packet)
enet_peer_disconnect(packet.peer, protocol::CHANNEL);
}
-void gui::bother::init(void)
+void bother::init(void)
{
bother_host = enet_host_create(nullptr, BOTHER_PEERS, 1, 0, 0);
bother_dispatcher.clear();
@@ -51,14 +51,14 @@ void gui::bother::init(void)
bother_dispatcher.sink<protocol::StatusResponse>().connect<&on_status_response_packet>();
}
-void gui::bother::shutdown(void)
+void bother::shutdown(void)
{
enet_host_destroy(bother_host);
bother_dispatcher.clear();
bother_set.clear();
}
-void gui::bother::update_late(void)
+void bother::update_late(void)
{
unsigned int free_peers = 0U;
@@ -121,7 +121,7 @@ void gui::bother::update_late(void)
}
}
-void gui::bother::ping(unsigned int identity, std::string_view host, std::uint16_t port)
+void bother::ping(unsigned int identity, std::string_view host, std::uint16_t port)
{
if(bother_set.count(identity)) {
// Already in the process
@@ -143,7 +143,7 @@ void gui::bother::ping(unsigned int identity, std::string_view host, std::uint16
bother_queue.push_back(item);
}
-void gui::bother::cancel(unsigned int identity)
+void bother::cancel(unsigned int identity)
{
bother_set.erase(identity);
diff --git a/src/game/client/gui/bother.hh b/src/game/client/gui/bother.hh
index b0355ca..ed4f84f 100644
--- a/src/game/client/gui/bother.hh
+++ b/src/game/client/gui/bother.hh
@@ -1,7 +1,5 @@
#pragma once
-namespace gui
-{
struct BotherResponseEvent final {
unsigned int identity;
bool is_server_unreachable;
@@ -12,13 +10,12 @@ struct BotherResponseEvent final {
std::uint32_t game_version_patch;
std::string motd;
};
-} // namespace gui
-namespace gui::bother
+namespace bother
{
void init(void);
void shutdown(void);
void update_late(void);
void ping(unsigned int identity, std::string_view host, std::uint16_t port);
void cancel(unsigned int identity);
-} // namespace gui::bother
+} // namespace bother
diff --git a/src/game/client/gui/chat.cc b/src/game/client/gui/chat.cc
index 70a1668..76260af 100644
--- a/src/game/client/gui/chat.cc
+++ b/src/game/client/gui/chat.cc
@@ -16,7 +16,7 @@
#include "client/config/keybind.hh"
#include "client/gui/gui_screen.hh"
-#include "client/gui/imdraw_ext.hh"
+#include "client/gui/imutils_text.hh"
#include "client/gui/language.hh"
#include "client/gui/settings.hh"
@@ -65,7 +65,7 @@ static void append_player_join(const std::string& sender)
{
GuiChatMessage message;
message.spawn = globals::curtime;
- message.text = std::format("{} {}", sender, gui::language::resolve("chat.client_join"));
+ message.text = std::format("{} {}", sender, language::resolve("chat.client_join"));
message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget);
history.push_back(message);
@@ -78,7 +78,7 @@ static void append_player_leave(const std::string& sender, const std::string& re
{
GuiChatMessage message;
message.spawn = globals::curtime;
- message.text = std::format("{} {} ({})", sender, gui::language::resolve("chat.client_left"), gui::language::resolve(reason.c_str()));
+ message.text = std::format("{} {} ({})", sender, language::resolve("chat.client_left"), language::resolve(reason.c_str()));
message.color = ImGui::GetStyleColorVec4(ImGuiCol_DragDropTarget);
history.push_back(message);
@@ -105,7 +105,7 @@ static void on_chat_message_packet(const protocol::ChatMessage& packet)
}
}
-static void on_glfw_key(const io::GlfwKeyEvent& event)
+static void on_glfw_key(const GlfwKeyEvent& event)
{
if(event.action == GLFW_PRESS) {
if((event.key == GLFW_KEY_ENTER) && (globals::gui_screen == GUI_CHAT)) {
@@ -138,7 +138,7 @@ static void on_glfw_key(const io::GlfwKeyEvent& event)
}
}
-void gui::client_chat::init(void)
+void client_chat::init(void)
{
globals::client_config.add_value("chat.key", key_chat);
globals::client_config.add_value("chat.history_size", history_size);
@@ -147,28 +147,28 @@ void gui::client_chat::init(void)
settings::add_slider(1, history_size, settings_location::VIDEO_GUI, "chat.history_size", false);
globals::dispatcher.sink<protocol::ChatMessage>().connect<&on_chat_message_packet>();
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
sfx_chat_message = resource::load<SoundEffect>("sounds/ui/chat_message.wav");
}
-void gui::client_chat::init_late(void)
+void client_chat::init_late(void)
{
}
-void gui::client_chat::shutdown(void)
+void client_chat::shutdown(void)
{
sfx_chat_message = nullptr;
}
-void gui::client_chat::update(void)
+void client_chat::update(void)
{
while(history.size() > history_size.get_value()) {
history.pop_front();
}
}
-void gui::client_chat::layout(void)
+void client_chat::layout(void)
{
auto viewport = ImGui::GetMainViewport();
auto window_start = ImVec2(0.0f, 0.0f);
@@ -177,7 +177,7 @@ void gui::client_chat::layout(void)
ImGui::SetNextWindowPos(window_start);
ImGui::SetNextWindowSize(window_size);
- ImGui::PushFont(globals::font_unscii16, 8.0f);
+ ImGui::PushFont(globals::font_unscii16, 16.0f);
if(!ImGui::Begin("###chat", nullptr, WINDOW_FLAGS)) {
ImGui::End();
@@ -235,7 +235,7 @@ void gui::client_chat::layout(void)
draw_list->AddRectFilled(rect_pos, rect_end, rect_col);
- imdraw_ext::text_shadow_w(it->text, text_pos, text_col, shadow_col, font, draw_list, 8.0f, window_size.x);
+ imutils::text_wr(draw_list, it->text, text_pos, text_col, shadow_col, font, window_size.x, ImGui::GetFontSize());
ypos -= rect_size.y;
}
@@ -245,12 +245,12 @@ void gui::client_chat::layout(void)
ImGui::PopFont();
}
-void gui::client_chat::clear(void)
+void client_chat::clear(void)
{
history.clear();
}
-void gui::client_chat::refresh_timings(void)
+void client_chat::refresh_timings(void)
{
for(auto it = history.begin(); it < history.end(); ++it) {
// Reset the spawn time so the fadeout timer
@@ -259,7 +259,7 @@ void gui::client_chat::refresh_timings(void)
}
}
-void gui::client_chat::print(const std::string& text)
+void client_chat::print(const std::string& text)
{
GuiChatMessage message = {};
message.spawn = globals::curtime;
diff --git a/src/game/client/gui/chat.hh b/src/game/client/gui/chat.hh
index 6a3ea33..91c3740 100644
--- a/src/game/client/gui/chat.hh
+++ b/src/game/client/gui/chat.hh
@@ -1,17 +1,17 @@
#pragma once
-namespace gui::client_chat
+namespace client_chat
{
void init(void);
void init_late(void);
void shutdown(void);
void update(void);
void layout(void);
-} // namespace gui::client_chat
+} // namespace client_chat
-namespace gui::client_chat
+namespace client_chat
{
void clear(void);
void refresh_timings(void);
void print(const std::string& string);
-} // namespace gui::client_chat
+} // namespace client_chat
diff --git a/src/game/client/gui/crosshair.cc b/src/game/client/gui/crosshair.cc
index 649602f..758a10b 100644
--- a/src/game/client/gui/crosshair.cc
+++ b/src/game/client/gui/crosshair.cc
@@ -13,7 +13,7 @@
static resource_ptr<TextureGUI> texture;
-void gui::crosshair::init(void)
+void crosshair::init(void)
{
texture = resource::load<TextureGUI>("textures/gui/hud_crosshair.png",
TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T | TEXTURE_GUI_LOAD_VFLIP);
@@ -24,12 +24,12 @@ void gui::crosshair::init(void)
}
}
-void gui::crosshair::shutdown(void)
+void crosshair::shutdown(void)
{
texture = nullptr;
}
-void gui::crosshair::layout(void)
+void crosshair::layout(void)
{
auto viewport = ImGui::GetMainViewport();
auto draw_list = ImGui::GetForegroundDrawList();
diff --git a/src/game/client/gui/crosshair.hh b/src/game/client/gui/crosshair.hh
index 589727e..6789e1e 100644
--- a/src/game/client/gui/crosshair.hh
+++ b/src/game/client/gui/crosshair.hh
@@ -1,8 +1,8 @@
#pragma once
-namespace gui::crosshair
+namespace crosshair
{
void init(void);
void shutdown(void);
void layout(void);
-} // namespace gui::crosshair
+} // namespace crosshair
diff --git a/src/game/client/gui/direct_connection.cc b/src/game/client/gui/direct_connection.cc
index 39ea2b5..d7cea64 100644
--- a/src/game/client/gui/direct_connection.cc
+++ b/src/game/client/gui/direct_connection.cc
@@ -29,7 +29,7 @@ static std::string str_password;
static std::string direct_hostname;
static std::string direct_password;
-static void on_glfw_key(const io::GlfwKeyEvent& event)
+static void on_glfw_key(const GlfwKeyEvent& event)
{
if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
if(globals::gui_screen == GUI_DIRECT_CONNECTION) {
@@ -39,14 +39,14 @@ static void on_glfw_key(const io::GlfwKeyEvent& event)
}
}
-static void on_language_set(const gui::LanguageSetEvent& event)
+static void on_language_set(const LanguageSetEvent& event)
{
- str_title = gui::language::resolve("direct_connection.title");
- str_connect = gui::language::resolve_gui("direct_connection.connect");
- str_cancel = gui::language::resolve_gui("direct_connection.cancel");
+ str_title = language::resolve("direct_connection.title");
+ str_connect = language::resolve_gui("direct_connection.connect");
+ str_cancel = language::resolve_gui("direct_connection.cancel");
- str_hostname = gui::language::resolve("direct_connection.hostname");
- str_password = gui::language::resolve("direct_connection.password");
+ str_hostname = language::resolve("direct_connection.hostname");
+ str_password = language::resolve("direct_connection.password");
}
static void connect_to_server(void)
@@ -72,13 +72,13 @@ static void connect_to_server(void)
session::connect(parsed_hostname.c_str(), parsed_port, direct_password.c_str());
}
-void gui::direct_connection::init(void)
+void direct_connection::init(void)
{
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
}
-void gui::direct_connection::layout(void)
+void direct_connection::layout(void)
{
auto viewport = ImGui::GetMainViewport();
auto window_start = ImVec2(0.25f * viewport->Size.x, 0.20f * viewport->Size.y);
diff --git a/src/game/client/gui/direct_connection.hh b/src/game/client/gui/direct_connection.hh
index aa02d7c..0a09a3f 100644
--- a/src/game/client/gui/direct_connection.hh
+++ b/src/game/client/gui/direct_connection.hh
@@ -1,7 +1,7 @@
#pragma once
-namespace gui::direct_connection
+namespace direct_connection
{
void init(void);
void layout(void);
-} // namespace gui::direct_connection
+} // namespace direct_connection
diff --git a/src/game/client/gui/hotbar.cc b/src/game/client/gui/hotbar.cc
index 663f263..b38c368 100644
--- a/src/game/client/gui/hotbar.cc
+++ b/src/game/client/gui/hotbar.cc
@@ -19,13 +19,13 @@
#include "client/globals.hh"
-constexpr static float ITEM_SIZE = 20.0f;
-constexpr static float ITEM_PADDING = 2.0f;
-constexpr static float SELECTOR_PADDING = 1.0f;
-constexpr static float HOTBAR_PADDING = 2.0f;
+constexpr static float ITEM_SIZE = 40.0f;
+constexpr static float ITEM_PADDING = 4.0f;
+constexpr static float SELECTOR_PADDING = 2.0f;
+constexpr static float HOTBAR_PADDING = 4.0f;
-unsigned int gui::hotbar::active_slot = 0U;
-std::array<const world::Item*, HOTBAR_SIZE> gui::hotbar::slots = {};
+unsigned int hotbar::active_slot = 0U;
+std::array<const Item*, HOTBAR_SIZE> hotbar::slots = {};
static config::KeyBind hotbar_keys[HOTBAR_SIZE];
@@ -40,22 +40,22 @@ static ImU32 get_color_alpha(ImGuiCol style_color, float alpha)
static void update_hotbar_item(void)
{
- auto current_item = gui::hotbar::slots[gui::hotbar::active_slot];
+ auto current_item = hotbar::slots[hotbar::active_slot];
if(current_item == nullptr) {
- gui::status_lines::unset(gui::STATUS_HOTBAR);
+ status_lines::unset(STATUS_HOTBAR);
}
else {
- gui::status_lines::set(gui::STATUS_HOTBAR, current_item->get_name(), ImVec4(1.0f, 1.0f, 1.0f, 1.0f), 5.0f);
+ status_lines::set(STATUS_HOTBAR, current_item->get_name(), ImVec4(1.0f, 1.0f, 1.0f, 1.0f), 5.0f);
}
}
-static void on_glfw_key(const io::GlfwKeyEvent& event)
+static void on_glfw_key(const GlfwKeyEvent& event)
{
if((event.action == GLFW_PRESS) && !globals::gui_screen) {
for(unsigned int i = 0U; i < HOTBAR_SIZE; ++i) {
if(hotbar_keys[i].equals(event.key)) {
- gui::hotbar::active_slot = i;
+ hotbar::active_slot = i;
update_hotbar_item();
break;
}
@@ -63,22 +63,22 @@ static void on_glfw_key(const io::GlfwKeyEvent& event)
}
}
-static void on_glfw_scroll(const io::GlfwScrollEvent& event)
+static void on_glfw_scroll(const GlfwScrollEvent& event)
{
if(!globals::gui_screen) {
if(event.dy < 0.0) {
- gui::hotbar::next_slot();
+ hotbar::next_slot();
return;
}
if(event.dy > 0.0) {
- gui::hotbar::prev_slot();
+ hotbar::prev_slot();
return;
}
}
}
-void gui::hotbar::init(void)
+void hotbar::init(void)
{
hotbar_keys[0].set_key(GLFW_KEY_1);
hotbar_keys[1].set_key(GLFW_KEY_2);
@@ -113,17 +113,17 @@ void gui::hotbar::init(void)
hotbar_background = resource::load<TextureGUI>("textures/gui/hud_hotbar.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
hotbar_selector = resource::load<TextureGUI>("textures/gui/hud_selector.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().connect<&on_glfw_scroll>();
+ globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<GlfwScrollEvent>().connect<&on_glfw_scroll>();
}
-void gui::hotbar::shutdown(void)
+void hotbar::shutdown(void)
{
hotbar_background = nullptr;
hotbar_selector = nullptr;
}
-void gui::hotbar::layout(void)
+void hotbar::layout(void)
{
auto& style = ImGui::GetStyle();
@@ -142,7 +142,7 @@ void gui::hotbar::layout(void)
// Draw the hotbar selector image
auto selector_padding_a = SELECTOR_PADDING * globals::gui_scale;
auto selector_padding_b = SELECTOR_PADDING * globals::gui_scale * 2.0f;
- auto selector_start = ImVec2(background_start.x + gui::hotbar::active_slot * item_size - selector_padding_a,
+ auto selector_start = ImVec2(background_start.x + hotbar::active_slot * item_size - selector_padding_a,
background_start.y - selector_padding_a);
auto selector_end = ImVec2(selector_start.x + item_size + selector_padding_b, selector_start.y + item_size + selector_padding_b);
draw_list->AddImage(hotbar_selector->handle, selector_start, selector_end);
@@ -153,7 +153,7 @@ void gui::hotbar::layout(void)
// Draw individual item textures in the hotbar
for(std::size_t i = 0; i < HOTBAR_SIZE; ++i) {
- auto item = gui::hotbar::slots[i];
+ auto item = hotbar::slots[i];
if((item == nullptr) || (item->get_cached_texture() == nullptr)) {
// There's either no item in the slot
@@ -167,16 +167,16 @@ void gui::hotbar::layout(void)
}
}
-void gui::hotbar::next_slot(void)
+void hotbar::next_slot(void)
{
- gui::hotbar::active_slot += 1U;
- gui::hotbar::active_slot %= HOTBAR_SIZE;
+ hotbar::active_slot += 1U;
+ hotbar::active_slot %= HOTBAR_SIZE;
update_hotbar_item();
}
-void gui::hotbar::prev_slot(void)
+void hotbar::prev_slot(void)
{
- gui::hotbar::active_slot += HOTBAR_SIZE - 1U;
- gui::hotbar::active_slot %= HOTBAR_SIZE;
+ hotbar::active_slot += HOTBAR_SIZE - 1U;
+ hotbar::active_slot %= HOTBAR_SIZE;
update_hotbar_item();
}
diff --git a/src/game/client/gui/hotbar.hh b/src/game/client/gui/hotbar.hh
index c529230..bba5e63 100644
--- a/src/game/client/gui/hotbar.hh
+++ b/src/game/client/gui/hotbar.hh
@@ -3,28 +3,25 @@
// TODO: design an inventory system and an item
// registry and integrate the hotbar into that system
-namespace world
-{
class Item;
-} // namespace world
constexpr static unsigned int HOTBAR_SIZE = 9U;
-namespace gui::hotbar
+namespace hotbar
{
extern unsigned int active_slot;
-extern std::array<const world::Item*, HOTBAR_SIZE> slots;
-} // namespace gui::hotbar
+extern std::array<const Item*, HOTBAR_SIZE> slots;
+} // namespace hotbar
-namespace gui::hotbar
+namespace hotbar
{
void init(void);
void shutdown(void);
void layout(void);
-} // namespace gui::hotbar
+} // namespace hotbar
-namespace gui::hotbar
+namespace hotbar
{
void next_slot(void);
void prev_slot(void);
-} // namespace gui::hotbar
+} // namespace hotbar
diff --git a/src/game/client/gui/imdraw_ext.cc b/src/game/client/gui/imdraw_ext.cc
deleted file mode 100644
index 4b44d5f..0000000
--- a/src/game/client/gui/imdraw_ext.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-#include "client/pch.hh"
-
-#include "client/gui/imdraw_ext.hh"
-
-#include "client/globals.hh"
-
-void gui::imdraw_ext::text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list)
-{
- imdraw_ext::text_shadow(text, position, text_color, shadow_color, font, draw_list, font->LegacySize);
-}
-
-void gui::imdraw_ext::text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size)
-{
- const auto shadow_position = ImVec2(position.x + 0.5f * globals::gui_scale, position.y + 0.5f * globals::gui_scale);
- draw_list->AddText(font, globals::gui_scale * font_size, shadow_position, shadow_color, text.c_str(), text.c_str() + text.size());
- draw_list->AddText(font, globals::gui_scale * font_size, position, text_color, text.c_str(), text.c_str() + text.size());
-}
-
-void gui::imdraw_ext::text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float wrap_width)
-{
- imdraw_ext::text_shadow_w(text, position, text_color, shadow_color, font, draw_list, font->LegacySize, wrap_width);
-}
-
-void gui::imdraw_ext::text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size, float wrap_width)
-{
- const auto shadow_position = ImVec2(position.x + 0.5f * globals::gui_scale, position.y + 0.5f * globals::gui_scale);
- draw_list->AddText(font, globals::gui_scale * font_size, shadow_position, shadow_color, text.c_str(), text.c_str() + text.size(),
- wrap_width);
- draw_list->AddText(font, globals::gui_scale * font_size, position, text_color, text.c_str(), text.c_str() + text.size(), wrap_width);
-}
diff --git a/src/game/client/gui/imdraw_ext.hh b/src/game/client/gui/imdraw_ext.hh
deleted file mode 100644
index a7e1503..0000000
--- a/src/game/client/gui/imdraw_ext.hh
+++ /dev/null
@@ -1,17 +0,0 @@
-#pragma once
-
-namespace gui::imdraw_ext
-{
-void text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list);
-void text_shadow(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font, ImDrawList* draw_list,
- float font_size);
-} // namespace gui::imdraw_ext
-
-namespace gui::imdraw_ext
-{
-void text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float wrap_width);
-void text_shadow_w(const std::string& text, const ImVec2& position, ImU32 text_color, ImU32 shadow_color, ImFont* font,
- ImDrawList* draw_list, float font_size, float wrap_width);
-} // namespace gui::imdraw_ext
diff --git a/src/game/client/gui/imutils_button.cc b/src/game/client/gui/imutils_button.cc
new file mode 100644
index 0000000..2017e33
--- /dev/null
+++ b/src/game/client/gui/imutils_button.cc
@@ -0,0 +1,95 @@
+#include "client/pch.hh"
+
+#include "client/gui/imutils_button.hh"
+
+void imutils::button(const char* title, const ImVec2& size, void (*callback)(void))
+{
+ assert(title);
+ assert(callback);
+
+ if(ImGui::Button(title, size)) {
+ callback();
+ }
+}
+
+void imutils::button(const char* title, void (*callback)(void))
+{
+ assert(title);
+ assert(callback);
+
+ if(ImGui::Button(title)) {
+ callback();
+ }
+}
+
+bool imutils::selectable_button(const char* label, const ImVec2& size, bool value)
+{
+ assert(label);
+
+ auto value_changed = false;
+
+ if(value) {
+ ImVec4 button_color(0.750f, 0.750f, 0.750f, 1.000f);
+ ImGui::PushStyleColor(ImGuiCol_Button, button_color);
+ ImGui::PushStyleColor(ImGuiCol_ButtonActive, button_color);
+ ImGui::PushStyleColor(ImGuiCol_ButtonHovered, button_color);
+ ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
+ }
+ else {
+ ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
+ }
+
+ if(ImGui::Button(label, size)) {
+ value_changed = true;
+ }
+
+ ImGui::PopStyleColor(value ? 4 : 1);
+
+ return value_changed;
+}
+
+bool imutils::toggle_button(const char* label, const ImVec2& size, bool& value)
+{
+ assert(label);
+
+ auto use_custom_color = !value;
+ auto value_changed = false;
+
+ if(use_custom_color) {
+ ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
+ }
+
+ if(ImGui::Button(label, size)) {
+ value_changed = true;
+ value = !value;
+ }
+
+ if(use_custom_color) {
+ ImGui::PopStyleColor();
+ }
+
+ return value_changed;
+}
+
+bool imutils::toggle_button(const char* label, bool& value)
+{
+ assert(label);
+
+ auto use_custom_color = !value;
+ auto value_changed = false;
+
+ if(use_custom_color) {
+ ImGui::PushStyleColor(ImGuiCol_Button, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
+ }
+
+ if(ImGui::Button(label)) {
+ value_changed = true;
+ value = !value;
+ }
+
+ if(use_custom_color) {
+ ImGui::PopStyleColor();
+ }
+
+ return value_changed;
+}
diff --git a/src/game/client/gui/imutils_button.hh b/src/game/client/gui/imutils_button.hh
new file mode 100644
index 0000000..0c80694
--- /dev/null
+++ b/src/game/client/gui/imutils_button.hh
@@ -0,0 +1,14 @@
+#pragma once
+
+namespace imutils
+{
+void button(const char* title, const ImVec2& size, void (*callback)(void));
+void button(const char* title, void (*callback)(void));
+} // namespace imutils
+
+namespace imutils
+{
+bool selectable_button(const char* label, const ImVec2& size, bool value);
+bool toggle_button(const char* label, const ImVec2& size, bool& value);
+bool toggle_button(const char* label, bool& value);
+} // namespace imutils
diff --git a/src/game/client/gui/imutils_popup.cc b/src/game/client/gui/imutils_popup.cc
new file mode 100644
index 0000000..f97facb
--- /dev/null
+++ b/src/game/client/gui/imutils_popup.cc
@@ -0,0 +1,56 @@
+#include "client/pch.hh"
+
+#include "client/gui/imutils_popup.hh"
+
+#include "client/globals.hh"
+
+int imutils::popup(const std::string& title, const std::string& question, const std::string* choices, std::size_t num_choices,
+ float font_scale)
+{
+ assert(choices);
+ assert(num_choices);
+
+ int result = POPUP_WAIT;
+
+ ImGui::PushFont(globals::font_unscii16, globals::font_unscii16->LegacySize);
+
+ if(ImGui::BeginPopupModal(title.c_str(), nullptr, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize)) {
+ const auto viewport = ImGui::GetMainViewport();
+ const auto& viewport_size = viewport->Size;
+
+ ImVec2 popup_size(ImGui::GetWindowSize());
+ ImVec2 popup_pos(viewport_size.x * 0.5f - popup_size.x * 0.5f, viewport_size.y * 0.5f - popup_size.y * 0.5f);
+
+ ImGui::PushTextWrapPos(popup_size.x);
+ ImGui::TextUnformatted(question.c_str());
+ ImGui::PopTextWrapPos();
+
+ ImGui::NewLine();
+
+ auto& style = ImGui::GetStyle();
+ auto& spacing = style.ItemSpacing;
+ ImVec2 button_size(0.5f * (ImGui::CalcItemWidth() - spacing.x), 0.0f);
+
+ for(std::size_t i = 0; i < num_choices; ++i) {
+ if(ImGui::Button(choices[i].c_str(), button_size)) {
+ result = static_cast<int>(i);
+ ImGui::CloseCurrentPopup();
+ }
+
+ if((i + 1) % 2 == 1) {
+ ImGui::SameLine();
+ }
+ else if(i + 1 < num_choices) {
+ ImGui::Dummy(ImVec2(0.0, spacing.y));
+ }
+ }
+
+ ImGui::SetWindowPos(popup_pos, ImGuiCond_Always);
+
+ ImGui::EndPopup();
+ }
+
+ ImGui::PopFont();
+
+ return result;
+}
diff --git a/src/game/client/gui/imutils_popup.hh b/src/game/client/gui/imutils_popup.hh
new file mode 100644
index 0000000..1678f87
--- /dev/null
+++ b/src/game/client/gui/imutils_popup.hh
@@ -0,0 +1,11 @@
+#pragma once
+
+/// Returned by popup::show whenever the popup is opened
+/// but there is no user action yet, so the UI should wait
+constexpr static int POPUP_WAIT = -1;
+
+namespace imutils
+{
+int popup(const std::string& title, const std::string& question, const std::string* choices, std::size_t num_choices,
+ float font_scale = 1.75f);
+} // namespace imutils
diff --git a/src/game/client/gui/imutils_text.cc b/src/game/client/gui/imutils_text.cc
new file mode 100644
index 0000000..1058c7f
--- /dev/null
+++ b/src/game/client/gui/imutils_text.cc
@@ -0,0 +1,46 @@
+#include "client/pch.hh"
+
+#include "client/gui/imutils_text.hh"
+
+#include "client/globals.hh"
+
+void imutils::text_nw(ImDrawList* list, std::string_view text, const ImVec2& pos, ImU32 color, ImU32 shadow, ImFont* font)
+{
+ assert(list);
+ assert(font);
+
+ imutils::text_nw(list, text, pos, color, shadow, font, font->LegacySize);
+}
+
+void imutils::text_nw(ImDrawList* list, std::string_view text, const ImVec2& pos, ImU32 color, ImU32 shadow, ImFont* font, float size)
+{
+ assert(list);
+ assert(font);
+
+ auto shift = static_cast<float>(globals::gui_scale);
+ auto shadow_pos = ImVec2(pos.x + shift, pos.y + shift);
+
+ list->AddText(font, size, shadow_pos, shadow, text.data(), text.data() + text.size());
+ list->AddText(font, size, pos, color, text.data(), text.data() + text.size());
+}
+
+void imutils::text_wr(ImDrawList* list, std::string_view text, const ImVec2& pos, ImU32 color, ImU32 shadow, ImFont* font, float wrap)
+{
+ assert(list);
+ assert(font);
+
+ imutils::text_wr(list, text, pos, color, shadow, font, wrap, font->LegacySize);
+}
+
+void imutils::text_wr(ImDrawList* list, std::string_view text, const ImVec2& pos, ImU32 color, ImU32 shadow, ImFont* font, float wrap,
+ float size)
+{
+ assert(list);
+ assert(font);
+
+ auto shift = static_cast<float>(globals::gui_scale);
+ auto shadow_pos = ImVec2(pos.x + shift, pos.y + shift);
+
+ list->AddText(font, size, shadow_pos, shadow, text.data(), text.data() + text.size(), wrap);
+ list->AddText(font, size, pos, color, text.data(), text.data() + text.size(), wrap);
+}
diff --git a/src/game/client/gui/imutils_text.hh b/src/game/client/gui/imutils_text.hh
new file mode 100644
index 0000000..64d06a4
--- /dev/null
+++ b/src/game/client/gui/imutils_text.hh
@@ -0,0 +1,9 @@
+#pragma once
+
+namespace imutils
+{
+void text_nw(ImDrawList* list, std::string_view text, const ImVec2& pos, ImU32 color, ImU32 shadow, ImFont* font);
+void text_nw(ImDrawList* list, std::string_view text, const ImVec2& pos, ImU32 color, ImU32 shadow, ImFont* font, float size);
+void text_wr(ImDrawList* list, std::string_view text, const ImVec2& pos, ImU32 color, ImU32 shadow, ImFont* font, float wrap);
+void text_wr(ImDrawList* list, std::string_view text, const ImVec2& pos, ImU32 color, ImU32 shadow, ImFont* font, float wrap, float size);
+} // namespace imutils
diff --git a/src/game/client/gui/language.cc b/src/game/client/gui/language.cc
index 0109ae6..8a2d8d1 100644
--- a/src/game/client/gui/language.cc
+++ b/src/game/client/gui/language.cc
@@ -19,20 +19,20 @@ constexpr static std::string_view DEFAULT_LANGUAGE = "en_US";
// system knows what language it can load and will act accordingly
constexpr static std::string_view MANIFEST_PATH = "lang/manifest.json";
-static gui::LanguageManifest manifest;
-static gui::LanguageIterator current_language;
+static LanguageManifest manifest;
+static LanguageIterator current_language;
static std::unordered_map<std::string, std::string> language_map;
-static std::unordered_map<std::string, gui::LanguageIterator> ietf_map;
+static std::unordered_map<std::string, LanguageIterator> ietf_map;
static config::String config_language(DEFAULT_LANGUAGE);
-static void send_language_event(gui::LanguageIterator new_language)
+static void send_language_event(LanguageIterator new_language)
{
- gui::LanguageSetEvent event;
+ LanguageSetEvent event;
event.new_language = new_language;
globals::dispatcher.trigger(event);
}
-void gui::language::init(void)
+void language::init(void)
{
globals::client_config.add_value("language", config_language);
@@ -41,7 +41,7 @@ void gui::language::init(void)
auto file = PHYSFS_openRead(std::string(MANIFEST_PATH).c_str());
if(file == nullptr) {
- spdlog::critical("language: {}: {}", MANIFEST_PATH, io::physfs_error());
+ spdlog::critical("language: {}: {}", MANIFEST_PATH, physfs_error());
std::terminate();
}
@@ -85,19 +85,19 @@ void gui::language::init(void)
current_language = manifest.cend();
}
-void gui::language::init_late(void)
+void language::init_late(void)
{
auto user_language = ietf_map.find(config_language.get_value());
if(user_language != ietf_map.cend()) {
- gui::language::set(user_language->second);
+ language::set(user_language->second);
return;
}
auto fallback = ietf_map.find(std::string(DEFAULT_LANGUAGE));
if(fallback != ietf_map.cend()) {
- gui::language::set(fallback->second);
+ language::set(fallback->second);
return;
}
@@ -106,7 +106,7 @@ void gui::language::init_late(void)
std::terminate();
}
-void gui::language::set(LanguageIterator new_language)
+void language::set(LanguageIterator new_language)
{
if(new_language != manifest.cend()) {
auto path = std::format("lang/lang.{}.json", new_language->ietf);
@@ -114,7 +114,7 @@ void gui::language::set(LanguageIterator new_language)
auto file = PHYSFS_openRead(path.c_str());
if(file == nullptr) {
- spdlog::warn("language: {}: {}", path, io::physfs_error());
+ spdlog::warn("language: {}: {}", path, physfs_error());
send_language_event(new_language);
return;
}
@@ -156,12 +156,12 @@ void gui::language::set(LanguageIterator new_language)
send_language_event(new_language);
}
-gui::LanguageIterator gui::language::get_current(void)
+LanguageIterator language::get_current(void)
{
return current_language;
}
-gui::LanguageIterator gui::language::find(std::string_view ietf)
+LanguageIterator language::find(std::string_view ietf)
{
const auto it = ietf_map.find(std::string(ietf));
if(it != ietf_map.cend()) {
@@ -172,17 +172,17 @@ gui::LanguageIterator gui::language::find(std::string_view ietf)
}
}
-gui::LanguageIterator gui::language::cbegin(void)
+LanguageIterator language::cbegin(void)
{
return manifest.cbegin();
}
-gui::LanguageIterator gui::language::cend(void)
+LanguageIterator language::cend(void)
{
return manifest.cend();
}
-std::string_view gui::language::resolve(std::string_view key)
+std::string_view language::resolve(std::string_view key)
{
const auto it = language_map.find(std::string(key));
@@ -193,10 +193,10 @@ std::string_view gui::language::resolve(std::string_view key)
return key;
}
-std::string gui::language::resolve_gui(std::string_view key)
+std::string language::resolve_gui(std::string_view key)
{
// We need window tags to retain their hierarchy when a language
// dynamically changes; ImGui allows to provide hidden unique identifiers
// to GUI primitives that have their name change dynamically, so we're using this
- return std::format("{}###{}", gui::language::resolve(key), key);
+ return std::format("{}###{}", language::resolve(key), key);
}
diff --git a/src/game/client/gui/language.hh b/src/game/client/gui/language.hh
index 90132d7..20c7520 100644
--- a/src/game/client/gui/language.hh
+++ b/src/game/client/gui/language.hh
@@ -1,7 +1,5 @@
#pragma once
-namespace gui
-{
struct LanguageInfo final {
std::string endonym; // Language's self-name
std::string display; // Display for the settings GUI
@@ -14,29 +12,28 @@ using LanguageIterator = LanguageManifest::const_iterator;
struct LanguageSetEvent final {
LanguageIterator new_language;
};
-} // namespace gui
-namespace gui::language
+namespace language
{
void init(void);
void init_late(void);
-} // namespace gui::language
+} // namespace language
-namespace gui::language
+namespace language
{
void set(LanguageIterator new_language);
-} // namespace gui::language
+} // namespace language
-namespace gui::language
+namespace language
{
LanguageIterator get_current(void);
LanguageIterator find(std::string_view ietf);
LanguageIterator cbegin(void);
LanguageIterator cend(void);
-} // namespace gui::language
+} // namespace language
-namespace gui::language
+namespace language
{
std::string_view resolve(std::string_view key);
std::string resolve_gui(std::string_view key);
-} // namespace gui::language
+} // namespace language
diff --git a/src/game/client/gui/main_menu.cc b/src/game/client/gui/main_menu.cc
index d60a507..d764449 100644
--- a/src/game/client/gui/main_menu.cc
+++ b/src/game/client/gui/main_menu.cc
@@ -9,6 +9,8 @@
#include "core/version.hh"
#include "client/gui/gui_screen.hh"
+#include "client/gui/imutils_button.hh"
+#include "client/gui/imutils_popup.hh"
#include "client/gui/language.hh"
#include "client/gui/window_title.hh"
@@ -19,18 +21,17 @@
#include "client/globals.hh"
#include "client/session.hh"
-constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
+static std::string str_button_play;
+static std::string str_button_resume;
+static std::string str_button_settings;
+static std::string str_button_disconnect;
+static std::string str_button_quit;
-static std::string str_play;
-static std::string str_resume;
-static std::string str_settings;
-static std::string str_leave;
-static std::string str_quit;
+static std::string str_quit_popup_title;
+static std::string str_quit_popup_question;
+static std::string str_quit_popup_choices[2];
-static resource_ptr<TextureGUI> title;
-static float title_aspect;
-
-static void on_glfw_key(const io::GlfwKeyEvent& event)
+static void on_glfw_key(const GlfwKeyEvent& event)
{
if(session::is_ingame() && (event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
if(globals::gui_screen == GUI_SCREEN_NONE) {
@@ -45,127 +46,106 @@ static void on_glfw_key(const io::GlfwKeyEvent& event)
}
}
-static void on_language_set(const gui::LanguageSetEvent& event)
+static void on_language_set(const LanguageSetEvent& event)
{
- str_play = gui::language::resolve_gui("main_menu.play");
- str_resume = gui::language::resolve_gui("main_menu.resume");
- str_settings = gui::language::resolve("main_menu.settings");
- str_leave = gui::language::resolve("main_menu.leave");
- str_quit = gui::language::resolve("main_menu.quit");
+ str_button_play = language::resolve_gui("main_menu.button.play");
+ str_button_resume = language::resolve_gui("main_menu.button.resume");
+ str_button_settings = language::resolve("main_menu.button.settings");
+ str_button_disconnect = language::resolve("main_menu.button.disconnect");
+ str_button_quit = language::resolve("main_menu.button.quit");
+
+ str_quit_popup_title = language::resolve_gui("main_menu.quit_popup.title");
+ str_quit_popup_question = language::resolve("main_menu.quit_popup.question");
+ str_quit_popup_choices[0] = language::resolve_gui("main_menu.quit_popup.choice.yes");
+ str_quit_popup_choices[1] = language::resolve_gui("main_menu.quit_popup.choice.no");
}
-void gui::main_menu::init(void)
+void main_menu::init(void)
{
- title = resource::load<TextureGUI>("textures/gui/menu_title.png", TEXTURE_GUI_LOAD_CLAMP_S | TEXTURE_GUI_LOAD_CLAMP_T);
-
- if(title == nullptr) {
- spdlog::critical("main_menu: texture load failed");
- std::terminate();
- }
-
- if(title->size.x > title->size.y) {
- title_aspect = static_cast<float>(title->size.x) / static_cast<float>(title->size.y);
- }
- else {
- title_aspect = static_cast<float>(title->size.y) / static_cast<float>(title->size.x);
- }
-
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
}
-void gui::main_menu::shutdown(void)
+void main_menu::shutdown(void)
{
- title = nullptr;
+ // empty
}
-void gui::main_menu::layout(void)
+void main_menu::layout(void)
{
const auto viewport = ImGui::GetMainViewport();
- const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.15f);
- const auto window_size = ImVec2(viewport->Size.x, viewport->Size.y);
+ const auto& viewport_size = viewport->Size;
- ImGui::SetNextWindowPos(window_start);
- ImGui::SetNextWindowSize(window_size);
+ ImVec2 margin(globals::gui_scale * 8.0f, globals::gui_scale * 8.0f);
+ ImVec2 control(globals::gui_scale * 256.0f, globals::gui_scale * 32.0f);
- if(ImGui::Begin("###main_menu", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.0f, 2.0f * globals::gui_scale));
+ ImGui::SetNextWindowPos({});
+ ImGui::SetNextWindowSize(viewport_size);
- if(session::is_ingame()) {
- ImGui::Dummy(ImVec2(0.0f, 32.0f * globals::gui_scale));
- }
- else {
- auto reference_height = 0.225f * window_size.y;
- auto image_width = glm::min(window_size.x, reference_height * title_aspect);
- auto image_height = image_width / title_aspect;
- ImGui::SetCursorPosX(0.5f * (window_size.x - image_width));
- ImGui::Image(title->handle, ImVec2(image_width, image_height));
- }
-
- ImGui::Dummy(ImVec2(0.0f, 24.0f * globals::gui_scale));
-
- const float button_width = 240.0f * globals::gui_scale;
- const float button_xpos = 0.5f * (window_size.x - button_width);
-
- if(session::is_ingame()) {
- ImGui::SetCursorPosX(button_xpos);
-
- if(ImGui::Button(str_resume.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_SCREEN_NONE;
- }
-
- ImGui::Spacing();
- }
- else {
- ImGui::SetCursorPosX(button_xpos);
+ ImGuiWindowFlags flags = 0U;
+ flags |= ImGuiWindowFlags_NoBackground;
+ flags |= ImGuiWindowFlags_NoDecoration;
- if(ImGui::Button(str_play.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_PLAY_MENU;
- }
-
- ImGui::Spacing();
- }
+ if(!ImGui::Begin("###gui::main_menu", nullptr, flags)) {
+ ImGui::End();
+ return;
+ }
- ImGui::SetCursorPosX(button_xpos);
+ ImGui::PushFont(globals::font_unscii16, 16.0f);
+ ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.000f, 0.000f, 0.000f, 0.000f));
+ ImGui::PushStyleColor(ImGuiCol_ButtonHovered, ImVec4(0.500f, 0.500f, 0.500f, 0.125f));
+ ImGui::PushStyleColor(ImGuiCol_ButtonActive, ImVec4(0.500f, 0.500f, 0.500f, 0.500f));
+ ImGui::PushStyleVarX(ImGuiStyleVar_FramePadding, 16.0f * globals::gui_scale);
+ ImGui::PushStyleVarX(ImGuiStyleVar_ButtonTextAlign, 0.0f);
+ ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
- if(ImGui::Button(str_settings.c_str(), ImVec2(button_width, 0.0f))) {
- globals::gui_screen = GUI_SETTINGS;
- }
+ ImVec2 cursor_pos(margin.x, viewport_size.y - margin.y);
- ImGui::Spacing();
+ cursor_pos.y -= control.y * 1.5f;
+ ImGui::SetCursorPos(cursor_pos);
- if(session::is_ingame()) {
- ImGui::SetCursorPosX(button_xpos);
+ if(session::is_ingame()) {
+ imutils::button(str_button_disconnect.c_str(), control, [] {
+ session::disconnect("protocol.client_disconnect");
+ });
+ }
+ else {
+ imutils::button(str_button_quit.c_str(), control, [] {
+ ImGui::OpenPopup(str_quit_popup_title.c_str());
+ });
+ }
- if(ImGui::Button(str_leave.c_str(), ImVec2(button_width, 0.0f))) {
- session::disconnect("protocol.client_disconnect");
- globals::gui_screen = GUI_PLAY_MENU;
- gui::window_title::update();
- }
+ cursor_pos.y -= control.y;
+ ImGui::SetCursorPos(cursor_pos);
- ImGui::Spacing();
- }
- else {
- ImGui::SetCursorPosX(button_xpos);
+ imutils::button(str_button_settings.c_str(), control, [] {
+ globals::gui_screen = GUI_SETTINGS;
+ });
- if(ImGui::Button(str_quit.c_str(), ImVec2(button_width, 0.0f))) {
- glfwSetWindowShouldClose(globals::window, true);
- }
+ cursor_pos.y -= control.y * 1.5f;
+ ImGui::SetCursorPos(cursor_pos);
- ImGui::Spacing();
- }
-
- if(!session::is_ingame()) {
- const auto& padding = ImGui::GetStyle().FramePadding;
- const auto& spacing = ImGui::GetStyle().ItemSpacing;
+ if(session::is_ingame()) {
+ imutils::button(str_button_resume.c_str(), control, [] {
+ globals::gui_screen = GUI_SCREEN_NONE;
+ });
+ }
+ else {
+ imutils::button(str_button_play.c_str(), control, [] {
+ globals::gui_screen = GUI_PLAY_MENU;
+ });
+ }
- ImGui::PushFont(globals::font_unscii8, 4.0f);
- ImGui::SetCursorScreenPos(ImVec2(padding.x + spacing.x, window_size.y - ImGui::GetFontSize() - padding.y - spacing.y));
- ImGui::Text("Voxelius %*s", version::full.size(), version::full.data()); // string_view is not always null-terminated
- ImGui::PopFont();
- }
+ ImGui::PopStyleVar(3);
+ ImGui::PopStyleColor(3);
+ ImGui::PopFont();
- ImGui::PopStyleVar();
+ if(0 == imutils::popup(str_quit_popup_title, str_quit_popup_question, str_quit_popup_choices, 2)) {
+ // We don't really have a good way to
+ // pass "i want to quit" boolean to the main loop,
+ // so instead we just raise an external interrupt signal
+ // which handler latches an internal flag in the main loop
+ std::raise(SIGINT);
}
ImGui::End();
diff --git a/src/game/client/gui/main_menu.hh b/src/game/client/gui/main_menu.hh
index 205f078..b5333d4 100644
--- a/src/game/client/gui/main_menu.hh
+++ b/src/game/client/gui/main_menu.hh
@@ -1,8 +1,8 @@
#pragma once
-namespace gui::main_menu
+namespace main_menu
{
void init(void);
void shutdown(void);
void layout(void);
-} // namespace gui::main_menu
+} // namespace main_menu
diff --git a/src/game/client/gui/message_box.cc b/src/game/client/gui/message_box.cc
index 59e2d33..d97267a 100644
--- a/src/game/client/gui/message_box.cc
+++ b/src/game/client/gui/message_box.cc
@@ -10,7 +10,7 @@
constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
struct Button final {
- gui::message_box_action action;
+ message_box_action action;
std::string str_title;
};
@@ -18,14 +18,14 @@ static std::string str_title;
static std::string str_subtitle;
static std::vector<Button> buttons;
-void gui::message_box::init(void)
+void message_box::init(void)
{
str_title = std::string();
str_subtitle = std::string();
buttons.clear();
}
-void gui::message_box::layout(void)
+void message_box::layout(void)
{
const auto viewport = ImGui::GetMainViewport();
const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.30f);
@@ -68,27 +68,27 @@ void gui::message_box::layout(void)
ImGui::End();
}
-void gui::message_box::reset(void)
+void message_box::reset(void)
{
str_title.clear();
str_subtitle.clear();
buttons.clear();
}
-void gui::message_box::set_title(std::string_view title)
+void message_box::set_title(std::string_view title)
{
- str_title = gui::language::resolve(title);
+ str_title = language::resolve(title);
}
-void gui::message_box::set_subtitle(std::string_view subtitle)
+void message_box::set_subtitle(std::string_view subtitle)
{
- str_subtitle = gui::language::resolve(subtitle);
+ str_subtitle = language::resolve(subtitle);
}
-void gui::message_box::add_button(std::string_view text, const message_box_action& action)
+void message_box::add_button(std::string_view text, const message_box_action& action)
{
Button button = {};
- button.str_title = std::format("{}###MessageBox_Button{}", gui::language::resolve(text), buttons.size());
+ button.str_title = std::format("{}###MessageBox_Button{}", language::resolve(text), buttons.size());
button.action = action;
buttons.push_back(button);
diff --git a/src/game/client/gui/message_box.hh b/src/game/client/gui/message_box.hh
index 74a6fbf..9da5358 100644
--- a/src/game/client/gui/message_box.hh
+++ b/src/game/client/gui/message_box.hh
@@ -1,20 +1,17 @@
#pragma once
-namespace gui
-{
using message_box_action = void (*)(void);
-} // namespace gui
-namespace gui::message_box
+namespace message_box
{
void init(void);
void layout(void);
void reset(void);
-} // namespace gui::message_box
+} // namespace message_box
-namespace gui::message_box
+namespace message_box
{
void set_title(std::string_view title);
void set_subtitle(std::string_view subtitle);
void add_button(std::string_view text, const message_box_action& action);
-} // namespace gui::message_box
+} // namespace message_box
diff --git a/src/game/client/gui/metrics.cc b/src/game/client/gui/metrics.cc
index bf46649..51b1ffa 100644
--- a/src/game/client/gui/metrics.cc
+++ b/src/game/client/gui/metrics.cc
@@ -15,7 +15,7 @@
#include "client/entity/camera.hh"
-#include "client/gui/imdraw_ext.hh"
+#include "client/gui/imutils_text.hh"
#include "client/game.hh"
#include "client/globals.hh"
@@ -27,13 +27,13 @@ constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground |
static std::basic_string<GLubyte> r_version;
static std::basic_string<GLubyte> r_renderer;
-void gui::metrics::init(void)
+void metrics::init(void)
{
r_version = std::basic_string<GLubyte>(glGetString(GL_VERSION));
r_renderer = std::basic_string<GLubyte>(glGetString(GL_RENDERER));
}
-void gui::metrics::layout(void)
+void metrics::layout(void)
{
if(!session::is_ingame()) {
// Sanity check; we are checking this
@@ -54,50 +54,50 @@ void gui::metrics::layout(void)
// Draw version
auto version_line = std::format("Voxelius {}", version::full);
- gui::imdraw_ext::text_shadow(version_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
+ imutils::text_nw(draw_list, version_line, position, text_color, shadow_color, globals::font_unscii8, font_size);
position.y += 1.5f * y_step;
// Draw client-side window framerate metrics
auto window_framerate = 1.0f / globals::window_frametime_avg;
auto window_frametime = 1000.0f * globals::window_frametime_avg;
auto window_fps_line = std::format("{:.02f} FPS [{:.02f} ms]", window_framerate, window_frametime);
- gui::imdraw_ext::text_shadow(window_fps_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
+ imutils::text_nw(draw_list, window_fps_line, position, text_color, shadow_color, globals::font_unscii8, font_size);
position.y += y_step;
// Draw world rendering metrics
auto drawcall_line = std::format("World: {} DC / {} TRI", globals::num_drawcalls, globals::num_triangles);
- gui::imdraw_ext::text_shadow(drawcall_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
+ imutils::text_nw(draw_list, drawcall_line, position, text_color, shadow_color, globals::font_unscii8, font_size);
position.y += y_step;
// Draw OpenGL version string
auto r_version_line = std::format("GL_VERSION: {}", reinterpret_cast<const char*>(r_version.c_str()));
- gui::imdraw_ext::text_shadow(r_version_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
+ imutils::text_nw(draw_list, r_version_line, position, text_color, shadow_color, globals::font_unscii8, font_size);
position.y += y_step;
// Draw OpenGL renderer string
auto r_renderer_line = std::format("GL_RENDERER: {}", reinterpret_cast<const char*>(r_renderer.c_str()));
- gui::imdraw_ext::text_shadow(r_renderer_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
+ imutils::text_nw(draw_list, r_renderer_line, position, text_color, shadow_color, globals::font_unscii8, font_size);
position.y += 1.5f * y_step;
- const auto& head = globals::dimension->entities.get<entity::Head>(globals::player);
- const auto& transform = globals::dimension->entities.get<entity::Transform>(globals::player);
- const auto& velocity = globals::dimension->entities.get<entity::Velocity>(globals::player);
+ const auto& head = globals::dimension->entities.get<Head>(globals::player);
+ const auto& transform = globals::dimension->entities.get<Transform>(globals::player);
+ const auto& velocity = globals::dimension->entities.get<Velocity>(globals::player);
// Draw player voxel position
auto voxel_position = coord::to_voxel(transform.chunk, transform.local);
auto voxel_line = std::format("voxel: [{} {} {}]", voxel_position.x, voxel_position.y, voxel_position.z);
- gui::imdraw_ext::text_shadow(voxel_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
+ imutils::text_nw(draw_list, voxel_line, position, text_color, shadow_color, globals::font_unscii8, font_size);
position.y += y_step;
// Draw player world position
auto world_line = std::format("world: [{} {} {}] [{:.03f} {:.03f} {:.03f}]", transform.chunk.x, transform.chunk.y, transform.chunk.z,
transform.local.x, transform.local.y, transform.local.z);
- gui::imdraw_ext::text_shadow(world_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
+ imutils::text_nw(draw_list, world_line, position, text_color, shadow_color, globals::font_unscii8, font_size);
position.y += y_step;
// Draw player look angles
auto angles = glm::degrees(transform.angles + head.angles);
auto angle_line = std::format("angle: [{: .03f} {: .03f} {: .03f}]", angles[0], angles[1], angles[2]);
- gui::imdraw_ext::text_shadow(angle_line, position, text_color, shadow_color, globals::font_unscii8, draw_list, font_size);
+ imutils::text_nw(draw_list, angle_line, position, text_color, shadow_color, globals::font_unscii8, font_size);
position.y += y_step;
}
diff --git a/src/game/client/gui/metrics.hh b/src/game/client/gui/metrics.hh
index 4898332..ab09c34 100644
--- a/src/game/client/gui/metrics.hh
+++ b/src/game/client/gui/metrics.hh
@@ -1,7 +1,7 @@
#pragma once
-namespace gui::metrics
+namespace metrics
{
void init(void);
void layout(void);
-} // namespace gui::metrics
+} // namespace metrics
diff --git a/src/game/client/gui/play_menu.cc b/src/game/client/gui/play_menu.cc
index 5b1ecde..ec263a7 100644
--- a/src/game/client/gui/play_menu.cc
+++ b/src/game/client/gui/play_menu.cc
@@ -146,7 +146,7 @@ static void edit_selected_server(void)
static void remove_selected_server(void)
{
- gui::bother::cancel(selected_server->identity);
+ bother::cancel(selected_server->identity);
for(auto it = servers_deque.cbegin(); it != servers_deque.cend(); ++it) {
if(selected_server == (*it)) {
@@ -165,7 +165,7 @@ static void join_selected_server(void)
}
}
-static void on_glfw_key(const io::GlfwKeyEvent& event)
+static void on_glfw_key(const GlfwKeyEvent& event)
{
if((event.key == GLFW_KEY_ESCAPE) && (event.action == GLFW_PRESS)) {
if(globals::gui_screen == GUI_PLAY_MENU) {
@@ -173,14 +173,13 @@ static void on_glfw_key(const io::GlfwKeyEvent& event)
if(adding_server) {
remove_selected_server();
}
- else {
- input_itemname.clear();
- input_hostname.clear();
- input_password.clear();
- editing_server = false;
- adding_server = false;
- return;
- }
+
+ input_itemname.clear();
+ input_hostname.clear();
+ input_password.clear();
+ editing_server = false;
+ adding_server = false;
+ return;
}
globals::gui_screen = GUI_MAIN_MENU;
@@ -190,23 +189,23 @@ static void on_glfw_key(const io::GlfwKeyEvent& event)
}
}
-static void on_language_set(const gui::LanguageSetEvent& event)
+static void on_language_set(const LanguageSetEvent& event)
{
- str_tab_servers = gui::language::resolve_gui("play_menu.tab.servers");
-
- str_join = gui::language::resolve_gui("play_menu.join");
- str_connect = gui::language::resolve_gui("play_menu.connect");
- str_add = gui::language::resolve_gui("play_menu.add");
- str_edit = gui::language::resolve_gui("play_menu.edit");
- str_remove = gui::language::resolve_gui("play_menu.remove");
- str_refresh = gui::language::resolve_gui("play_menu.refresh");
-
- str_status_init = gui::language::resolve("play_menu.status.init");
- str_status_ping = gui::language::resolve("play_menu.status.ping");
- str_status_fail = gui::language::resolve("play_menu.status.fail");
+ str_tab_servers = language::resolve_gui("play_menu.tab.servers");
+
+ str_join = language::resolve_gui("play_menu.join");
+ str_connect = language::resolve_gui("play_menu.connect");
+ str_add = language::resolve_gui("play_menu.add");
+ str_edit = language::resolve_gui("play_menu.edit");
+ str_remove = language::resolve_gui("play_menu.remove");
+ str_refresh = language::resolve_gui("play_menu.refresh");
+
+ str_status_init = language::resolve("play_menu.status.init");
+ str_status_ping = language::resolve("play_menu.status.ping");
+ str_status_fail = language::resolve("play_menu.status.fail");
}
-static void on_bother_response(const gui::BotherResponseEvent& event)
+static void on_bother_response(const BotherResponseEvent& event)
{
for(auto item : servers_deque) {
if(item->identity == event.identity) {
@@ -284,7 +283,7 @@ static void layout_server_item(ServerStatusItem* item)
version_color = ImGui::GetColorU32(ImGuiCol_PlotHistogram);
}
- ImGui::PushFont(globals::font_unscii8, 4.0f);
+ ImGui::PushFont(globals::font_unscii8, 8.0f);
std::string version_toast;
@@ -366,7 +365,7 @@ static void layout_server_edit(ServerStatusItem* item)
input_itemname.clear();
input_hostname.clear();
- gui::bother::cancel(item->identity);
+ bother::cancel(item->identity);
}
ImGui::EndDisabled();
@@ -461,14 +460,14 @@ static void layout_servers_buttons(void)
if(item->status != item_status::PINGING) {
if(!editing_server || item != selected_server) {
item->status = item_status::UNKNOWN;
- gui::bother::cancel(item->identity);
+ bother::cancel(item->identity);
}
}
}
}
}
-void gui::play_menu::init(void)
+void play_menu::init(void)
{
if(auto file = PHYSFS_openRead(std::string(SERVERS_TXT).c_str())) {
auto source = std::string(PHYSFS_fileLength(file), char(0x00));
@@ -513,12 +512,12 @@ void gui::play_menu::init(void)
}
}
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
globals::dispatcher.sink<BotherResponseEvent>().connect<&on_bother_response>();
}
-void gui::play_menu::shutdown(void)
+void play_menu::shutdown(void)
{
std::ostringstream stream;
@@ -537,7 +536,7 @@ void gui::play_menu::shutdown(void)
servers_deque.clear();
}
-void gui::play_menu::layout(void)
+void play_menu::layout(void)
{
const auto viewport = ImGui::GetMainViewport();
const auto window_start = ImVec2(viewport->Size.x * 0.05f, viewport->Size.y * 0.05f);
@@ -582,11 +581,11 @@ void gui::play_menu::layout(void)
ImGui::End();
}
-void gui::play_menu::update_late(void)
+void play_menu::update_late(void)
{
for(auto item : servers_deque) {
if(item->status == item_status::UNKNOWN) {
- gui::bother::ping(item->identity, item->hostname.c_str(), item->port);
+ bother::ping(item->identity, item->hostname.c_str(), item->port);
item->status = item_status::PINGING;
continue;
}
diff --git a/src/game/client/gui/play_menu.hh b/src/game/client/gui/play_menu.hh
index 1b1f003..5069592 100644
--- a/src/game/client/gui/play_menu.hh
+++ b/src/game/client/gui/play_menu.hh
@@ -1,9 +1,9 @@
#pragma once
-namespace gui::play_menu
+namespace play_menu
{
void init(void);
void shutdown(void);
void layout(void);
void update_late(void);
-} // namespace gui::play_menu
+} // namespace play_menu
diff --git a/src/game/client/gui/progress_bar.cc b/src/game/client/gui/progress_bar.cc
index 1732f72..6cc7fae 100644
--- a/src/game/client/gui/progress_bar.cc
+++ b/src/game/client/gui/progress_bar.cc
@@ -12,16 +12,16 @@ constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground |
static std::string str_title;
static std::string str_button;
-static gui::progress_bar_action button_action;
+static progress_bar_action button_action;
-void gui::progress_bar::init(void)
+void progress_bar::init(void)
{
str_title = "Loading";
str_button = std::string();
button_action = nullptr;
}
-void gui::progress_bar::layout(void)
+void progress_bar::layout(void)
{
const auto viewport = ImGui::GetMainViewport();
const auto window_start = ImVec2(0.0f, viewport->Size.y * 0.30f);
@@ -92,20 +92,20 @@ void gui::progress_bar::layout(void)
ImGui::End();
}
-void gui::progress_bar::reset(void)
+void progress_bar::reset(void)
{
str_title.clear();
str_button.clear();
button_action = nullptr;
}
-void gui::progress_bar::set_title(std::string_view title)
+void progress_bar::set_title(std::string_view title)
{
- str_title = gui::language::resolve(title);
+ str_title = language::resolve(title);
}
-void gui::progress_bar::set_button(std::string_view text, const progress_bar_action& action)
+void progress_bar::set_button(std::string_view text, const progress_bar_action& action)
{
- str_button = std::format("{}###ProgressBar_Button", gui::language::resolve(text));
+ str_button = std::format("{}###ProgressBar_Button", language::resolve(text));
button_action = action;
}
diff --git a/src/game/client/gui/progress_bar.hh b/src/game/client/gui/progress_bar.hh
index 7a0581d..931cad0 100644
--- a/src/game/client/gui/progress_bar.hh
+++ b/src/game/client/gui/progress_bar.hh
@@ -1,19 +1,16 @@
#pragma once
-namespace gui
-{
using progress_bar_action = void (*)(void);
-} // namespace gui
-namespace gui::progress_bar
+namespace progress_bar
{
void init(void);
void layout(void);
-} // namespace gui::progress_bar
+} // namespace progress_bar
-namespace gui::progress_bar
+namespace progress_bar
{
void reset(void);
void set_title(std::string_view title);
void set_button(std::string_view text, const progress_bar_action& action);
-} // namespace gui::progress_bar
+} // namespace progress_bar
diff --git a/src/game/client/gui/scoreboard.cc b/src/game/client/gui/scoreboard.cc
index 4f14de8..efd2d6d 100644
--- a/src/game/client/gui/scoreboard.cc
+++ b/src/game/client/gui/scoreboard.cc
@@ -28,7 +28,7 @@ static void on_scoreboard_update_packet(const protocol::ScoreboardUpdate& packet
max_username_size = 0.0f;
}
-void gui::scoreboard::init(void)
+void scoreboard::init(void)
{
globals::client_config.add_value("scoreboard.key", list_key);
@@ -37,7 +37,7 @@ void gui::scoreboard::init(void)
globals::dispatcher.sink<protocol::ScoreboardUpdate>().connect<&on_scoreboard_update_packet>();
}
-void gui::scoreboard::layout(void)
+void scoreboard::layout(void)
{
if(globals::gui_screen == GUI_SCREEN_NONE && session::is_ingame() && glfwGetKey(globals::window, list_key.get_key()) == GLFW_PRESS) {
const auto viewport = ImGui::GetMainViewport();
diff --git a/src/game/client/gui/scoreboard.hh b/src/game/client/gui/scoreboard.hh
index 320e185..86f8088 100644
--- a/src/game/client/gui/scoreboard.hh
+++ b/src/game/client/gui/scoreboard.hh
@@ -1,7 +1,7 @@
#pragma once
-namespace gui::scoreboard
+namespace scoreboard
{
void init(void);
void layout(void);
-} // namespace gui::scoreboard
+} // namespace scoreboard
diff --git a/src/game/client/gui/settings.cc b/src/game/client/gui/settings.cc
index 70852b2..b456909 100644
--- a/src/game/client/gui/settings.cc
+++ b/src/game/client/gui/settings.cc
@@ -15,6 +15,7 @@
#include "client/config/keybind.hh"
#include "client/gui/gui_screen.hh"
+#include "client/gui/imutils_button.hh"
#include "client/gui/language.hh"
#include "client/io/gamepad.hh"
@@ -25,22 +26,33 @@
constexpr static ImGuiWindowFlags WINDOW_FLAGS = ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoDecoration;
constexpr static unsigned int NUM_LOCATIONS = static_cast<unsigned int>(settings_location::COUNT);
+constexpr static const char* TOOLTIP_TEXT = "[?]";
+
+enum class setting_type {
+ CHECKBOX, ///< config::Boolean
+ INPUT_INT, ///< config::Number<int>
+ INPUT_FLOAT, ///< config::Number<float>
+ INPUT_UINT, ///< config::Number<unsigned int>
+ INPUT_STRING, ///< config::String
+ SLIDER_INT, ///< config::Number<int>
+ SLIDER_FLOAT, ///< config::Number<float>
+ SLIDER_UINT, ///< config::Number<unsigned int>
+ STEPPER_INT, ///< config::Number<int>
+ STEPPER_UINT, ///< config::Number<unsigned int>
+ KEYBIND, ///< config::KeyBind
+ GAMEPAD_AXIS, ///< config::GamepadAxis
+ GAMEPAD_BUTTON, ///< config::GamepadButton
+ LANGUAGE_SELECT, ///< config::String internally
+};
-enum class setting_type : unsigned int {
- CHECKBOX = 0x0000U, ///< config::Boolean
- INPUT_INT = 0x0001U, ///< config::Number<int>
- INPUT_FLOAT = 0x0002U, ///< config::Number<float>
- INPUT_UINT = 0x0003U, ///< config::Number<unsigned int>
- INPUT_STRING = 0x0004U, ///< config::String
- SLIDER_INT = 0x0005U, ///< config::Number<int>
- SLIDER_FLOAT = 0x0006U, ///< config::Number<float>
- SLIDER_UINT = 0x0007U, ///< config::Number<unsigned int>
- STEPPER_INT = 0x0008U, ///< config::Number<int>
- STEPPER_UINT = 0x0009U, ///< config::Number<unsigned int>
- KEYBIND = 0x000AU, ///< config::KeyBind
- GAMEPAD_AXIS = 0x000BU, ///< config::GamepadAxis
- GAMEPAD_BUTTON = 0x000CU, ///< config::GamepadButton
- LANGUAGE_SELECT = 0x000DU, ///< config::String internally
+enum class gui_location {
+ GENERAL,
+ BINDINGS,
+ AUDIO,
+ VIDEO,
+ KEYBOARD,
+ MOUSE,
+ GAMEPAD,
};
class SettingValue {
@@ -206,42 +218,41 @@ public:
virtual void layout(void) const override;
};
-static std::string str_checkbox_false;
-static std::string str_checkbox_true;
+static std::string str_label_movement;
+static std::string str_label_gameplay;
+static std::string str_label_miscellaneous;
+static std::string str_label_gui;
+static std::string str_label_levels;
-static std::string str_tab_general;
-static std::string str_tab_input;
-static std::string str_tab_video;
-static std::string str_tab_sound;
+static std::string str_location_general;
+static std::string str_location_video;
+static std::string str_location_audio;
+static std::string str_location_keyboard;
+static std::string str_location_mouse;
+static std::string str_location_gamepad;
-static std::string str_input_keyboard;
-static std::string str_input_gamepad;
-static std::string str_input_mouse;
+static std::string str_separator_settings;
+static std::string str_separator_devices;
-static std::string str_keyboard_movement;
-static std::string str_keyboard_gameplay;
-static std::string str_keyboard_misc;
+static std::string str_checkbox_false;
+static std::string str_checkbox_true;
-static std::string str_gamepad_movement;
-static std::string str_gamepad_gameplay;
-static std::string str_gamepad_misc;
+static std::vector<std::shared_ptr<SettingValue>> values_all;
+static std::vector<std::shared_ptr<SettingValue>> values[NUM_LOCATIONS];
static std::string str_gamepad_axis_prefix;
static std::string str_gamepad_button_prefix;
static std::string str_gamepad_checkbox_tooltip;
-static std::string str_video_gui;
-
-static std::string str_sound_levels;
-
-static std::vector<SettingValue*> values_all;
-static std::vector<SettingValue*> values[NUM_LOCATIONS];
+static gui_location selected_location;
void SettingValue::layout_tooltip(void) const
{
if(has_tooltip) {
- ImGui::SameLine();
- ImGui::TextDisabled("[?]");
+ ImVec2 tooltip_size(ImGui::CalcTextSize(TOOLTIP_TEXT));
+
+ ImGui::SameLine(ImGui::GetWindowWidth() - tooltip_size.x - ImGui::GetStyle().WindowPadding.x);
+ ImGui::TextDisabled(TOOLTIP_TEXT);
if(ImGui::BeginItemTooltip()) {
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 16.0f);
@@ -397,7 +408,7 @@ void SettingValue_StepperInt::refresh_wids(void)
{
for(std::size_t i = 0; i < wids.size(); ++i) {
auto key = std::format("settings.value.{}.{}", name, i);
- wids[i] = std::format("{}###{}", gui::language::resolve(key.c_str()), static_cast<const void*>(value));
+ wids[i] = std::format("{}###{}", language::resolve(key.c_str()), static_cast<const void*>(value));
}
}
@@ -428,7 +439,7 @@ void SettingValue_StepperUnsigned::refresh_wids(void)
{
for(std::size_t i = 0; i < wids.size(); ++i) {
auto key = std::format("settings.value.{}.{}", name, i);
- wids[i] = std::format("{}###{}", gui::language::resolve(key.c_str()), static_cast<const void*>(value));
+ wids[i] = std::format("{}###{}", language::resolve(key.c_str()), static_cast<const void*>(value));
}
}
@@ -509,12 +520,12 @@ void SettingValue_GamepadButton::refresh_wids(void)
void SettingValue_Language::layout(void) const
{
- auto current_language = gui::language::get_current();
+ auto current_language = language::get_current();
if(ImGui::BeginCombo(wid.c_str(), current_language->endonym.c_str())) {
- for(auto it = gui::language::cbegin(); it != gui::language::cend(); ++it) {
+ for(auto it = language::cbegin(); it != language::cend(); ++it) {
if(ImGui::Selectable(it->display.c_str(), it == current_language)) {
- gui::language::set(it);
+ language::set(it);
continue;
}
}
@@ -528,27 +539,27 @@ void SettingValue_Language::layout(void) const
static void refresh_input_wids(void)
{
- for(SettingValue* value : values_all) {
+ for(auto& value : values_all) {
if(value->type == setting_type::KEYBIND) {
- auto keybind = static_cast<SettingValue_KeyBind*>(value);
+ auto keybind = std::static_pointer_cast<SettingValue_KeyBind>(value);
keybind->refresh_wids();
continue;
}
if(value->type == setting_type::GAMEPAD_AXIS) {
- auto gamepad_axis = static_cast<SettingValue_GamepadAxis*>(value);
+ auto gamepad_axis = std::static_pointer_cast<SettingValue_GamepadAxis>(value);
gamepad_axis->refresh_wids();
continue;
}
if(value->type == setting_type::GAMEPAD_BUTTON) {
- auto gamepad_button = static_cast<SettingValue_GamepadButton*>(value);
+ auto gamepad_button = std::static_pointer_cast<SettingValue_GamepadButton>(value);
gamepad_button->refresh_wids();
}
}
}
-static void on_glfw_key(const io::GlfwKeyEvent& event)
+static void on_glfw_key(const GlfwKeyEvent& event)
{
if((event.action == GLFW_PRESS) && (event.key != DEBUG_KEY)) {
if(globals::gui_keybind_ptr || globals::gui_gamepad_axis_ptr || globals::gui_gamepad_button_ptr) {
@@ -581,7 +592,7 @@ static void on_glfw_key(const io::GlfwKeyEvent& event)
}
}
-static void on_gamepad_axis(const io::GamepadAxisEvent& event)
+static void on_gamepad_axis(const GamepadAxisEvent& event)
{
if(globals::gui_gamepad_axis_ptr) {
auto& io = ImGui::GetIO();
@@ -596,7 +607,7 @@ static void on_gamepad_axis(const io::GamepadAxisEvent& event)
}
}
-static void on_gamepad_button(const io::GamepadButtonEvent& event)
+static void on_gamepad_button(const GamepadButtonEvent& event)
{
if(globals::gui_gamepad_button_ptr) {
auto& io = ImGui::GetIO();
@@ -611,56 +622,51 @@ static void on_gamepad_button(const io::GamepadButtonEvent& event)
}
}
-static void on_language_set(const gui::LanguageSetEvent& event)
+static void on_language_set(const LanguageSetEvent& event)
{
- str_checkbox_false = gui::language::resolve("settings.checkbox.false");
- str_checkbox_true = gui::language::resolve("settings.checkbox.true");
-
- str_tab_general = gui::language::resolve("settings.tab.general");
- str_tab_input = gui::language::resolve("settings.tab.input");
- str_tab_video = gui::language::resolve("settings.tab.video");
- str_tab_sound = gui::language::resolve("settings.tab.sound");
-
- str_input_keyboard = gui::language::resolve("settings.input.keyboard");
- str_input_gamepad = gui::language::resolve("settings.input.gamepad");
- str_input_mouse = gui::language::resolve("settings.input.mouse");
-
- str_keyboard_movement = gui::language::resolve("settings.keyboard.movement");
- str_keyboard_gameplay = gui::language::resolve("settings.keyboard.gameplay");
- str_keyboard_misc = gui::language::resolve("settings.keyboard.misc");
-
- str_gamepad_movement = gui::language::resolve("settings.gamepad.movement");
- str_gamepad_gameplay = gui::language::resolve("settings.gamepad.gameplay");
- str_gamepad_misc = gui::language::resolve("settings.gamepad.misc");
-
- str_gamepad_axis_prefix = gui::language::resolve("settings.gamepad.axis");
- str_gamepad_button_prefix = gui::language::resolve("settings.gamepad.button");
- str_gamepad_checkbox_tooltip = gui::language::resolve("settings.gamepad.checkbox_tooltip");
-
- str_video_gui = gui::language::resolve("settings.video.gui");
-
- str_sound_levels = gui::language::resolve("settings.sound.levels");
-
- for(SettingValue* value : values_all) {
+ str_label_movement = language::resolve("settings.label.movement");
+ str_label_gameplay = language::resolve("settings.label.gameplay");
+ str_label_miscellaneous = language::resolve("settings.label.miscellaneous");
+ str_label_gui = language::resolve("settings.label.gui");
+ str_label_levels = language::resolve("settings.label.levels");
+
+ str_location_general = language::resolve_gui("settings.location.general");
+ str_location_keyboard = language::resolve_gui("settings.location.keyboard");
+ str_location_mouse = language::resolve_gui("settings.location.mouse");
+ str_location_gamepad = language::resolve_gui("settings.location.gamepad");
+ str_location_video = language::resolve_gui("settings.location.video");
+ str_location_audio = language::resolve_gui("settings.location.audio");
+
+ str_separator_settings = language::resolve("settings.separator.settings");
+ str_separator_devices = language::resolve("settings.separator.devices");
+
+ str_checkbox_false = language::resolve("settings.checkbox.false");
+ str_checkbox_true = language::resolve("settings.checkbox.true");
+
+ str_gamepad_axis_prefix = language::resolve("settings.gamepad.axis");
+ str_gamepad_button_prefix = language::resolve("settings.gamepad.button");
+ str_gamepad_checkbox_tooltip = language::resolve("settings.gamepad.checkbox_tooltip");
+
+ for(auto value : values_all) {
if(value->type == setting_type::CHECKBOX) {
- auto checkbox = static_cast<SettingValue_CheckBox*>(value);
+ auto checkbox = std::static_pointer_cast<SettingValue_CheckBox>(value);
checkbox->refresh_wids();
}
if(value->type == setting_type::STEPPER_INT) {
- auto stepper = static_cast<SettingValue_StepperInt*>(value);
+ auto stepper = std::static_pointer_cast<SettingValue_StepperInt>(value);
stepper->refresh_wids();
}
if(value->type == setting_type::STEPPER_UINT) {
- auto stepper = static_cast<SettingValue_StepperUnsigned*>(value);
+ auto stepper = std::static_pointer_cast<SettingValue_StepperUnsigned>(value);
stepper->refresh_wids();
}
- value->title = gui::language::resolve(std::format("settings.value.{}", value->name).c_str());
+ value->title = language::resolve(std::format("settings.value.{}", value->name).c_str());
if(value->has_tooltip) {
- value->tooltip = gui::language::resolve(std::format("settings.tooltip.{}", value->name).c_str());
+ value->tooltip = language::resolve(std::format("settings.tooltip.{}", value->name).c_str());
}
}
}
@@ -669,120 +675,32 @@ static void layout_values(settings_location location)
{
ImGui::PushItemWidth(ImGui::CalcItemWidth() * 0.70f);
- for(const SettingValue* value : values[static_cast<unsigned int>(location)]) {
+ for(auto& value : values[static_cast<unsigned int>(location)]) {
value->layout();
}
ImGui::PopItemWidth();
}
-static void layout_general(void)
-{
- if(ImGui::BeginChild("###settings.general.child")) {
- layout_values(settings_location::GENERAL);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_keyboard(void)
-{
- if(ImGui::BeginChild("###settings.input.keyboard.child")) {
- ImGui::SeparatorText(str_keyboard_movement.c_str());
- layout_values(settings_location::KEYBOARD_MOVEMENT);
- ImGui::SeparatorText(str_keyboard_gameplay.c_str());
- layout_values(settings_location::KEYBOARD_GAMEPLAY);
- ImGui::SeparatorText(str_keyboard_misc.c_str());
- layout_values(settings_location::KEYBOARD_MISC);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_gamepad(void)
-{
- if(ImGui::BeginChild("###settings.input.gamepad.child")) {
- layout_values(settings_location::GAMEPAD);
- ImGui::SeparatorText(str_gamepad_movement.c_str());
- layout_values(settings_location::GAMEPAD_MOVEMENT);
- ImGui::SeparatorText(str_gamepad_gameplay.c_str());
- layout_values(settings_location::GAMEPAD_GAMEPLAY);
- ImGui::SeparatorText(str_gamepad_misc.c_str());
- layout_values(settings_location::GAMEPAD_MISC);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input_mouse(void)
-{
- if(ImGui::BeginChild("###settings.input.mouse.child")) {
- layout_values(settings_location::MOUSE);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_input(void)
-{
- if(ImGui::BeginTabBar("###settings.input.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) {
- if(ImGui::BeginTabItem(str_input_keyboard.c_str())) {
- layout_input_keyboard();
- ImGui::EndTabItem();
- }
-
- if(io::gamepad::available) {
- if(ImGui::BeginTabItem(str_input_gamepad.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_input_gamepad();
- ImGui::EndTabItem();
- }
- }
-
- if(ImGui::BeginTabItem(str_input_mouse.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_input_mouse();
- ImGui::EndTabItem();
- }
-
- ImGui::EndTabBar();
- }
-}
-
-static void layout_video(void)
-{
- if(ImGui::BeginChild("###settings.video.child")) {
- layout_values(settings_location::VIDEO);
- ImGui::SeparatorText(str_video_gui.c_str());
- layout_values(settings_location::VIDEO_GUI);
- }
-
- ImGui::EndChild();
-}
-
-static void layout_sound(void)
+static void layout_location_selectable(const std::string& label, gui_location target_location, const ImVec2& size)
{
- if(ImGui::BeginChild("###settings.sound.child")) {
- layout_values(settings_location::SOUND);
- ImGui::SeparatorText(str_sound_levels.c_str());
- layout_values(settings_location::SOUND_LEVELS);
+ if(imutils::selectable_button(label.c_str(), size, selected_location == target_location)) {
+ selected_location = target_location;
}
-
- ImGui::EndChild();
}
void settings::init(void)
{
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GamepadAxisEvent>().connect<&on_gamepad_axis>();
- globals::dispatcher.sink<io::GamepadButtonEvent>().connect<&on_gamepad_button>();
- globals::dispatcher.sink<gui::LanguageSetEvent>().connect<&on_language_set>();
+ globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<GamepadAxisEvent>().connect<&on_gamepad_axis>();
+ globals::dispatcher.sink<GamepadButtonEvent>().connect<&on_gamepad_button>();
+ globals::dispatcher.sink<LanguageSetEvent>().connect<&on_language_set>();
}
void settings::init_late(void)
{
for(std::size_t i = 0; i < NUM_LOCATIONS; ++i) {
- std::sort(values[i].begin(), values[i].end(), [](const SettingValue* a, const SettingValue* b) {
+ std::sort(values[i].begin(), values[i].end(), [](const auto& a, const auto& b) {
return a->priority < b->priority;
});
}
@@ -792,68 +710,122 @@ void settings::init_late(void)
void settings::shutdown(void)
{
- for(const SettingValue* value : values_all)
- delete value;
- for(std::size_t i = 0; i < NUM_LOCATIONS; values[i++].clear())
- ;
+ for(std::size_t i = 0; i < NUM_LOCATIONS; ++i) {
+ values[i].clear();
+ }
+
values_all.clear();
}
void settings::layout(void)
{
- const ImGuiViewport* viewport = ImGui::GetMainViewport();
- const ImVec2 window_start = ImVec2(viewport->Size.x * 0.05f, viewport->Size.y * 0.05f);
- const ImVec2 window_size = ImVec2(viewport->Size.x * 0.90f, viewport->Size.y * 0.90f);
+ const auto viewport = ImGui::GetMainViewport();
+ auto window_start = ImVec2(viewport->Size.x * 0.025f, viewport->Size.y * 0.025f);
+ auto window_size = ImVec2(viewport->Size.x * 0.95f, viewport->Size.y * 0.95f);
ImGui::SetNextWindowPos(window_start);
ImGui::SetNextWindowSize(window_size);
- if(ImGui::Begin("###settings", nullptr, WINDOW_FLAGS)) {
- ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(3.0f * globals::gui_scale, 3.0f * globals::gui_scale));
+ ImGui::PushFont(globals::font_unscii16, 16.0f);
+ ImGui::PushStyleVarX(ImGuiStyleVar_FramePadding, 8.0f * globals::gui_scale);
+ ImGui::PushStyleVarY(ImGuiStyleVar_FramePadding, 3.2f * globals::gui_scale);
- if(ImGui::BeginTabBar("###settings.tabs", ImGuiTabBarFlags_FittingPolicyResizeDown)) {
- if(ImGui::TabItemButton("<<")) {
- globals::gui_screen = GUI_MAIN_MENU;
- globals::gui_keybind_ptr = nullptr;
- }
+ if(ImGui::Begin("###settings.window", nullptr, WINDOW_FLAGS)) {
+ auto sidebar_width = 0.25f * window_size.x;
+ auto draw_list = ImGui::GetWindowDrawList();
+ auto separator_color = ImGui::GetColorU32(ImGuiCol_Text);
- if(ImGui::BeginTabItem(str_tab_general.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_general();
- ImGui::EndTabItem();
- }
+ if(ImGui::BeginChild("###settings.window.sidebar", ImVec2(sidebar_width, -1.0f), 0, ImGuiWindowFlags_AlwaysUseWindowPadding)) {
+ auto selectable_height = 24.0f * globals::gui_scale;
+ auto selectable_size = ImVec2(ImGui::GetContentRegionAvail().x, selectable_height);
- if(ImGui::BeginTabItem(str_tab_input.c_str())) {
- layout_input();
- ImGui::EndTabItem();
- }
+ ImGui::PushStyleVar(ImGuiStyleVar_SelectableTextAlign, ImVec2(0.5f, 0.5f));
- if(ImGui::BeginTabItem(str_tab_video.c_str())) {
- globals::gui_keybind_ptr = nullptr;
- layout_video();
- ImGui::EndTabItem();
- }
+ ImGui::BeginDisabled(globals::gui_gamepad_axis_ptr || globals::gui_gamepad_button_ptr || globals::gui_keybind_ptr);
+
+ if(ImGui::Button("<<###settings.window.back", ImVec2(-1.0f, 0.0f))) {
+ globals::gui_screen = GUI_MAIN_MENU;
- if(globals::sound_ctx && globals::sound_dev) {
- if(ImGui::BeginTabItem(str_tab_sound.c_str())) {
+ if(globals::gui_keybind_ptr) {
+ globals::gui_keybind_ptr->set_key(GLFW_KEY_UNKNOWN);
globals::gui_keybind_ptr = nullptr;
- layout_sound();
- ImGui::EndTabItem();
}
}
- ImGui::EndTabBar();
+ ImGui::SeparatorText(str_separator_settings.c_str());
+ layout_location_selectable(str_location_general, gui_location::GENERAL, selectable_size);
+ layout_location_selectable(str_location_video, gui_location::VIDEO, selectable_size);
+ layout_location_selectable(str_location_audio, gui_location::AUDIO, selectable_size);
+
+ ImGui::SeparatorText(str_separator_devices.c_str());
+ layout_location_selectable(str_location_keyboard, gui_location::KEYBOARD, selectable_size);
+ layout_location_selectable(str_location_mouse, gui_location::MOUSE, selectable_size);
+ layout_location_selectable(str_location_gamepad, gui_location::GAMEPAD, selectable_size);
+
+ ImGui::EndDisabled();
+
+ ImGui::PopStyleVar();
}
- ImGui::PopStyleVar();
+ ImGui::EndChild();
+ ImGui::SameLine();
+
+ if(ImGui::BeginChild("###settings.window.contents", ImVec2(-1.0f, -1.0f), 0, ImGuiWindowFlags_AlwaysUseWindowPadding)) {
+ switch(selected_location) {
+ case gui_location::GENERAL:
+ layout_values(settings_location::GENERAL);
+ break;
+
+ case gui_location::VIDEO:
+ layout_values(settings_location::VIDEO);
+ ImGui::SeparatorText(str_label_gui.c_str());
+ layout_values(settings_location::VIDEO_GUI);
+ break;
+
+ case gui_location::AUDIO:
+ ImGui::BeginDisabled(globals::sound_ctx == nullptr);
+ layout_values(settings_location::SOUND);
+ ImGui::SeparatorText(str_label_levels.c_str());
+ layout_values(settings_location::SOUND_LEVELS);
+ ImGui::EndDisabled();
+ break;
+
+ case gui_location::KEYBOARD:
+ ImGui::SeparatorText(str_label_movement.c_str());
+ layout_values(settings_location::KEYBOARD_MOVEMENT);
+ ImGui::SeparatorText(str_label_gameplay.c_str());
+ layout_values(settings_location::KEYBOARD_GAMEPLAY);
+ ImGui::SeparatorText(str_label_miscellaneous.c_str());
+ layout_values(settings_location::KEYBOARD_MISC);
+ break;
+
+ case gui_location::MOUSE:
+ layout_values(settings_location::MOUSE);
+ break;
+
+ case gui_location::GAMEPAD:
+ ImGui::SeparatorText(str_label_movement.c_str());
+ layout_values(settings_location::GAMEPAD_MOVEMENT);
+ ImGui::SeparatorText(str_label_gameplay.c_str());
+ layout_values(settings_location::GAMEPAD_GAMEPLAY);
+ ImGui::SeparatorText(str_label_miscellaneous.c_str());
+ layout_values(settings_location::GAMEPAD_MISC);
+ break;
+ }
+ }
+
+ ImGui::EndChild();
}
+ ImGui::PopStyleVar(2);
+ ImGui::PopFont();
+
ImGui::End();
}
void settings::add_checkbox(int priority, config::Boolean& value, settings_location location, std::string_view name, bool tooltip)
{
- auto setting_value = new SettingValue_CheckBox;
+ auto setting_value = std::make_shared<SettingValue_CheckBox>();
setting_value->type = setting_type::CHECKBOX;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -868,7 +840,7 @@ void settings::add_checkbox(int priority, config::Boolean& value, settings_locat
void settings::add_input(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
{
- auto setting_value = new SettingValue_InputInt;
+ auto setting_value = std::make_shared<SettingValue_InputInt>();
setting_value->type = setting_type::INPUT_INT;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -884,7 +856,7 @@ void settings::add_input(int priority, config::Int& value, settings_location loc
void settings::add_input(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
std::string_view fmt)
{
- auto setting_value = new SettingValue_InputFloat;
+ auto setting_value = std::make_shared<SettingValue_InputFloat>();
setting_value->type = setting_type::INPUT_FLOAT;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -900,7 +872,7 @@ void settings::add_input(int priority, config::Float& value, settings_location l
void settings::add_input(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
{
- auto setting_value = new SettingValue_InputUnsigned;
+ auto setting_value = std::make_shared<SettingValue_InputUnsigned>();
setting_value->type = setting_type::INPUT_UINT;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -916,7 +888,7 @@ void settings::add_input(int priority, config::Unsigned& value, settings_locatio
void settings::add_input(int priority, config::String& value, settings_location location, std::string_view name, bool tooltip,
bool allow_whitespace)
{
- auto setting_value = new SettingValue_InputString;
+ auto setting_value = std::make_shared<SettingValue_InputString>();
setting_value->type = setting_type::INPUT_STRING;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -932,7 +904,7 @@ void settings::add_input(int priority, config::String& value, settings_location
void settings::add_slider(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
{
- auto setting_value = new SettingValue_SliderInt;
+ auto setting_value = std::make_shared<SettingValue_SliderInt>();
setting_value->type = setting_type::SLIDER_INT;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -948,7 +920,7 @@ void settings::add_slider(int priority, config::Int& value, settings_location lo
void settings::add_slider(int priority, config::Float& value, settings_location location, std::string_view name, bool tooltip,
std::string_view fmt)
{
- auto setting_value = new SettingValue_SliderFloat;
+ auto setting_value = std::make_shared<SettingValue_SliderFloat>();
setting_value->type = setting_type::SLIDER_FLOAT;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -964,7 +936,7 @@ void settings::add_slider(int priority, config::Float& value, settings_location
void settings::add_slider(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
{
- auto setting_value = new SettingValue_SliderUnsigned;
+ auto setting_value = std::make_shared<SettingValue_SliderUnsigned>();
setting_value->type = setting_type::SLIDER_UINT;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -979,7 +951,7 @@ void settings::add_slider(int priority, config::Unsigned& value, settings_locati
void settings::add_stepper(int priority, config::Int& value, settings_location location, std::string_view name, bool tooltip)
{
- auto setting_value = new SettingValue_StepperInt;
+ auto setting_value = std::make_shared<SettingValue_StepperInt>();
setting_value->type = setting_type::STEPPER_INT;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -995,7 +967,7 @@ void settings::add_stepper(int priority, config::Int& value, settings_location l
void settings::add_stepper(int priority, config::Unsigned& value, settings_location location, std::string_view name, bool tooltip)
{
- auto setting_value = new SettingValue_StepperUnsigned;
+ auto setting_value = std::make_shared<SettingValue_StepperUnsigned>();
setting_value->type = setting_type::STEPPER_UINT;
setting_value->priority = priority;
setting_value->has_tooltip = tooltip;
@@ -1011,7 +983,7 @@ void settings::add_stepper(int priority, config::Unsigned& value, settings_locat
void settings::add_keybind(int priority, config::KeyBind& value, settings_location location, std::string_view name)
{
- auto setting_value = new SettingValue_KeyBind;
+ auto setting_value = std::make_shared<SettingValue_KeyBind>();
setting_value->type = setting_type::KEYBIND;
setting_value->priority = priority;
setting_value->has_tooltip = false;
@@ -1026,7 +998,7 @@ void settings::add_keybind(int priority, config::KeyBind& value, settings_locati
void settings::add_gamepad_axis(int priority, config::GamepadAxis& value, settings_location location, std::string_view name)
{
- auto setting_value = new SettingValue_GamepadAxis;
+ auto setting_value = std::make_shared<SettingValue_GamepadAxis>();
setting_value->type = setting_type::GAMEPAD_AXIS;
setting_value->priority = priority;
setting_value->has_tooltip = false;
@@ -1041,7 +1013,7 @@ void settings::add_gamepad_axis(int priority, config::GamepadAxis& value, settin
void settings::add_gamepad_button(int priority, config::GamepadButton& value, settings_location location, std::string_view name)
{
- auto setting_value = new SettingValue_GamepadButton;
+ auto setting_value = std::make_shared<SettingValue_GamepadButton>();
setting_value->type = setting_type::GAMEPAD_BUTTON;
setting_value->priority = priority;
setting_value->has_tooltip = false;
@@ -1056,13 +1028,13 @@ void settings::add_gamepad_button(int priority, config::GamepadButton& value, se
void settings::add_language_select(int priority, settings_location location, std::string_view name)
{
- auto setting_value = new SettingValue_Language;
+ auto setting_value = std::make_shared<SettingValue_Language>();
setting_value->type = setting_type::LANGUAGE_SELECT;
setting_value->priority = priority;
setting_value->has_tooltip = false;
setting_value->name = name;
- setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value));
+ setting_value->wid = std::format("###{}", static_cast<const void*>(setting_value.get()));
values[static_cast<unsigned int>(location)].push_back(setting_value);
values_all.push_back(setting_value);
diff --git a/src/game/client/gui/splash.cc b/src/game/client/gui/splash.cc
index fab3ad8..cb035e9 100644
--- a/src/game/client/gui/splash.cc
+++ b/src/game/client/gui/splash.cc
@@ -32,24 +32,24 @@ static float texture_alpha;
static std::uint64_t end_time;
static std::string current_text;
-static void on_glfw_key(const io::GlfwKeyEvent& event)
+static void on_glfw_key(const GlfwKeyEvent& event)
{
end_time = UINT64_C(0);
}
-static void on_glfw_mouse_button(const io::GlfwMouseButtonEvent& event)
+static void on_glfw_mouse_button(const GlfwMouseButtonEvent& event)
{
end_time = UINT64_C(0);
}
-static void on_glfw_scroll(const io::GlfwScrollEvent& event)
+static void on_glfw_scroll(const GlfwScrollEvent& event)
{
end_time = UINT64_C(0);
}
-void gui::client_splash::init(void)
+void client_splash::init(void)
{
- if(io::cmdline::contains("nosplash")) {
+ if(cmdline::contains("nosplash")) {
texture = nullptr;
texture_aspect = 0.0f;
texture_alpha = 0.0f;
@@ -74,7 +74,7 @@ void gui::client_splash::init(void)
}
}
-void gui::client_splash::init_late(void)
+void client_splash::init_late(void)
{
if(!texture) {
// We don't have to waste time
@@ -84,11 +84,11 @@ void gui::client_splash::init_late(void)
end_time = utils::unix_microseconds() + DELAY_MICROSECONDS;
- globals::dispatcher.sink<io::GlfwKeyEvent>().connect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwMouseButtonEvent>().connect<&on_glfw_mouse_button>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().connect<&on_glfw_scroll>();
+ globals::dispatcher.sink<GlfwKeyEvent>().connect<&on_glfw_key>();
+ globals::dispatcher.sink<GlfwMouseButtonEvent>().connect<&on_glfw_mouse_button>();
+ globals::dispatcher.sink<GlfwScrollEvent>().connect<&on_glfw_scroll>();
- current_text = gui::language::resolve("splash.skip_prompt");
+ current_text = language::resolve("splash.skip_prompt");
while(!glfwWindowShouldClose(globals::window)) {
const std::uint64_t curtime = utils::unix_microseconds();
@@ -100,12 +100,12 @@ void gui::client_splash::init_late(void)
texture_alpha = glm::smoothstep(0.25f, 0.6f, static_cast<float>(remains) / static_cast<float>(DELAY_MICROSECONDS));
- gui::client_splash::render();
+ client_splash::render();
}
- globals::dispatcher.sink<io::GlfwKeyEvent>().disconnect<&on_glfw_key>();
- globals::dispatcher.sink<io::GlfwMouseButtonEvent>().disconnect<&on_glfw_mouse_button>();
- globals::dispatcher.sink<io::GlfwScrollEvent>().disconnect<&on_glfw_scroll>();
+ globals::dispatcher.sink<GlfwKeyEvent>().disconnect<&on_glfw_key>();
+ globals::dispatcher.sink<GlfwMouseButtonEvent>().disconnect<&on_glfw_mouse_button>();
+ globals::dispatcher.sink<GlfwScrollEvent>().disconnect<&on_glfw_scroll>();
texture = nullptr;
texture_aspect = 0.0f;
@@ -113,7 +113,7 @@ void gui::client_splash::init_late(void)
end_time = UINT64_C(0);
}
-void gui::client_splash::render(void)
+void client_splash::render(void)
{
if(!texture) {
// We don't have to waste time
@@ -152,7 +152,7 @@ void gui::client_splash::render(void)
const ImVec2 image_pos = ImVec2(image_x, image_y);
if(!current_text.empty()) {
- ImGui::PushFont(globals::font_unscii8, 16.0f);
+ ImGui::PushFont(globals::font_unscii8, 8.0f);
ImGui::SetCursorPos(ImVec2(16.0f, 16.0f));
ImGui::TextDisabled("%s", current_text.c_str());
ImGui::PopFont();
diff --git a/src/game/client/gui/splash.hh b/src/game/client/gui/splash.hh
index 3ce63e4..ca612fe 100644
--- a/src/game/client/gui/splash.hh
+++ b/src/game/client/gui/splash.hh
@@ -1,8 +1,8 @@
#pragma once
-namespace gui::client_splash
+namespace client_splash
{
void init(void);
void init_late(void);
void render(void);
-} // namespace gui::client_splash
+} // namespace client_splash
diff --git a/src/game/client/gui/status_lines.cc b/src/game/client/gui/status_lines.cc
index 74d0dbe..ce661a3 100644
--- a/src/game/client/gui/status_lines.cc
+++ b/src/game/client/gui/status_lines.cc
@@ -2,21 +2,21 @@
#include "client/gui/status_lines.hh"
-#include "client/gui/imdraw_ext.hh"
+#include "client/gui/imutils_text.hh"
#include "client/globals.hh"
-static float line_offsets[gui::STATUS_COUNT];
-static ImFont* line_fonts[gui::STATUS_COUNT];
-static float line_sizes[gui::STATUS_COUNT];
+static float line_offsets[STATUS_COUNT];
+static ImFont* line_fonts[STATUS_COUNT];
+static float line_sizes[STATUS_COUNT];
-static ImVec4 line_text_colors[gui::STATUS_COUNT];
-static ImVec4 line_shadow_colors[gui::STATUS_COUNT];
-static std::string line_strings[gui::STATUS_COUNT];
-static std::uint64_t line_spawns[gui::STATUS_COUNT];
-static float line_fadeouts[gui::STATUS_COUNT];
+static ImVec4 line_text_colors[STATUS_COUNT];
+static ImVec4 line_shadow_colors[STATUS_COUNT];
+static std::string line_strings[STATUS_COUNT];
+static std::uint64_t line_spawns[STATUS_COUNT];
+static float line_fadeouts[STATUS_COUNT];
-void gui::status_lines::init(void)
+void status_lines::init(void)
{
for(unsigned int i = 0U; i < STATUS_COUNT; ++i) {
line_text_colors[i] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
@@ -27,19 +27,19 @@ void gui::status_lines::init(void)
}
}
-void gui::status_lines::init_late(void)
+void status_lines::init_late(void)
{
- line_offsets[STATUS_DEBUG] = 64.0f;
- line_offsets[STATUS_HOTBAR] = 40.0f;
+ line_offsets[STATUS_DEBUG] = 128.0f;
+ line_offsets[STATUS_HOTBAR] = 80.0f;
}
-void gui::status_lines::layout(void)
+void status_lines::layout(void)
{
line_fonts[STATUS_DEBUG] = globals::font_unscii8;
- line_sizes[STATUS_DEBUG] = 4.0f;
+ line_sizes[STATUS_DEBUG] = 8.0f;
line_fonts[STATUS_HOTBAR] = globals::font_unscii16;
- line_sizes[STATUS_HOTBAR] = 8.0f;
+ line_sizes[STATUS_HOTBAR] = 16.0f;
auto viewport = ImGui::GetMainViewport();
auto draw_list = ImGui::GetForegroundDrawList();
@@ -61,11 +61,11 @@ void gui::status_lines::layout(void)
auto color_U32 = ImGui::GetColorU32(ImVec4(color.x, color.y, color.z, color.w * alpha));
auto shadow_U32 = ImGui::GetColorU32(ImVec4(shadow.x, shadow.y, shadow.z, color.w * alpha));
- gui::imdraw_ext::text_shadow(text, pos, color_U32, shadow_U32, font, draw_list, line_sizes[i]);
+ imutils::text_nw(draw_list, text, pos, color_U32, shadow_U32, font, line_sizes[i] * globals::gui_scale);
}
}
-void gui::status_lines::set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout)
+void status_lines::set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout)
{
line_text_colors[line] = ImVec4(color.x, color.y, color.z, color.w);
line_shadow_colors[line] = ImVec4(color.x * 0.1f, color.y * 0.1f, color.z * 0.1f, color.w);
@@ -74,7 +74,7 @@ void gui::status_lines::set(unsigned int line, std::string_view text, const ImVe
line_fadeouts[line] = fadeout;
}
-void gui::status_lines::unset(unsigned int line)
+void status_lines::unset(unsigned int line)
{
line_text_colors[line] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
line_shadow_colors[line] = ImVec4(0.0f, 0.0f, 0.0f, 0.0f);
diff --git a/src/game/client/gui/status_lines.hh b/src/game/client/gui/status_lines.hh
index 98cbde1..b921947 100644
--- a/src/game/client/gui/status_lines.hh
+++ b/src/game/client/gui/status_lines.hh
@@ -1,21 +1,18 @@
#pragma once
-namespace gui
-{
constexpr static unsigned int STATUS_DEBUG = 0x0000; // generic debug line
constexpr static unsigned int STATUS_HOTBAR = 0x0001; // hotbar item line
constexpr static unsigned int STATUS_COUNT = 0x0002;
-} // namespace gui
-namespace gui::status_lines
+namespace status_lines
{
void init(void);
void init_late(void);
void layout(void);
-} // namespace gui::status_lines
+} // namespace status_lines
-namespace gui::status_lines
+namespace status_lines
{
void set(unsigned int line, std::string_view text, const ImVec4& color, float fadeout);
void unset(unsigned int line);
-} // namespace gui::status_lines
+} // namespace status_lines
diff --git a/src/game/client/gui/window_title.cc b/src/game/client/gui/window_title.cc
index 787a7fa..b15f2c5 100644
--- a/src/game/client/gui/window_title.cc
+++ b/src/game/client/gui/window_title.cc
@@ -8,7 +8,7 @@
#include "client/globals.hh"
-void gui::window_title::update(void)
+void window_title::update(void)
{
glfwSetWindowTitle(globals::window, std::format("Voxelius {}: {}", version::triplet, splash::get()).c_str());
}
diff --git a/src/game/client/gui/window_title.hh b/src/game/client/gui/window_title.hh
index af1ab7c..544ed44 100644
--- a/src/game/client/gui/window_title.hh
+++ b/src/game/client/gui/window_title.hh
@@ -1,6 +1,6 @@
#pragma once
-namespace gui::window_title
+namespace window_title
{
void update(void);
-} // namespace gui::window_title
+} // namespace window_title