Move dropdown button text and icon code to dropdown button class

This commit is contained in:
dec05eba
2024-08-01 18:38:06 +02:00
parent 5d40409fc6
commit 6624db873c
13 changed files with 644 additions and 102 deletions

2
TODO
View File

@@ -9,3 +9,5 @@ Maybe change design to have black triangles appear and get larger until they fil
All of these things should be done with vertex buffer, for real 3D.
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.

66
include/GsrInfo.hpp Normal file
View File

@@ -0,0 +1,66 @@
#pragma once
#include <string>
#include <vector>
#include <mglpp/system/vec.hpp>
namespace gsr {
struct SupportedVideoCodecs {
bool h264 = false;
bool hevc = false;
bool av1 = false;
bool vp8 = false;
bool vp9 = false;
};
struct GsrMonitor {
std::string name;
mgl::vec2i size;
};
struct SupportedCaptureOptions {
bool window = false;
bool focused = false;
bool screen = false;
bool portal = false;
std::vector<GsrMonitor> monitors;
};
enum class DisplayServer {
UNKNOWN,
X11,
WAYLAND
};
struct SystemInfo {
DisplayServer display_server = DisplayServer::UNKNOWN;
};
enum class GpuVendor {
UNKNOWN,
AMD,
INTEL,
NVIDIA
};
struct GpuInfo {
GpuVendor vendor = GpuVendor::UNKNOWN;
};
struct GsrInfo {
SystemInfo system_info;
GpuInfo gpu_info;
SupportedVideoCodecs supported_video_codecs;
SupportedCaptureOptions supported_capture_options;
};
enum class GsrInfoExitStatus {
OK,
FAILED_TO_RUN_COMMAND,
OPENGL_FAILED,
NO_DRM_CARD
};
GsrInfoExitStatus get_gpu_screen_recorder_info(GsrInfo *gsr_info);
}

18
include/Theme.hpp Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#include <mglpp/graphics/Color.hpp>
namespace gsr {
struct GsrInfo;
struct Theme {
Theme() = default;
Theme(const Theme&) = delete;
Theme& operator=(const Theme&) = delete;
mgl::Color tint_color = mgl::Color(118, 185, 0);
};
void init_theme(const gsr::GsrInfo &gsr_info);
const Theme& get_theme();
}

View File

@@ -0,0 +1,54 @@
#pragma once
#include "Widget.hpp"
#include <string>
#include <functional>
#include <vector>
#include <mglpp/graphics/Text.hpp>
#include <mglpp/graphics/Sprite.hpp>
namespace gsr {
class DropdownButton : public Widget {
public:
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(const DropdownButton&) = delete;
DropdownButton& operator=(const DropdownButton&) = delete;
bool on_event(mgl::Event &event, mgl::Window &window) override;
void draw(mgl::Window &window) override;
void add_item(const std::string &text, const std::string &id);
void set_item_label(const std::string &id, const std::string &new_label);
void set_activated(bool activated);
mgl::vec2f get_size();
std::function<void(const std::string &id)> on_click;
private:
void update_if_dirty();
private:
struct Item {
mgl::Text text;
std::string id;
};
std::vector<Item> items;
mgl::Font *title_font;
mgl::Font *description_font;
mgl::vec2f size;
bool mouse_inside = false;
bool show_dropdown = false;
bool dirty = true;
mgl::vec2f max_size;
int mouse_inside_item = -1;
mgl::Text title;
mgl::Text description;
mgl::Sprite icon_sprite;
std::string description_activated;
std::string description_deactivated;
bool activated = false;
};
}

13
include/gui/Utils.hpp Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <mglpp/system/vec.hpp>
#include <mglpp/graphics/Color.hpp>
namespace mgl {
class Window;
}
namespace gsr {
// Inner border
void draw_rectangle_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size, mgl::Color color, float border_size);
}

179
src/GsrInfo.cpp Normal file
View File

@@ -0,0 +1,179 @@
#include "../include/GsrInfo.hpp"
#include <string.h>
#include <functional>
namespace gsr {
using StringSplitCallback = std::function<bool(std::string_view line)>;
static void string_split_char(const std::string &str, char delimiter, StringSplitCallback callback_func) {
size_t index = 0;
while(index < str.size()) {
size_t new_index = str.find(delimiter, index);
if(new_index == std::string::npos)
new_index = str.size();
if(!callback_func({str.data() + index, new_index - index}))
break;
index = new_index + 1;
}
}
static void parse_system_info_line(GsrInfo *gsr_info, const std::string &line) {
const size_t space_index = line.find(' ');
if(space_index == std::string::npos)
return;
const std::string_view attribute_name = {line.c_str(), space_index};
const std::string_view attribute_value = {line.c_str() + space_index + 1, line.size() - (space_index + 1)};
if(attribute_name == "display_server") {
if(attribute_value == "x11")
gsr_info->system_info.display_server = DisplayServer::X11;
else if(attribute_value == "wayland")
gsr_info->system_info.display_server = DisplayServer::WAYLAND;
}
}
static void parse_gpu_info_line(GsrInfo *gsr_info, const std::string &line) {
const size_t space_index = line.find(' ');
if(space_index == std::string::npos)
return;
const std::string_view attribute_name = {line.c_str(), space_index};
const std::string_view attribute_value = {line.c_str() + space_index + 1, line.size() - (space_index + 1)};
if(attribute_name == "vendor") {
if(attribute_value == "amd")
gsr_info->gpu_info.vendor = GpuVendor::AMD;
else if(attribute_value == "intel")
gsr_info->gpu_info.vendor = GpuVendor::INTEL;
else if(attribute_value == "nvidia")
gsr_info->gpu_info.vendor = GpuVendor::NVIDIA;
}
}
static void parse_video_codecs_line(GsrInfo *gsr_info, const std::string &line) {
if(line == "h264")
gsr_info->supported_video_codecs.h264 = true;
else if(line == "hevc")
gsr_info->supported_video_codecs.hevc = true;
else if(line == "av1")
gsr_info->supported_video_codecs.av1 = true;
else if(line == "vp8")
gsr_info->supported_video_codecs.vp8 = true;
else if(line == "vp9")
gsr_info->supported_video_codecs.vp9 = true;
}
static GsrMonitor capture_option_line_to_monitor(const std::string &line) {
size_t space_index = line.find(' ');
if(space_index == std::string::npos)
return { line, {0, 0} };
mgl::vec2i size = {0, 0};
if(sscanf(line.c_str() + space_index + 1, "%dx%d", &size.x, &size.y) != 2)
size = {0, 0};
return { line.substr(0, space_index), size };
}
static void parse_capture_options_line(GsrInfo *gsr_info, const std::string &line) {
if(line == "window")
gsr_info->supported_capture_options.window = true;
else if(line == "focused")
gsr_info->supported_capture_options.focused = true;
else if(line == "screen")
gsr_info->supported_capture_options.screen = true;
else if(line == "portal")
gsr_info->supported_capture_options.portal = true;
else
gsr_info->supported_capture_options.monitors.push_back(capture_option_line_to_monitor(line));
}
enum class GsrInfoSection {
UNKNOWN,
SYSTEM_INFO,
GPU_INFO,
VIDEO_CODECS,
CAPTURE_OPTIONS
};
static bool starts_with(const std::string &str, const char *substr) {
size_t len = strlen(substr);
return str.size() >= len && memcmp(str.data(), substr, len) == 0;
}
GsrInfoExitStatus get_gpu_screen_recorder_info(GsrInfo *gsr_info) {
*gsr_info = GsrInfo{};
FILE *f = popen("gpu-screen-recorder --info", "r");
if(!f) {
fprintf(stderr, "error: 'gpu-screen-recorder --info' failed\n");
return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
}
char output[8192];
ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f);
if(bytes_read < 0 || ferror(f)) {
fprintf(stderr, "error: failed to read 'gpu-screen-recorder --info' output\n");
pclose(f);
return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
}
output[bytes_read] = '\0';
GsrInfoSection section = GsrInfoSection::UNKNOWN;
string_split_char(output, '\n', [&](std::string_view line) {
const std::string line_str(line.data(), line.size());
if(starts_with(line_str, "section=")) {
const char *section_name = line_str.c_str() + 8;
if(strcmp(section_name, "system_info") == 0)
section = GsrInfoSection::SYSTEM_INFO;
else if(strcmp(section_name, "gpu_info") == 0)
section = GsrInfoSection::GPU_INFO;
else if(strcmp(section_name, "video_codecs") == 0)
section = GsrInfoSection::VIDEO_CODECS;
else if(strcmp(section_name, "capture_options") == 0)
section = GsrInfoSection::CAPTURE_OPTIONS;
else
section = GsrInfoSection::UNKNOWN;
return true;
}
switch(section) {
case GsrInfoSection::UNKNOWN: {
break;
}
case GsrInfoSection::SYSTEM_INFO: {
parse_system_info_line(gsr_info, line_str);
break;
}
case GsrInfoSection::GPU_INFO: {
parse_gpu_info_line(gsr_info, line_str);
break;
}
case GsrInfoSection::VIDEO_CODECS: {
parse_video_codecs_line(gsr_info, line_str);
break;
}
case GsrInfoSection::CAPTURE_OPTIONS: {
parse_capture_options_line(gsr_info, line_str);
break;
}
}
return true;
});
int status = pclose(f);
if(WIFEXITED(status)) {
switch(WEXITSTATUS(status)) {
case 0: return GsrInfoExitStatus::OK;
case 22: return GsrInfoExitStatus::OPENGL_FAILED;
case 23: return GsrInfoExitStatus::NO_DRM_CARD;
default: return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
}
}
return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
}
}

34
src/Theme.cpp Normal file
View File

@@ -0,0 +1,34 @@
#include "../include/Theme.hpp"
#include "../include/GsrInfo.hpp"
#include <assert.h>
namespace gsr {
static Theme theme;
static bool initialized = false;
void init_theme(const gsr::GsrInfo &gsr_info) {
switch(gsr_info.gpu_info.vendor) {
case gsr::GpuVendor::UNKNOWN: {
break;
}
case gsr::GpuVendor::AMD: {
theme.tint_color = mgl::Color(221, 0, 49);
break;
}
case gsr::GpuVendor::INTEL: {
theme.tint_color = mgl::Color(8, 109, 183);
break;
}
case gsr::GpuVendor::NVIDIA: {
theme.tint_color = mgl::Color(118, 185, 0);
break;
}
}
initialized = true;
}
const Theme& get_theme() {
assert(initialized);
return theme;
}
}

View File

@@ -1,4 +1,5 @@
#include "../../include/gui/Button.hpp"
#include "../../include/Theme.hpp"
#include <mglpp/graphics/Rectangle.hpp>
#include <mglpp/window/Window.hpp>
#include <mglpp/window/Event.hpp>
@@ -40,7 +41,7 @@ namespace gsr {
}
const int border_size = 5;
const mgl::Color border_color(118, 185, 0);
const mgl::Color border_color = gsr::get_theme().tint_color;
// Green line at top
{

View File

@@ -1,4 +1,6 @@
#include "../../include/gui/ComboBox.hpp"
#include "../../include/gui/Utils.hpp"
#include "../../include/Theme.hpp"
#include <mglpp/graphics/Rectangle.hpp>
#include <mglpp/graphics/Font.hpp>
#include <mglpp/window/Window.hpp>
@@ -46,40 +48,6 @@ namespace gsr {
return true;
}
static void draw_rectangle_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size, mgl::Color color, float border_size) {
// Green line at top
{
mgl::Rectangle rect({ size.x, border_size });
rect.set_position(pos);
rect.set_color(color);
window.draw(rect);
}
// Green line at bottom
{
mgl::Rectangle rect({ size.x, border_size });
rect.set_position(pos + mgl::vec2f(0.0f, size.y - border_size));
rect.set_color(color);
window.draw(rect);
}
// Green line at left
{
mgl::Rectangle rect({ border_size, size.y - border_size * 2 });
rect.set_position(pos + mgl::vec2f(0, border_size));
rect.set_color(color);
window.draw(rect);
}
// Green line at right
{
mgl::Rectangle rect({ border_size, size.y - border_size * 2 });
rect.set_position(pos + mgl::vec2f(size.x - border_size, border_size));
rect.set_color(color);
window.draw(rect);
}
}
void ComboBox::draw(mgl::Window &window) {
update_if_dirty();
@@ -102,10 +70,10 @@ namespace gsr {
mgl::vec2f pos = position + mgl::vec2f(padding_left, padding_top);
Item &item = items[selected_item];
item.text.set_position(pos);
item.text.set_position(pos.floor());
if(show_dropdown) {
const int border_size = 3;
const mgl::Color border_color(118, 185, 0);
const mgl::Color border_color = gsr::get_theme().tint_color;
draw_rectangle_outline(window, pos - mgl::vec2f(padding_left, padding_top), item_size, border_color, border_size);
}
window.draw(item.text);
@@ -113,7 +81,7 @@ namespace gsr {
for(size_t i = 0; i < items.size(); ++i) {
Item &item = items[i];
item.text.set_position(pos);
item.text.set_position(pos.floor());
const mgl::FloatRect text_bounds = item.text.get_bounds();
if(show_dropdown) {
@@ -121,7 +89,7 @@ namespace gsr {
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) {
mgl::Rectangle item_background(text_bounds.position - mgl::vec2f(padding_left, padding_top), item_size);
item_background.set_color(mgl::Color(118, 185, 0));
item_background.set_color(gsr::get_theme().tint_color);
window.draw(item_background);
} else {
/*const int border_size = 3;

181
src/gui/DropdownButton.cpp Normal file
View File

@@ -0,0 +1,181 @@
#include "../../include/gui/DropdownButton.hpp"
#include "../../include/gui/Utils.hpp"
#include "../../include/Theme.hpp"
#include <mglpp/graphics/Rectangle.hpp>
#include <mglpp/graphics/Texture.hpp>
#include <mglpp/window/Window.hpp>
#include <mglpp/window/Event.hpp>
#include <mglpp/system/FloatRect.hpp>
namespace gsr {
static const float padding_top = 10.0f;
static const float padding_bottom = 10.0f;
static const float padding_left = 10.0f;
static const float padding_right = 10.0f;
static const int border_size = 5;
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) :
title_font(title_font), description_font(description_font), size(size), title(title, *title_font), description(description_deactivated, *description_font),
description_activated(description_activated), description_deactivated(description_deactivated)
{
if(icon_texture && icon_texture->is_valid()) {
icon_sprite.set_texture(icon_texture);
icon_sprite.set_height((int)(size.y * 0.5f));
}
this->description.set_color(mgl::Color(150, 150, 150));
}
bool DropdownButton::on_event(mgl::Event &event, mgl::Window&) {
if(event.type == mgl::Event::MouseMoved) {
const mgl::vec2f collision_margin(1.0f, 1.0f); // Makes sure that multiple buttons that are next to each other wont activate at the same time when the cursor is right between them
const bool inside = mgl::FloatRect(position + collision_margin, size - collision_margin).contains({ (float)event.mouse_move.x, (float)event.mouse_move.y });
if(mouse_inside && !inside) {
mouse_inside = false;
} else if(!mouse_inside && inside) {
mouse_inside = true;
}
} else if(event.type == mgl::Event::MouseButtonPressed) {
const bool clicked_inside = mouse_inside;
show_dropdown = clicked_inside;
if(on_click && mouse_inside_item >= 0 && mouse_inside_item < (int)items.size())
on_click(items[mouse_inside_item].id);
}
return true;
}
void DropdownButton::draw(mgl::Window &window) {
update_if_dirty();
if(show_dropdown) {
// Background
{
mgl::Rectangle rect(size);
rect.set_position(position);
rect.set_color(mgl::Color(0, 0, 0, 255));
window.draw(rect);
}
const mgl::Color border_color = gsr::get_theme().tint_color;
// Green line at top
{
mgl::Rectangle rect({ size.x, border_size });
rect.set_position(position);
rect.set_color(border_color);
window.draw(rect);
}
} else if(mouse_inside) {
// Background
{
mgl::Rectangle rect(size);
rect.set_position(position);
rect.set_color(mgl::Color(0, 0, 0, 255));
window.draw(rect);
}
const mgl::Color border_color = gsr::get_theme().tint_color;
draw_rectangle_outline(window, position, size, border_color, border_size);
} else {
// Background
mgl::Rectangle rect(size);
rect.set_position(position);
rect.set_color(mgl::Color(0, 0, 0, 220));
window.draw(rect);
}
const int text_margin = size.y * 0.085;
const auto title_bounds = title.get_bounds();
title.set_position((position + mgl::vec2f(size.x * 0.5f - title_bounds.size.x * 0.5f, text_margin)).floor());
window.draw(title);
const auto description_bounds = description.get_bounds();
description.set_position((position + mgl::vec2f(size.x * 0.5f - description_bounds.size.x * 0.5f, size.y - description_bounds.size.y - text_margin)).floor());
window.draw(description);
if(icon_sprite.get_texture()->is_valid()) {
icon_sprite.set_position((position + size * 0.5f - icon_sprite.get_size() * 0.5f).floor());
window.draw(icon_sprite);
}
mouse_inside_item = -1;
if(show_dropdown) {
const mgl::vec2i mouse_pos = window.get_mouse_position();
mgl::Rectangle dropdown_bg(max_size);
dropdown_bg.set_position(position + mgl::vec2f(0.0f, size.y));
dropdown_bg.set_color(mgl::Color(0, 0, 0));
window.draw(dropdown_bg);
mgl::vec2f item_position = dropdown_bg.get_position();
for(size_t i = 0; i < items.size(); ++i) {
auto &item = items[i];
const auto text_bounds = item.text.get_bounds();
const float item_height = padding_top + text_bounds.size.y + padding_bottom;
if(mouse_inside_item == -1) {
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 });
if(inside) {
draw_rectangle_outline(window, item_position, item_size, gsr::get_theme().tint_color, 5);
mouse_inside_item = i;
}
}
item.text.set_position((item_position + mgl::vec2f(padding_left, item_height * 0.5f - text_bounds.size.y * 0.5f)).floor());
window.draw(item.text);
item_position.y += item_height;
}
}
}
void DropdownButton::add_item(const std::string &text, const std::string &id) {
items.push_back({mgl::Text(text, *title_font), id});
dirty = true;
}
void DropdownButton::set_item_label(const std::string &id, const std::string &new_label) {
for(auto &item : items) {
if(item.id == id) {
item.text.set_string(new_label);
dirty = true;
return;
}
}
}
void DropdownButton::set_activated(bool activated) {
if(this->activated == activated)
return;
this->activated = activated;
if(activated) {
description = mgl::Text(description_activated, *description_font);
description.set_color(get_theme().tint_color);
icon_sprite.set_color(get_theme().tint_color);
} else {
description = mgl::Text(description_deactivated, *description_font);
description.set_color(mgl::Color(150, 150, 150));
icon_sprite.set_color(mgl::Color(255, 255, 255));
}
}
void DropdownButton::update_if_dirty() {
if(!dirty)
return;
max_size = { size.x, 0.0f };
for(Item &item : items) {
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.y += bounds.y + padding_top + padding_bottom;
}
dirty = false;
}
mgl::vec2f DropdownButton::get_size() {
update_if_dirty();
return size;
}
}

43
src/gui/Utils.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "../../include/gui/Utils.hpp"
#include <mglpp/window/Window.hpp>
#include <mglpp/graphics/Rectangle.hpp>
namespace gsr {
// TODO: Use vertices to make it one draw call
void draw_rectangle_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size, mgl::Color color, float border_size) {
pos = pos.floor();
size = size.floor();
border_size = (int)border_size;
// Green line at top
{
mgl::Rectangle rect({ size.x, border_size });
rect.set_position(pos);
rect.set_color(color);
window.draw(rect);
}
// Green line at bottom
{
mgl::Rectangle rect({ size.x, border_size });
rect.set_position(pos + mgl::vec2f(0.0f, size.y - border_size));
rect.set_color(color);
window.draw(rect);
}
// Green line at left
{
mgl::Rectangle rect({ border_size, size.y - border_size * 2 });
rect.set_position(pos + mgl::vec2f(0, border_size));
rect.set_color(color);
window.draw(rect);
}
// Green line at right
{
mgl::Rectangle rect({ border_size, size.y - border_size * 2 });
rect.set_position(pos + mgl::vec2f(size.x - border_size, border_size));
rect.set_color(color);
window.draw(rect);
}
}
}

View File

@@ -42,10 +42,11 @@ namespace gsr {
Widget *widget = *it;
if(widget->move_to_top) {
widget->move_to_top = false;
if(widgets.back() != widget) {
std::swap(*it, widgets.back());
/*if(widgets.back() != widget) {
widgets.erase(it);
widgets.push_back(widget);
}
}*/
}
}

View File

@@ -1,8 +1,10 @@
#include "../include/gui/WidgetContainer.hpp"
#include "../include/gui/Button.hpp"
#include "../include/gui/DropdownButton.hpp"
#include "../include/gui/ComboBox.hpp"
#include "../include/Process.hpp"
#include "../include/Theme.hpp"
#include "../include/GsrInfo.hpp"
#include <stdio.h>
#include <stdlib.h>
@@ -138,6 +140,15 @@ int main(int argc, char **argv) {
signal(SIGINT, sigint_handler);
gsr::GsrInfo gsr_info;
// TODO:
gsr::GsrInfoExitStatus gsr_info_exit_status = gsr::get_gpu_screen_recorder_info(&gsr_info);
if(gsr_info_exit_status != gsr::GsrInfoExitStatus::OK) {
fprintf(stderr, "error: failed to get gpu-screen-recorder info\n");
exit(1);
}
gsr::init_theme(gsr_info);
std::string program_root_dir = dirname(argv[0]);
if(!program_root_dir.empty() && program_root_dir.back() != '/')
program_root_dir += '/';
@@ -225,10 +236,7 @@ int main(int argc, char **argv) {
bg_screenshot_overlay.set_color(bg_color);
struct MainButton {
mgl::Text title;
mgl::Text description;
mgl::Sprite icon;
std::unique_ptr<gsr::Button> button;
std::unique_ptr<gsr::DropdownButton> button;
gsr::GsrMode mode;
};
@@ -256,26 +264,17 @@ int main(int argc, char **argv) {
&stream_button_texture
};
const int button_height = window_create_params.size.y / 6.0f;
const int button_height = window_create_params.size.y / 5.0f;
const int button_width = button_height;
std::vector<MainButton> main_buttons;
for(int i = 0; i < 3; ++i) {
mgl::Text title(titles[i], {0.0f, 0.0f}, title_font);
title.set_color(mgl::Color(255, 255, 255));
mgl::Text description(descriptions_off[i], {0.0f, 0.0f}, font);
description.set_color(mgl::Color(150, 150, 150));
mgl::Sprite sprite(textures[i]);
sprite.set_height(button_height * 0.5f);
auto button = std::make_unique<gsr::Button>(mgl::vec2f(button_width, button_height));
auto button = std::make_unique<gsr::DropdownButton>(&title_font, &font, titles[i], descriptions_on[i], descriptions_off[i], textures[i], mgl::vec2f(button_width, button_height));
button->add_item("Start", "start");
button->add_item("Settings", "settings");
MainButton main_button = {
std::move(title),
std::move(description),
std::move(sprite),
std::move(button),
gsr::GsrMode::Unknown
};
@@ -285,7 +284,6 @@ int main(int argc, char **argv) {
auto update_overlay_shape = [&](std::optional<gsr::GsrMode> gsr_mode = std::nullopt) {
fprintf(stderr, "update overlay shape!\n");
const int main_button_margin = button_height * 0.085;// * get_config().scale;
const int spacing = 0;// * get_config().scale;
const int combined_spacing = spacing * std::max(0, (int)main_buttons.size() - 1);
@@ -303,37 +301,18 @@ int main(int argc, char **argv) {
for(size_t i = 0; i < main_buttons.size(); ++i) {
if(main_buttons[i].mode != gsr::GsrMode::Unknown && main_buttons[i].mode == gsr_mode.value()) {
main_buttons[i].description.set_string(descriptions_on[i]);
main_buttons[i].description.set_color(mgl::Color(118, 185, 0));
main_buttons[i].icon.set_color(mgl::Color(118, 185, 0));
main_buttons[i].button->set_activated(true);
} else {
main_buttons[i].description.set_string(descriptions_off[i]);
main_buttons[i].description.set_color(mgl::Color(150, 150, 150));
main_buttons[i].icon.set_color(mgl::Color(255, 255, 255));
main_buttons[i].button->set_activated(false);
}
main_buttons[i].title.set_position(
mgl::vec2f(
main_button_pos.x + per_button_width * 0.5f - main_buttons[i].title.get_bounds().size.x * 0.5f,
main_button_pos.y + main_button_margin).floor());
main_buttons[i].description.set_position(
mgl::vec2f(
main_button_pos.x + per_button_width * 0.5f - main_buttons[i].description.get_bounds().size.x * 0.5f,
main_button_pos.y + overlay_desired_size.y - main_buttons[i].description.get_bounds().size.y - main_button_margin).floor());
main_buttons[i].icon.set_position(
mgl::vec2f(
main_button_pos.x + per_button_width * 0.5f - main_buttons[i].icon.get_texture()->get_size().x * main_buttons[i].icon.get_scale().x * 0.5f,
main_button_pos.y + overlay_desired_size.y * 0.5f - main_buttons[i].icon.get_texture()->get_size().y * main_buttons[i].icon.get_scale().y * 0.5f).floor());
main_buttons[i].button->set_position(main_button_pos.to_vec2f());
main_button_pos.x += per_button_width + combined_spacing;
}
};
// Replay
main_buttons[0].button->on_click = [&]() {
main_buttons[0].button->on_click = [&](const std::string &id) {
/*
char window_to_record_str[32];
snprintf(window_to_record_str, sizeof(window_to_record_str), "%ld", target_window);
@@ -353,9 +332,12 @@ int main(int argc, char **argv) {
// TODO: Monitor /tmp/gpu-screen-recorder and update ui to match state
// Record
main_buttons[1].button->on_click = [&]() {
window.close();
usleep(1000 * 50); // 50 milliseconds
main_buttons[1].button->on_click = [&](const std::string &id) {
if(id != "start")
return;
// window.close();
// usleep(1000 * 50); // 50 milliseconds
pid_t gpu_screen_recorder_process = -1;
gsr::GsrMode gsr_mode = gsr::GsrMode::Unknown;
@@ -366,12 +348,13 @@ int main(int argc, char **argv) {
perror("waitpid failed");
/* Ignore... */
}
window.set_visible(false);
window.close();
return;
//exit(0);
//update_overlay_shape(gsr::GsrMode::Unknown);
// window.set_visible(false);
// window.close();
// return;
//exit(0);
update_overlay_shape(gsr::GsrMode::Unknown);
main_buttons[1].button->set_item_label(id, "Start");
return;
}
const char *args[] = {
@@ -382,10 +365,14 @@ int main(int argc, char **argv) {
nullptr
};
gsr::exec_program_daemonized(args);
//update_overlay_shape(gsr::GsrMode::Record);
update_overlay_shape(gsr::GsrMode::Record);
main_buttons[1].button->set_item_label(id, "Stop");
//exit(0);
window.set_visible(false);
window.close();
// window.set_visible(false);
// window.close();
// TODO: Show notification with args:
// "Recording has started" 3.0 ./images/record.png 76b900
};
main_buttons[1].mode = gsr::GsrMode::Record;
@@ -415,11 +402,11 @@ int main(int argc, char **argv) {
//XGrabServer(display);
mgl::Rectangle top_bar_background(mgl::vec2f(window.get_size().x, window.get_size().y*0.05f).floor());
mgl::Rectangle top_bar_background(mgl::vec2f(window.get_size().x, window.get_size().y*0.06f).floor());
top_bar_background.set_color(mgl::Color(0, 0, 0, 220));
mgl::Text top_bar_text("GPU Screen Recorder", top_bar_font);
//top_bar_text.set_color(mgl::Color(118, 185, 0));
//top_bar_text.set_color(gsr::get_theme().tint_color);
top_bar_text.set_position((top_bar_background.get_position() + top_bar_background.get_size()*0.5f - top_bar_text.get_bounds().size*0.5f).floor());
// gsr::ComboBox record_area_box(&title_font);
@@ -458,7 +445,7 @@ int main(int argc, char **argv) {
// framerate_title.set_position(mgl::vec2f(framerate_box.get_position().x, framerate_box.get_position().y - title_font.get_character_size() - 10.0f));
mgl::Texture close_texture;
if(!close_texture.load_from_file("images/cross.png", {false, false, false}))
if(!close_texture.load_from_file("images/cross.png"))
startup_error("failed to load texture: images/cross.png");
mgl::Sprite close_sprite(&close_texture);
@@ -489,7 +476,7 @@ int main(int argc, char **argv) {
const float settings_topline_thickness = 5.0f;
mgl::Rectangle settings_topline(settings_background.get_position() - mgl::vec2f(0.0f, settings_topline_thickness), mgl::vec2f(settings_background.get_size().x, settings_topline_thickness));
settings_topline.set_color(mgl::Color(118, 185, 0));
settings_topline.set_color(gsr::get_theme().tint_color);
*/
mgl::Clock state_update_timer;
@@ -517,11 +504,6 @@ int main(int argc, char **argv) {
// window.draw(video_quality_title);
// window.draw(framerate_title);
widget_container.draw(window);
for(auto &main_button : main_buttons) {
window.draw(main_button.icon);
window.draw(main_button.title);
window.draw(main_button.description);
}
window.draw(top_bar_background);
window.draw(top_bar_text);
window.draw(logo_sprite);