mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-03-31 09:17:04 +09:00
Move dropdown button text and icon code to dropdown button class
This commit is contained in:
2
TODO
2
TODO
@@ -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.
|
All of these things should be done with vertex buffer, for real 3D.
|
||||||
|
|
||||||
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.
|
||||||
66
include/GsrInfo.hpp
Normal file
66
include/GsrInfo.hpp
Normal 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
18
include/Theme.hpp
Normal 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();
|
||||||
|
}
|
||||||
54
include/gui/DropdownButton.hpp
Normal file
54
include/gui/DropdownButton.hpp
Normal 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
13
include/gui/Utils.hpp
Normal 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
179
src/GsrInfo.cpp
Normal 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
34
src/Theme.cpp
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "../../include/gui/Button.hpp"
|
#include "../../include/gui/Button.hpp"
|
||||||
|
#include "../../include/Theme.hpp"
|
||||||
#include <mglpp/graphics/Rectangle.hpp>
|
#include <mglpp/graphics/Rectangle.hpp>
|
||||||
#include <mglpp/window/Window.hpp>
|
#include <mglpp/window/Window.hpp>
|
||||||
#include <mglpp/window/Event.hpp>
|
#include <mglpp/window/Event.hpp>
|
||||||
@@ -40,7 +41,7 @@ namespace gsr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int border_size = 5;
|
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
|
// Green line at top
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
#include "../../include/gui/ComboBox.hpp"
|
#include "../../include/gui/ComboBox.hpp"
|
||||||
|
#include "../../include/gui/Utils.hpp"
|
||||||
|
#include "../../include/Theme.hpp"
|
||||||
#include <mglpp/graphics/Rectangle.hpp>
|
#include <mglpp/graphics/Rectangle.hpp>
|
||||||
#include <mglpp/graphics/Font.hpp>
|
#include <mglpp/graphics/Font.hpp>
|
||||||
#include <mglpp/window/Window.hpp>
|
#include <mglpp/window/Window.hpp>
|
||||||
@@ -46,40 +48,6 @@ namespace gsr {
|
|||||||
return true;
|
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) {
|
void ComboBox::draw(mgl::Window &window) {
|
||||||
update_if_dirty();
|
update_if_dirty();
|
||||||
|
|
||||||
@@ -102,10 +70,10 @@ namespace gsr {
|
|||||||
mgl::vec2f pos = position + mgl::vec2f(padding_left, padding_top);
|
mgl::vec2f pos = position + mgl::vec2f(padding_left, padding_top);
|
||||||
|
|
||||||
Item &item = items[selected_item];
|
Item &item = items[selected_item];
|
||||||
item.text.set_position(pos);
|
item.text.set_position(pos.floor());
|
||||||
if(show_dropdown) {
|
if(show_dropdown) {
|
||||||
const int border_size = 3;
|
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);
|
draw_rectangle_outline(window, pos - mgl::vec2f(padding_left, padding_top), item_size, border_color, border_size);
|
||||||
}
|
}
|
||||||
window.draw(item.text);
|
window.draw(item.text);
|
||||||
@@ -113,7 +81,7 @@ namespace gsr {
|
|||||||
|
|
||||||
for(size_t i = 0; i < items.size(); ++i) {
|
for(size_t i = 0; i < items.size(); ++i) {
|
||||||
Item &item = items[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();
|
const mgl::FloatRect text_bounds = item.text.get_bounds();
|
||||||
|
|
||||||
if(show_dropdown) {
|
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 });
|
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), item_size);
|
||||||
item_background.set_color(mgl::Color(118, 185, 0));
|
item_background.set_color(gsr::get_theme().tint_color);
|
||||||
window.draw(item_background);
|
window.draw(item_background);
|
||||||
} else {
|
} else {
|
||||||
/*const int border_size = 3;
|
/*const int border_size = 3;
|
||||||
|
|||||||
181
src/gui/DropdownButton.cpp
Normal file
181
src/gui/DropdownButton.cpp
Normal 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
43
src/gui/Utils.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,10 +42,11 @@ namespace gsr {
|
|||||||
Widget *widget = *it;
|
Widget *widget = *it;
|
||||||
if(widget->move_to_top) {
|
if(widget->move_to_top) {
|
||||||
widget->move_to_top = false;
|
widget->move_to_top = false;
|
||||||
if(widgets.back() != widget) {
|
std::swap(*it, widgets.back());
|
||||||
|
/*if(widgets.back() != widget) {
|
||||||
widgets.erase(it);
|
widgets.erase(it);
|
||||||
widgets.push_back(widget);
|
widgets.push_back(widget);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
104
src/main.cpp
104
src/main.cpp
@@ -1,8 +1,10 @@
|
|||||||
|
|
||||||
#include "../include/gui/WidgetContainer.hpp"
|
#include "../include/gui/WidgetContainer.hpp"
|
||||||
#include "../include/gui/Button.hpp"
|
#include "../include/gui/DropdownButton.hpp"
|
||||||
#include "../include/gui/ComboBox.hpp"
|
#include "../include/gui/ComboBox.hpp"
|
||||||
#include "../include/Process.hpp"
|
#include "../include/Process.hpp"
|
||||||
|
#include "../include/Theme.hpp"
|
||||||
|
#include "../include/GsrInfo.hpp"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -138,6 +140,15 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
signal(SIGINT, sigint_handler);
|
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]);
|
std::string program_root_dir = dirname(argv[0]);
|
||||||
if(!program_root_dir.empty() && program_root_dir.back() != '/')
|
if(!program_root_dir.empty() && program_root_dir.back() != '/')
|
||||||
program_root_dir += '/';
|
program_root_dir += '/';
|
||||||
@@ -225,10 +236,7 @@ int main(int argc, char **argv) {
|
|||||||
bg_screenshot_overlay.set_color(bg_color);
|
bg_screenshot_overlay.set_color(bg_color);
|
||||||
|
|
||||||
struct MainButton {
|
struct MainButton {
|
||||||
mgl::Text title;
|
std::unique_ptr<gsr::DropdownButton> button;
|
||||||
mgl::Text description;
|
|
||||||
mgl::Sprite icon;
|
|
||||||
std::unique_ptr<gsr::Button> button;
|
|
||||||
gsr::GsrMode mode;
|
gsr::GsrMode mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -256,26 +264,17 @@ int main(int argc, char **argv) {
|
|||||||
&stream_button_texture
|
&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;
|
const int button_width = button_height;
|
||||||
|
|
||||||
std::vector<MainButton> main_buttons;
|
std::vector<MainButton> main_buttons;
|
||||||
|
|
||||||
for(int i = 0; i < 3; ++i) {
|
for(int i = 0; i < 3; ++i) {
|
||||||
mgl::Text title(titles[i], {0.0f, 0.0f}, title_font);
|
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));
|
||||||
title.set_color(mgl::Color(255, 255, 255));
|
button->add_item("Start", "start");
|
||||||
|
button->add_item("Settings", "settings");
|
||||||
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));
|
|
||||||
|
|
||||||
MainButton main_button = {
|
MainButton main_button = {
|
||||||
std::move(title),
|
|
||||||
std::move(description),
|
|
||||||
std::move(sprite),
|
|
||||||
std::move(button),
|
std::move(button),
|
||||||
gsr::GsrMode::Unknown
|
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) {
|
auto update_overlay_shape = [&](std::optional<gsr::GsrMode> gsr_mode = std::nullopt) {
|
||||||
fprintf(stderr, "update overlay shape!\n");
|
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 spacing = 0;// * get_config().scale;
|
||||||
const int combined_spacing = spacing * std::max(0, (int)main_buttons.size() - 1);
|
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) {
|
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()) {
|
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].button->set_activated(true);
|
||||||
main_buttons[i].description.set_color(mgl::Color(118, 185, 0));
|
|
||||||
main_buttons[i].icon.set_color(mgl::Color(118, 185, 0));
|
|
||||||
} else {
|
} else {
|
||||||
main_buttons[i].description.set_string(descriptions_off[i]);
|
main_buttons[i].button->set_activated(false);
|
||||||
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].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_buttons[i].button->set_position(main_button_pos.to_vec2f());
|
||||||
main_button_pos.x += per_button_width + combined_spacing;
|
main_button_pos.x += per_button_width + combined_spacing;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Replay
|
// Replay
|
||||||
main_buttons[0].button->on_click = [&]() {
|
main_buttons[0].button->on_click = [&](const std::string &id) {
|
||||||
/*
|
/*
|
||||||
char window_to_record_str[32];
|
char window_to_record_str[32];
|
||||||
snprintf(window_to_record_str, sizeof(window_to_record_str), "%ld", target_window);
|
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
|
// TODO: Monitor /tmp/gpu-screen-recorder and update ui to match state
|
||||||
|
|
||||||
// Record
|
// Record
|
||||||
main_buttons[1].button->on_click = [&]() {
|
main_buttons[1].button->on_click = [&](const std::string &id) {
|
||||||
window.close();
|
if(id != "start")
|
||||||
usleep(1000 * 50); // 50 milliseconds
|
return;
|
||||||
|
|
||||||
|
// window.close();
|
||||||
|
// usleep(1000 * 50); // 50 milliseconds
|
||||||
|
|
||||||
pid_t gpu_screen_recorder_process = -1;
|
pid_t gpu_screen_recorder_process = -1;
|
||||||
gsr::GsrMode gsr_mode = gsr::GsrMode::Unknown;
|
gsr::GsrMode gsr_mode = gsr::GsrMode::Unknown;
|
||||||
@@ -366,12 +348,13 @@ int main(int argc, char **argv) {
|
|||||||
perror("waitpid failed");
|
perror("waitpid failed");
|
||||||
/* Ignore... */
|
/* Ignore... */
|
||||||
}
|
}
|
||||||
window.set_visible(false);
|
// window.set_visible(false);
|
||||||
window.close();
|
// window.close();
|
||||||
return;
|
// return;
|
||||||
//exit(0);
|
//exit(0);
|
||||||
//update_overlay_shape(gsr::GsrMode::Unknown);
|
update_overlay_shape(gsr::GsrMode::Unknown);
|
||||||
//return;
|
main_buttons[1].button->set_item_label(id, "Start");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *args[] = {
|
const char *args[] = {
|
||||||
@@ -382,10 +365,14 @@ int main(int argc, char **argv) {
|
|||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
gsr::exec_program_daemonized(args);
|
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);
|
//exit(0);
|
||||||
window.set_visible(false);
|
// window.set_visible(false);
|
||||||
window.close();
|
// window.close();
|
||||||
|
|
||||||
|
// TODO: Show notification with args:
|
||||||
|
// "Recording has started" 3.0 ./images/record.png 76b900
|
||||||
};
|
};
|
||||||
main_buttons[1].mode = gsr::GsrMode::Record;
|
main_buttons[1].mode = gsr::GsrMode::Record;
|
||||||
|
|
||||||
@@ -415,11 +402,11 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
//XGrabServer(display);
|
//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));
|
top_bar_background.set_color(mgl::Color(0, 0, 0, 220));
|
||||||
|
|
||||||
mgl::Text top_bar_text("GPU Screen Recorder", top_bar_font);
|
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());
|
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);
|
// 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));
|
// 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;
|
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");
|
startup_error("failed to load texture: images/cross.png");
|
||||||
|
|
||||||
mgl::Sprite close_sprite(&close_texture);
|
mgl::Sprite close_sprite(&close_texture);
|
||||||
@@ -489,7 +476,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
const float settings_topline_thickness = 5.0f;
|
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));
|
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;
|
mgl::Clock state_update_timer;
|
||||||
@@ -517,11 +504,6 @@ int main(int argc, char **argv) {
|
|||||||
// window.draw(video_quality_title);
|
// window.draw(video_quality_title);
|
||||||
// window.draw(framerate_title);
|
// window.draw(framerate_title);
|
||||||
widget_container.draw(window);
|
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_background);
|
||||||
window.draw(top_bar_text);
|
window.draw(top_bar_text);
|
||||||
window.draw(logo_sprite);
|
window.draw(logo_sprite);
|
||||||
|
|||||||
Reference in New Issue
Block a user