mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-04-24 18:42:59 +09:00
Fix window not visible in fullscreen applications
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
# GPU Screen Recorder UI
|
# GPU Screen Recorder UI
|
||||||
A fullscreen overlay UI for [GPU Screen Recorder](https://git.dec05eba.com/gpu-screen-recorder/about/), in the style of ShadowPlay.
|
A fullscreen overlay UI for [GPU Screen Recorder](https://git.dec05eba.com/gpu-screen-recorder/about/) in the style of ShadowPlay.
|
||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
GPU Screen Recorder UI uses meson build system so you need to install `meson` to build GPU Screen Recorder UI.
|
GPU Screen Recorder UI uses meson build system so you need to install `meson` to build GPU Screen Recorder UI.
|
||||||
|
|||||||
@@ -32,13 +32,14 @@ namespace gsr {
|
|||||||
|
|
||||||
class Overlay {
|
class Overlay {
|
||||||
public:
|
public:
|
||||||
Overlay(mgl::Window &window, std::string resources_path, GsrInfo gsr_info, egl_functions egl_funcs, mgl::Color bg_color);
|
Overlay(std::string resources_path, GsrInfo gsr_info, egl_functions egl_funcs, mgl::Color bg_color);
|
||||||
Overlay(const Overlay&) = delete;
|
Overlay(const Overlay&) = delete;
|
||||||
Overlay& operator=(const Overlay&) = delete;
|
Overlay& operator=(const Overlay&) = delete;
|
||||||
~Overlay();
|
~Overlay();
|
||||||
|
|
||||||
void on_event(mgl::Event &event, mgl::Window &window);
|
void handle_events();
|
||||||
void draw(mgl::Window &window);
|
void on_event(mgl::Event &event);
|
||||||
|
void draw();
|
||||||
|
|
||||||
void show();
|
void show();
|
||||||
void hide();
|
void hide();
|
||||||
@@ -80,7 +81,8 @@ namespace gsr {
|
|||||||
KeyBindingCallback callback;
|
KeyBindingCallback callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
mgl::Window &window;
|
std::unique_ptr<mgl::Window> window;
|
||||||
|
mgl::Event event;
|
||||||
std::string resources_path;
|
std::string resources_path;
|
||||||
GsrInfo gsr_info;
|
GsrInfo gsr_info;
|
||||||
egl_functions egl_funcs;
|
egl_functions egl_funcs;
|
||||||
|
|||||||
@@ -18,10 +18,6 @@ namespace gsr {
|
|||||||
float window_width = 0.0f;
|
float window_width = 0.0f;
|
||||||
float window_height = 0.0f;
|
float window_height = 0.0f;
|
||||||
|
|
||||||
mgl::Color tint_color = mgl::Color(118, 185, 0);
|
|
||||||
mgl::Color page_bg_color = mgl::Color(38, 43, 47);
|
|
||||||
mgl::Color text_color = mgl::Color(255, 255, 255);
|
|
||||||
|
|
||||||
mgl::MemoryMappedFile body_font_file;
|
mgl::MemoryMappedFile body_font_file;
|
||||||
mgl::MemoryMappedFile title_font_file;
|
mgl::MemoryMappedFile title_font_file;
|
||||||
mgl::Font body_font;
|
mgl::Font body_font;
|
||||||
@@ -50,8 +46,17 @@ namespace gsr {
|
|||||||
bool set_window_size(mgl::vec2i window_size);
|
bool set_window_size(mgl::vec2i window_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool init_theme(const GsrInfo &gsr_info, const std::string &resources_path);
|
bool init_theme(const std::string &resources_path);
|
||||||
void deinit_theme();
|
void deinit_theme();
|
||||||
|
|
||||||
Theme& get_theme();
|
Theme& get_theme();
|
||||||
|
|
||||||
|
struct ColorTheme {
|
||||||
|
mgl::Color tint_color = mgl::Color(118, 185, 0);
|
||||||
|
mgl::Color page_bg_color = mgl::Color(38, 43, 47);
|
||||||
|
mgl::Color text_color = mgl::Color(255, 255, 255);
|
||||||
|
};
|
||||||
|
|
||||||
|
bool init_color_theme(const GsrInfo &gsr_info);
|
||||||
|
void deinit_color_theme();
|
||||||
|
ColorTheme& get_color_theme();
|
||||||
}
|
}
|
||||||
193
src/Overlay.cpp
193
src/Overlay.cpp
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
#include <X11/cursorfont.h>
|
#include <X11/cursorfont.h>
|
||||||
#include <mglpp/system/Rect.hpp>
|
#include <mglpp/system/Rect.hpp>
|
||||||
#include <mglpp/window/Event.hpp>
|
#include <mglpp/window/Event.hpp>
|
||||||
@@ -184,16 +185,13 @@ namespace gsr {
|
|||||||
return XGetSelectionOwner(dpy, prop_atom) != None;
|
return XGetSelectionOwner(dpy, prop_atom) != None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Overlay::Overlay(mgl::Window &window, std::string resources_path, GsrInfo gsr_info, egl_functions egl_funcs, mgl::Color bg_color) :
|
Overlay::Overlay(std::string resources_path, GsrInfo gsr_info, egl_functions egl_funcs, mgl::Color bg_color) :
|
||||||
window(window),
|
|
||||||
resources_path(std::move(resources_path)),
|
resources_path(std::move(resources_path)),
|
||||||
gsr_info(gsr_info),
|
gsr_info(gsr_info),
|
||||||
egl_funcs(egl_funcs),
|
egl_funcs(egl_funcs),
|
||||||
bg_color(bg_color),
|
bg_color(bg_color),
|
||||||
bg_screenshot_overlay({0.0f, 0.0f}),
|
bg_screenshot_overlay({0.0f, 0.0f}),
|
||||||
top_bar_background({0.0f, 0.0f}),
|
top_bar_background({0.0f, 0.0f}),
|
||||||
top_bar_text("GPU Screen Recorder", get_theme().top_bar_font),
|
|
||||||
logo_sprite(&get_theme().logo_texture),
|
|
||||||
close_button_widget({0.0f, 0.0f}),
|
close_button_widget({0.0f, 0.0f}),
|
||||||
config(gsr_info)
|
config(gsr_info)
|
||||||
{
|
{
|
||||||
@@ -211,6 +209,8 @@ namespace gsr {
|
|||||||
std::optional<Config> new_config = read_config(gsr_info);
|
std::optional<Config> new_config = read_config(gsr_info);
|
||||||
if(new_config)
|
if(new_config)
|
||||||
config = std::move(new_config.value());
|
config = std::move(new_config.value());
|
||||||
|
|
||||||
|
gsr::init_color_theme(gsr_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
Overlay::~Overlay() {
|
Overlay::~Overlay() {
|
||||||
@@ -237,7 +237,7 @@ namespace gsr {
|
|||||||
|
|
||||||
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
|
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
|
||||||
if(recording_status == RecordingStatus::RECORD && config.record_config.show_video_saved_notifications)
|
if(recording_status == RecordingStatus::RECORD && config.record_config.show_video_saved_notifications)
|
||||||
show_notification("Recording has been saved", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::RECORD);
|
show_notification("Recording has been saved", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,18 +259,27 @@ namespace gsr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlay::on_event(mgl::Event &event, mgl::Window &window) {
|
void Overlay::handle_events() {
|
||||||
if(!visible)
|
if(!visible || !window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
close_button_widget.on_event(event, window, mgl::vec2f(0.0f, 0.0f));
|
while(window->poll_event(event)) {
|
||||||
if(!page_stack.on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
|
on_event(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Overlay::on_event(mgl::Event &event) {
|
||||||
|
if(!visible || !window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
close_button_widget.on_event(event, *window, mgl::vec2f(0.0f, 0.0f));
|
||||||
|
if(!page_stack.on_event(event, *window, mgl::vec2f(0.0f, 0.0f)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
process_key_bindings(event);
|
process_key_bindings(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlay::draw(mgl::Window &window) {
|
void Overlay::draw() {
|
||||||
update_notification_process_status();
|
update_notification_process_status();
|
||||||
update_gsr_process_status();
|
update_gsr_process_status();
|
||||||
|
|
||||||
@@ -282,42 +291,88 @@ namespace gsr {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!window)
|
||||||
|
return;
|
||||||
|
|
||||||
|
window->clear();
|
||||||
|
|
||||||
if(window_texture_sprite.get_texture() && window_texture.texture_id) {
|
if(window_texture_sprite.get_texture() && window_texture.texture_id) {
|
||||||
window.draw(window_texture_sprite);
|
window->draw(window_texture_sprite);
|
||||||
window.draw(bg_screenshot_overlay);
|
window->draw(bg_screenshot_overlay);
|
||||||
} else if(screenshot_texture.is_valid()) {
|
} else if(screenshot_texture.is_valid()) {
|
||||||
window.draw(screenshot_sprite);
|
window->draw(screenshot_sprite);
|
||||||
window.draw(bg_screenshot_overlay);
|
window->draw(bg_screenshot_overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
close_button_widget.draw(window, mgl::vec2f(0.0f, 0.0f));
|
close_button_widget.draw(*window, mgl::vec2f(0.0f, 0.0f));
|
||||||
page_stack.draw(window, mgl::vec2f(0.0f, 0.0f));
|
page_stack.draw(*window, mgl::vec2f(0.0f, 0.0f));
|
||||||
|
|
||||||
|
window->display();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlay::show() {
|
void Overlay::show() {
|
||||||
mgl_window *win = window.internal_window();
|
window.reset();
|
||||||
|
window = std::make_unique<mgl::Window>();
|
||||||
|
gsr::deinit_theme();
|
||||||
|
|
||||||
|
mgl::vec2i window_size = { 1280, 720 };
|
||||||
|
mgl::vec2i window_pos = { 0, 0 };
|
||||||
|
|
||||||
|
mgl::Window::CreateParams window_create_params;
|
||||||
|
window_create_params.size = window_size;
|
||||||
|
window_create_params.min_size = window_size;
|
||||||
|
window_create_params.max_size = window_size;
|
||||||
|
window_create_params.position = window_pos;
|
||||||
|
window_create_params.hidden = true;
|
||||||
|
window_create_params.override_redirect = true;
|
||||||
|
window_create_params.background_color = bg_color;
|
||||||
|
window_create_params.support_alpha = true;
|
||||||
|
window_create_params.window_type = MGL_WINDOW_TYPE_NOTIFICATION;
|
||||||
|
window_create_params.render_api = MGL_RENDER_API_EGL;
|
||||||
|
|
||||||
|
if(!window->create("gsr ui", window_create_params))
|
||||||
|
fprintf(stderr, "error: failed to create window\n");
|
||||||
|
|
||||||
|
mgl_context *context = mgl_get_context();
|
||||||
|
Display *display = (Display*)context->connection;
|
||||||
|
|
||||||
|
unsigned char data = 2; // Prefer being composed to allow transparency
|
||||||
|
XChangeProperty(display, window->get_system_handle(), XInternAtom(display, "_NET_WM_BYPASS_COMPOSITOR", False), XA_CARDINAL, 32, PropModeReplace, &data, 1);
|
||||||
|
|
||||||
|
data = 1;
|
||||||
|
XChangeProperty(display, window->get_system_handle(), XInternAtom(display, "GAMESCOPE_EXTERNAL_OVERLAY", False), XA_CARDINAL, 32, PropModeReplace, &data, 1);
|
||||||
|
|
||||||
|
if(!gsr::init_theme(resources_path)) {
|
||||||
|
fprintf(stderr, "Error: failed to load theme\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mgl_window *win = window->internal_window();
|
||||||
if(win->num_monitors == 0) {
|
if(win->num_monitors == 0) {
|
||||||
fprintf(stderr, "gsr warning: no monitors found, not showing overlay\n");
|
fprintf(stderr, "gsr warning: no monitors found, not showing overlay\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mgl_monitor *focused_monitor = find_monitor_by_cursor_position(window);
|
const mgl_monitor *focused_monitor = find_monitor_by_cursor_position(*window);
|
||||||
const mgl::vec2i window_pos(focused_monitor->pos.x, focused_monitor->pos.y);
|
window_pos = {focused_monitor->pos.x, focused_monitor->pos.y};
|
||||||
const mgl::vec2i window_size(focused_monitor->size.x, focused_monitor->size.y);
|
window_size = {focused_monitor->size.x, focused_monitor->size.y};
|
||||||
get_theme().set_window_size(window_size);
|
get_theme().set_window_size(window_size);
|
||||||
|
|
||||||
window.set_size(window_size);
|
window->set_size(window_size);
|
||||||
window.set_size_limits(window_size, window_size);
|
window->set_size_limits(window_size, window_size);
|
||||||
window.set_position(window_pos);
|
window->set_position(window_pos);
|
||||||
|
|
||||||
update_compositor_texture(focused_monitor);
|
update_compositor_texture(focused_monitor);
|
||||||
|
|
||||||
audio_devices = get_audio_devices();
|
audio_devices = get_audio_devices();
|
||||||
|
|
||||||
|
top_bar_text = mgl::Text("GPU Screen Recorder", get_theme().top_bar_font);
|
||||||
|
logo_sprite = mgl::Sprite(&get_theme().logo_texture);
|
||||||
|
|
||||||
bg_screenshot_overlay = mgl::Rectangle(mgl::vec2f(get_theme().window_width, get_theme().window_height));
|
bg_screenshot_overlay = mgl::Rectangle(mgl::vec2f(get_theme().window_width, get_theme().window_height));
|
||||||
top_bar_background = mgl::Rectangle(mgl::vec2f(get_theme().window_width, get_theme().window_height*0.06f).floor());
|
top_bar_background = mgl::Rectangle(mgl::vec2f(get_theme().window_width, get_theme().window_height*0.06f).floor());
|
||||||
top_bar_text = mgl::Text("GPU Screen Recorder", get_theme().top_bar_font);
|
top_bar_text = mgl::Text("GPU Screen Recorder", get_theme().top_bar_font);
|
||||||
@@ -326,7 +381,7 @@ namespace gsr {
|
|||||||
|
|
||||||
bg_screenshot_overlay.set_color(bg_color);
|
bg_screenshot_overlay.set_color(bg_color);
|
||||||
top_bar_background.set_color(mgl::Color(0, 0, 0, 180));
|
top_bar_background.set_color(mgl::Color(0, 0, 0, 180));
|
||||||
//top_bar_text.set_color(get_theme().tint_color);
|
//top_bar_text.set_color(get_color_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());
|
||||||
|
|
||||||
logo_sprite.set_height((int)(top_bar_background.get_size().y * 0.65f));
|
logo_sprite.set_height((int)(top_bar_background.get_size().y * 0.65f));
|
||||||
@@ -419,7 +474,7 @@ namespace gsr {
|
|||||||
const float padding_size = std::max(1.0f, 0.003f * get_theme().window_height);
|
const float padding_size = std::max(1.0f, 0.003f * get_theme().window_height);
|
||||||
const mgl::vec2f padding(padding_size, padding_size);
|
const mgl::vec2f padding(padding_size, padding_size);
|
||||||
if(mgl::FloatRect(pos, size).contains(window.get_mouse_position().to_vec2f()))
|
if(mgl::FloatRect(pos, size).contains(window.get_mouse_position().to_vec2f()))
|
||||||
draw_rectangle_outline(window, pos.floor(), size.floor(), get_theme().tint_color, border_size);
|
draw_rectangle_outline(window, pos.floor(), size.floor(), get_color_theme().tint_color, border_size);
|
||||||
|
|
||||||
mgl::Sprite close_sprite(&get_theme().close_texture);
|
mgl::Sprite close_sprite(&get_theme().close_texture);
|
||||||
close_sprite.set_position(pos + padding);
|
close_sprite.set_position(pos + padding);
|
||||||
@@ -441,12 +496,9 @@ namespace gsr {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
mgl_context *context = mgl_get_context();
|
window->set_fullscreen(true);
|
||||||
Display *display = (Display*)context->connection;
|
window->set_visible(true);
|
||||||
|
make_window_sticky(display, window->get_system_handle());
|
||||||
window.set_fullscreen(true);
|
|
||||||
window.set_visible(true);
|
|
||||||
make_window_sticky(display, window.get_system_handle());
|
|
||||||
|
|
||||||
if(default_cursor) {
|
if(default_cursor) {
|
||||||
XFreeCursor(display, default_cursor);
|
XFreeCursor(display, default_cursor);
|
||||||
@@ -458,26 +510,26 @@ namespace gsr {
|
|||||||
// TODO: Hmm, these dont work in owlboy. Maybe owlboy uses xi2 and that breaks this (does it?).
|
// TODO: Hmm, these dont work in owlboy. Maybe owlboy uses xi2 and that breaks this (does it?).
|
||||||
// Remove these grabs when debugging with a debugger, or your X11 session will appear frozen
|
// Remove these grabs when debugging with a debugger, or your X11 session will appear frozen
|
||||||
|
|
||||||
// XGrabPointer(display, window.get_system_handle(), True,
|
// XGrabPointer(display, window->get_system_handle(), True,
|
||||||
// ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
|
// ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
|
||||||
// Button1MotionMask | Button2MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask |
|
// Button1MotionMask | Button2MotionMask | Button3MotionMask | Button4MotionMask | Button5MotionMask |
|
||||||
// ButtonMotionMask,
|
// ButtonMotionMask,
|
||||||
// GrabModeAsync, GrabModeAsync, None, default_cursor, CurrentTime);
|
// GrabModeAsync, GrabModeAsync, None, default_cursor, CurrentTime);
|
||||||
// TODO: This breaks global hotkeys
|
// TODO: This breaks global hotkeys
|
||||||
//XGrabKeyboard(display, window.get_system_handle(), True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
//XGrabKeyboard(display, window->get_system_handle(), True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
|
||||||
XSetInputFocus(display, window.get_system_handle(), RevertToParent, CurrentTime);
|
XSetInputFocus(display, window->get_system_handle(), RevertToParent, CurrentTime);
|
||||||
XFlush(display);
|
XFlush(display);
|
||||||
|
|
||||||
//window.set_fullscreen(true);
|
//window->set_fullscreen(true);
|
||||||
|
|
||||||
visible = true;
|
visible = true;
|
||||||
|
|
||||||
mgl::Event event;
|
mgl::Event event;
|
||||||
event.type = mgl::Event::MouseMoved;
|
event.type = mgl::Event::MouseMoved;
|
||||||
event.mouse_move.x = window.get_mouse_position().x;
|
event.mouse_move.x = window->get_mouse_position().x;
|
||||||
event.mouse_move.y = window.get_mouse_position().y;
|
event.mouse_move.y = window->get_mouse_position().y;
|
||||||
on_event(event, window);
|
on_event(event);
|
||||||
|
|
||||||
if(gpu_screen_recorder_process > 0) {
|
if(gpu_screen_recorder_process > 0) {
|
||||||
switch(recording_status) {
|
switch(recording_status) {
|
||||||
@@ -514,7 +566,12 @@ namespace gsr {
|
|||||||
|
|
||||||
window_texture_deinit(&window_texture);
|
window_texture_deinit(&window_texture);
|
||||||
visible = false;
|
visible = false;
|
||||||
window.set_visible(false);
|
if(window) {
|
||||||
|
window->set_visible(false);
|
||||||
|
window.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
gsr::deinit_theme();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlay::toggle_show() {
|
void Overlay::toggle_show() {
|
||||||
@@ -534,10 +591,10 @@ namespace gsr {
|
|||||||
|
|
||||||
if(paused) {
|
if(paused) {
|
||||||
update_ui_recording_unpaused();
|
update_ui_recording_unpaused();
|
||||||
show_notification("Recording has been unpaused", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::RECORD);
|
show_notification("Recording has been unpaused", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
|
||||||
} else {
|
} else {
|
||||||
update_ui_recording_paused();
|
update_ui_recording_paused();
|
||||||
show_notification("Recording has been paused", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::RECORD);
|
show_notification("Recording has been paused", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
kill(gpu_screen_recorder_process, SIGUSR2);
|
kill(gpu_screen_recorder_process, SIGUSR2);
|
||||||
@@ -646,7 +703,7 @@ namespace gsr {
|
|||||||
update_ui_replay_stopped();
|
update_ui_replay_stopped();
|
||||||
if(exit_code == 0) {
|
if(exit_code == 0) {
|
||||||
if(config.replay_config.show_replay_stopped_notifications)
|
if(config.replay_config.show_replay_stopped_notifications)
|
||||||
show_notification("Replay stopped", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::REPLAY);
|
show_notification("Replay stopped", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_process, exit_code);
|
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_process, exit_code);
|
||||||
show_notification("Replay stopped because of an error", 3.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY);
|
show_notification("Replay stopped because of an error", 3.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY);
|
||||||
@@ -657,7 +714,7 @@ namespace gsr {
|
|||||||
update_ui_recording_stopped();
|
update_ui_recording_stopped();
|
||||||
if(exit_code == 0) {
|
if(exit_code == 0) {
|
||||||
if(config.record_config.show_video_saved_notifications)
|
if(config.record_config.show_video_saved_notifications)
|
||||||
show_notification("Recording has been saved", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::RECORD);
|
show_notification("Recording has been saved", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_process, exit_code);
|
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_process, exit_code);
|
||||||
show_notification("Failed to start/save recording", 3.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD);
|
show_notification("Failed to start/save recording", 3.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD);
|
||||||
@@ -668,7 +725,7 @@ namespace gsr {
|
|||||||
update_ui_streaming_stopped();
|
update_ui_streaming_stopped();
|
||||||
if(exit_code == 0) {
|
if(exit_code == 0) {
|
||||||
if(config.streaming_config.show_streaming_stopped_notifications)
|
if(config.streaming_config.show_streaming_stopped_notifications)
|
||||||
show_notification("Streaming has stopped", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::STREAM);
|
show_notification("Streaming has stopped", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_process, exit_code);
|
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_process, exit_code);
|
||||||
show_notification("Streaming stopped because of an error", 3.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM);
|
show_notification("Streaming stopped because of an error", 3.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM);
|
||||||
@@ -794,7 +851,7 @@ namespace gsr {
|
|||||||
|
|
||||||
kill(gpu_screen_recorder_process, SIGUSR1);
|
kill(gpu_screen_recorder_process, SIGUSR1);
|
||||||
if(config.replay_config.show_replay_saved_notifications)
|
if(config.replay_config.show_replay_saved_notifications)
|
||||||
show_notification("Replay saved", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::REPLAY);
|
show_notification("Replay saved", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlay::on_press_start_replay() {
|
void Overlay::on_press_start_replay() {
|
||||||
@@ -803,16 +860,16 @@ namespace gsr {
|
|||||||
case RecordingStatus::REPLAY:
|
case RecordingStatus::REPLAY:
|
||||||
break;
|
break;
|
||||||
case RecordingStatus::RECORD:
|
case RecordingStatus::RECORD:
|
||||||
show_notification("Unable to start replay when recording.\nStop recording before starting replay", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::RECORD);
|
show_notification("Unable to start replay when recording.\nStop recording before starting replay.", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
|
||||||
return;
|
return;
|
||||||
case RecordingStatus::STREAM:
|
case RecordingStatus::STREAM:
|
||||||
show_notification("Unable to start replay when streaming.\nStop streaming before starting replay", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::STREAM);
|
show_notification("Unable to start replay when streaming.\nStop streaming before starting replay.", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
// window.close();
|
// window->close();
|
||||||
// usleep(1000 * 50); // 50 milliseconds
|
// usleep(1000 * 50); // 50 milliseconds
|
||||||
|
|
||||||
if(gpu_screen_recorder_process > 0) {
|
if(gpu_screen_recorder_process > 0) {
|
||||||
@@ -829,7 +886,7 @@ namespace gsr {
|
|||||||
|
|
||||||
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
|
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
|
||||||
if(config.replay_config.show_replay_stopped_notifications)
|
if(config.replay_config.show_replay_stopped_notifications)
|
||||||
show_notification("Replay stopped", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::REPLAY);
|
show_notification("Replay stopped", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -905,7 +962,7 @@ namespace gsr {
|
|||||||
// program and start another one. This can also be used to check when the notification has finished by checking with waitpid NOWAIT
|
// program and start another one. This can also be used to check when the notification has finished by checking with waitpid NOWAIT
|
||||||
// to see when the program has exit.
|
// to see when the program has exit.
|
||||||
if(config.replay_config.show_replay_started_notifications)
|
if(config.replay_config.show_replay_started_notifications)
|
||||||
show_notification("Replay has started", 3.0, get_theme().tint_color, get_theme().tint_color, NotificationType::REPLAY);
|
show_notification("Replay has started", 3.0, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::REPLAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlay::on_press_start_record() {
|
void Overlay::on_press_start_record() {
|
||||||
@@ -914,16 +971,16 @@ namespace gsr {
|
|||||||
case RecordingStatus::RECORD:
|
case RecordingStatus::RECORD:
|
||||||
break;
|
break;
|
||||||
case RecordingStatus::REPLAY:
|
case RecordingStatus::REPLAY:
|
||||||
show_notification("Unable to start recording when replay is turned on.\nTurn off replay before starting recording", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::REPLAY);
|
show_notification("Unable to start recording when replay is turned on.\nTurn off replay before starting recording.", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
|
||||||
return;
|
return;
|
||||||
case RecordingStatus::STREAM:
|
case RecordingStatus::STREAM:
|
||||||
show_notification("Unable to start recording when streaming.\nStop streaming before starting recording", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::STREAM);
|
show_notification("Unable to start recording when streaming.\nStop streaming before starting recording.", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
// window.close();
|
// window->close();
|
||||||
// usleep(1000 * 50); // 50 milliseconds
|
// usleep(1000 * 50); // 50 milliseconds
|
||||||
|
|
||||||
if(gpu_screen_recorder_process > 0) {
|
if(gpu_screen_recorder_process > 0) {
|
||||||
@@ -933,8 +990,8 @@ namespace gsr {
|
|||||||
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);
|
||||||
gpu_screen_recorder_process = -1;
|
gpu_screen_recorder_process = -1;
|
||||||
@@ -943,7 +1000,7 @@ namespace gsr {
|
|||||||
|
|
||||||
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
|
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
|
||||||
if(config.record_config.show_video_saved_notifications)
|
if(config.record_config.show_video_saved_notifications)
|
||||||
show_notification("Recording has been saved", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::RECORD);
|
show_notification("Recording has been saved", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1019,10 +1076,10 @@ namespace gsr {
|
|||||||
// program and start another one. This can also be used to check when the notification has finished by checking with waitpid NOWAIT
|
// program and start another one. This can also be used to check when the notification has finished by checking with waitpid NOWAIT
|
||||||
// to see when the program has exit.
|
// to see when the program has exit.
|
||||||
if(config.record_config.show_recording_started_notifications)
|
if(config.record_config.show_recording_started_notifications)
|
||||||
show_notification("Recording has started", 3.0, get_theme().tint_color, get_theme().tint_color, NotificationType::RECORD);
|
show_notification("Recording has started", 3.0, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::RECORD);
|
||||||
//exit(0);
|
//exit(0);
|
||||||
// window.set_visible(false);
|
// window->set_visible(false);
|
||||||
// window.close();
|
// window->close();
|
||||||
|
|
||||||
// TODO: Show notification with args:
|
// TODO: Show notification with args:
|
||||||
// "Recording has started" 3.0 ./images/record.png 76b900
|
// "Recording has started" 3.0 ./images/record.png 76b900
|
||||||
@@ -1066,16 +1123,16 @@ namespace gsr {
|
|||||||
case RecordingStatus::STREAM:
|
case RecordingStatus::STREAM:
|
||||||
break;
|
break;
|
||||||
case RecordingStatus::REPLAY:
|
case RecordingStatus::REPLAY:
|
||||||
show_notification("Unable to start streaming when replay is turned on.\nTurn off replay before starting streaming", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::REPLAY);
|
show_notification("Unable to start streaming when replay is turned on.\nTurn off replay before starting streaming.", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
|
||||||
return;
|
return;
|
||||||
case RecordingStatus::RECORD:
|
case RecordingStatus::RECORD:
|
||||||
show_notification("Unable to start streaming when recording.\nStop recording before starting streaming", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::RECORD);
|
show_notification("Unable to start streaming when recording.\nStop recording before starting streaming.", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
// window.close();
|
// window->close();
|
||||||
// usleep(1000 * 50); // 50 milliseconds
|
// usleep(1000 * 50); // 50 milliseconds
|
||||||
|
|
||||||
if(gpu_screen_recorder_process > 0) {
|
if(gpu_screen_recorder_process > 0) {
|
||||||
@@ -1092,7 +1149,7 @@ namespace gsr {
|
|||||||
|
|
||||||
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
|
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
|
||||||
if(config.streaming_config.show_streaming_stopped_notifications)
|
if(config.streaming_config.show_streaming_stopped_notifications)
|
||||||
show_notification("Streaming has stopped", 3.0, mgl::Color(255, 255, 255), get_theme().tint_color, NotificationType::STREAM);
|
show_notification("Streaming has stopped", 3.0, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1173,7 +1230,7 @@ namespace gsr {
|
|||||||
// program and start another one. This can also be used to check when the notification has finished by checking with waitpid NOWAIT
|
// program and start another one. This can also be used to check when the notification has finished by checking with waitpid NOWAIT
|
||||||
// to see when the program has exit.
|
// to see when the program has exit.
|
||||||
if(config.streaming_config.show_streaming_started_notifications)
|
if(config.streaming_config.show_streaming_started_notifications)
|
||||||
show_notification("Streaming has started", 3.0, get_theme().tint_color, get_theme().tint_color, NotificationType::STREAM);
|
show_notification("Streaming has started", 3.0, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::STREAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Overlay::update_compositor_texture(const mgl_monitor *monitor) {
|
bool Overlay::update_compositor_texture(const mgl_monitor *monitor) {
|
||||||
@@ -1191,7 +1248,7 @@ namespace gsr {
|
|||||||
bool window_texture_loaded = false;
|
bool window_texture_loaded = false;
|
||||||
const Window window_at_cursor_position = get_window_at_cursor_position(display);
|
const Window window_at_cursor_position = get_window_at_cursor_position(display);
|
||||||
if(is_window_fullscreen_on_monitor(display, window_at_cursor_position, monitor) && window_at_cursor_position)
|
if(is_window_fullscreen_on_monitor(display, window_at_cursor_position, monitor) && window_at_cursor_position)
|
||||||
window_texture_loaded = window_texture_init(&window_texture, display, mgl_window_get_egl_display(window.internal_window()), window_at_cursor_position, egl_funcs) == 0;
|
window_texture_loaded = window_texture_init(&window_texture, display, mgl_window_get_egl_display(window->internal_window()), window_at_cursor_position, egl_funcs) == 0;
|
||||||
|
|
||||||
if(window_texture_loaded && window_texture.texture_id) {
|
if(window_texture_loaded && window_texture.texture_id) {
|
||||||
window_texture_texture = mgl::Texture(window_texture.texture_id, MGL_TEXTURE_FORMAT_RGB);
|
window_texture_texture = mgl::Texture(window_texture.texture_id, MGL_TEXTURE_FORMAT_RGB);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
static Theme *theme = nullptr;
|
static Theme *theme = nullptr;
|
||||||
|
static ColorTheme *color_theme = nullptr;
|
||||||
|
|
||||||
bool Theme::set_window_size(mgl::vec2i window_size) {
|
bool Theme::set_window_size(mgl::vec2i window_size) {
|
||||||
if(std::abs(window_size.x - window_width) < 0.1f && std::abs(window_size.y - window_height) < 0.1f)
|
if(std::abs(window_size.x - window_width) < 0.1f && std::abs(window_size.y - window_height) < 0.1f)
|
||||||
@@ -25,30 +26,12 @@ namespace gsr {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init_theme(const GsrInfo &gsr_info, const std::string &resources_path) {
|
bool init_theme(const std::string &resources_path) {
|
||||||
if(theme)
|
if(theme)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
theme = new Theme();
|
theme = new Theme();
|
||||||
|
|
||||||
switch(gsr_info.gpu_info.vendor) {
|
|
||||||
case GpuVendor::UNKNOWN: {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GpuVendor::AMD: {
|
|
||||||
theme->tint_color = mgl::Color(221, 0, 49);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GpuVendor::INTEL: {
|
|
||||||
theme->tint_color = mgl::Color(8, 109, 183);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case GpuVendor::NVIDIA: {
|
|
||||||
theme->tint_color = mgl::Color(118, 185, 0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!theme->body_font_file.load((resources_path + "fonts/NotoSans-Regular.ttf").c_str(), mgl::MemoryMappedFile::LoadOptions{true, false}))
|
if(!theme->body_font_file.load((resources_path + "fonts/NotoSans-Regular.ttf").c_str(), mgl::MemoryMappedFile::LoadOptions{true, false}))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
@@ -118,4 +101,43 @@ namespace gsr {
|
|||||||
assert(theme);
|
assert(theme);
|
||||||
return *theme;
|
return *theme;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool init_color_theme(const GsrInfo &gsr_info) {
|
||||||
|
if(color_theme)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
color_theme = new ColorTheme();
|
||||||
|
|
||||||
|
switch(gsr_info.gpu_info.vendor) {
|
||||||
|
case GpuVendor::UNKNOWN: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GpuVendor::AMD: {
|
||||||
|
color_theme->tint_color = mgl::Color(221, 0, 49);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GpuVendor::INTEL: {
|
||||||
|
color_theme->tint_color = mgl::Color(8, 109, 183);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GpuVendor::NVIDIA: {
|
||||||
|
color_theme->tint_color = mgl::Color(118, 185, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deinit_color_theme() {
|
||||||
|
if(color_theme) {
|
||||||
|
delete color_theme;
|
||||||
|
color_theme = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorTheme& get_color_theme() {
|
||||||
|
assert(color_theme);
|
||||||
|
return *color_theme;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ namespace gsr {
|
|||||||
|
|
||||||
const bool mouse_inside = mgl::FloatRect(draw_pos, item_size).contains(window.get_mouse_position().to_vec2f()) && !has_parent_with_selected_child_widget();
|
const bool mouse_inside = mgl::FloatRect(draw_pos, item_size).contains(window.get_mouse_position().to_vec2f()) && !has_parent_with_selected_child_widget();
|
||||||
if(mouse_inside) {
|
if(mouse_inside) {
|
||||||
const mgl::Color outline_color = (bg_color == get_theme().tint_color) ? mgl::Color(255, 255, 255) : get_theme().tint_color;
|
const mgl::Color outline_color = (bg_color == get_color_theme().tint_color) ? mgl::Color(255, 255, 255) : get_color_theme().tint_color;
|
||||||
draw_rectangle_outline(window, draw_pos, item_size, outline_color, std::max(1.0f, border_scale * get_theme().window_height));
|
draw_rectangle_outline(window, draw_pos, item_size, outline_color, std::max(1.0f, border_scale * get_theme().window_height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ namespace gsr {
|
|||||||
background_sprite(&get_theme().checkbox_background_texture),
|
background_sprite(&get_theme().checkbox_background_texture),
|
||||||
circle_sprite(&get_theme().checkbox_circle_texture)
|
circle_sprite(&get_theme().checkbox_circle_texture)
|
||||||
{
|
{
|
||||||
background_sprite.set_color(get_theme().tint_color);
|
background_sprite.set_color(get_color_theme().tint_color);
|
||||||
circle_sprite.set_color(get_theme().tint_color);
|
circle_sprite.set_color(get_color_theme().tint_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckBox::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
|
bool CheckBox::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
|
||||||
@@ -62,7 +62,7 @@ namespace gsr {
|
|||||||
apply_animation();
|
apply_animation();
|
||||||
|
|
||||||
const mgl::Color background_color_unchecked(0, 0, 0, 120);
|
const mgl::Color background_color_unchecked(0, 0, 0, 120);
|
||||||
const mgl::Color background_color_checked = color_multiply(get_theme().tint_color, 0.6f);
|
const mgl::Color background_color_checked = color_multiply(get_color_theme().tint_color, 0.6f);
|
||||||
background_sprite.set_color(interpolate_color(background_color_unchecked, background_color_checked, toggle_animation_value));
|
background_sprite.set_color(interpolate_color(background_color_unchecked, background_color_checked, toggle_animation_value));
|
||||||
background_sprite.set_position(draw_pos.floor());
|
background_sprite.set_position(draw_pos.floor());
|
||||||
window.draw(background_sprite);
|
window.draw(background_sprite);
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ namespace gsr {
|
|||||||
cursor_inside = mgl::FloatRect(items_draw_pos, item_size).contains(mouse_pos);
|
cursor_inside = mgl::FloatRect(items_draw_pos, item_size).contains(mouse_pos);
|
||||||
if(cursor_inside) {
|
if(cursor_inside) {
|
||||||
mgl::Rectangle item_background(items_draw_pos.floor(), item_size.floor());
|
mgl::Rectangle item_background(items_draw_pos.floor(), item_size.floor());
|
||||||
item_background.set_color(get_theme().tint_color);
|
item_background.set_color(get_color_theme().tint_color);
|
||||||
window.draw(item_background);
|
window.draw(item_background);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -184,7 +184,7 @@ namespace gsr {
|
|||||||
|
|
||||||
void ComboBox::draw_item_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size) {
|
void ComboBox::draw_item_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size) {
|
||||||
const int border_size = std::max(1.0f, border_scale * get_theme().window_height);
|
const int border_size = std::max(1.0f, border_scale * get_theme().window_height);
|
||||||
const mgl::Color border_color = get_theme().tint_color;
|
const mgl::Color border_color = get_color_theme().tint_color;
|
||||||
draw_rectangle_outline(window, pos.floor(), size.floor(), border_color, border_size);
|
draw_rectangle_outline(window, pos.floor(), size.floor(), border_color, border_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace gsr {
|
|||||||
window.draw(rect);
|
window.draw(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mgl::Color border_color = get_theme().tint_color;
|
const mgl::Color border_color = get_color_theme().tint_color;
|
||||||
|
|
||||||
// Green line at top
|
// Green line at top
|
||||||
{
|
{
|
||||||
@@ -100,7 +100,7 @@ namespace gsr {
|
|||||||
window.draw(rect);
|
window.draw(rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
const mgl::Color border_color = get_theme().tint_color;
|
const mgl::Color border_color = get_color_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
|
||||||
@@ -144,14 +144,14 @@ namespace gsr {
|
|||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
const float separator_height = std::max(1.0f, item_size.y * 0.05f);
|
const float separator_height = std::max(1.0f, item_size.y * 0.05f);
|
||||||
mgl::Rectangle separator((item_position - mgl::vec2f(0.0f, separator_height * 0.5f)).floor(), mgl::vec2f(item_size.x, separator_height).floor());
|
mgl::Rectangle separator((item_position - mgl::vec2f(0.0f, separator_height * 0.5f)).floor(), mgl::vec2f(item_size.x, separator_height).floor());
|
||||||
separator.set_color(get_theme().page_bg_color);
|
separator.set_color(get_color_theme().page_bg_color);
|
||||||
window.draw(separator);
|
window.draw(separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mouse_inside_item == -1) {
|
if(mouse_inside_item == -1) {
|
||||||
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, get_theme().tint_color, border_size);
|
draw_rectangle_outline(window, item_position, item_size, get_color_theme().tint_color, border_size);
|
||||||
mouse_inside_item = i;
|
mouse_inside_item = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,8 +212,8 @@ namespace gsr {
|
|||||||
this->activated = activated;
|
this->activated = activated;
|
||||||
|
|
||||||
if(activated) {
|
if(activated) {
|
||||||
description.set_color(get_theme().tint_color);
|
description.set_color(get_color_theme().tint_color);
|
||||||
icon_sprite.set_color(get_theme().tint_color);
|
icon_sprite.set_color(get_color_theme().tint_color);
|
||||||
} else {
|
} else {
|
||||||
description.set_color(mgl::Color(150, 150, 150));
|
description.set_color(mgl::Color(150, 150, 150));
|
||||||
icon_sprite.set_color(mgl::Color(255, 255, 255));
|
icon_sprite.set_color(mgl::Color(255, 255, 255));
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace gsr {
|
|||||||
static const float caret_width_scale = 0.001f;
|
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_color_theme().text_color);
|
||||||
set_text(text);
|
set_text(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ namespace gsr {
|
|||||||
|
|
||||||
if(selected) {
|
if(selected) {
|
||||||
const int border_size = std::max(1.0f, border_scale * get_theme().window_height);
|
const int border_size = std::max(1.0f, 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_color_theme().tint_color, border_size);
|
||||||
|
|
||||||
const int caret_width = std::max(1.0f, caret_width_scale * get_theme().window_height);
|
const int caret_width = std::max(1.0f, caret_width_scale * get_theme().window_height);
|
||||||
mgl::Rectangle caret({(float)caret_width, text.get_bounds().size.y});
|
mgl::Rectangle caret({(float)caret_width, text.get_bounds().size.y});
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace gsr {
|
|||||||
if(i == selected_item) {
|
if(i == selected_item) {
|
||||||
mgl::Rectangle selected_item_background(item_size.floor());
|
mgl::Rectangle selected_item_background(item_size.floor());
|
||||||
selected_item_background.set_position(item_pos.floor());
|
selected_item_background.set_position(item_pos.floor());
|
||||||
selected_item_background.set_color(get_theme().tint_color);
|
selected_item_background.set_color(get_color_theme().tint_color);
|
||||||
window.draw(selected_item_background);
|
window.draw(selected_item_background);
|
||||||
}
|
}
|
||||||
if(!has_parent_with_selected_child_widget() && mouse_over_item == -1 && mgl::FloatRect(item_pos, item_size).contains(mouse_pos)) {
|
if(!has_parent_with_selected_child_widget() && mouse_over_item == -1 && mgl::FloatRect(item_pos, item_size).contains(mouse_pos)) {
|
||||||
@@ -102,7 +102,7 @@ namespace gsr {
|
|||||||
// selected_item_background.set_color(mgl::Color(20, 20, 20, 150));
|
// selected_item_background.set_color(mgl::Color(20, 20, 20, 150));
|
||||||
// window.draw(selected_item_background);
|
// window.draw(selected_item_background);
|
||||||
const float border_scale = 0.0015f;
|
const float border_scale = 0.0015f;
|
||||||
draw_rectangle_outline(window, item_pos.floor(), item_size.floor(), get_theme().tint_color, border_scale * get_theme().window_height);
|
draw_rectangle_outline(window, item_pos.floor(), item_size.floor(), get_color_theme().tint_color, border_scale * get_theme().window_height);
|
||||||
mouse_over_item = i;
|
mouse_over_item = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +249,7 @@ namespace gsr {
|
|||||||
up_arrow_sprite.set_height((int)(current_directory_background_size.y * 0.8f));
|
up_arrow_sprite.set_height((int)(current_directory_background_size.y * 0.8f));
|
||||||
up_arrow_sprite.set_position((draw_pos + mgl::vec2f(file_chooser_body_ptr->get_size().x - up_arrow_sprite.get_size().x, current_directory_background_size.y * 0.5f - up_arrow_sprite.get_size().y * 0.5f)).floor());
|
up_arrow_sprite.set_position((draw_pos + mgl::vec2f(file_chooser_body_ptr->get_size().x - up_arrow_sprite.get_size().x, current_directory_background_size.y * 0.5f - up_arrow_sprite.get_size().y * 0.5f)).floor());
|
||||||
const bool mouse_inside_up_arrow = mgl::FloatRect(up_arrow_sprite.get_position(), up_arrow_sprite.get_size()).contains(window.get_mouse_position().to_vec2f()) && !has_parent_with_selected_child_widget();
|
const bool mouse_inside_up_arrow = mgl::FloatRect(up_arrow_sprite.get_position(), up_arrow_sprite.get_size()).contains(window.get_mouse_position().to_vec2f()) && !has_parent_with_selected_child_widget();
|
||||||
up_arrow_sprite.set_color(mouse_inside_up_arrow ? get_theme().tint_color : mgl::Color(255, 255, 255));
|
up_arrow_sprite.set_color(mouse_inside_up_arrow ? get_color_theme().tint_color : mgl::Color(255, 255, 255));
|
||||||
window.draw(up_arrow_sprite);
|
window.draw(up_arrow_sprite);
|
||||||
|
|
||||||
current_directory_background_size.x = file_chooser_body_ptr->get_size().x - up_arrow_sprite.get_size().x - up_button_spacing_scale * get_theme().window_height;
|
current_directory_background_size.x = file_chooser_body_ptr->get_size().x - up_arrow_sprite.get_size().x - up_button_spacing_scale * get_theme().window_height;
|
||||||
@@ -258,7 +258,7 @@ namespace gsr {
|
|||||||
current_directory_background.set_position(draw_pos.floor());
|
current_directory_background.set_position(draw_pos.floor());
|
||||||
window.draw(current_directory_background);
|
window.draw(current_directory_background);
|
||||||
|
|
||||||
current_directory_text.set_color(get_theme().text_color);
|
current_directory_text.set_color(get_color_theme().text_color);
|
||||||
current_directory_text.set_position((draw_pos + mgl::vec2f(current_directory_padding.x, current_directory_background_size.y * 0.5f - current_directory_text.get_bounds().size.y * 0.5f)).floor());
|
current_directory_text.set_position((draw_pos + mgl::vec2f(current_directory_padding.x, current_directory_background_size.y * 0.5f - current_directory_text.get_bounds().size.y * 0.5f)).floor());
|
||||||
window.draw(current_directory_text);
|
window.draw(current_directory_text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,12 +55,12 @@ namespace gsr {
|
|||||||
|
|
||||||
mgl::Rectangle background(content_page_size);
|
mgl::Rectangle background(content_page_size);
|
||||||
background.set_position(content_page_position);
|
background.set_position(content_page_position);
|
||||||
background.set_color(get_theme().page_bg_color);
|
background.set_color(get_color_theme().page_bg_color);
|
||||||
window.draw(background);
|
window.draw(background);
|
||||||
|
|
||||||
mgl::Rectangle border(mgl::vec2f(content_page_size.x, get_border_size()).floor());
|
mgl::Rectangle border(mgl::vec2f(content_page_size.x, get_border_size()).floor());
|
||||||
border.set_position(content_page_position);
|
border.set_position(content_page_position);
|
||||||
border.set_color(get_theme().tint_color);
|
border.set_color(get_color_theme().tint_color);
|
||||||
window.draw(border);
|
window.draw(border);
|
||||||
|
|
||||||
draw_page_label(window, content_page_position);
|
draw_page_label(window, content_page_position);
|
||||||
|
|||||||
@@ -72,13 +72,13 @@ namespace gsr {
|
|||||||
const mgl::vec2f item_size = item.text.get_bounds().size + mgl::vec2f(padding_left + padding_right, padding_top + padding_bottom);
|
const mgl::vec2f item_size = item.text.get_bounds().size + mgl::vec2f(padding_left + padding_right, padding_top + padding_bottom);
|
||||||
mgl::Rectangle background(item_size.floor());
|
mgl::Rectangle background(item_size.floor());
|
||||||
background.set_position(draw_pos.floor());
|
background.set_position(draw_pos.floor());
|
||||||
background.set_color(i == selected_item ? get_theme().tint_color : mgl::Color(0, 0, 0, 120));
|
background.set_color(i == selected_item ? get_color_theme().tint_color : mgl::Color(0, 0, 0, 120));
|
||||||
window.draw(background);
|
window.draw(background);
|
||||||
|
|
||||||
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(can_select_item && mouse_inside) {
|
if(can_select_item && mouse_inside) {
|
||||||
const int border_size = std::max(1.0f, border_scale * get_theme().window_height);
|
const int border_size = std::max(1.0f, border_scale * get_theme().window_height);
|
||||||
const mgl::Color border_color = i == selected_item ? mgl::Color(255, 255, 255) : get_theme().tint_color;
|
const mgl::Color border_color = i == selected_item ? mgl::Color(255, 255, 255) : get_color_theme().tint_color;
|
||||||
draw_rectangle_outline(window, draw_pos.floor(), item_size.floor(), border_color, border_size);
|
draw_rectangle_outline(window, draw_pos.floor(), item_size.floor(), border_color, border_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace gsr {
|
|||||||
settings_title_text("Settings", get_theme().title_font)
|
settings_title_text("Settings", get_theme().title_font)
|
||||||
{
|
{
|
||||||
auto content_page = std::make_unique<GsrPage>();
|
auto content_page = std::make_unique<GsrPage>();
|
||||||
content_page->add_button("Back", "back", get_theme().page_bg_color);
|
content_page->add_button("Back", "back", get_color_theme().page_bg_color);
|
||||||
content_page->on_click = [page_stack](const std::string &id) {
|
content_page->on_click = [page_stack](const std::string &id) {
|
||||||
if(id == "back")
|
if(id == "back")
|
||||||
page_stack->pop();
|
page_stack->pop();
|
||||||
@@ -68,14 +68,14 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<Widget> SettingsPage::create_record_area(const GsrInfo &gsr_info) {
|
std::unique_ptr<Widget> SettingsPage::create_record_area(const GsrInfo &gsr_info) {
|
||||||
auto record_area_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto record_area_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
record_area_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Capture target:", get_theme().text_color));
|
record_area_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Capture target:", get_color_theme().text_color));
|
||||||
record_area_list->add_widget(create_record_area_box(gsr_info));
|
record_area_list->add_widget(create_record_area_box(gsr_info));
|
||||||
return record_area_list;
|
return record_area_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_select_window() {
|
std::unique_ptr<List> SettingsPage::create_select_window() {
|
||||||
auto select_window_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto select_window_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
select_window_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Select window:", get_theme().text_color));
|
select_window_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Select window:", get_color_theme().text_color));
|
||||||
select_window_list->add_widget(std::make_unique<Button>(&get_theme().body_font, "Click here to select a window...", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120)));
|
select_window_list->add_widget(std::make_unique<Button>(&get_theme().body_font, "Click here to select a window...", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120)));
|
||||||
select_window_list_ptr = select_window_list.get();
|
select_window_list_ptr = select_window_list.get();
|
||||||
return select_window_list;
|
return select_window_list;
|
||||||
@@ -98,14 +98,14 @@ namespace gsr {
|
|||||||
std::unique_ptr<List> SettingsPage::create_area_size() {
|
std::unique_ptr<List> SettingsPage::create_area_size() {
|
||||||
auto area_size_params_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
|
auto area_size_params_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
|
||||||
area_size_params_list->add_widget(create_area_width_entry());
|
area_size_params_list->add_widget(create_area_width_entry());
|
||||||
area_size_params_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "x", get_theme().text_color));
|
area_size_params_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "x", get_color_theme().text_color));
|
||||||
area_size_params_list->add_widget(create_area_height_entry());
|
area_size_params_list->add_widget(create_area_height_entry());
|
||||||
return area_size_params_list;
|
return area_size_params_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_area_size_section() {
|
std::unique_ptr<List> SettingsPage::create_area_size_section() {
|
||||||
auto area_size_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto area_size_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
area_size_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Area size:", get_theme().text_color));
|
area_size_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Area size:", get_color_theme().text_color));
|
||||||
area_size_list->add_widget(create_area_size());
|
area_size_list->add_widget(create_area_size());
|
||||||
area_size_list_ptr = area_size_list.get();
|
area_size_list_ptr = area_size_list.get();
|
||||||
return area_size_list;
|
return area_size_list;
|
||||||
@@ -128,14 +128,14 @@ namespace gsr {
|
|||||||
std::unique_ptr<List> SettingsPage::create_video_resolution() {
|
std::unique_ptr<List> SettingsPage::create_video_resolution() {
|
||||||
auto area_size_params_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
|
auto area_size_params_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
|
||||||
area_size_params_list->add_widget(create_video_width_entry());
|
area_size_params_list->add_widget(create_video_width_entry());
|
||||||
area_size_params_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "x", get_theme().text_color));
|
area_size_params_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "x", get_color_theme().text_color));
|
||||||
area_size_params_list->add_widget(create_video_height_entry());
|
area_size_params_list->add_widget(create_video_height_entry());
|
||||||
return area_size_params_list;
|
return area_size_params_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_video_resolution_section() {
|
std::unique_ptr<List> SettingsPage::create_video_resolution_section() {
|
||||||
auto video_resolution_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto video_resolution_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
video_resolution_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video resolution:", get_theme().text_color));
|
video_resolution_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video resolution:", get_color_theme().text_color));
|
||||||
video_resolution_list->add_widget(create_video_resolution());
|
video_resolution_list->add_widget(create_video_resolution());
|
||||||
video_resolution_list_ptr = video_resolution_list.get();
|
video_resolution_list_ptr = video_resolution_list.get();
|
||||||
return video_resolution_list;
|
return video_resolution_list;
|
||||||
@@ -150,7 +150,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_restore_portal_session_section() {
|
std::unique_ptr<List> SettingsPage::create_restore_portal_session_section() {
|
||||||
auto restore_portal_session_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto restore_portal_session_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
restore_portal_session_list->add_widget(std::make_unique<Label>(&get_theme().body_font, " ", get_theme().text_color));
|
restore_portal_session_list->add_widget(std::make_unique<Label>(&get_theme().body_font, " ", get_color_theme().text_color));
|
||||||
restore_portal_session_list->add_widget(create_restore_portal_session_checkbox());
|
restore_portal_session_list->add_widget(create_restore_portal_session_checkbox());
|
||||||
restore_portal_session_list_ptr = restore_portal_session_list.get();
|
restore_portal_session_list_ptr = restore_portal_session_list.get();
|
||||||
return restore_portal_session_list;
|
return restore_portal_session_list;
|
||||||
@@ -234,7 +234,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_video_quality_box() {
|
std::unique_ptr<List> SettingsPage::create_video_quality_box() {
|
||||||
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video quality:", get_theme().text_color));
|
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video quality:", get_color_theme().text_color));
|
||||||
|
|
||||||
auto video_quality_box = std::make_unique<ComboBox>(&get_theme().body_font);
|
auto video_quality_box = std::make_unique<ComboBox>(&get_theme().body_font);
|
||||||
video_quality_box->add_item("Custom (Constant bitrate, recommended for live streaming)", "custom");
|
video_quality_box->add_item("Custom (Constant bitrate, recommended for live streaming)", "custom");
|
||||||
@@ -261,7 +261,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_video_bitrate() {
|
std::unique_ptr<List> SettingsPage::create_video_bitrate() {
|
||||||
auto video_bitrate_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto video_bitrate_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
video_bitrate_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video bitrate (kbps):", get_theme().text_color));
|
video_bitrate_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video bitrate (kbps):", get_color_theme().text_color));
|
||||||
video_bitrate_list->add_widget(create_video_bitrate_entry());
|
video_bitrate_list->add_widget(create_video_bitrate_entry());
|
||||||
video_bitrate_list_ptr = video_bitrate_list.get();
|
video_bitrate_list_ptr = video_bitrate_list.get();
|
||||||
return video_bitrate_list;
|
return video_bitrate_list;
|
||||||
@@ -277,7 +277,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_color_range() {
|
std::unique_ptr<List> SettingsPage::create_color_range() {
|
||||||
auto color_range_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto color_range_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
color_range_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Color range:", get_theme().text_color));
|
color_range_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Color range:", get_color_theme().text_color));
|
||||||
color_range_list->add_widget(create_color_range_box());
|
color_range_list->add_widget(create_color_range_box());
|
||||||
color_range_list_ptr = color_range_list.get();
|
color_range_list_ptr = color_range_list.get();
|
||||||
return color_range_list;
|
return color_range_list;
|
||||||
@@ -323,7 +323,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_video_codec(const GsrInfo &gsr_info) {
|
std::unique_ptr<List> SettingsPage::create_video_codec(const GsrInfo &gsr_info) {
|
||||||
auto video_codec_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto video_codec_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
video_codec_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video codec:", get_theme().text_color));
|
video_codec_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video codec:", get_color_theme().text_color));
|
||||||
video_codec_list->add_widget(create_video_codec_box(gsr_info));
|
video_codec_list->add_widget(create_video_codec_box(gsr_info));
|
||||||
video_codec_ptr = video_codec_list.get();
|
video_codec_ptr = video_codec_list.get();
|
||||||
return video_codec_list;
|
return video_codec_list;
|
||||||
@@ -339,7 +339,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_audio_codec() {
|
std::unique_ptr<List> SettingsPage::create_audio_codec() {
|
||||||
auto audio_codec_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto audio_codec_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
audio_codec_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Audio codec:", get_theme().text_color));
|
audio_codec_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Audio codec:", get_color_theme().text_color));
|
||||||
audio_codec_list->add_widget(create_audio_codec_box());
|
audio_codec_list->add_widget(create_audio_codec_box());
|
||||||
audio_codec_ptr = audio_codec_list.get();
|
audio_codec_ptr = audio_codec_list.get();
|
||||||
return audio_codec_list;
|
return audio_codec_list;
|
||||||
@@ -354,7 +354,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_framerate() {
|
std::unique_ptr<List> SettingsPage::create_framerate() {
|
||||||
auto framerate_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto framerate_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
framerate_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Frame rate:", get_theme().text_color));
|
framerate_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Frame rate:", get_color_theme().text_color));
|
||||||
framerate_list->add_widget(create_framerate_entry());
|
framerate_list->add_widget(create_framerate_entry());
|
||||||
return framerate_list;
|
return framerate_list;
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_framerate_mode() {
|
std::unique_ptr<List> SettingsPage::create_framerate_mode() {
|
||||||
auto framerate_mode_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto framerate_mode_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
framerate_mode_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Frame rate mode:", get_theme().text_color));
|
framerate_mode_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Frame rate mode:", get_color_theme().text_color));
|
||||||
framerate_mode_list->add_widget(create_framerate_mode_box());
|
framerate_mode_list->add_widget(create_framerate_mode_box());
|
||||||
framerate_mode_list_ptr = framerate_mode_list.get();
|
framerate_mode_list_ptr = framerate_mode_list.get();
|
||||||
return framerate_mode_list;
|
return framerate_mode_list;
|
||||||
@@ -470,13 +470,13 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_save_directory(const char *label) {
|
std::unique_ptr<List> SettingsPage::create_save_directory(const char *label) {
|
||||||
auto save_directory_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto save_directory_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
save_directory_list->add_widget(std::make_unique<Label>(&get_theme().body_font, label, get_theme().text_color));
|
save_directory_list->add_widget(std::make_unique<Label>(&get_theme().body_font, label, get_color_theme().text_color));
|
||||||
auto save_directory_button = std::make_unique<Button>(&get_theme().body_font, get_videos_dir().c_str(), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
auto save_directory_button = std::make_unique<Button>(&get_theme().body_font, get_videos_dir().c_str(), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
||||||
save_directory_button_ptr = save_directory_button.get();
|
save_directory_button_ptr = save_directory_button.get();
|
||||||
save_directory_button->on_click = [this]() {
|
save_directory_button->on_click = [this]() {
|
||||||
auto select_directory_page = std::make_unique<GsrPage>();
|
auto select_directory_page = std::make_unique<GsrPage>();
|
||||||
select_directory_page->add_button("Save", "save", get_theme().tint_color);
|
select_directory_page->add_button("Save", "save", get_color_theme().tint_color);
|
||||||
select_directory_page->add_button("Cancel", "cancel", get_theme().page_bg_color);
|
select_directory_page->add_button("Cancel", "cancel", get_color_theme().page_bg_color);
|
||||||
|
|
||||||
auto file_chooser = std::make_unique<FileChooser>(save_directory_button_ptr->get_text().c_str(), select_directory_page->get_inner_size());
|
auto file_chooser = std::make_unique<FileChooser>(save_directory_button_ptr->get_text().c_str(), select_directory_page->get_inner_size());
|
||||||
FileChooser *file_chooser_ptr = file_chooser.get();
|
FileChooser *file_chooser_ptr = file_chooser.get();
|
||||||
@@ -506,7 +506,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_container_section() {
|
std::unique_ptr<List> SettingsPage::create_container_section() {
|
||||||
auto container_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto container_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
container_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Container:", get_theme().text_color));
|
container_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Container:", get_color_theme().text_color));
|
||||||
container_list->add_widget(create_container_box());
|
container_list->add_widget(create_container_box());
|
||||||
return container_list;
|
return container_list;
|
||||||
}
|
}
|
||||||
@@ -520,7 +520,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_replay_time() {
|
std::unique_ptr<List> SettingsPage::create_replay_time() {
|
||||||
auto replay_time_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto replay_time_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
replay_time_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Replay time in seconds:", get_theme().text_color));
|
replay_time_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Replay time in seconds:", get_color_theme().text_color));
|
||||||
replay_time_list->add_widget(create_replay_time_entry());
|
replay_time_list->add_widget(create_replay_time_entry());
|
||||||
return replay_time_list;
|
return replay_time_list;
|
||||||
}
|
}
|
||||||
@@ -612,14 +612,14 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_streaming_service_section() {
|
std::unique_ptr<List> SettingsPage::create_streaming_service_section() {
|
||||||
auto streaming_service_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto streaming_service_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
streaming_service_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Stream service:", get_theme().text_color));
|
streaming_service_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Stream service:", get_color_theme().text_color));
|
||||||
streaming_service_list->add_widget(create_streaming_service_box());
|
streaming_service_list->add_widget(create_streaming_service_box());
|
||||||
return streaming_service_list;
|
return streaming_service_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_stream_key_section() {
|
std::unique_ptr<List> SettingsPage::create_stream_key_section() {
|
||||||
auto stream_key_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto stream_key_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
stream_key_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Stream key:", get_theme().text_color));
|
stream_key_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Stream key:", get_color_theme().text_color));
|
||||||
|
|
||||||
auto twitch_stream_key_entry = std::make_unique<Entry>(&get_theme().body_font, "", get_theme().body_font.get_character_size() * 20);
|
auto twitch_stream_key_entry = std::make_unique<Entry>(&get_theme().body_font, "", get_theme().body_font.get_character_size() * 20);
|
||||||
twitch_stream_key_entry_ptr = twitch_stream_key_entry.get();
|
twitch_stream_key_entry_ptr = twitch_stream_key_entry.get();
|
||||||
@@ -635,7 +635,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_stream_url_section() {
|
std::unique_ptr<List> SettingsPage::create_stream_url_section() {
|
||||||
auto stream_url_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto stream_url_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
stream_url_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "URL:", get_theme().text_color));
|
stream_url_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "URL:", get_color_theme().text_color));
|
||||||
|
|
||||||
auto stream_url_entry = std::make_unique<Entry>(&get_theme().body_font, "", get_theme().body_font.get_character_size() * 20);
|
auto stream_url_entry = std::make_unique<Entry>(&get_theme().body_font, "", get_theme().body_font.get_character_size() * 20);
|
||||||
stream_url_entry_ptr = stream_url_entry.get();
|
stream_url_entry_ptr = stream_url_entry.get();
|
||||||
@@ -657,7 +657,7 @@ namespace gsr {
|
|||||||
|
|
||||||
std::unique_ptr<List> SettingsPage::create_stream_container_section() {
|
std::unique_ptr<List> SettingsPage::create_stream_container_section() {
|
||||||
auto container_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
auto container_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||||
container_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Container:", get_theme().text_color));
|
container_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Container:", get_color_theme().text_color));
|
||||||
container_list->add_widget(create_stream_container_box());
|
container_list->add_widget(create_stream_container_box());
|
||||||
container_list_ptr = container_list.get();
|
container_list_ptr = container_list.get();
|
||||||
return container_list;
|
return container_list;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace gsr {
|
|||||||
static const float title_spacing_scale = 0.015f;
|
static const float title_spacing_scale = 0.015f;
|
||||||
|
|
||||||
Subsection::Subsection(const char *title, std::unique_ptr<Widget> inner_widget, mgl::vec2f size) :
|
Subsection::Subsection(const char *title, std::unique_ptr<Widget> inner_widget, mgl::vec2f size) :
|
||||||
label(&get_theme().title_font, title, get_theme().text_color),
|
label(&get_theme().title_font, title, get_color_theme().text_color),
|
||||||
inner_widget(std::move(inner_widget)),
|
inner_widget(std::move(inner_widget)),
|
||||||
size(size)
|
size(size)
|
||||||
{
|
{
|
||||||
|
|||||||
61
src/main.cpp
61
src/main.cpp
@@ -8,12 +8,8 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
|
||||||
#include <X11/Xatom.h>
|
|
||||||
#include <X11/keysym.h>
|
#include <X11/keysym.h>
|
||||||
#include <mglpp/mglpp.hpp>
|
#include <mglpp/mglpp.hpp>
|
||||||
#include <mglpp/window/Window.hpp>
|
|
||||||
#include <mglpp/window/Event.hpp>
|
|
||||||
#include <mglpp/system/Clock.hpp>
|
#include <mglpp/system/Clock.hpp>
|
||||||
|
|
||||||
// TODO: Make keyboard controllable for steam deck (and other controllers).
|
// TODO: Make keyboard controllable for steam deck (and other controllers).
|
||||||
@@ -31,11 +27,6 @@ extern "C" {
|
|||||||
|
|
||||||
const mgl::Color bg_color(0, 0, 0, 100);
|
const mgl::Color bg_color(0, 0, 0, 100);
|
||||||
|
|
||||||
static void startup_error(const char *msg) {
|
|
||||||
fprintf(stderr, "Error: %s\n", msg);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static sig_atomic_t running = 1;
|
static sig_atomic_t running = 1;
|
||||||
static void sigint_handler(int signal) {
|
static void sigint_handler(int signal) {
|
||||||
(void)signal;
|
(void)signal;
|
||||||
@@ -75,7 +66,6 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
mgl::Init init;
|
mgl::Init init;
|
||||||
mgl_context *context = mgl_get_context();
|
mgl_context *context = mgl_get_context();
|
||||||
Display *display = (Display*)context->connection;
|
|
||||||
|
|
||||||
egl_functions egl_funcs;
|
egl_functions egl_funcs;
|
||||||
egl_funcs.eglGetError = (decltype(egl_funcs.eglGetError))context->gl.eglGetProcAddress("eglGetError");
|
egl_funcs.eglGetError = (decltype(egl_funcs.eglGetError))context->gl.eglGetProcAddress("eglGetError");
|
||||||
@@ -88,39 +78,9 @@ int main(int argc, char **argv) {
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
mgl::vec2i window_size = { 1280, 720 };
|
|
||||||
mgl::vec2i window_pos = { 0, 0 };
|
|
||||||
|
|
||||||
mgl::Window::CreateParams window_create_params;
|
|
||||||
window_create_params.size = window_size;
|
|
||||||
window_create_params.min_size = window_size;
|
|
||||||
window_create_params.max_size = window_size;
|
|
||||||
window_create_params.position = window_pos;
|
|
||||||
window_create_params.hidden = true;
|
|
||||||
window_create_params.override_redirect = true;
|
|
||||||
window_create_params.background_color = bg_color;
|
|
||||||
window_create_params.support_alpha = true;
|
|
||||||
window_create_params.window_type = MGL_WINDOW_TYPE_NOTIFICATION;
|
|
||||||
window_create_params.render_api = MGL_RENDER_API_EGL;
|
|
||||||
|
|
||||||
mgl::Window window;
|
|
||||||
if(!window.create("gsr ui", window_create_params))
|
|
||||||
startup_error("failed to create window");
|
|
||||||
|
|
||||||
unsigned char data = 2; // Prefer being composed to allow transparency
|
|
||||||
XChangeProperty(display, window.get_system_handle(), XInternAtom(display, "_NET_WM_BYPASS_COMPOSITOR", False), XA_CARDINAL, 32, PropModeReplace, &data, 1);
|
|
||||||
|
|
||||||
data = 1;
|
|
||||||
XChangeProperty(display, window.get_system_handle(), XInternAtom(display, "GAMESCOPE_EXTERNAL_OVERLAY", False), XA_CARDINAL, 32, PropModeReplace, &data, 1);
|
|
||||||
|
|
||||||
if(!gsr::init_theme(gsr_info, resources_path)) {
|
|
||||||
fprintf(stderr, "Error: failed to load theme\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "info: gsr ui is now ready, waiting for inputs. Press alt+z to show/hide the overlay\n");
|
fprintf(stderr, "info: gsr ui is now ready, waiting for inputs. Press alt+z to show/hide the overlay\n");
|
||||||
|
|
||||||
auto overlay = std::make_unique<gsr::Overlay>(window, resources_path, gsr_info, egl_funcs, bg_color);
|
auto overlay = std::make_unique<gsr::Overlay>(resources_path, gsr_info, egl_funcs, bg_color);
|
||||||
//overlay.show();
|
//overlay.show();
|
||||||
|
|
||||||
gsr::GlobalHotkeysX11 global_hotkeys;
|
gsr::GlobalHotkeysX11 global_hotkeys;
|
||||||
@@ -172,28 +132,21 @@ int main(int argc, char **argv) {
|
|||||||
if(!replay_save_hotkey_registered)
|
if(!replay_save_hotkey_registered)
|
||||||
fprintf(stderr, "error: failed to register hotkey alt+f10 for saving replay because the hotkey is registered by another program\n");
|
fprintf(stderr, "error: failed to register hotkey alt+f10 for saving replay because the hotkey is registered by another program\n");
|
||||||
|
|
||||||
mgl::Event event;
|
|
||||||
mgl::Clock frame_delta_clock;
|
mgl::Clock frame_delta_clock;
|
||||||
while(window.is_open() && running) {
|
while(running) {
|
||||||
const double frame_delta_seconds = frame_delta_clock.get_elapsed_time_seconds();
|
const double frame_delta_seconds = frame_delta_clock.get_elapsed_time_seconds();
|
||||||
frame_delta_clock.restart();
|
frame_delta_clock.restart();
|
||||||
gsr::set_frame_delta_seconds(frame_delta_seconds);
|
gsr::set_frame_delta_seconds(frame_delta_seconds);
|
||||||
|
|
||||||
global_hotkeys.poll_events();
|
global_hotkeys.poll_events();
|
||||||
while(window.poll_event(event)) {
|
overlay->handle_events();
|
||||||
overlay->on_event(event, window);
|
overlay->draw();
|
||||||
}
|
|
||||||
|
|
||||||
window.clear(bg_color);
|
|
||||||
overlay->draw(window);
|
|
||||||
window.display();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
overlay.reset();
|
|
||||||
|
|
||||||
fprintf(stderr, "info: shutting down!\n");
|
fprintf(stderr, "info: shutting down!\n");
|
||||||
|
overlay.reset();
|
||||||
gsr::deinit_theme();
|
gsr::deinit_theme();
|
||||||
window.close();
|
gsr::deinit_color_theme();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user