Make sure all sizes are scaled by window size, make sure all elements are visible for very low resolutions and text doesn't get too small

This commit is contained in:
dec05eba
2024-08-06 08:59:38 +02:00
parent b3f5a53ece
commit b229b060ad
8 changed files with 81 additions and 45 deletions

2
TODO
View File

@@ -10,8 +10,6 @@ Maybe change design to have black triangles appear and get larger until they fil
DISPLAY gamescope-0 DISPLAY gamescope-0
Colorscheme should follow graphics card in use. On nvidia use nvidia green, on intel use intel blue and on amd use amd red.
Optimize list/page when having a few items in it (dont use vector<unique_ptr<Widget>>). Optimize list/page when having a few items in it (dont use vector<unique_ptr<Widget>>).
Only redraw ui if changed (dirty state, propagate upward. Set dirty when adding widget or changing any visible properly on a widget or when event updates how the widget should be displayed). Only redraw ui if changed (dirty state, propagate upward. Set dirty when adding widget or changing any visible properly on a widget or when event updates how the widget should be displayed).

View File

@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Widget.hpp" #include "Widget.hpp"
#include <functional>
#include <mglpp/graphics/Color.hpp> #include <mglpp/graphics/Color.hpp>
#include <mglpp/graphics/Text.hpp> #include <mglpp/graphics/Text.hpp>
@@ -17,8 +16,7 @@ namespace gsr {
void draw(mgl::Window &window, mgl::vec2f offset) override; void draw(mgl::Window &window, mgl::vec2f offset) override;
mgl::vec2f get_size() override; mgl::vec2f get_size() override;
bool is_checked() const;
std::function<void()> on_click;
private: private:
mgl::vec2f get_checkbox_size(); mgl::vec2f get_checkbox_size();
private: private:

View File

@@ -37,13 +37,13 @@ namespace gsr {
if(!theme->title_font_file.load("/usr/share/fonts/noto/NotoSans-Bold.ttf", mgl::MemoryMappedFile::LoadOptions{true, false})) if(!theme->title_font_file.load("/usr/share/fonts/noto/NotoSans-Bold.ttf", mgl::MemoryMappedFile::LoadOptions{true, false}))
goto error; goto error;
if(!theme->title_font.load_from_file(theme->title_font_file, window_size.y * 0.019f)) if(!theme->title_font.load_from_file(theme->title_font_file, std::max(16.0f, window_size.y * 0.019f)))
goto error; goto error;
if(!theme->top_bar_font.load_from_file(theme->title_font_file, window_size.y * 0.03f)) if(!theme->top_bar_font.load_from_file(theme->title_font_file, std::max(23.0f, window_size.y * 0.03f)))
goto error; goto error;
if(!theme->body_font.load_from_file(theme->body_font_file, window_size.y * 0.015f)) if(!theme->body_font.load_from_file(theme->body_font_file, std::max(13.0f, window_size.y * 0.015f)))
goto error; goto error;
if(!theme->combobox_arrow.load_from_file((resources_path + "images/combobox_arrow.png").c_str(), {false, false, false})) if(!theme->combobox_arrow.load_from_file((resources_path + "images/combobox_arrow.png").c_str(), {false, false, false}))

View File

@@ -7,10 +7,10 @@
#include <mglpp/system/FloatRect.hpp> #include <mglpp/system/FloatRect.hpp>
namespace gsr { namespace gsr {
static const float padding_top = 10.0f; static const float padding_top_scale = 0.004629f;
static const float padding_bottom = 10.0f; static const float padding_bottom_scale = 0.004629f;
static const float padding_left = 10.0f; static const float padding_left_scale = 0.007f;
static const float padding_right = 10.0f; static const float padding_right_scale = 0.007f;
Button::Button(mgl::Font *font, const char *text, mgl::vec2f size, mgl::Color bg_color) : size(size), bg_color(bg_color), text(text, *font) { Button::Button(mgl::Font *font, const char *text, mgl::vec2f size, mgl::Color bg_color) : size(size), bg_color(bg_color), text(text, *font) {
@@ -40,10 +40,15 @@ namespace gsr {
const bool mouse_inside = mgl::FloatRect(draw_pos, item_size).contains(window.get_mouse_position().to_vec2f()); const bool mouse_inside = mgl::FloatRect(draw_pos, item_size).contains(window.get_mouse_position().to_vec2f());
if(mouse_inside) if(mouse_inside)
draw_rectangle_outline(window, draw_pos, item_size, gsr::get_theme().tint_color, border_scale * gsr::get_theme().window_height); draw_rectangle_outline(window, draw_pos, item_size, get_theme().tint_color, border_scale * get_theme().window_height);
} }
mgl::vec2f Button::get_size() { mgl::vec2f Button::get_size() {
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
const int padding_left = padding_left_scale * get_theme().window_height;
const int padding_right = padding_right_scale * get_theme().window_height;
const mgl::vec2f text_bounds = text.get_bounds().size; const mgl::vec2f text_bounds = text.get_bounds().size;
mgl::vec2f s = size; mgl::vec2f s = size;
if(s.x < 0.0001f) if(s.x < 0.0001f)

View File

@@ -18,11 +18,8 @@ namespace gsr {
bool CheckBox::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) { bool CheckBox::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) { if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
const bool clicked_inside = mgl::FloatRect(position + offset, get_size()).contains({ (float)event.mouse_button.x, (float)event.mouse_button.y }); const bool clicked_inside = mgl::FloatRect(position + offset, get_size()).contains({ (float)event.mouse_button.x, (float)event.mouse_button.y });
if(clicked_inside) { if(clicked_inside)
checked = !checked; checked = !checked;
if(on_click)
on_click();
}
} }
return true; return true;
} }
@@ -40,7 +37,7 @@ namespace gsr {
const float side_margin = checked_margin_scale * get_theme().window_height; const float side_margin = checked_margin_scale * get_theme().window_height;
mgl::Rectangle background(get_checkbox_size() - mgl::vec2f(side_margin, side_margin).floor() * 2.0f); mgl::Rectangle background(get_checkbox_size() - mgl::vec2f(side_margin, side_margin).floor() * 2.0f);
background.set_position(draw_pos.floor() + mgl::vec2f(side_margin, side_margin).floor()); background.set_position(draw_pos.floor() + mgl::vec2f(side_margin, side_margin).floor());
background.set_color(gsr::get_theme().tint_color); background.set_color(get_theme().tint_color);
window.draw(background); window.draw(background);
} }
@@ -50,8 +47,8 @@ namespace gsr {
const bool mouse_inside = mgl::FloatRect(draw_pos, get_size()).contains(window.get_mouse_position().to_vec2f()); const bool mouse_inside = mgl::FloatRect(draw_pos, get_size()).contains(window.get_mouse_position().to_vec2f());
if(mouse_inside) { if(mouse_inside) {
const int border_size = border_scale * gsr::get_theme().window_height; const int border_size = std::max(1.0f, border_scale * get_theme().window_height);
const mgl::Color border_color = gsr::get_theme().tint_color; const mgl::Color border_color = get_theme().tint_color;
draw_rectangle_outline(window, draw_pos, checkbox_size, border_color, border_size); draw_rectangle_outline(window, draw_pos, checkbox_size, border_color, border_size);
} }
} }
@@ -68,4 +65,8 @@ namespace gsr {
const mgl::vec2f text_bounds = text.get_bounds().size; const mgl::vec2f text_bounds = text.get_bounds().size;
return mgl::vec2f(text_bounds.y, text_bounds.y).floor(); return mgl::vec2f(text_bounds.y, text_bounds.y).floor();
} }
bool CheckBox::is_checked() const {
return checked;
}
} }

View File

@@ -8,10 +8,10 @@
#include <assert.h> #include <assert.h>
namespace gsr { namespace gsr {
static const float padding_top = 10.0f; static const float padding_top_scale = 0.004629f;
static const float padding_bottom = 10.0f; static const float padding_bottom_scale = 0.004629f;
static const float padding_left = 10.0f; static const float padding_left_scale = 0.007f;
static const float padding_right = 10.0f; static const float padding_right_scale = 0.007f;
static const float border_scale = 0.0015f; static const float border_scale = 0.0015f;
ComboBox::ComboBox(mgl::Font *font) : font(font), dropdown_arrow(&get_theme().combobox_arrow) { ComboBox::ComboBox(mgl::Font *font) : font(font), dropdown_arrow(&get_theme().combobox_arrow) {
@@ -19,6 +19,10 @@ namespace gsr {
} }
bool ComboBox::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) { bool ComboBox::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
const int padding_left = padding_left_scale * get_theme().window_height;
if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) { if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
const mgl::vec2f draw_pos = position + offset; const mgl::vec2f draw_pos = position + offset;
const mgl::vec2f mouse_pos = { (float)event.mouse_button.x, (float)event.mouse_button.y }; const mgl::vec2f mouse_pos = { (float)event.mouse_button.x, (float)event.mouse_button.y };
@@ -61,6 +65,11 @@ namespace gsr {
if(items.empty()) if(items.empty())
return; return;
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
const int padding_left = padding_left_scale * get_theme().window_height;
const int padding_right = padding_right_scale * get_theme().window_height;
const mgl::vec2f draw_pos = (position + offset).floor(); const mgl::vec2f draw_pos = (position + offset).floor();
const mgl::vec2f item_size(max_size.x, font->get_character_size() + padding_top + padding_bottom); const mgl::vec2f item_size(max_size.x, font->get_character_size() + padding_top + padding_bottom);
@@ -89,8 +98,8 @@ namespace gsr {
Item &item = items[selected_item]; Item &item = items[selected_item];
item.text.set_position(pos.floor()); item.text.set_position(pos.floor());
if(show_dropdown || mouse_inside) { if(show_dropdown || mouse_inside) {
const int border_size = border_scale * gsr::get_theme().window_height; const int border_size = border_scale * get_theme().window_height;
const mgl::Color border_color = gsr::get_theme().tint_color; const mgl::Color border_color = get_theme().tint_color;
draw_rectangle_outline(window, pos - mgl::vec2f(padding_left, padding_top), item_size.floor(), border_color, border_size); draw_rectangle_outline(window, pos - mgl::vec2f(padding_left, padding_top), item_size.floor(), border_color, border_size);
} }
window.draw(item.text); window.draw(item.text);
@@ -105,8 +114,8 @@ namespace gsr {
if(!inside) { if(!inside) {
inside = mgl::FloatRect(text_bounds.position - mgl::vec2f(padding_left, padding_top), item_size).contains({ (float)mouse_pos.x, (float)mouse_pos.y }); inside = mgl::FloatRect(text_bounds.position - mgl::vec2f(padding_left, padding_top), item_size).contains({ (float)mouse_pos.x, (float)mouse_pos.y });
if(inside) { if(inside) {
mgl::Rectangle item_background(text_bounds.position - mgl::vec2f(padding_left, padding_top), item_size); mgl::Rectangle item_background((text_bounds.position - mgl::vec2f(padding_left, padding_top)).floor(), item_size.floor());
item_background.set_color(gsr::get_theme().tint_color); item_background.set_color(get_theme().tint_color);
window.draw(item_background); window.draw(item_background);
} else { } else {
/*const int border_size = 3; /*const int border_size = 3;
@@ -139,7 +148,12 @@ namespace gsr {
if(!dirty) if(!dirty)
return; return;
max_size = { 0.0f, font->get_character_size() + padding_top + padding_bottom }; const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
const int padding_left = padding_left_scale * get_theme().window_height;
const int padding_right = padding_right_scale * get_theme().window_height;
max_size = { 0.0f, font->get_character_size() + (float)padding_top + (float)padding_bottom };
for(Item &item : items) { for(Item &item : items) {
const mgl::vec2f bounds = item.text.get_bounds().size; const mgl::vec2f bounds = item.text.get_bounds().size;
max_size.x = std::max(max_size.x, bounds.x + padding_left + padding_right); max_size.x = std::max(max_size.x, bounds.x + padding_left + padding_right);
@@ -151,10 +165,15 @@ namespace gsr {
mgl::vec2f ComboBox::get_size() { mgl::vec2f ComboBox::get_size() {
update_if_dirty(); update_if_dirty();
return { max_size.x, font->get_character_size() + padding_top + padding_bottom };
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
return { max_size.x, font->get_character_size() + (float)padding_top + (float)padding_bottom };
} }
float ComboBox::get_dropdown_arrow_height() const { float ComboBox::get_dropdown_arrow_height() const {
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
return (font->get_character_size() + padding_top + padding_bottom) * 0.4f; return (font->get_character_size() + padding_top + padding_bottom) * 0.4f;
} }
} }

View File

@@ -8,10 +8,10 @@
#include <mglpp/system/FloatRect.hpp> #include <mglpp/system/FloatRect.hpp>
namespace gsr { namespace gsr {
static const float padding_top = 15.0f; static const float padding_top_scale = 0.00694f;
static const float padding_bottom = 15.0f; static const float padding_bottom_scale = 0.00694f;
static const float padding_left = 20.0f; static const float padding_left_scale = 0.009259f;
static const float padding_right = 20.0f; static const float padding_right_scale = 0.009259f;
static const float border_scale = 0.003f; static const float border_scale = 0.003f;
DropdownButton::DropdownButton(mgl::Font *title_font, mgl::Font *description_font, const char *title, const char *description_activated, const char *description_deactivated, mgl::Texture *icon_texture, mgl::vec2f size) : DropdownButton::DropdownButton(mgl::Font *title_font, mgl::Font *description_font, const char *title, const char *description_activated, const char *description_deactivated, mgl::Texture *icon_texture, mgl::vec2f size) :
@@ -59,7 +59,11 @@ namespace gsr {
update_if_dirty(); update_if_dirty();
const mgl::vec2f draw_pos = position + offset; const mgl::vec2f draw_pos = position + offset;
const int border_size = border_scale * gsr::get_theme().window_height;
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
const int padding_left = padding_left_scale * get_theme().window_height;
const int border_size = border_scale * get_theme().window_height;
if(show_dropdown) { if(show_dropdown) {
// Background // Background
@@ -70,7 +74,7 @@ namespace gsr {
window.draw(rect); window.draw(rect);
} }
const mgl::Color border_color = gsr::get_theme().tint_color; const mgl::Color border_color = get_theme().tint_color;
// Green line at top // Green line at top
{ {
@@ -88,7 +92,7 @@ namespace gsr {
window.draw(rect); window.draw(rect);
} }
const mgl::Color border_color = gsr::get_theme().tint_color; const mgl::Color border_color = get_theme().tint_color;
draw_rectangle_outline(window, draw_pos, size, border_color, border_size); draw_rectangle_outline(window, draw_pos, size, border_color, border_size);
} else { } else {
// Background // Background
@@ -132,7 +136,7 @@ namespace gsr {
const mgl::vec2f item_size(max_size.x, item_height); const mgl::vec2f item_size(max_size.x, item_height);
const bool inside = mgl::FloatRect(item_position, item_size).contains({ (float)mouse_pos.x, (float)mouse_pos.y }); const bool inside = mgl::FloatRect(item_position, item_size).contains({ (float)mouse_pos.x, (float)mouse_pos.y });
if(inside) { if(inside) {
draw_rectangle_outline(window, item_position, item_size, gsr::get_theme().tint_color, 5); draw_rectangle_outline(window, item_position, item_size, get_theme().tint_color, border_size);
mouse_inside_item = i; mouse_inside_item = i;
} }
} }
@@ -180,6 +184,11 @@ namespace gsr {
if(!dirty) if(!dirty)
return; return;
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
const int padding_left = padding_left_scale * get_theme().window_height;
const int padding_right = padding_right_scale * get_theme().window_height;
max_size = { size.x, 0.0f }; max_size = { size.x, 0.0f };
for(Item &item : items) { for(Item &item : items) {
const mgl::vec2f bounds = item.text.get_bounds().size; const mgl::vec2f bounds = item.text.get_bounds().size;

View File

@@ -9,11 +9,12 @@
#include <optional> #include <optional>
namespace gsr { namespace gsr {
static const float padding_top = 10.0f; static const float padding_top_scale = 0.004629f;
static const float padding_bottom = 10.0f; static const float padding_bottom_scale = 0.004629f;
static const float padding_left = 10.0f; static const float padding_left_scale = 0.007f;
static const float padding_right = 10.0f; static const float padding_right_scale = 0.007f;
static const float border_scale = 0.0015f; static const float border_scale = 0.0015f;
static const float caret_width_scale = 0.001f;
Entry::Entry(mgl::Font *font, const char *text, float max_width) : text("", *font), max_width(max_width) { Entry::Entry(mgl::Font *font, const char *text, float max_width) : text("", *font), max_width(max_width) {
this->text.set_color(get_theme().text_color); this->text.set_color(get_theme().text_color);
@@ -41,17 +42,20 @@ namespace gsr {
void Entry::draw(mgl::Window &window, mgl::vec2f offset) { void Entry::draw(mgl::Window &window, mgl::vec2f offset) {
const mgl::vec2f draw_pos = position + offset; const mgl::vec2f draw_pos = position + offset;
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_left = padding_left_scale * get_theme().window_height;
mgl::Rectangle background(get_size()); mgl::Rectangle background(get_size());
background.set_position(draw_pos.floor()); background.set_position(draw_pos.floor());
background.set_color(selected ? mgl::Color(0, 0, 0, 255) : mgl::Color(0, 0, 0, 120)); background.set_color(selected ? mgl::Color(0, 0, 0, 255) : mgl::Color(0, 0, 0, 120));
window.draw(background); window.draw(background);
if(selected) { if(selected) {
const int border_size = border_scale * gsr::get_theme().window_height; const int border_size = border_scale * get_theme().window_height;
draw_rectangle_outline(window, draw_pos.floor(), get_size().floor(), get_theme().tint_color, border_size); draw_rectangle_outline(window, draw_pos.floor(), get_size().floor(), get_theme().tint_color, border_size);
const int caret_width = 2; const int caret_width = std::max(1.0f, caret_width_scale * get_theme().window_height);
mgl::Rectangle caret({caret_width, text.get_bounds().size.y}); mgl::Rectangle caret({(float)caret_width, text.get_bounds().size.y});
caret.set_position((draw_pos + mgl::vec2f(padding_left + caret_offset_x, padding_top)).floor()); caret.set_position((draw_pos + mgl::vec2f(padding_left + caret_offset_x, padding_top)).floor());
caret.set_color(mgl::Color(255, 255, 255)); caret.set_color(mgl::Color(255, 255, 255));
window.draw(caret); window.draw(caret);
@@ -62,6 +66,8 @@ namespace gsr {
} }
mgl::vec2f Entry::get_size() { mgl::vec2f Entry::get_size() {
const int padding_top = padding_top_scale * get_theme().window_height;
const int padding_bottom = padding_bottom_scale * get_theme().window_height;
return { max_width, text.get_bounds().size.y + padding_top + padding_bottom }; return { max_width, text.get_bounds().size.y + padding_top + padding_bottom };
} }