Add led indicator setting, use one setting for notifications, move it under general

This commit is contained in:
dec05eba
2025-11-07 22:05:14 +01:00
parent be07070789
commit 70df557c2b
13 changed files with 291 additions and 168 deletions

View File

@@ -199,8 +199,8 @@ namespace gsr {
{"streaming.record_options.overclock", &config.streaming_config.record_options.overclock},
{"streaming.record_options.record_cursor", &config.streaming_config.record_options.record_cursor},
{"streaming.record_options.restore_portal_session", &config.streaming_config.record_options.restore_portal_session},
{"streaming.show_streaming_started_notifications", &config.streaming_config.show_streaming_started_notifications},
{"streaming.show_streaming_stopped_notifications", &config.streaming_config.show_streaming_stopped_notifications},
{"streaming.record_options.show_notifications", &config.streaming_config.record_options.show_notifications},
{"streaming.record_options.use_led_indicator", &config.streaming_config.record_options.use_led_indicator},
{"streaming.service", &config.streaming_config.streaming_service},
{"streaming.youtube.key", &config.streaming_config.youtube.stream_key},
{"streaming.twitch.key", &config.streaming_config.twitch.stream_key},
@@ -231,10 +231,9 @@ namespace gsr {
{"record.record_options.overclock", &config.record_config.record_options.overclock},
{"record.record_options.record_cursor", &config.record_config.record_options.record_cursor},
{"record.record_options.restore_portal_session", &config.record_config.record_options.restore_portal_session},
{"record.record_options.show_notifications", &config.replay_config.record_options.show_notifications},
{"record.record_options.use_led_indicator", &config.replay_config.record_options.use_led_indicator},
{"record.save_video_in_game_folder", &config.record_config.save_video_in_game_folder},
{"record.show_recording_started_notifications", &config.record_config.show_recording_started_notifications},
{"record.show_video_saved_notifications", &config.record_config.show_video_saved_notifications},
{"record.show_video_paused_notifications", &config.record_config.show_video_paused_notifications},
{"record.save_directory", &config.record_config.save_directory},
{"record.container", &config.record_config.container},
{"record.start_stop_hotkey", &config.record_config.start_stop_hotkey},
@@ -261,12 +260,11 @@ namespace gsr {
{"replay.record_options.overclock", &config.replay_config.record_options.overclock},
{"replay.record_options.record_cursor", &config.replay_config.record_options.record_cursor},
{"replay.record_options.restore_portal_session", &config.replay_config.record_options.restore_portal_session},
{"replay.record_options.show_notifications", &config.replay_config.record_options.show_notifications},
{"replay.record_options.use_led_indicator", &config.replay_config.record_options.use_led_indicator},
{"replay.turn_on_replay_automatically_mode", &config.replay_config.turn_on_replay_automatically_mode},
{"replay.save_video_in_game_folder", &config.replay_config.save_video_in_game_folder},
{"replay.restart_replay_on_save", &config.replay_config.restart_replay_on_save},
{"replay.show_replay_started_notifications", &config.replay_config.show_replay_started_notifications},
{"replay.show_replay_stopped_notifications", &config.replay_config.show_replay_stopped_notifications},
{"replay.show_replay_saved_notifications", &config.replay_config.show_replay_saved_notifications},
{"replay.save_directory", &config.replay_config.save_directory},
{"replay.container", &config.replay_config.container},
{"replay.time", &config.replay_config.replay_time},
@@ -286,7 +284,8 @@ namespace gsr {
{"screenshot.restore_portal_session", &config.screenshot_config.restore_portal_session},
{"screenshot.save_screenshot_in_game_folder", &config.screenshot_config.save_screenshot_in_game_folder},
{"screenshot.save_screenshot_to_clipboard", &config.screenshot_config.save_screenshot_to_clipboard},
{"screenshot.show_screenshot_saved_notifications", &config.screenshot_config.show_screenshot_saved_notifications},
{"screenshot.show_notifications", &config.screenshot_config.show_notifications},
{"screenshot.use_led_indicator", &config.screenshot_config.use_led_indicator},
{"screenshot.save_directory", &config.screenshot_config.save_directory},
{"screenshot.take_screenshot_hotkey", &config.screenshot_config.take_screenshot_hotkey},
{"screenshot.take_screenshot_region_hotkey", &config.screenshot_config.take_screenshot_region_hotkey},

51
src/LedIndicator.cpp Normal file
View File

@@ -0,0 +1,51 @@
#include "../include/LedIndicator.hpp"
#include <X11/XKBlib.h>
namespace gsr {
LedIndicator::LedIndicator(Display *dpy) : dpy(dpy) {
scroll_lock_atom = XInternAtom(dpy, "Scroll Lock", False);
XkbSetNamedIndicator(dpy, scroll_lock_atom, True, False, False, NULL);
}
LedIndicator::~LedIndicator() {
XkbSetNamedIndicator(dpy, scroll_lock_atom, True, False, False, NULL);
}
void LedIndicator::set_led(bool enabled) {
led_enabled = enabled;
perform_blink = false;
}
void LedIndicator::blink() {
perform_blink = true;
blink_timer.restart();
}
void LedIndicator::update_led(bool new_state) {
if(new_state == led_indicator_on)
return;
led_indicator_on = new_state;
XkbSetNamedIndicator(dpy, scroll_lock_atom, True, new_state, False, NULL);
}
void LedIndicator::update() {
if(perform_blink) {
const double blink_elapsed_sec = blink_timer.get_elapsed_time_seconds();
if(blink_elapsed_sec < 0.2) {
update_led(false);
} else if(blink_elapsed_sec < 0.4) {
update_led(true);
} else if(blink_elapsed_sec < 0.6) {
update_led(false);
} else if(blink_elapsed_sec < 0.8) {
update_led(true);
} else {
perform_blink = false;
}
} else {
update_led(led_enabled);
}
}
}

View File

@@ -32,6 +32,7 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/XKBlib.h>
#include <X11/cursorfont.h>
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/XInput2.h>
@@ -502,9 +503,9 @@ namespace gsr {
if(config.main_config.joystick_hotkeys_enable_option == "enable_hotkeys")
global_hotkeys_js = register_joystick_hotkeys(this);
x11_mapping_display = XOpenDisplay(nullptr);
if(x11_mapping_display)
XKeysymToKeycode(x11_mapping_display, XK_F1); // If we dont call we will never get a MappingNotify
x11_dpy = XOpenDisplay(nullptr);
if(x11_dpy)
XKeysymToKeycode(x11_dpy, XK_F1); // If we dont call we will never get a MappingNotify
else
fprintf(stderr, "Warning: XOpenDisplay failed to mapping notify\n");
@@ -520,6 +521,9 @@ namespace gsr {
show_notification("Wayland doesn't support GPU Screen Recorder properly,\nthings may not work as expected. Use X11 if you experience issues.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::NONE, nullptr, NotificationLevel::ERROR);
}
}
if(x11_dpy)
led_indicator = std::make_unique<LedIndicator>(x11_dpy);
}
Overlay::~Overlay() {
@@ -555,11 +559,13 @@ namespace gsr {
gpu_screen_recorder_screenshot_process = -1;
}
led_indicator.reset();
close_gpu_screen_recorder_output();
deinit_color_theme();
if(x11_mapping_display)
XCloseDisplay(x11_mapping_display);
if(x11_dpy)
XCloseDisplay(x11_dpy);
}
void Overlay::xi_setup() {
@@ -703,12 +709,12 @@ namespace gsr {
}
void Overlay::handle_keyboard_mapping_event() {
if(!x11_mapping_display)
if(!x11_dpy)
return;
bool mapping_updated = false;
while(XPending(x11_mapping_display)) {
XNextEvent(x11_mapping_display, &x11_mapping_xev);
while(XPending(x11_dpy)) {
XNextEvent(x11_dpy, &x11_mapping_xev);
if(x11_mapping_xev.type == MappingNotify) {
XRefreshKeyboardMapping(&x11_mapping_xev.xmapping);
mapping_updated = true;
@@ -720,6 +726,9 @@ namespace gsr {
}
void Overlay::handle_events() {
if(led_indicator)
led_indicator->update();
if(global_hotkeys_ungrab_keyboard) {
global_hotkeys_ungrab_keyboard = false;
show_notification(
@@ -1512,14 +1521,17 @@ namespace gsr {
if(paused) {
paused_clock.restart();
update_ui_recording_paused();
if(config.record_config.show_video_paused_notifications)
if(config.record_config.record_options.show_notifications)
show_notification("Recording has been paused", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
} else {
paused_total_time_seconds += paused_clock.get_elapsed_time_seconds();
update_ui_recording_unpaused();
if(config.record_config.show_video_paused_notifications)
if(config.record_config.record_options.show_notifications)
show_notification("Recording has been unpaused", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
}
if(led_indicator && config.record_config.record_options.use_led_indicator)
led_indicator->blink();
}
void Overlay::update_upause_status() {
@@ -1923,7 +1935,10 @@ namespace gsr {
switch(notification_type) {
case NotificationType::RECORD: {
if(!config.record_config.show_video_saved_notifications)
if(led_indicator && config.record_config.record_options.use_led_indicator)
led_indicator->blink();
if(!config.record_config.record_options.show_notifications)
return;
const std::string duration_str = to_duration_string(recording_duration_clock.get_elapsed_time_seconds() - paused_total_time_seconds - (paused ? paused_clock.get_elapsed_time_seconds() : 0.0));
@@ -1934,7 +1949,10 @@ namespace gsr {
break;
}
case NotificationType::REPLAY: {
if(!config.replay_config.show_replay_saved_notifications)
if(led_indicator && config.replay_config.record_options.use_led_indicator)
led_indicator->blink();
if(!config.replay_config.record_options.show_notifications)
return;
const std::string duration_str = to_duration_string(get_time_passed_in_replay_buffer_seconds());
@@ -1945,7 +1963,10 @@ namespace gsr {
break;
}
case NotificationType::SCREENSHOT: {
if(!config.screenshot_config.show_screenshot_saved_notifications)
if(led_indicator && config.screenshot_config.use_led_indicator)
led_indicator->blink();
if(!config.screenshot_config.show_notifications)
return;
snprintf(msg, sizeof(msg), "Saved a screenshot of %s\nto \"%s\"",
@@ -1977,14 +1998,20 @@ namespace gsr {
replay_save_show_notification = false;
if(config.replay_config.save_video_in_game_folder) {
save_video_in_current_game_directory(replay_saved_filepath, NotificationType::REPLAY);
} else if(config.replay_config.show_replay_saved_notifications) {
const std::string duration_str = to_duration_string(get_time_passed_in_replay_buffer_seconds());
return;
} else {
if(config.replay_config.record_options.show_notifications) {
const std::string duration_str = to_duration_string(get_time_passed_in_replay_buffer_seconds());
char msg[512];
snprintf(msg, sizeof(msg), "Saved a %s replay of %s",
duration_str.c_str(),
capture_target_get_notification_name(recording_capture_target.c_str(), true).c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY, recording_capture_target.c_str());
char msg[512];
snprintf(msg, sizeof(msg), "Saved a %s replay of %s",
duration_str.c_str(),
capture_target_get_notification_name(recording_capture_target.c_str(), true).c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY, recording_capture_target.c_str());
}
if(led_indicator && config.replay_config.record_options.use_led_indicator)
led_indicator->blink();
}
}
@@ -2094,26 +2121,36 @@ namespace gsr {
replay_save_duration_min = 0;
update_ui_replay_stopped();
if(exit_code == 0) {
if(config.replay_config.show_replay_stopped_notifications)
if(config.replay_config.record_options.show_notifications)
show_notification("Replay stopped", short_notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
} else {
on_gsr_process_error(exit_code, NotificationType::REPLAY);
}
if(led_indicator && current_recording_config.replay_config.record_options.use_led_indicator)
led_indicator->set_led(false);
break;
}
case RecordingStatus::RECORD: {
update_ui_recording_stopped();
on_stop_recording(exit_code, record_filepath);
if(led_indicator && current_recording_config.record_config.record_options.use_led_indicator)
led_indicator->set_led(false);
break;
}
case RecordingStatus::STREAM: {
update_ui_streaming_stopped();
if(exit_code == 0) {
if(config.streaming_config.show_streaming_stopped_notifications)
if(config.streaming_config.record_options.show_notifications)
show_notification("Streaming has stopped", short_notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
} else {
on_gsr_process_error(exit_code, NotificationType::STREAM);
}
if(led_indicator && current_recording_config.streaming_config.record_options.use_led_indicator)
led_indicator->set_led(false);
break;
}
}
@@ -2139,14 +2176,19 @@ namespace gsr {
if(exit_code == 0) {
if(config.screenshot_config.save_screenshot_in_game_folder) {
save_video_in_current_game_directory(screenshot_filepath.c_str(), NotificationType::SCREENSHOT);
} else if(config.screenshot_config.show_screenshot_saved_notifications) {
char msg[512];
snprintf(msg, sizeof(msg), "Saved a screenshot of %s",
capture_target_get_notification_name(screenshot_capture_target.c_str(), true).c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::SCREENSHOT, screenshot_capture_target.c_str());
} else {
if(config.screenshot_config.show_notifications) {
char msg[512];
snprintf(msg, sizeof(msg), "Saved a screenshot of %s",
capture_target_get_notification_name(screenshot_capture_target.c_str(), true).c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::SCREENSHOT, screenshot_capture_target.c_str());
if(config.screenshot_config.save_screenshot_to_clipboard)
clipboard_file.set_current_file(screenshot_filepath, filename_to_clipboard_file_type(screenshot_filepath));
if(config.screenshot_config.save_screenshot_to_clipboard)
clipboard_file.set_current_file(screenshot_filepath, filename_to_clipboard_file_type(screenshot_filepath));
}
if(led_indicator && config.screenshot_config.use_led_indicator)
led_indicator->blink();
}
} else {
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_screenshot_process, exit_code);
@@ -2242,18 +2284,24 @@ namespace gsr {
if(exit_code == 0) {
if(config.record_config.save_video_in_game_folder) {
save_video_in_current_game_directory(video_filepath.c_str(), NotificationType::RECORD);
} else if(config.record_config.show_video_saved_notifications) {
const std::string duration_str = to_duration_string(recording_duration_clock.get_elapsed_time_seconds() - paused_total_time_seconds - (paused ? paused_clock.get_elapsed_time_seconds() : 0.0));
} else {
if(config.record_config.record_options.show_notifications) {
const std::string duration_str = to_duration_string(recording_duration_clock.get_elapsed_time_seconds() - paused_total_time_seconds - (paused ? paused_clock.get_elapsed_time_seconds() : 0.0));
char msg[512];
snprintf(msg, sizeof(msg), "Saved a %s recording of %s",
duration_str.c_str(),
capture_target_get_notification_name(recording_capture_target.c_str(), true).c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD, recording_capture_target.c_str());
char msg[512];
snprintf(msg, sizeof(msg), "Saved a %s recording of %s",
duration_str.c_str(),
capture_target_get_notification_name(recording_capture_target.c_str(), true).c_str());
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD, recording_capture_target.c_str());
}
if(led_indicator && config.record_config.record_options.use_led_indicator)
led_indicator->blink();
}
} else {
on_gsr_process_error(exit_code, NotificationType::RECORD);
}
update_ui_recording_stopped();
replay_recording = false;
}
@@ -2540,6 +2588,7 @@ namespace gsr {
replay_saved_duration_sec = replay_duration_clock.get_elapsed_time_seconds();
if(replay_restart_on_save)
replay_duration_clock.restart();
kill(gpu_screen_recorder_process, SIGUSR1);
}
@@ -2654,8 +2703,11 @@ namespace gsr {
replay_save_duration_min = 0;
update_ui_replay_stopped();
if(led_indicator && current_recording_config.replay_config.record_options.use_led_indicator)
led_indicator->set_led(false);
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
if(!disable_notification && config.replay_config.show_replay_stopped_notifications)
if(!disable_notification && config.replay_config.record_options.show_notifications)
show_notification("Replay stopped", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
return true;
@@ -2753,6 +2805,9 @@ namespace gsr {
} else {
recording_status = RecordingStatus::REPLAY;
update_ui_replay_started();
if(led_indicator && config.replay_config.record_options.use_led_indicator)
led_indicator->set_led(true);
}
prepare_gsr_output_for_reading();
@@ -2766,7 +2821,7 @@ namespace gsr {
// TODO: Do not run this is a daemon. Instead get the pid and when launching another notification close the current notification
// 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.
if(!disable_notification && config.replay_config.show_replay_started_notifications) {
if(!disable_notification && config.replay_config.record_options.show_notifications) {
char msg[256];
snprintf(msg, sizeof(msg), "Started replaying %s", capture_target_get_notification_name(recording_capture_target.c_str(), false).c_str());
show_notification(msg, short_notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::REPLAY, recording_capture_target.c_str());
@@ -2795,7 +2850,7 @@ namespace gsr {
if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) {
if(!replay_recording) {
if(config.record_config.show_recording_started_notifications)
if(config.record_config.record_options.show_notifications)
show_notification("Started recording in the replay session", short_notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::RECORD);
update_ui_recording_started();
@@ -2803,7 +2858,11 @@ namespace gsr {
// selected what to capture and accepted it.
recording_duration_clock.restart();
update_upause_status();
if(led_indicator && config.record_config.record_options.use_led_indicator)
led_indicator->blink();
}
replay_recording = true;
kill(gpu_screen_recorder_process, SIGRTMIN);
} else {
@@ -2817,7 +2876,7 @@ namespace gsr {
if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) {
if(!replay_recording) {
if(config.record_config.show_recording_started_notifications)
if(config.record_config.record_options.show_notifications)
show_notification("Started recording in the streaming session", short_notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::RECORD);
update_ui_recording_started();
@@ -2825,7 +2884,11 @@ namespace gsr {
// selected what to capture and accepted it.
recording_duration_clock.restart();
update_upause_status();
if(led_indicator && config.record_config.record_options.use_led_indicator)
led_indicator->blink();
}
replay_recording = true;
kill(gpu_screen_recorder_process, SIGRTMIN);
} else {
@@ -2855,6 +2918,9 @@ namespace gsr {
update_ui_recording_stopped();
update_upause_status();
record_filepath.clear();
if(led_indicator && current_recording_config.record_config.record_options.use_led_indicator)
led_indicator->set_led(false);
return;
}
@@ -2935,6 +3001,9 @@ namespace gsr {
} else {
recording_status = RecordingStatus::RECORD;
update_ui_recording_started();
if(led_indicator && config.record_config.record_options.use_led_indicator)
led_indicator->set_led(true);
}
prepare_gsr_output_for_reading();
@@ -2945,7 +3014,7 @@ namespace gsr {
// Starting recording in 3...
// 2...
// 1...
if(config.record_config.show_recording_started_notifications) {
if(config.record_config.record_options.show_notifications) {
char msg[256];
snprintf(msg, sizeof(msg), "Started recording %s", capture_target_get_notification_name(recording_capture_target.c_str(), false).c_str());
show_notification(msg, short_notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::RECORD, recording_capture_target.c_str());
@@ -3031,8 +3100,11 @@ namespace gsr {
recording_status = RecordingStatus::NONE;
update_ui_streaming_stopped();
if(led_indicator && current_recording_config.streaming_config.record_options.use_led_indicator)
led_indicator->set_led(false);
// 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.record_options.show_notifications)
show_notification("Streaming has stopped", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
return;
}
@@ -3120,6 +3192,9 @@ namespace gsr {
} else {
recording_status = RecordingStatus::STREAM;
update_ui_streaming_started();
if(led_indicator && config.streaming_config.record_options.use_led_indicator)
led_indicator->set_led(true);
}
prepare_gsr_output_for_reading();
@@ -3133,7 +3208,7 @@ namespace gsr {
// TODO: Do not run this is a daemon. Instead get the pid and when launching another notification close the current notification
// 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.
if(config.streaming_config.show_streaming_started_notifications) {
if(config.streaming_config.record_options.show_notifications) {
char msg[256];
snprintf(msg, sizeof(msg), "Started streaming %s", capture_target_get_notification_name(recording_capture_target.c_str(), false).c_str());
show_notification(msg, short_notification_timeout_seconds, get_color_theme().tint_color, get_color_theme().tint_color, NotificationType::STREAM, recording_capture_target.c_str());

View File

@@ -221,20 +221,29 @@ namespace gsr {
return checkbox;
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_notifications() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show screenshot notifications");
checkbox->set_checked(true);
show_notification_checkbox_ptr = checkbox.get();
return checkbox;
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_led_indicator() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Blink scroll lock led when taking a screenshot");
checkbox->set_checked(true);
led_indicator_checkbox_ptr = checkbox.get();
return checkbox;
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_general_section() {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(create_save_screenshot_in_game_folder());
list->add_widget(create_save_screenshot_to_clipboard());
list->add_widget(create_notifications());
list->add_widget(create_led_indicator());
return std::make_unique<Subsection>("General", std::move(list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_notifications_section() {
auto show_screenshot_saved_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show screenshot saved notification");
show_screenshot_saved_notification_checkbox->set_checked(true);
show_screenshot_saved_notification_checkbox_ptr = show_screenshot_saved_notification_checkbox.get();
return std::make_unique<Subsection>("Notifications", std::move(show_screenshot_saved_notification_checkbox), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_settings() {
auto page_list = std::make_unique<List>(List::Orientation::VERTICAL);
page_list->set_spacing(0.018f);
@@ -248,7 +257,6 @@ namespace gsr {
settings_list->add_widget(create_image_section());
settings_list->add_widget(create_file_info_section());
settings_list->add_widget(create_general_section());
settings_list->add_widget(create_notifications_section());
settings_scrollable_page_ptr->add_widget(std::move(settings_list));
return page_list;
}
@@ -291,7 +299,8 @@ namespace gsr {
save_directory_button_ptr->set_text(config.screenshot_config.save_directory);
save_screenshot_in_game_folder_checkbox_ptr->set_checked(config.screenshot_config.save_screenshot_in_game_folder);
save_screenshot_to_clipboard_checkbox_ptr->set_checked(config.screenshot_config.save_screenshot_to_clipboard);
show_screenshot_saved_notification_checkbox_ptr->set_checked(config.screenshot_config.show_screenshot_saved_notifications);
show_notification_checkbox_ptr->set_checked(config.screenshot_config.show_notifications);
led_indicator_checkbox_ptr->set_checked(config.screenshot_config.use_led_indicator);
if(config.screenshot_config.image_width == 0)
config.screenshot_config.image_width = 1920;
@@ -320,7 +329,8 @@ namespace gsr {
config.screenshot_config.save_directory = save_directory_button_ptr->get_text();
config.screenshot_config.save_screenshot_in_game_folder = save_screenshot_in_game_folder_checkbox_ptr->is_checked();
config.screenshot_config.save_screenshot_to_clipboard = save_screenshot_to_clipboard_checkbox_ptr->is_checked();
config.screenshot_config.show_screenshot_saved_notifications = show_screenshot_saved_notification_checkbox_ptr->is_checked();
config.screenshot_config.show_notifications = show_notification_checkbox_ptr->is_checked();
config.screenshot_config.use_led_indicator = led_indicator_checkbox_ptr->is_checked();
if(config.screenshot_config.image_width == 0)
config.screenshot_config.image_width = 1920;

View File

@@ -821,16 +821,33 @@ namespace gsr {
replay_time_label_ptr->set_text(buffer);
}
void SettingsPage::view_changed(bool advanced_view, Subsection *notifications_subsection_ptr) {
void SettingsPage::view_changed(bool advanced_view) {
color_range_list_ptr->set_visible(advanced_view);
audio_codec_ptr->set_visible(advanced_view);
video_codec_ptr->set_visible(advanced_view);
framerate_mode_list_ptr->set_visible(advanced_view);
notifications_subsection_ptr->set_visible(advanced_view);
set_application_audio_options_visible(audio_track_section_list_ptr, advanced_view, *gsr_info);
settings_scrollable_page_ptr->reset_scroll();
}
std::unique_ptr<CheckBox> SettingsPage::create_led_indicator(const char *type) {
char label_str[256];
snprintf(label_str, sizeof(label_str), "Show %s status with scroll lock led", type);
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, label_str);
checkbox->set_checked(false);
led_indicator_checkbox_ptr = checkbox.get();
return checkbox;
}
std::unique_ptr<CheckBox> SettingsPage::create_notifications(const char *type) {
char label_str[256];
snprintf(label_str, sizeof(label_str), "Show %s notifications", type);
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, label_str);
checkbox->set_checked(true);
show_notification_checkbox_ptr = checkbox.get();
return checkbox;
}
void SettingsPage::add_replay_widgets() {
auto file_info_list = std::make_unique<List>(List::Orientation::VERTICAL);
auto file_info_data_list = std::make_unique<List>(List::Orientation::HORIZONTAL);
@@ -846,33 +863,14 @@ namespace gsr {
general_list->add_widget(create_save_replay_in_game_folder());
if(gsr_info->system_info.gsr_version >= GsrVersion{5, 0, 3})
general_list->add_widget(create_restart_replay_on_save());
settings_list_ptr->add_widget(std::make_unique<Subsection>("General", std::move(general_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
general_list->add_widget(create_notifications("replay"));
general_list->add_widget(create_led_indicator("replay"));
settings_list_ptr->add_widget(std::make_unique<Subsection>("General", std::move(general_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
settings_list_ptr->add_widget(std::make_unique<Subsection>("Autostart", create_start_replay_automatically(), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
auto checkboxes_list = std::make_unique<List>(List::Orientation::VERTICAL);
auto show_replay_started_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show replay started notification");
show_replay_started_notification_checkbox->set_checked(true);
show_replay_started_notification_checkbox_ptr = show_replay_started_notification_checkbox.get();
checkboxes_list->add_widget(std::move(show_replay_started_notification_checkbox));
auto show_replay_stopped_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show replay stopped notification");
show_replay_stopped_notification_checkbox->set_checked(true);
show_replay_stopped_notification_checkbox_ptr = show_replay_stopped_notification_checkbox.get();
checkboxes_list->add_widget(std::move(show_replay_stopped_notification_checkbox));
auto show_replay_saved_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show replay saved notification");
show_replay_saved_notification_checkbox->set_checked(true);
show_replay_saved_notification_checkbox_ptr = show_replay_saved_notification_checkbox.get();
checkboxes_list->add_widget(std::move(show_replay_saved_notification_checkbox));
auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
Subsection *notifications_subsection_ptr = notifications_subsection.get();
settings_list_ptr->add_widget(std::move(notifications_subsection));
view_radio_button_ptr->on_selection_changed = [this, notifications_subsection_ptr](const std::string&, const std::string &id) {
view_changed(id == "advanced", notifications_subsection_ptr);
view_radio_button_ptr->on_selection_changed = [this](const std::string&, const std::string &id) {
view_changed(id == "advanced");
return true;
};
view_radio_button_ptr->on_selection_changed("Simple", "simple");
@@ -917,33 +915,18 @@ namespace gsr {
file_info_data_list->add_widget(create_container_section());
file_info_list->add_widget(std::move(file_info_data_list));
file_info_list->add_widget(create_estimated_record_file_size());
settings_list_ptr->add_widget(std::make_unique<Subsection>("File info", std::move(file_info_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
settings_list_ptr->add_widget(std::make_unique<Subsection>("General", create_save_recording_in_game_folder(), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
auto general_list = std::make_unique<List>(List::Orientation::VERTICAL);
general_list->add_widget(create_save_recording_in_game_folder());
general_list->add_widget(create_notifications("recording"));
general_list->add_widget(create_led_indicator("recording"));
auto checkboxes_list = std::make_unique<List>(List::Orientation::VERTICAL);
settings_list_ptr->add_widget(std::make_unique<Subsection>("General", std::move(general_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
auto show_recording_started_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show recording started notification");
show_recording_started_notification_checkbox->set_checked(true);
show_recording_started_notification_checkbox_ptr = show_recording_started_notification_checkbox.get();
checkboxes_list->add_widget(std::move(show_recording_started_notification_checkbox));
auto show_video_saved_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show video saved notification");
show_video_saved_notification_checkbox->set_checked(true);
show_video_saved_notification_checkbox_ptr = show_video_saved_notification_checkbox.get();
checkboxes_list->add_widget(std::move(show_video_saved_notification_checkbox));
auto show_video_paused_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show video paused/unpaused notification");
show_video_paused_notification_checkbox->set_checked(true);
show_video_paused_notification_checkbox_ptr = show_video_paused_notification_checkbox.get();
checkboxes_list->add_widget(std::move(show_video_paused_notification_checkbox));
auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
Subsection *notifications_subsection_ptr = notifications_subsection.get();
settings_list_ptr->add_widget(std::move(notifications_subsection));
view_radio_button_ptr->on_selection_changed = [this, notifications_subsection_ptr](const std::string&, const std::string &id) {
view_changed(id == "advanced", notifications_subsection_ptr);
view_radio_button_ptr->on_selection_changed = [this](const std::string&, const std::string &id) {
view_changed(id == "advanced");
return true;
};
view_radio_button_ptr->on_selection_changed("Simple", "simple");
@@ -1063,23 +1046,15 @@ namespace gsr {
streaming_info_list->add_widget(create_streaming_service_section());
streaming_info_list->add_widget(create_stream_key_section());
streaming_info_list->add_widget(create_stream_custom_section());
settings_list_ptr->add_widget(std::make_unique<Subsection>("Streaming info", std::move(streaming_info_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
auto checkboxes_list = std::make_unique<List>(List::Orientation::VERTICAL);
auto general_list = std::make_unique<List>(List::Orientation::VERTICAL);
general_list->add_widget(create_save_recording_in_game_folder());
general_list->add_widget(create_notifications("streaming"));
general_list->add_widget(create_led_indicator("streaming"));
auto show_streaming_started_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show streaming started notification");
show_streaming_started_notification_checkbox->set_checked(true);
show_streaming_started_notification_checkbox_ptr = show_streaming_started_notification_checkbox.get();
checkboxes_list->add_widget(std::move(show_streaming_started_notification_checkbox));
auto show_streaming_stopped_notification_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show streaming stopped notification");
show_streaming_stopped_notification_checkbox->set_checked(true);
show_streaming_stopped_notification_checkbox_ptr = show_streaming_stopped_notification_checkbox.get();
checkboxes_list->add_widget(std::move(show_streaming_stopped_notification_checkbox));
auto notifications_subsection = std::make_unique<Subsection>("Notifications", std::move(checkboxes_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
Subsection *notifications_subsection_ptr = notifications_subsection.get();
settings_list_ptr->add_widget(std::move(notifications_subsection));
settings_list_ptr->add_widget(std::make_unique<Subsection>("General", std::move(general_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
streaming_service_box_ptr->on_selection_changed = [this](const std::string&, const std::string &id) {
const bool twitch_option = id == "twitch";
@@ -1095,8 +1070,8 @@ namespace gsr {
};
streaming_service_box_ptr->on_selection_changed("Twitch", "twitch");
view_radio_button_ptr->on_selection_changed = [this, notifications_subsection_ptr](const std::string&, const std::string &id) {
view_changed(id == "advanced", notifications_subsection_ptr);
view_radio_button_ptr->on_selection_changed = [this](const std::string&, const std::string &id) {
view_changed(id == "advanced");
return true;
};
view_radio_button_ptr->on_selection_changed("Simple", "simple");
@@ -1217,6 +1192,8 @@ namespace gsr {
//record_options.overclock = false;
record_cursor_checkbox_ptr->set_checked(record_options.record_cursor);
restore_portal_session_checkbox_ptr->set_checked(record_options.restore_portal_session);
show_notification_checkbox_ptr->set_checked(record_options.show_notifications);
led_indicator_checkbox_ptr->set_checked(record_options.use_led_indicator);
if(record_options.record_area_width == 0)
record_options.record_area_width = 1920;
@@ -1262,9 +1239,7 @@ namespace gsr {
save_replay_in_game_folder_ptr->set_checked(config.replay_config.save_video_in_game_folder);
if(restart_replay_on_save)
restart_replay_on_save->set_checked(config.replay_config.restart_replay_on_save);
show_replay_started_notification_checkbox_ptr->set_checked(config.replay_config.show_replay_started_notifications);
show_replay_stopped_notification_checkbox_ptr->set_checked(config.replay_config.show_replay_stopped_notifications);
show_replay_saved_notification_checkbox_ptr->set_checked(config.replay_config.show_replay_saved_notifications);
save_directory_button_ptr->set_text(config.replay_config.save_directory);
container_box_ptr->set_selected_item(config.replay_config.container);
@@ -1278,17 +1253,12 @@ namespace gsr {
void SettingsPage::load_record() {
load_common(config.record_config.record_options);
save_recording_in_game_folder_ptr->set_checked(config.record_config.save_video_in_game_folder);
show_recording_started_notification_checkbox_ptr->set_checked(config.record_config.show_recording_started_notifications);
show_video_saved_notification_checkbox_ptr->set_checked(config.record_config.show_video_saved_notifications);
show_video_paused_notification_checkbox_ptr->set_checked(config.record_config.show_video_paused_notifications);
save_directory_button_ptr->set_text(config.record_config.save_directory);
container_box_ptr->set_selected_item(config.record_config.container);
}
void SettingsPage::load_stream() {
load_common(config.streaming_config.record_options);
show_streaming_started_notification_checkbox_ptr->set_checked(config.streaming_config.show_streaming_started_notifications);
show_streaming_stopped_notification_checkbox_ptr->set_checked(config.streaming_config.show_streaming_stopped_notifications);
streaming_service_box_ptr->set_selected_item(config.streaming_config.streaming_service);
youtube_stream_key_entry_ptr->set_text(config.streaming_config.youtube.stream_key);
twitch_stream_key_entry_ptr->set_text(config.streaming_config.twitch.stream_key);
@@ -1354,6 +1324,8 @@ namespace gsr {
//record_options.overclock = false;
record_options.record_cursor = record_cursor_checkbox_ptr->is_checked();
record_options.restore_portal_session = restore_portal_session_checkbox_ptr->is_checked();
record_options.show_notifications = show_notification_checkbox_ptr->is_checked();
record_options.use_led_indicator = led_indicator_checkbox_ptr->is_checked();
if(record_options.record_area_width == 0)
record_options.record_area_width = 1920;
@@ -1404,9 +1376,6 @@ namespace gsr {
config.replay_config.save_video_in_game_folder = save_replay_in_game_folder_ptr->is_checked();
if(restart_replay_on_save)
config.replay_config.restart_replay_on_save = restart_replay_on_save->is_checked();
config.replay_config.show_replay_started_notifications = show_replay_started_notification_checkbox_ptr->is_checked();
config.replay_config.show_replay_stopped_notifications = show_replay_stopped_notification_checkbox_ptr->is_checked();
config.replay_config.show_replay_saved_notifications = show_replay_saved_notification_checkbox_ptr->is_checked();
config.replay_config.save_directory = save_directory_button_ptr->get_text();
config.replay_config.container = container_box_ptr->get_selected_id();
config.replay_config.replay_time = atoi(replay_time_entry_ptr->get_text().c_str());
@@ -1421,17 +1390,12 @@ namespace gsr {
void SettingsPage::save_record() {
save_common(config.record_config.record_options);
config.record_config.save_video_in_game_folder = save_recording_in_game_folder_ptr->is_checked();
config.record_config.show_recording_started_notifications = show_recording_started_notification_checkbox_ptr->is_checked();
config.record_config.show_video_saved_notifications = show_video_saved_notification_checkbox_ptr->is_checked();
config.record_config.show_video_paused_notifications = show_video_paused_notification_checkbox_ptr->is_checked();
config.record_config.save_directory = save_directory_button_ptr->get_text();
config.record_config.container = container_box_ptr->get_selected_id();
}
void SettingsPage::save_stream() {
save_common(config.streaming_config.record_options);
config.streaming_config.show_streaming_started_notifications = show_streaming_started_notification_checkbox_ptr->is_checked();
config.streaming_config.show_streaming_stopped_notifications = show_streaming_stopped_notification_checkbox_ptr->is_checked();
config.streaming_config.streaming_service = streaming_service_box_ptr->get_selected_id();
config.streaming_config.youtube.stream_key = youtube_stream_key_entry_ptr->get_text();
config.streaming_config.twitch.stream_key = twitch_stream_key_entry_ptr->get_text();