Add Russian and Ukrainian translation and create translation template.

- Introduced a new translation template file for GPU Screen Recorder UI.
- Improved some translation methods
This commit is contained in:
Andrew
2026-01-27 00:17:03 +03:00
committed by dec05eba
parent ca0e001376
commit 03b4407d11
11 changed files with 1699 additions and 354 deletions

View File

@@ -10,6 +10,7 @@
#include "../include/gui/ScreenshotSettingsPage.hpp"
#include "../include/gui/GlobalSettingsPage.hpp"
#include "../include/gui/Utils.hpp"
#include "../include/Translation.hpp"
#include "../include/KwinWorkaround.hpp"
#include "../include/HyprlandWorkaround.hpp"
#include "../include/gui/PageStack.hpp"
@@ -20,6 +21,7 @@
#include "../include/CursorTracker/CursorTrackerWayland.hpp"
#include <iomanip>
#include <iostream>
#include <string.h>
#include <assert.h>
#include <sys/wait.h>
@@ -549,7 +551,7 @@ namespace gsr {
if(!config.main_config.wayland_warning_shown) {
config.main_config.wayland_warning_shown = true;
save_config(config);
show_notification("Wayland doesn't support GPU Screen Recorder UI properly,\nthings may not work as expected. Use X11 if you experience issues.", notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
show_notification(TR("Wayland doesn't support GPU Screen Recorder UI properly,\nthings may not work as expected. Use X11 if you experience issues."), notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
}
const std::string wm_name = get_window_manager_name(x11_dpy);
@@ -775,8 +777,8 @@ namespace gsr {
if(global_hotkeys_ungrab_keyboard) {
global_hotkeys_ungrab_keyboard = false;
show_notification(
"Some keyboard remapping software conflicts with GPU Screen Recorder on your system.\n"
"Keyboards have been ungrabbed, applications will now receive the hotkeys you press."
TR("Some keyboard remapping software conflicts with GPU Screen Recorder on your system.\n"
"Keyboards have been ungrabbed, applications will now receive the hotkeys you press.")
, 7.0, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
config.main_config.hotkeys_enable_option = "enable_hotkeys_no_grab";
@@ -816,7 +818,7 @@ namespace gsr {
if(selected_window && selected_window != DefaultRootWindow(display)) {
on_window_selected();
} else {
show_notification("No window selected", notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
show_notification(TR("No window selected"), notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
}
on_window_selected = nullptr;
}
@@ -867,7 +869,7 @@ namespace gsr {
start_region_capture = false;
hide();
if(!region_selector.start(get_color_theme().tint_color)) {
show_notification("Failed to start region capture", notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to start region capture"), notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
on_region_selected = nullptr;
}
}
@@ -876,7 +878,7 @@ namespace gsr {
start_window_capture = false;
hide();
if(!window_selector.start(get_color_theme().tint_color)) {
show_notification("Failed to start window capture", notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to start window capture"), notification_error_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
on_window_selected = nullptr;
}
}
@@ -1244,16 +1246,16 @@ namespace gsr {
List * main_buttons_list_ptr = main_buttons_list.get();
main_buttons_list->set_spacing(0.0f);
{
auto button = std::make_unique<DropdownButton>(&get_theme().title_font, &get_theme().body_font, "Instant Replay", "Off", &get_theme().replay_button_texture,
auto button = std::make_unique<DropdownButton>(&get_theme().title_font, &get_theme().body_font, TR("Instant Replay"), TR("Off"), &get_theme().replay_button_texture,
mgl::vec2f(button_width, button_height));
replay_dropdown_button_ptr = button.get();
button->add_item("Turn on", "start", config.replay_config.start_stop_hotkey.to_string(false, false));
button->add_item("Save", "save", config.replay_config.save_hotkey.to_string(false, false));
button->add_item(TR("Turn on"), "start", config.replay_config.start_stop_hotkey.to_string(false, false));
button->add_item(TR("Save"), "save", config.replay_config.save_hotkey.to_string(false, false));
if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) {
button->add_item("Save 1 min", "save_1_min", config.replay_config.save_1_min_hotkey.to_string(false, false));
button->add_item("Save 10 min", "save_10_min", config.replay_config.save_10_min_hotkey.to_string(false, false));
button->add_item(TR("Save 1 min"), "save_1_min", config.replay_config.save_1_min_hotkey.to_string(false, false));
button->add_item(TR("Save 10 min"), "save_10_min", config.replay_config.save_10_min_hotkey.to_string(false, false));
}
button->add_item("Settings", "settings");
button->add_item(TR("Settings"), "settings");
button->set_item_icon("start", &get_theme().play_texture);
button->set_item_icon("save", &get_theme().save_texture);
button->set_item_icon("save_1_min", &get_theme().save_texture);
@@ -1265,7 +1267,7 @@ namespace gsr {
replay_settings_page->on_config_changed = [this]() {
replay_startup_mode = replay_startup_string_to_type(config.replay_config.turn_on_replay_automatically_mode.c_str());
if(recording_status == RecordingStatus::REPLAY)
show_notification("Replay settings have been modified.\nYou may need to restart replay to apply the changes.", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
show_notification(TR("Replay settings have been modified.\nYou may need to restart replay to apply the changes."), notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
};
page_stack.push(std::move(replay_settings_page));
} else if(id == "save") {
@@ -1284,12 +1286,12 @@ namespace gsr {
main_buttons_list->add_widget(std::move(button));
}
{
auto button = std::make_unique<DropdownButton>(&get_theme().title_font, &get_theme().body_font, "Record", "Not recording", &get_theme().record_button_texture,
auto button = std::make_unique<DropdownButton>(&get_theme().title_font, &get_theme().body_font, TR("Record"), TR("Not recording"), &get_theme().record_button_texture,
mgl::vec2f(button_width, button_height));
record_dropdown_button_ptr = button.get();
button->add_item("Start", "start", config.record_config.start_stop_hotkey.to_string(false, false));
button->add_item("Pause", "pause", config.record_config.pause_unpause_hotkey.to_string(false, false));
button->add_item("Settings", "settings");
button->add_item(TR("Start"), "start", config.record_config.start_stop_hotkey.to_string(false, false));
button->add_item(TR("Pause"), "pause", config.record_config.pause_unpause_hotkey.to_string(false, false));
button->add_item(TR("Settings"), "settings");
button->set_item_icon("start", &get_theme().play_texture);
button->set_item_icon("pause", &get_theme().pause_texture);
button->set_item_icon("settings", &get_theme().settings_extra_small_texture);
@@ -1298,7 +1300,7 @@ namespace gsr {
auto record_settings_page = std::make_unique<SettingsPage>(SettingsPage::Type::RECORD, &gsr_info, config, &page_stack, supports_window_title);
record_settings_page->on_config_changed = [this]() {
if(recording_status == RecordingStatus::RECORD)
show_notification("Recording settings have been modified.\nYou may need to restart recording to apply the changes.", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
show_notification(TR("Recording settings have been modified.\nYou may need to restart recording to apply the changes."), notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::RECORD);
update_led_indicator_after_settings_change();
};
@@ -1313,11 +1315,11 @@ namespace gsr {
main_buttons_list->add_widget(std::move(button));
}
{
auto button = std::make_unique<DropdownButton>(&get_theme().title_font, &get_theme().body_font, "Livestream", "Not streaming", &get_theme().stream_button_texture,
auto button = std::make_unique<DropdownButton>(&get_theme().title_font, &get_theme().body_font, TR("Livestream"), TR("Not streaming"), &get_theme().stream_button_texture,
mgl::vec2f(button_width, button_height));
stream_dropdown_button_ptr = button.get();
button->add_item("Start", "start", config.streaming_config.start_stop_hotkey.to_string(false, false));
button->add_item("Settings", "settings");
button->add_item(TR("Start"), "start", config.streaming_config.start_stop_hotkey.to_string(false, false));
button->add_item(TR("Settings"), "settings");
button->set_item_icon("start", &get_theme().play_texture);
button->set_item_icon("settings", &get_theme().settings_extra_small_texture);
button->on_click = [this](const std::string &id) {
@@ -1325,7 +1327,7 @@ namespace gsr {
auto stream_settings_page = std::make_unique<SettingsPage>(SettingsPage::Type::STREAM, &gsr_info, config, &page_stack, supports_window_title);
stream_settings_page->on_config_changed = [this]() {
if(recording_status == RecordingStatus::STREAM)
show_notification("Streaming settings have been modified.\nYou may need to restart streaming to apply the changes.", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
show_notification(TR("Streaming settings have been modified.\nYou may need to restart streaming to apply the changes."), notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
update_led_indicator_after_settings_change();
};
@@ -1357,12 +1359,12 @@ namespace gsr {
if(exit_status == 127) {
if(enable)
show_notification("Failed to add GPU Screen Recorder to system startup.\nThis option only works on systems that use systemd.\nYou have to manually add \"gsr-ui\" to system startup on systems that uses another init system.", 7.0, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to add GPU Screen Recorder to system startup.\nThis option only works on systems that use systemd.\nYou have to manually add \"gsr-ui\" to system startup on systems that uses another init system."), 7.0, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
} else {
if(enable)
show_notification("Failed to add GPU Screen Recorder to system startup", notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to add GPU Screen Recorder to system startup"), notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
else
show_notification("Failed to remove GPU Screen Recorder from system startup", notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to remove GPU Screen Recorder from system startup"), notification_timeout_seconds, mgl::Color(255, 255, 255), mgl::Color(255, 0, 0), NotificationType::NOTICE, nullptr, NotificationLevel::ERROR);
}
};
@@ -1587,12 +1589,12 @@ namespace gsr {
paused_clock.restart();
update_ui_recording_paused();
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);
show_notification(TR("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.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);
show_notification(TR("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)
@@ -1715,7 +1717,7 @@ namespace gsr {
static std::string capture_target_get_notification_name(const char *capture_target, bool save) {
std::string result;
if(is_capture_target_monitor(capture_target)) {
result = "this monitor";
result = TR("this monitor");
} else if(is_number(capture_target)) {
mgl_context *context = mgl_get_context();
Display *display = (Display*)context->connection;
@@ -1725,16 +1727,16 @@ namespace gsr {
const std::optional<std::string> window_title = get_window_title(display, window_id);
if(save) {
result = "window";
result = TR("window");
} else if(window_title) {
result = strip(window_title.value());
truncate_string(result, 30);
result = "window \"" + result + "\"";
result = TRF("window \"%s\"", result.c_str());
} else {
result = std::string("window ") + capture_target;
result = TRF("window %s", capture_target);
}
} else {
result = capture_target;
result = TR(capture_target);
}
return result;
}
@@ -1939,19 +1941,46 @@ namespace gsr {
seconds -= (minutes * 60);
std::string result;
if(hours > 0)
result += std::to_string(hours) + " hour" + (hours == 1 ? "" : "s");
if(hours > 0) {
if (Translation::instance().plural_numbers_are_complex()) {
result += TRPF("%d hour", hours, hours);
}
else {
if(hours == 1)
result += TRF("%d hour", hours);
else
result += TRF("%d hours", hours);
}
}
if(minutes > 0) {
if(!result.empty())
result += " ";
result += std::to_string(minutes) + " minute" + (minutes == 1 ? "" : "s");
if (Translation::instance().plural_numbers_are_complex()) {
result += TRPF("%d minute", minutes, minutes);
}
else {
if(minutes == 1)
result += TRF("%d minute", minutes);
else
result += TRF("%d minutes", minutes);
}
}
if(seconds > 0 || (hours == 0 && minutes == 0)) {
if(!result.empty())
result += " ";
result += std::to_string(seconds) + " second" + (seconds == 1 ? "" : "s");
if (Translation::instance().plural_numbers_are_complex()) {
result += TRPF("%d second", seconds, seconds);
}
else {
if(seconds == 1)
result += TRF("%d second", seconds);
else
result += TRF("%d seconds", seconds);
}
}
return result;
@@ -2019,7 +2048,7 @@ namespace gsr {
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));
snprintf(msg, sizeof(msg), "Saved a %s recording of %s\nto \"%s\"",
snprintf(msg, sizeof(msg), TR("Saved a %s recording of %s\nto \"%s\""),
duration_str.c_str(),
capture_target_get_notification_name(recording_capture_target.c_str(), true).c_str(), focused_window_name.c_str());
capture_target = recording_capture_target.c_str();
@@ -2030,7 +2059,7 @@ namespace gsr {
return;
const std::string duration_str = to_duration_string(get_time_passed_in_replay_buffer_seconds());
snprintf(msg, sizeof(msg), "Saved a %s replay of %s\nto \"%s\"",
snprintf(msg, sizeof(msg), TR("Saved a %s replay of %s\nto \"%s\""),
duration_str.c_str(),
capture_target_get_notification_name(recording_capture_target.c_str(), true).c_str(), focused_window_name.c_str());
capture_target = recording_capture_target.c_str();
@@ -2040,7 +2069,7 @@ namespace gsr {
if(!config.screenshot_config.show_notifications)
return;
snprintf(msg, sizeof(msg), "Saved a screenshot of %s\nto \"%s\"",
snprintf(msg, sizeof(msg), TR("Saved a screenshot of %s\nto \"%s\""),
capture_target_get_notification_name(screenshot_capture_target.c_str(), true).c_str(), focused_window_name.c_str());
capture_target = screenshot_capture_target.c_str();
break;
@@ -2072,7 +2101,7 @@ namespace gsr {
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",
snprintf(msg, sizeof(msg), TR("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());
@@ -2086,7 +2115,7 @@ namespace gsr {
if(replay_save_show_notification && replay_save_clock.get_elapsed_time_seconds() >= replay_saving_notification_timeout_seconds) {
replay_save_show_notification = false;
if(config.replay_config.record_options.show_notifications)
show_notification("Saving replay, this might take some time", notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
show_notification(TR("Saving replay, this might take some time"), notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
}
if(gpu_screen_recorder_process_output_file) {
@@ -2131,17 +2160,17 @@ namespace gsr {
void Overlay::on_gsr_process_error(int exit_code, NotificationType notification_type) {
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_process, exit_code);
if(exit_code == 50) {
show_notification("Desktop portal capture failed.\nEither you canceled the desktop portal or your Wayland compositor doesn't support desktop portal capture\nor it's incorrectly setup on your system.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
show_notification(TR("Desktop portal capture failed.\nEither you canceled the desktop portal or your Wayland compositor doesn't support desktop portal capture\nor it's incorrectly setup on your system."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
} else if(exit_code == 51) {
show_notification("Monitor capture failed.\nThe monitor you are trying to capture is invalid.\nPlease validate your capture settings.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
show_notification(TR("Monitor capture failed.\nThe monitor you are trying to capture is invalid.\nPlease validate your capture settings."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
} else if(exit_code == 52) {
show_notification("Capture failed. Neither H264, HEVC nor AV1 video codecs are supported\non your system or you are trying to capture at a resolution higher than your\nsystem supports for each video codec.", 10.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
show_notification(TR("Capture failed. Neither H264, HEVC nor AV1 video codecs are supported\non your system or you are trying to capture at a resolution higher than your\nsystem supports for each video codec."), 10.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
} else if(exit_code == 53) {
show_notification("Capture failed. Your system doesn't support the resolution you are trying to\nrecord at with the video codec you have chosen.\nChange capture resolution or video codec and try again.\nNote: AV1 supports the highest resolution, then HEVC and then H264.", 10.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
show_notification(TR("Capture failed. Your system doesn't support the resolution you are trying to\nrecord at with the video codec you have chosen.\nChange capture resolution or video codec and try again.\nNote: AV1 supports the highest resolution, then HEVC and then H264."), 10.0, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
} else if(exit_code == 54) {
show_notification("Capture failed. Your system doesn't support the video codec you have chosen.\nChange video codec and try again.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
show_notification(TR("Capture failed. Your system doesn't support the video codec you have chosen.\nChange video codec and try again."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
} else if(exit_code == 60) {
show_notification("Stopped capture because the user canceled the desktop portal", notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
show_notification(TR("Stopped capture because the user canceled the desktop portal"), notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
} else {
const char *prefix = "";
switch(notification_type) {
@@ -2149,21 +2178,21 @@ namespace gsr {
case NotificationType::NOTICE:
break;
case NotificationType::SCREENSHOT:
prefix = "Failed to take a screenshot";
prefix = TR("Failed to take a screenshot");
break;
case NotificationType::RECORD:
prefix = "Failed to start/save recording";
prefix = TR("Failed to start/save recording");
break;
case NotificationType::REPLAY:
prefix = "Replay stopped because of an error";
prefix = TR("Replay stopped because of an error");
break;
case NotificationType::STREAM:
prefix = "Streaming stopped because of an error";
prefix = TR("Streaming stopped because of an error");
break;
}
char msg[256];
snprintf(msg, sizeof(msg), "%s. Verify if settings are correct", prefix);
snprintf(msg, sizeof(msg), TR("%s. Verify if settings are correct"), prefix);
show_notification(msg, notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), notification_type, nullptr, NotificationLevel::ERROR);
}
}
@@ -2192,7 +2221,7 @@ namespace gsr {
update_ui_replay_stopped();
if(exit_code == 0) {
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);
show_notification(TR("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);
}
@@ -2214,7 +2243,7 @@ namespace gsr {
update_ui_streaming_stopped();
if(exit_code == 0) {
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);
show_notification(TR("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);
}
@@ -2248,7 +2277,7 @@ namespace gsr {
save_video_in_current_game_directory(screenshot_filepath, NotificationType::SCREENSHOT);
} 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());
snprintf(msg, sizeof(msg), TR("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());
}
@@ -2267,7 +2296,7 @@ namespace gsr {
}
} else {
fprintf(stderr, "Warning: gpu-screen-recorder (%d) exited with exit status %d\n", (int)gpu_screen_recorder_screenshot_process, exit_code);
show_notification("Failed to take a screenshot. Verify if settings are correct", notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::SCREENSHOT, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to take a screenshot. Verify if settings are correct"), notification_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::SCREENSHOT, nullptr, NotificationLevel::ERROR);
}
gpu_screen_recorder_screenshot_process = -1;
@@ -2375,7 +2404,7 @@ namespace gsr {
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",
snprintf(msg, sizeof(msg), TR("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());
@@ -2401,8 +2430,8 @@ namespace gsr {
if(!visible || recording_status != RecordingStatus::RECORD)
return;
record_dropdown_button_ptr->set_description("Paused");
record_dropdown_button_ptr->set_item_label("pause", "Unpause");
record_dropdown_button_ptr->set_description(TR("Paused"));
record_dropdown_button_ptr->set_item_label("pause", TR("Unpause"));
record_dropdown_button_ptr->set_item_icon("pause", &get_theme().play_texture);
}
@@ -2410,8 +2439,8 @@ namespace gsr {
if(!visible || recording_status != RecordingStatus::RECORD)
return;
record_dropdown_button_ptr->set_description("Recording");
record_dropdown_button_ptr->set_item_label("pause", "Pause");
record_dropdown_button_ptr->set_description(TR("Recording"));
record_dropdown_button_ptr->set_item_label("pause", TR("Pause"));
record_dropdown_button_ptr->set_item_icon("pause", &get_theme().pause_texture);
}
@@ -2419,9 +2448,9 @@ namespace gsr {
if(!visible)
return;
record_dropdown_button_ptr->set_item_label("start", "Stop and save");
record_dropdown_button_ptr->set_item_label("start", TR("Stop and save"));
record_dropdown_button_ptr->set_activated(true);
record_dropdown_button_ptr->set_description("Recording");
record_dropdown_button_ptr->set_description(TR("Recording"));
record_dropdown_button_ptr->set_item_icon("start", &get_theme().stop_texture);
record_dropdown_button_ptr->set_item_enabled("pause", recording_status == RecordingStatus::RECORD);
}
@@ -2430,12 +2459,12 @@ namespace gsr {
if(!visible)
return;
record_dropdown_button_ptr->set_item_label("start", "Start");
record_dropdown_button_ptr->set_item_label("start", TR("Start"));
record_dropdown_button_ptr->set_activated(false);
record_dropdown_button_ptr->set_description("Not recording");
record_dropdown_button_ptr->set_description(TR("Not recording"));
record_dropdown_button_ptr->set_item_icon("start", &get_theme().play_texture);
record_dropdown_button_ptr->set_item_label("pause", "Pause");
record_dropdown_button_ptr->set_item_label("pause", TR("Pause"));
record_dropdown_button_ptr->set_item_icon("pause", &get_theme().pause_texture);
record_dropdown_button_ptr->set_item_enabled("pause", false);
update_upause_status();
@@ -2446,9 +2475,9 @@ namespace gsr {
if(!visible)
return;
stream_dropdown_button_ptr->set_item_label("start", "Stop");
stream_dropdown_button_ptr->set_item_label("start", TR("Stop"));
stream_dropdown_button_ptr->set_activated(true);
stream_dropdown_button_ptr->set_description("Streaming");
stream_dropdown_button_ptr->set_description(TR("Streaming"));
stream_dropdown_button_ptr->set_item_icon("start", &get_theme().stop_texture);
}
@@ -2456,9 +2485,9 @@ namespace gsr {
if(!visible)
return;
stream_dropdown_button_ptr->set_item_label("start", "Start");
stream_dropdown_button_ptr->set_item_label("start", TR("Start"));
stream_dropdown_button_ptr->set_activated(false);
stream_dropdown_button_ptr->set_description("Not streaming");
stream_dropdown_button_ptr->set_description(TR("Not streaming"));
stream_dropdown_button_ptr->set_item_icon("start", &get_theme().play_texture);
update_ui_recording_stopped();
}
@@ -2467,9 +2496,9 @@ namespace gsr {
if(!visible)
return;
replay_dropdown_button_ptr->set_item_label("start", "Turn off");
replay_dropdown_button_ptr->set_item_label("start", TR("Turn off"));
replay_dropdown_button_ptr->set_activated(true);
replay_dropdown_button_ptr->set_description("On");
replay_dropdown_button_ptr->set_description(TR("On"));
replay_dropdown_button_ptr->set_item_icon("start", &get_theme().stop_texture);
replay_dropdown_button_ptr->set_item_enabled("save", true);
replay_dropdown_button_ptr->set_item_enabled("save_1_min", current_recording_config.replay_config.replay_time >= 60);
@@ -2480,9 +2509,9 @@ namespace gsr {
if(!visible)
return;
replay_dropdown_button_ptr->set_item_label("start", "Turn on");
replay_dropdown_button_ptr->set_item_label("start", TR("Turn on"));
replay_dropdown_button_ptr->set_activated(false);
replay_dropdown_button_ptr->set_description("Off");
replay_dropdown_button_ptr->set_description(TR("Off"));
replay_dropdown_button_ptr->set_item_icon("start", &get_theme().play_texture);
replay_dropdown_button_ptr->set_item_enabled("save", false);
replay_dropdown_button_ptr->set_item_enabled("save_1_min", false);
@@ -2837,10 +2866,10 @@ namespace gsr {
case RecordingStatus::REPLAY:
break;
case RecordingStatus::RECORD:
show_notification("Unable to start replay when recording.\nStop recording before starting replay.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD, nullptr, NotificationLevel::ERROR);
show_notification(TR("Unable to start replay when recording.\nStop recording before starting replay."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD, nullptr, NotificationLevel::ERROR);
return false;
case RecordingStatus::STREAM:
show_notification("Unable to start replay when streaming.\nStop streaming before starting replay.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM, nullptr, NotificationLevel::ERROR);
show_notification(TR("Unable to start replay when streaming.\nStop streaming before starting replay."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM, nullptr, NotificationLevel::ERROR);
return false;
}
@@ -2867,7 +2896,7 @@ namespace gsr {
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
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);
show_notification(TR("Replay stopped"), notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::REPLAY);
return true;
}
@@ -2876,7 +2905,7 @@ namespace gsr {
recording_capture_target = get_capture_target(config.replay_config.record_options.record_area_option, capture_options);
if(!validate_capture_target(config.replay_config.record_options.record_area_option, capture_options)) {
char err_msg[256];
snprintf(err_msg, sizeof(err_msg), "Failed to start replay, capture target \"%s\" is invalid.\nPlease change capture target in settings", recording_capture_target.c_str());
snprintf(err_msg, sizeof(err_msg), TR("Failed to start replay, capture target \"%s\" is invalid.\nPlease change capture target in settings"), recording_capture_target.c_str());
show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY, nullptr, NotificationLevel::ERROR);
return false;
}
@@ -2961,7 +2990,7 @@ namespace gsr {
gpu_screen_recorder_process = exec_program(args.data(), &gpu_screen_recorder_process_output_fd);
if(gpu_screen_recorder_process == -1) {
show_notification("Failed to launch gpu-screen-recorder to start replay", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to launch gpu-screen-recorder to start replay"), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY, nullptr, NotificationLevel::ERROR);
return false;
} else {
recording_status = RecordingStatus::REPLAY;
@@ -2984,7 +3013,7 @@ namespace gsr {
// to see when the program has exit.
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());
snprintf(msg, sizeof(msg), TR("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());
}
@@ -3012,7 +3041,7 @@ namespace gsr {
if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) {
if(!replay_recording) {
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);
show_notification(TR("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();
// TODO: This will be incorrect if the user uses portal capture, as capture wont start until the user has
@@ -3033,7 +3062,7 @@ namespace gsr {
replay_recording = true;
kill(gpu_screen_recorder_process, SIGRTMIN);
} else {
show_notification("Unable to start recording when replay is turned on.\nTurn off replay before starting recording.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), get_color_theme().tint_color, NotificationType::REPLAY, nullptr, NotificationLevel::ERROR);
show_notification(TR("Unable to start recording when replay is turned on.\nTurn off replay before starting recording."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), get_color_theme().tint_color, NotificationType::REPLAY, nullptr, NotificationLevel::ERROR);
}
return;
}
@@ -3044,7 +3073,7 @@ namespace gsr {
if(gsr_info.system_info.gsr_version >= GsrVersion{5, 4, 0}) {
if(!replay_recording) {
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);
show_notification(TR("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();
// TODO: This will be incorrect if the user uses portal capture, as capture wont start until the user has
@@ -3065,7 +3094,7 @@ namespace gsr {
replay_recording = true;
kill(gpu_screen_recorder_process, SIGRTMIN);
} else {
show_notification("Unable to start recording when streaming.\nStop streaming before starting recording.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), get_color_theme().tint_color, NotificationType::STREAM, nullptr, NotificationLevel::ERROR);
show_notification(TR("Unable to start recording when streaming.\nStop streaming before starting recording."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), get_color_theme().tint_color, NotificationType::STREAM, nullptr, NotificationLevel::ERROR);
}
return;
}
@@ -3116,7 +3145,7 @@ namespace gsr {
recording_capture_target = get_capture_target(record_area_option, capture_options);
if(!validate_capture_target(record_area_option, capture_options)) {
char err_msg[256];
snprintf(err_msg, sizeof(err_msg), "Failed to start recording, capture target \"%s\" is invalid.\nPlease change capture target in settings", recording_capture_target.c_str());
snprintf(err_msg, sizeof(err_msg), TR("Failed to start recording, capture target \"%s\" is invalid.\nPlease change capture target in settings"), recording_capture_target.c_str());
show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD, nullptr, NotificationLevel::ERROR);
return;
}
@@ -3193,7 +3222,7 @@ namespace gsr {
record_filepath = output_file;
gpu_screen_recorder_process = exec_program(args.data(), &gpu_screen_recorder_process_output_fd);
if(gpu_screen_recorder_process == -1) {
show_notification("Failed to launch gpu-screen-recorder to start recording", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to launch gpu-screen-recorder to start recording"), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD, nullptr, NotificationLevel::ERROR);
return;
} else {
recording_status = RecordingStatus::RECORD;
@@ -3213,7 +3242,7 @@ namespace gsr {
// 1...
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());
snprintf(msg, sizeof(msg), TR("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());
}
@@ -3278,10 +3307,10 @@ namespace gsr {
case RecordingStatus::STREAM:
break;
case RecordingStatus::REPLAY:
show_notification("Unable to start streaming when replay is turned on.\nTurn off replay before starting streaming.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY, nullptr, NotificationLevel::ERROR);
show_notification(TR("Unable to start streaming when replay is turned on.\nTurn off replay before starting streaming."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::REPLAY, nullptr, NotificationLevel::ERROR);
return;
case RecordingStatus::RECORD:
show_notification("Unable to start streaming when recording.\nStop recording before starting streaming.", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD, nullptr, NotificationLevel::ERROR);
show_notification(TR("Unable to start streaming when recording.\nStop recording before starting streaming."), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::RECORD, nullptr, NotificationLevel::ERROR);
return;
}
@@ -3306,7 +3335,7 @@ namespace gsr {
// TODO: Show this with a slight delay to make sure it doesn't show up in the video
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);
show_notification(TR("Streaming has stopped"), notification_timeout_seconds, mgl::Color(255, 255, 255), get_color_theme().tint_color, NotificationType::STREAM);
return;
}
@@ -3314,7 +3343,7 @@ namespace gsr {
recording_capture_target = get_capture_target(config.streaming_config.record_options.record_area_option, capture_options);
if(!validate_capture_target(config.streaming_config.record_options.record_area_option, capture_options)) {
char err_msg[256];
snprintf(err_msg, sizeof(err_msg), "Failed to start streaming, capture target \"%s\" is invalid.\nPlease change capture target in settings", recording_capture_target.c_str());
snprintf(err_msg, sizeof(err_msg), TR("Failed to start streaming, capture target \"%s\" is invalid.\nPlease change capture target in settings"), recording_capture_target.c_str());
show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM, nullptr, NotificationLevel::ERROR);
return;
}
@@ -3395,7 +3424,7 @@ namespace gsr {
gpu_screen_recorder_process = exec_program(args.data(), &gpu_screen_recorder_process_output_fd);
if(gpu_screen_recorder_process == -1) {
show_notification("Failed to launch gpu-screen-recorder to start streaming", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to launch gpu-screen-recorder to start streaming"), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::STREAM, nullptr, NotificationLevel::ERROR);
return;
} else {
recording_status = RecordingStatus::STREAM;
@@ -3418,7 +3447,7 @@ namespace gsr {
// to see when the program has exit.
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());
snprintf(msg, sizeof(msg), TR("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());
}
@@ -3452,7 +3481,7 @@ namespace gsr {
screenshot_capture_target = get_capture_target(record_area_option, capture_options);
if(!validate_capture_target(record_area_option, capture_options)) {
char err_msg[256];
snprintf(err_msg, sizeof(err_msg), "Failed to take a screenshot, capture target \"%s\" is invalid.\nPlease change capture target in settings", screenshot_capture_target.c_str());
snprintf(err_msg, sizeof(err_msg), TR("Failed to take a screenshot, capture target \"%s\" is invalid.\nPlease change capture target in settings"), screenshot_capture_target.c_str());
show_notification(err_msg, notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::SCREENSHOT, nullptr, NotificationLevel::ERROR);
return;
}
@@ -3523,7 +3552,7 @@ namespace gsr {
screenshot_filepath = output_file;
gpu_screen_recorder_screenshot_process = exec_program(args.data(), nullptr);
if(gpu_screen_recorder_screenshot_process == -1) {
show_notification("Failed to launch gpu-screen-recorder to take a screenshot", notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::SCREENSHOT, nullptr, NotificationLevel::ERROR);
show_notification(TR("Failed to launch gpu-screen-recorder to take a screenshot"), notification_error_timeout_seconds, mgl::Color(255, 0, 0), mgl::Color(255, 0, 0), NotificationType::SCREENSHOT, nullptr, NotificationLevel::ERROR);
}
}

View File

@@ -1,8 +1,11 @@
#include "../include/Translation.hpp"
#include <cstdio>
#include <cstring>
#include <iostream>
#include <unordered_map>
#include <fstream>
namespace gsr {
std::string Translation::get_system_language() {
const char* lang = getenv("LANGUAGE");
@@ -35,8 +38,38 @@ namespace gsr {
return str.substr(start, end - start + 1);
}
void Translation::process_escapes(std::string& str) {
size_t pos = 0;
while ((pos = str.find("\\n", pos)) != std::string::npos) {
str.replace(pos, 2, "\n");
pos += 1;
}
}
bool Translation::is_language_supported(const char* lang) {
std::string paths[] = {
std::string("translations/") + lang + ".txt",
std::string(this->translations_directory) + lang + ".txt"
};
for (const auto& path : paths) {
std::ifstream file(path);
if (file.is_open()) {
return true;
}
}
return false;
}
bool Translation::load_language(const char* lang) {
translations.clear();
if (!is_language_supported(lang)) {
fprintf(stderr, "Warning: language '%s' is not supported\n", lang);
return false;
}
current_language = lang;
if (strcmp(lang, "en") == 0) {
@@ -61,18 +94,17 @@ namespace gsr {
size_t eq_pos = line.find('=');
if (eq_pos == std::string::npos) continue;
std::string key = trim(line.substr(0, eq_pos));
std::string value = trim(line.substr(eq_pos + 1));
std::string key = line.substr(0, eq_pos);
std::string value = line.substr(eq_pos + 1);
size_t pos = 0;
while ((pos = value.find("\\n", pos)) != std::string::npos) {
value.replace(pos, 2, "\n");
pos += 1;
}
// Process escape sequences in both key and value
process_escapes(key);
process_escapes(value);
translations[key] = value;
}
fprintf(stderr, "Info: Loaded translation file for '%s' from %s\n", lang, path.c_str());
return true;
}
@@ -91,11 +123,65 @@ namespace gsr {
load_language(initial_language == nullptr ? get_system_language().c_str() : initial_language);
}
bool Translation::plural_numbers_are_complex() {
if (
current_language == "ru" ||
current_language == "uk" ||
current_language == "pl" ||
current_language == "cs" ||
current_language == "sk" ||
current_language == "hr" ||
current_language == "sl"
) {
return true;
}
return current_language != "en";
}
std::string Translation::get_complex_plural_number_key(const char* key, int number) {
std::string s_key = key;
if (current_language == "ru" || current_language == "uk") {
int n = number % 100;
if (n >= 11 && n <= 14) {
return s_key + "_many";
}
n = number % 10;
if (n == 1) {
return s_key + "_one";
}
if (n >= 2 && n <= 4) {
return s_key + "_few";
}
return s_key + "_many";
} else if (current_language == "pl") {
int n = number % 100;
if (n >= 12 && n <= 14) {
return s_key + "_many";
}
n = number % 10;
if (n == 1) {
return s_key + "_one";
}
if (n >= 2 && n <= 4) {
return s_key + "_few";
}
return s_key + "_many";
}
// Add more languages as needed
return key; // default fallback
}
const char* Translation::translate(const char* key) {
auto it = translations.find(key);
if (it != translations.end()) {
return it->second.c_str();
}
#ifndef DNDEBUG
if(current_language != "en")
fprintf(stderr, "Warning: translation key '%s' not found\n", key);
#endif
return key; // falling back if nothing found
}
}
}

View File

@@ -3,6 +3,7 @@
#include "../../include/Overlay.hpp"
#include "../../include/Theme.hpp"
#include "../../include/Process.hpp"
#include "../../include/Translation.hpp"
#include "../../include/gui/GsrPage.hpp"
#include "../../include/gui/PageStack.hpp"
#include "../../include/gui/ScrollablePage.hpp"
@@ -80,8 +81,8 @@ namespace gsr {
gsr_info(gsr_info),
page_stack(page_stack)
{
auto content_page = std::make_unique<GsrPage>("Global", "Settings");
content_page->add_button("Back", "back", get_color_theme().page_bg_color);
auto content_page = std::make_unique<GsrPage>(TR("Global"), TR("Settings"));
content_page->add_button(TR("Back"), "back", get_color_theme().page_bg_color);
content_page->on_click = [page_stack](const std::string &id) {
if(id == "back")
page_stack->pop();
@@ -98,9 +99,9 @@ namespace gsr {
if(!configure_hotkey_button)
return;
mgl::Text title_text("Press a key combination to use for the hotkey \"" + hotkey_configure_action_name + "\":", get_theme().title_font);
mgl::Text title_text(TRF("Press a key combination to use for the hotkey: \"%s\"", hotkey_configure_action_name.c_str()), get_theme().title_font);
mgl::Text hotkey_text(configure_hotkey_button->get_text(), get_theme().top_bar_font);
mgl::Text description_text("Alpha-numerical keys can't be used alone in hotkeys, they have to be used one or more of these keys: Alt, Ctrl, Shift and Super.\nPress Esc to cancel or Backspace to remove the hotkey.", get_theme().body_font);
mgl::Text description_text(TR("Alpha-numerical keys can't be used alone in hotkeys, they have to be used one or more of these keys: Alt, Ctrl, Shift and Super.\nPress Esc to cancel or Backspace to remove the hotkey."), get_theme().body_font);
const float text_max_width = std::max(title_text.get_bounds().size.x, std::max(hotkey_text.get_bounds().size.x, description_text.get_bounds().size.x));
const float padding_horizontal = int(get_theme().window_height * 0.01f);
@@ -143,12 +144,12 @@ namespace gsr {
std::unique_ptr<Subsection> GlobalSettingsPage::create_appearance_subsection(ScrollablePage *parent_page) {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Accent color", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Accent color"), get_color_theme().text_color));
auto tint_color_radio_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::HORIZONTAL);
tint_color_radio_button_ptr = tint_color_radio_button.get();
tint_color_radio_button->add_item("Red", "amd");
tint_color_radio_button->add_item("Green", "nvidia");
tint_color_radio_button->add_item("Blue", "intel");
tint_color_radio_button->add_item(TR("Red"), "amd");
tint_color_radio_button->add_item(TR("Green"), "nvidia");
tint_color_radio_button->add_item(TR("Blue"), "intel");
tint_color_radio_button->on_selection_changed = [](const std::string&, const std::string &id) {
if(id == "amd")
get_color_theme().tint_color = mgl::Color(221, 0, 49);
@@ -159,16 +160,16 @@ namespace gsr {
return true;
};
list->add_widget(std::move(tint_color_radio_button));
return std::make_unique<Subsection>("Appearance", std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Appearance"), std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
}
std::unique_ptr<Subsection> GlobalSettingsPage::create_startup_subsection(ScrollablePage *parent_page) {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Start program on system startup?", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Start program on system startup?"), get_color_theme().text_color));
auto startup_radio_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::HORIZONTAL);
startup_radio_button_ptr = startup_radio_button.get();
startup_radio_button->add_item("Yes", "start_on_system_startup");
startup_radio_button->add_item("No", "dont_start_on_system_startup");
startup_radio_button->add_item(TR("Yes"), "start_on_system_startup");
startup_radio_button->add_item(TR("No"), "dont_start_on_system_startup");
startup_radio_button->on_selection_changed = [&](const std::string&, const std::string &id) {
bool enable = false;
if(id == "dont_start_on_system_startup")
@@ -186,16 +187,16 @@ namespace gsr {
return exit_status == 0;
};
list->add_widget(std::move(startup_radio_button));
return std::make_unique<Subsection>("Startup", std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Startup"), std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
}
std::unique_ptr<RadioButton> GlobalSettingsPage::create_enable_keyboard_hotkeys_button() {
auto enable_hotkeys_radio_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::VERTICAL);
enable_keyboard_hotkeys_radio_button_ptr = enable_hotkeys_radio_button.get();
enable_hotkeys_radio_button->add_item("Yes", "enable_hotkeys");
enable_hotkeys_radio_button->add_item("Yes, but only grab virtual devices (supports some input remapping software)", "enable_hotkeys_virtual_devices");
enable_hotkeys_radio_button->add_item("Yes, but don't grab devices (supports all input remapping software)", "enable_hotkeys_no_grab");
enable_hotkeys_radio_button->add_item("No", "disable_hotkeys");
enable_hotkeys_radio_button->add_item(TR("Yes"), "enable_hotkeys");
enable_hotkeys_radio_button->add_item(TR("Yes, but only grab virtual devices (supports some input remapping software)"), "enable_hotkeys_virtual_devices");
enable_hotkeys_radio_button->add_item(TR("Yes, but don't grab devices (supports all input remapping software)"), "enable_hotkeys_no_grab");
enable_hotkeys_radio_button->add_item(TR("No"), "disable_hotkeys");
enable_hotkeys_radio_button->on_selection_changed = [&](const std::string&, const std::string &id) {
if(on_keyboard_hotkey_changed)
on_keyboard_hotkey_changed(id.c_str());
@@ -207,8 +208,8 @@ namespace gsr {
std::unique_ptr<RadioButton> GlobalSettingsPage::create_enable_joystick_hotkeys_button() {
auto enable_hotkeys_radio_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::HORIZONTAL);
enable_joystick_hotkeys_radio_button_ptr = enable_hotkeys_radio_button.get();
enable_hotkeys_radio_button->add_item("Yes", "enable_hotkeys");
enable_hotkeys_radio_button->add_item("No", "disable_hotkeys");
enable_hotkeys_radio_button->add_item(TR("Yes"), "enable_hotkeys");
enable_hotkeys_radio_button->add_item(TR("No"), "disable_hotkeys");
enable_hotkeys_radio_button->on_selection_changed = [&](const std::string&, const std::string &id) {
if(on_joystick_hotkey_changed)
on_joystick_hotkey_changed(id.c_str());
@@ -220,7 +221,7 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_show_hide_hotkey_options() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Show/hide UI:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Show/hide UI:"), get_color_theme().text_color));
auto show_hide_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
show_hide_button_ptr = show_hide_button.get();
list->add_widget(std::move(show_hide_button));
@@ -235,12 +236,12 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_replay_hotkey_options() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Turn replay on/off:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Turn replay on/off:"), get_color_theme().text_color));
auto turn_replay_on_off_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
turn_replay_on_off_button_ptr = turn_replay_on_off_button.get();
list->add_widget(std::move(turn_replay_on_off_button));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Save replay:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Save replay:"), get_color_theme().text_color));
auto save_replay_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
save_replay_button_ptr = save_replay_button.get();
list->add_widget(std::move(save_replay_button));
@@ -259,12 +260,12 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_replay_partial_save_hotkey_options() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Save 1 minute replay:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Save 1 minute replay:"), get_color_theme().text_color));
auto save_replay_1_min_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
save_replay_1_min_button_ptr = save_replay_1_min_button.get();
list->add_widget(std::move(save_replay_1_min_button));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Save 10 minute replay:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Save 10 minute replay:"), get_color_theme().text_color));
auto save_replay_10_min_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
save_replay_10_min_button_ptr = save_replay_10_min_button.get();
list->add_widget(std::move(save_replay_10_min_button));
@@ -283,12 +284,12 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_record_hotkey_options() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Start/stop recording:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Start/stop recording:"), get_color_theme().text_color));
auto start_stop_recording_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
start_stop_recording_button_ptr = start_stop_recording_button.get();
list->add_widget(std::move(start_stop_recording_button));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Pause/unpause recording:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Pause/unpause recording:"), get_color_theme().text_color));
auto pause_unpause_recording_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
pause_unpause_recording_button_ptr = pause_unpause_recording_button.get();
list->add_widget(std::move(pause_unpause_recording_button));
@@ -307,16 +308,16 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_record_hotkey_window_region_options() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Start/stop recording a region:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Start/stop recording a region:"), get_color_theme().text_color));
auto start_stop_recording_region_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
start_stop_recording_region_button_ptr = start_stop_recording_region_button.get();
list->add_widget(std::move(start_stop_recording_region_button));
char str[128];
if(gsr_info->system_info.display_server == DisplayServer::X11)
snprintf(str, sizeof(str), "Start/stop recording a window:");
snprintf(str, sizeof(str), TR("Start/stop recording a window:"));
else
snprintf(str, sizeof(str), "Start/stop recording with desktop portal:");
snprintf(str, sizeof(str), TR("Start/stop recording with desktop portal:"));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, str, get_color_theme().text_color));
auto start_stop_recording_window_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
@@ -337,7 +338,7 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_stream_hotkey_options() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Start/stop streaming:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Start/stop streaming:"), get_color_theme().text_color));
auto start_stop_streaming_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
start_stop_streaming_button_ptr = start_stop_streaming_button.get();
list->add_widget(std::move(start_stop_streaming_button));
@@ -352,7 +353,7 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_screenshot_hotkey_options() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Take a screenshot:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Take a screenshot:"), get_color_theme().text_color));
auto take_screenshot_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
take_screenshot_button_ptr = take_screenshot_button.get();
list->add_widget(std::move(take_screenshot_button));
@@ -367,7 +368,7 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_screenshot_region_hotkey_options() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Take a screenshot of a region:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Take a screenshot of a region:"), get_color_theme().text_color));
auto take_screenshot_region_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
take_screenshot_region_button_ptr = take_screenshot_region_button.get();
list->add_widget(std::move(take_screenshot_region_button));
@@ -384,9 +385,9 @@ namespace gsr {
char str[128];
if(gsr_info->system_info.display_server == DisplayServer::X11)
snprintf(str, sizeof(str), "Take a screenshot of a window:");
snprintf(str, sizeof(str), TR("Take a screenshot of a window:"));
else
snprintf(str, sizeof(str), "Take a screenshot with desktop portal:");
snprintf(str, sizeof(str), TR("Take a screenshot with desktop portal:"));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, str, get_color_theme().text_color));
auto take_screenshot_window_button = std::make_unique<Button>(&get_theme().body_font, "", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
@@ -403,7 +404,7 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_hotkey_control_buttons() {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
auto clear_hotkeys_button = std::make_unique<Button>(&get_theme().body_font, "Clear hotkeys", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto clear_hotkeys_button = std::make_unique<Button>(&get_theme().body_font, TR("Clear hotkeys"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
clear_hotkeys_button->on_click = [this] {
for_each_config_hotkey([&](ConfigHotkey *config_hotkey_item) {
*config_hotkey_item = {mgl::Keyboard::Unknown, 0};
@@ -413,7 +414,7 @@ namespace gsr {
};
list->add_widget(std::move(clear_hotkeys_button));
auto reset_hotkeys_button = std::make_unique<Button>(&get_theme().body_font, "Reset hotkeys to default", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto reset_hotkeys_button = std::make_unique<Button>(&get_theme().body_font, TR("Reset hotkeys to default"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
reset_hotkeys_button->on_click = [this] {
config.set_hotkeys_to_default();
load_hotkeys();
@@ -426,9 +427,9 @@ namespace gsr {
static std::unique_ptr<List> create_joystick_hotkey_text(mgl::Texture *image1, mgl::Texture *image2, float max_height, const char *suffix) {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Press", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Press"), get_color_theme().text_color));
list->add_widget(std::make_unique<Image>(image1, mgl::vec2f{max_height, 1000.0f}, Image::ScaleBehavior::SCALE));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "and", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("and"), get_color_theme().text_color));
list->add_widget(std::make_unique<Image>(image2, mgl::vec2f{max_height, 1000.0f}, Image::ScaleBehavior::SCALE));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, suffix, get_color_theme().text_color));
return list;
@@ -437,9 +438,9 @@ namespace gsr {
std::unique_ptr<Subsection> GlobalSettingsPage::create_keyboard_hotkey_subsection(ScrollablePage *parent_page) {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
List *list_ptr = list.get();
auto subsection = std::make_unique<Subsection>("Keyboard hotkeys", std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
auto subsection = std::make_unique<Subsection>(TR("Keyboard hotkeys"), std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
list_ptr->add_widget(std::make_unique<Label>(&get_theme().body_font, "Enable keyboard hotkeys?", get_color_theme().text_color));
list_ptr->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Enable keyboard hotkeys?"), get_color_theme().text_color));
list_ptr->add_widget(create_enable_keyboard_hotkeys_button());
list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Orientation::HORIZONTAL, subsection->get_inner_size().x));
list_ptr->add_widget(create_show_hide_hotkey_options());
@@ -458,23 +459,23 @@ namespace gsr {
std::unique_ptr<Subsection> GlobalSettingsPage::create_controller_hotkey_subsection(ScrollablePage *parent_page) {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
List *list_ptr = list.get();
auto subsection = std::make_unique<Subsection>("Controller hotkeys", std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
auto subsection = std::make_unique<Subsection>(TR("Controller hotkeys"), std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
list_ptr->add_widget(std::make_unique<Label>(&get_theme().body_font, "Enable controller hotkeys?", get_color_theme().text_color));
list_ptr->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Enable controller hotkeys?"), get_color_theme().text_color));
list_ptr->add_widget(create_enable_joystick_hotkeys_button());
list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Orientation::HORIZONTAL, subsection->get_inner_size().x));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_options_texture, get_theme().body_font.get_character_size(), "to show/hide the UI"));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_dpad_up_texture, get_theme().body_font.get_character_size(), "to take a screenshot"));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_dpad_down_texture, get_theme().body_font.get_character_size(), "to save a replay"));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_dpad_left_texture, get_theme().body_font.get_character_size(), "to start/stop recording"));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_dpad_right_texture, get_theme().body_font.get_character_size(), "to turn replay on/off"));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_cross_texture, get_theme().body_font.get_character_size(), "to save a 1 minute replay"));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_triangle_texture, get_theme().body_font.get_character_size(), "to save a 10 minute replay"));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_options_texture, get_theme().body_font.get_character_size(), TR("to show/hide the UI")));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_dpad_up_texture, get_theme().body_font.get_character_size(), TR("to take a screenshot")));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_dpad_down_texture, get_theme().body_font.get_character_size(), TR("to save a replay")));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_dpad_left_texture, get_theme().body_font.get_character_size(), TR("to start/stop recording")));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_dpad_right_texture, get_theme().body_font.get_character_size(), TR("to turn replay on/off")));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_cross_texture, get_theme().body_font.get_character_size(), TR("to save a 1 minute replay")));
list_ptr->add_widget(create_joystick_hotkey_text(&get_theme().ps4_home_texture, &get_theme().ps4_triangle_texture, get_theme().body_font.get_character_size(), TR("to save a 10 minute replay")));
return subsection;
}
std::unique_ptr<Button> GlobalSettingsPage::create_exit_program_button() {
auto exit_program_button = std::make_unique<Button>(&get_theme().body_font, "Exit program", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto exit_program_button = std::make_unique<Button>(&get_theme().body_font, TR("Exit program"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
exit_program_button->on_click = [&]() {
if(on_click_exit_program_button)
on_click_exit_program_button("exit");
@@ -483,7 +484,7 @@ namespace gsr {
}
std::unique_ptr<Button> GlobalSettingsPage::create_go_back_to_old_ui_button() {
auto exit_program_button = std::make_unique<Button>(&get_theme().body_font, "Go back to the old UI", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto exit_program_button = std::make_unique<Button>(&get_theme().body_font, TR("Go back to the old UI"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
exit_program_button->on_click = [&]() {
if(on_click_exit_program_button)
on_click_exit_program_button("back-to-old-ui");
@@ -493,12 +494,12 @@ namespace gsr {
std::unique_ptr<List> GlobalSettingsPage::create_notification_speed() {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Notification speed", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Notification speed"), get_color_theme().text_color));
auto radio_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::HORIZONTAL);
notification_speed_button_ptr = radio_button.get();
radio_button->add_item("Normal", "normal");
radio_button->add_item("Fast", "fast");
radio_button->add_item(TR("Normal"), "normal");
radio_button->add_item(TR("Fast"), "fast");
radio_button->on_selection_changed = [this](const std::string&, const std::string &id) {
if(id == "normal")
overlay->set_notification_speed(NotificationSpeed::NORMAL);
@@ -514,7 +515,7 @@ namespace gsr {
std::unique_ptr<Subsection> GlobalSettingsPage::create_application_options_subsection(ScrollablePage *parent_page) {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
List *list_ptr = list.get();
auto subsection = std::make_unique<Subsection>("Application options", std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
auto subsection = std::make_unique<Subsection>(TR("Application options"), std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
list_ptr->add_widget(create_notification_speed());
list_ptr->add_widget(std::make_unique<LineSeparator>(LineSeparator::Orientation::HORIZONTAL, subsection->get_inner_size().x));
@@ -535,28 +536,28 @@ namespace gsr {
char str[128];
const std::string gsr_version = gsr_info->system_info.gsr_version.to_string();
snprintf(str, sizeof(str), "GSR version: %s", gsr_version.c_str());
snprintf(str, sizeof(str), TR("GSR version: %s"), gsr_version.c_str());
list->add_widget(std::make_unique<Label>(&get_theme().body_font, str, get_color_theme().text_color));
snprintf(str, sizeof(str), "GSR-UI version: %s", GSR_UI_VERSION);
snprintf(str, sizeof(str), TR("GSR-UI version: %s"), GSR_UI_VERSION);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, str, get_color_theme().text_color));
if(inside_flatpak) {
snprintf(str, sizeof(str), "Flatpak version: %s", GSR_FLATPAK_VERSION);
snprintf(str, sizeof(str), TR("Flatpak version: %s"), GSR_FLATPAK_VERSION);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, str, get_color_theme().text_color));
}
snprintf(str, sizeof(str), "GPU vendor: %s", gpu_vendor_to_string(gsr_info->gpu_info.vendor));
snprintf(str, sizeof(str), TR("GPU vendor: %s"), gpu_vendor_to_string(gsr_info->gpu_info.vendor));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, str, get_color_theme().text_color));
return std::make_unique<Subsection>("Application info", std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Application info"), std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
}
std::unique_ptr<Subsection> GlobalSettingsPage::create_donate_subsection(ScrollablePage *parent_page) {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "If you would like to donate you can do so by donating at https://buymeacoffee.com/dec05eba:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("If you would like to donate you can do so by donating at https://buymeacoffee.com/dec05eba:"), get_color_theme().text_color));
auto donate_button = std::make_unique<Button>(&get_theme().body_font, "Donate", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto donate_button = std::make_unique<Button>(&get_theme().body_font, TR("Donate"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
donate_button->on_click = [this] {
const char *args[] = { "xdg-open", "https://buymeacoffee.com/dec05eba", nullptr };
exec_program_daemonized(args);
@@ -564,8 +565,8 @@ namespace gsr {
};
list->add_widget(std::move(donate_button));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "All donations go toward developing software (including GPU Screen Recorder)\nand buying hardware to test the software.", get_color_theme().text_color));
return std::make_unique<Subsection>("Donate", std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("All donations go toward developing software (including GPU Screen Recorder)\nand buying hardware to test the software."), get_color_theme().text_color));
return std::make_unique<Subsection>(TR("Donate"), std::move(list), mgl::vec2f(parent_page->get_inner_size().x, 0.0f));
}
void GlobalSettingsPage::add_widgets() {
@@ -792,50 +793,50 @@ namespace gsr {
hotkey_configure_action_name = "";
break;
case ConfigureHotkeyType::REPLAY_START_STOP:
hotkey_configure_action_name = "Turn replay on/off";
hotkey_configure_action_name = TR("Turn replay on/off");
break;
case ConfigureHotkeyType::REPLAY_SAVE:
hotkey_configure_action_name = "Save replay";
hotkey_configure_action_name = TR("Save replay");
break;
case ConfigureHotkeyType::REPLAY_SAVE_1_MIN:
hotkey_configure_action_name = "Save 1 minute replay";
hotkey_configure_action_name = TR("Save 1 minute replay");
break;
case ConfigureHotkeyType::REPLAY_SAVE_10_MIN:
hotkey_configure_action_name = "Save 10 minute replay";
hotkey_configure_action_name = TR("Save 10 minute replay");
break;
case ConfigureHotkeyType::RECORD_START_STOP:
hotkey_configure_action_name = "Start/stop recording";
hotkey_configure_action_name = TR("Start/stop recording");
break;
case ConfigureHotkeyType::RECORD_PAUSE_UNPAUSE:
hotkey_configure_action_name = "Pause/unpause recording";
hotkey_configure_action_name = TR("Pause/unpause recording");
break;
case ConfigureHotkeyType::RECORD_START_STOP_REGION:
hotkey_configure_action_name = "Start/stop recording a region";
hotkey_configure_action_name = TR("Start/stop recording a region");
break;
case ConfigureHotkeyType::RECORD_START_STOP_WINDOW:
if(gsr_info->system_info.display_server == DisplayServer::X11)
hotkey_configure_action_name = "Start/stop recording a window";
hotkey_configure_action_name = TR("Start/stop recording a window");
else
hotkey_configure_action_name = "Start/stop recording with desktop portal";
hotkey_configure_action_name = TR("Start/stop recording with desktop portal");
break;
case ConfigureHotkeyType::STREAM_START_STOP:
hotkey_configure_action_name = "Start/stop streaming";
hotkey_configure_action_name = TR("Start/stop streaming");
break;
case ConfigureHotkeyType::TAKE_SCREENSHOT:
hotkey_configure_action_name = "Take a screenshot";
hotkey_configure_action_name = TR("Take a screenshot");
break;
case ConfigureHotkeyType::TAKE_SCREENSHOT_REGION:
hotkey_configure_action_name = "Take a screenshot of a region";
hotkey_configure_action_name = TR("Take a screenshot of a region");
break;
case ConfigureHotkeyType::TAKE_SCREENSHOT_WINDOW: {
if(gsr_info->system_info.display_server == DisplayServer::X11)
hotkey_configure_action_name = "Take a screenshot of a window";
hotkey_configure_action_name = TR("Take a screenshot of a window");
else
hotkey_configure_action_name = "Take a screenshot with desktop portal";
hotkey_configure_action_name = TR("Take a screenshot with desktop portal");
break;
}
case ConfigureHotkeyType::SHOW_HIDE:
hotkey_configure_action_name = "Show/hide UI";
hotkey_configure_action_name = TR("Show/hide UI");
break;
}
}
@@ -866,7 +867,7 @@ namespace gsr {
}
if(hotkey_used_by_another_action) {
const std::string error_msg = "The hotkey \"" + configure_config_hotkey.to_string() + " is already used for something else";
const std::string error_msg = TR("The hotkey \"") + configure_config_hotkey.to_string() + TR("\" is already used for something else");
overlay->show_notification(error_msg.c_str(), 3.0, mgl::Color(255, 0, 0, 255), mgl::Color(255, 0, 0, 255), NotificationType::NONE);
config_hotkey_button->set_text(config_hotkey->to_string());
configure_config_hotkey = {0, 0};

View File

@@ -4,6 +4,7 @@
#include "../../include/Theme.hpp"
#include "../../include/GsrInfo.hpp"
#include "../../include/Utils.hpp"
#include "../../include/Translation.hpp"
#include "../../include/gui/List.hpp"
#include "../../include/gui/ScrollablePage.hpp"
#include "../../include/gui/Label.hpp"
@@ -20,8 +21,8 @@ namespace gsr {
{
capture_options = get_supported_capture_options(*gsr_info);
auto content_page = std::make_unique<GsrPage>("Screenshot", "Settings");
content_page->add_button("Back", "back", get_color_theme().page_bg_color);
auto content_page = std::make_unique<GsrPage>(TR("Screenshot"), TR("Settings"));
content_page->add_button(TR("Back"), "back", get_color_theme().page_bg_color);
content_page->on_click = [page_stack](const std::string &id) {
if(id == "back")
page_stack->pop();
@@ -37,25 +38,25 @@ namespace gsr {
auto record_area_box = std::make_unique<ComboBox>(&get_theme().body_font);
// TODO: Show options not supported but disable them
if(capture_options.window)
record_area_box->add_item("Window", "window");
record_area_box->add_item(TR("Window"), "window");
if(capture_options.region)
record_area_box->add_item("Region", "region");
record_area_box->add_item(TR("Region"), "region");
if(!capture_options.monitors.empty())
record_area_box->add_item("Focused monitor", "focused_monitor");
record_area_box->add_item(TR("Focused monitor"), "focused_monitor");
for(const auto &monitor : capture_options.monitors) {
char name[256];
snprintf(name, sizeof(name), "Monitor %s (%dx%d)", monitor.name.c_str(), monitor.size.x, monitor.size.y);
snprintf(name, sizeof(name), TR("Monitor %s (%dx%d)"), monitor.name.c_str(), monitor.size.x, monitor.size.y);
record_area_box->add_item(name, monitor.name);
}
if(capture_options.portal)
record_area_box->add_item("Desktop portal", "portal");
record_area_box->add_item(TR("Desktop portal"), "portal");
record_area_box_ptr = record_area_box.get();
return record_area_box;
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_record_area() {
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 source:", get_color_theme().text_color));
record_area_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Capture source:"), get_color_theme().text_color));
record_area_list->add_widget(create_record_area_box());
return record_area_list;
}
@@ -84,14 +85,14 @@ namespace gsr {
std::unique_ptr<List> ScreenshotSettingsPage::create_image_resolution_section() {
auto image_resolution_list = std::make_unique<List>(List::Orientation::VERTICAL);
image_resolution_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Image resolution limit:", get_color_theme().text_color));
image_resolution_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Image resolution limit:"), get_color_theme().text_color));
image_resolution_list->add_widget(create_image_resolution());
image_resolution_list_ptr = image_resolution_list.get();
return image_resolution_list;
}
std::unique_ptr<CheckBox> ScreenshotSettingsPage::create_restore_portal_session_checkbox() {
auto restore_portal_session_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Restore portal session");
auto restore_portal_session_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Restore portal session"));
restore_portal_session_checkbox->set_checked(true);
restore_portal_session_checkbox_ptr = restore_portal_session_checkbox.get();
return restore_portal_session_checkbox;
@@ -106,7 +107,7 @@ namespace gsr {
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_change_image_resolution_section() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Change image resolution");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Change image resolution"));
change_image_resolution_checkbox_ptr = checkbox.get();
return checkbox;
}
@@ -121,18 +122,18 @@ namespace gsr {
ll->add_widget(std::move(capture_target_list));
ll->add_widget(create_change_image_resolution_section());
return std::make_unique<Subsection>("Capture", std::move(ll), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Capture"), std::move(ll), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<List> ScreenshotSettingsPage::create_image_quality_section() {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Image quality:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Image quality:"), get_color_theme().text_color));
auto image_quality_box = std::make_unique<ComboBox>(&get_theme().body_font);
image_quality_box->add_item("Medium", "medium");
image_quality_box->add_item("High", "high");
image_quality_box->add_item("Very high (Recommended)", "very_high");
image_quality_box->add_item("Ultra", "ultra");
image_quality_box->add_item(TR("Medium"), "medium");
image_quality_box->add_item(TR("High"), "high");
image_quality_box->add_item(TR("Very high (Recommended)"), "very_high");
image_quality_box->add_item(TR("Ultra"), "ultra");
image_quality_box->set_selected_item("very_high");
image_quality_box_ptr = image_quality_box.get();
@@ -142,7 +143,7 @@ namespace gsr {
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_record_cursor_section() {
auto record_cursor_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Record cursor");
auto record_cursor_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Record cursor"));
record_cursor_checkbox->set_checked(true);
record_cursor_checkbox_ptr = record_cursor_checkbox.get();
return record_cursor_checkbox;
@@ -152,7 +153,7 @@ namespace gsr {
auto image_section_list = std::make_unique<List>(List::Orientation::VERTICAL);
image_section_list->add_widget(create_image_quality_section());
image_section_list->add_widget(create_record_cursor_section());
return std::make_unique<Subsection>("Image", std::move(image_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Image"), std::move(image_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<List> ScreenshotSettingsPage::create_save_directory(const char *label) {
@@ -161,9 +162,9 @@ namespace gsr {
auto save_directory_button = std::make_unique<Button>(&get_theme().body_font, get_pictures_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->on_click = [this]() {
auto select_directory_page = std::make_unique<GsrPage>("File", "Settings");
select_directory_page->add_button("Save", "save", get_color_theme().tint_color);
select_directory_page->add_button("Cancel", "cancel", get_color_theme().page_bg_color);
auto select_directory_page = std::make_unique<GsrPage>(TR("File"), TR("Settings"));
select_directory_page->add_button(TR("Save"), "save", get_color_theme().tint_color);
select_directory_page->add_button(TR("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());
FileChooser *file_chooser_ptr = file_chooser.get();
@@ -196,48 +197,48 @@ namespace gsr {
std::unique_ptr<List> ScreenshotSettingsPage::create_image_format_section() {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Image format:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Image format:"), get_color_theme().text_color));
list->add_widget(create_image_format_box());
return list;
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_file_info_section() {
auto file_info_data_list = std::make_unique<List>(List::Orientation::HORIZONTAL);
file_info_data_list->add_widget(create_save_directory("Directory to save screenshots:"));
file_info_data_list->add_widget(create_save_directory(TR("Directory to save screenshots:")));
file_info_data_list->add_widget(create_image_format_section());
return std::make_unique<Subsection>("File info", std::move(file_info_data_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("File info"), std::move(file_info_data_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<CheckBox> ScreenshotSettingsPage::create_save_screenshot_in_game_folder() {
char text[256];
snprintf(text, sizeof(text), "Save screenshot in a folder based on the focused applications name%s", supports_window_title ? "" : " (X11 applications only)");
snprintf(text, sizeof(text), "%s%s", TR("Save screenshot in a folder based on the focused applications name"), supports_window_title ? "" : " (X11 applications only)");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, text);
save_screenshot_in_game_folder_checkbox_ptr = checkbox.get();
return checkbox;
}
std::unique_ptr<CheckBox> ScreenshotSettingsPage::create_save_screenshot_to_clipboard() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, gsr_info->system_info.display_server == DisplayServer::X11 ? "Save screenshot to clipboard" : "Save screenshot to clipboard (Not supported properly by Wayland)");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, gsr_info->system_info.display_server == DisplayServer::X11 ? TR("Save screenshot to clipboard") : TR("Save screenshot to clipboard (Not supported properly by Wayland)"));
save_screenshot_to_clipboard_checkbox_ptr = checkbox.get();
return checkbox;
}
std::unique_ptr<CheckBox> ScreenshotSettingsPage::create_save_screenshot_to_disk() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Save screenshot to disk");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Save screenshot to disk"));
save_screenshot_to_disk_checkbox_ptr = checkbox.get();
checkbox->set_checked(true);
return checkbox;
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_notifications() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Show screenshot notifications");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("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");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Blink scroll lock led when taking a screenshot"));
checkbox->set_checked(true);
led_indicator_checkbox_ptr = checkbox.get();
return checkbox;
@@ -248,14 +249,14 @@ namespace gsr {
list->add_widget(create_save_screenshot_in_game_folder());
list->add_widget(create_save_screenshot_to_clipboard());
list->add_widget(create_save_screenshot_to_disk());
return std::make_unique<Subsection>("General", std::move(list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("General"), std::move(list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_screenshot_indicator_section() {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(create_notifications());
list->add_widget(create_led_indicator());
return std::make_unique<Subsection>("Screenshot indicator", std::move(list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Screenshot indicator"), std::move(list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<List> ScreenshotSettingsPage::create_custom_script_screenshot_entry() {
@@ -270,13 +271,13 @@ namespace gsr {
std::unique_ptr<List> ScreenshotSettingsPage::create_custom_script_screenshot() {
auto custom_script_screenshot_list = std::make_unique<List>(List::Orientation::VERTICAL);
custom_script_screenshot_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Command to open the screenshot with:", get_color_theme().text_color));
custom_script_screenshot_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Command to open the screenshot with:"), get_color_theme().text_color));
custom_script_screenshot_list->add_widget(create_custom_script_screenshot_entry());
return custom_script_screenshot_list;
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_custom_script_screenshot_section() {
return std::make_unique<Subsection>("Script", create_custom_script_screenshot(), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Script"), create_custom_script_screenshot(), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<Widget> ScreenshotSettingsPage::create_settings() {

View File

@@ -10,6 +10,7 @@
#include "../../include/Theme.hpp"
#include "../../include/GsrInfo.hpp"
#include "../../include/Utils.hpp"
#include "../../include/Translation.hpp"
#include <mglpp/window/Window.hpp>
#include <mglpp/window/Event.hpp>
@@ -29,9 +30,9 @@ namespace gsr {
static const char* settings_page_type_to_title_text(SettingsPage::Type type) {
switch(type) {
case SettingsPage::Type::REPLAY: return "Instant Replay";
case SettingsPage::Type::RECORD: return "Record";
case SettingsPage::Type::STREAM: return "Livestream";
case SettingsPage::Type::REPLAY: return TR("Instant Replay");
case SettingsPage::Type::RECORD: return TR("Record");
case SettingsPage::Type::STREAM: return TR("Livestream");
}
return "";
}
@@ -48,8 +49,8 @@ namespace gsr {
application_audio = get_application_audio();
capture_options = get_supported_capture_options(*gsr_info);
auto content_page = std::make_unique<GsrPage>(settings_page_type_to_title_text(type), "Settings");
content_page->add_button("Back", "back", get_color_theme().page_bg_color);
auto content_page = std::make_unique<GsrPage>(settings_page_type_to_title_text(type), TR("Settings"));
content_page->add_button(TR("Back"), "back", get_color_theme().page_bg_color);
content_page->on_click = [page_stack](const std::string &id) {
if(id == "back")
page_stack->pop();
@@ -64,8 +65,8 @@ namespace gsr {
std::unique_ptr<RadioButton> SettingsPage::create_view_radio_button() {
auto view_radio_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::HORIZONTAL);
view_radio_button->add_item("Simple view", "simple");
view_radio_button->add_item("Advanced view", "advanced");
view_radio_button->add_item(TR("Simple view"), "simple");
view_radio_button->add_item(TR("Advanced view"), "advanced");
view_radio_button->set_horizontal_alignment(Widget::Alignment::CENTER);
view_radio_button_ptr = view_radio_button.get();
return view_radio_button;
@@ -75,27 +76,27 @@ namespace gsr {
auto record_area_box = std::make_unique<ComboBox>(&get_theme().body_font);
// TODO: Show options not supported but disable them
if(capture_options.window)
record_area_box->add_item("Window", "window");
record_area_box->add_item(TR("Window"), "window");
if(capture_options.focused)
record_area_box->add_item("Follow focused window", "focused");
record_area_box->add_item(TR("Follow focused window"), "focused");
if(capture_options.region)
record_area_box->add_item("Region", "region");
record_area_box->add_item(TR("Region"), "region");
if(!capture_options.monitors.empty())
record_area_box->add_item("Focused monitor", "focused_monitor");
record_area_box->add_item(TR("Focused monitor"), "focused_monitor");
for(const auto &monitor : capture_options.monitors) {
char name[256];
snprintf(name, sizeof(name), "Monitor %s (%dx%d)", monitor.name.c_str(), monitor.size.x, monitor.size.y);
snprintf(name, sizeof(name), TR("Monitor %s (%dx%d)"), monitor.name.c_str(), monitor.size.x, monitor.size.y);
record_area_box->add_item(name, monitor.name);
}
if(capture_options.portal)
record_area_box->add_item("Desktop portal", "portal");
record_area_box->add_item(TR("Desktop portal"), "portal");
record_area_box_ptr = record_area_box.get();
return record_area_box;
}
std::unique_ptr<Widget> SettingsPage::create_record_area() {
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 source:", get_color_theme().text_color));
record_area_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Capture source:"), get_color_theme().text_color));
record_area_list->add_widget(create_record_area_box());
return record_area_list;
}
@@ -124,7 +125,7 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_area_size_section() {
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_color_theme().text_color));
area_size_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Area size:"), get_color_theme().text_color));
area_size_list->add_widget(create_area_size());
area_size_list_ptr = area_size_list.get();
return area_size_list;
@@ -154,14 +155,14 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_video_resolution_section() {
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 limit:", get_color_theme().text_color));
video_resolution_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Video resolution limit:"), get_color_theme().text_color));
video_resolution_list->add_widget(create_video_resolution());
video_resolution_list_ptr = video_resolution_list.get();
return video_resolution_list;
}
std::unique_ptr<CheckBox> SettingsPage::create_restore_portal_session_checkbox() {
auto restore_portal_session_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Restore portal session");
auto restore_portal_session_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Restore portal session"));
restore_portal_session_checkbox->set_checked(true);
restore_portal_session_checkbox_ptr = restore_portal_session_checkbox.get();
return restore_portal_session_checkbox;
@@ -176,7 +177,7 @@ namespace gsr {
}
std::unique_ptr<Widget> SettingsPage::create_change_video_resolution_section() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Change video resolution");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Change video resolution"));
change_video_resolution_checkbox_ptr = checkbox.get();
return checkbox;
}
@@ -192,15 +193,15 @@ namespace gsr {
ll->add_widget(std::move(capture_target_list));
ll->add_widget(create_change_video_resolution_section());
return std::make_unique<Subsection>("Capture", std::move(ll), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Capture"), std::move(ll), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<List> SettingsPage::create_webcam_sources() {
auto ll = std::make_unique<List>(List::Orientation::VERTICAL);
ll->add_widget(std::make_unique<Label>(&get_theme().body_font, "Webcam source:", get_color_theme().text_color));
ll->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Webcam source:"), get_color_theme().text_color));
auto combobox = std::make_unique<ComboBox>(&get_theme().body_font);
combobox->add_item("None", "");
combobox->add_item(TR("None"), "");
for(const GsrCamera &camera : capture_options.cameras) {
combobox->add_item(camera.path, camera.path);
}
@@ -222,13 +223,13 @@ namespace gsr {
return;
webcam_body_list_ptr->set_visible(true);
webcam_video_format_box_ptr->add_item("Auto (recommended)", "auto");
webcam_video_format_box_ptr->add_item(TR("Auto (recommended)"), "auto");
if(!it->yuyv_setups.empty())
webcam_video_format_box_ptr->add_item("YUYV", "yuyv");
webcam_video_format_box_ptr->add_item(TR("YUYV"), "yuyv");
if(!it->mjpeg_setups.empty())
webcam_video_format_box_ptr->add_item("Motion-JPEG", "mjpeg");
webcam_video_format_box_ptr->add_item(TR("Motion-JPEG"), "mjpeg");
webcam_video_format_box_ptr->set_selected_item("auto");
webcam_video_format_box_ptr->set_selected_item(get_current_record_options().webcam_video_format);
@@ -253,7 +254,7 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_webcam_video_setups() {
auto ll = std::make_unique<List>(List::Orientation::VERTICAL);
ll->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video setup:", get_color_theme().text_color));
ll->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Video setup:"), get_color_theme().text_color));
auto combobox = std::make_unique<ComboBox>(&get_theme().body_font);
webcam_video_setup_box_ptr = combobox.get();
@@ -274,7 +275,7 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_webcam_video_format() {
auto ll = std::make_unique<List>(List::Orientation::VERTICAL);
ll->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video format:", get_color_theme().text_color));
ll->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Video format:"), get_color_theme().text_color));
auto combobox = std::make_unique<ComboBox>(&get_theme().body_font);
webcam_video_format_box_ptr = combobox.get();
@@ -382,7 +383,7 @@ namespace gsr {
{
draw_rectangle_outline(window, pos, size, mgl::Color(255, 0, 0, 255), screen_border);
mgl::Text screen_text("Screen", get_theme().camera_setup_font);
mgl::Text screen_text(TR("Screen"), get_theme().camera_setup_font);
screen_text.set_position((pos + size * 0.5f - screen_text.get_bounds().size * 0.5f).floor());
window.draw(screen_text);
}
@@ -397,7 +398,7 @@ namespace gsr {
// resize_area.set_color(mgl::Color(0, 0, 255, 255));
// window.draw(resize_area);
mgl::Text webcam_text("Webcam", get_theme().camera_setup_font);
mgl::Text webcam_text(TR("Webcam"), get_theme().camera_setup_font);
webcam_text.set_position((webcam_box_drawn_pos + webcam_box_drawn_size * 0.5f - webcam_text.get_bounds().size * 0.5f).floor());
window.draw(webcam_text);
}
@@ -457,7 +458,7 @@ namespace gsr {
}
std::unique_ptr<CheckBox> SettingsPage::create_flip_camera_checkbox() {
auto flip_camera_horizontally_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Flip camera horizontally");
auto flip_camera_horizontally_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Flip camera horizontally"));
flip_camera_horizontally_checkbox_ptr = flip_camera_horizontally_checkbox.get();
return flip_camera_horizontally_checkbox;
}
@@ -467,7 +468,7 @@ namespace gsr {
webcam_body_list_ptr = body_list.get();
body_list->set_visible(false);
body_list->add_widget(create_webcam_location_widget());
body_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "* Right click in the bottom right corner to resize the webcam", get_color_theme().text_color));
body_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("* Right click in the bottom right corner to resize the webcam"), get_color_theme().text_color));
body_list->add_widget(create_flip_camera_checkbox());
body_list->add_widget(create_webcam_video_setup_list());
return body_list;
@@ -477,7 +478,7 @@ namespace gsr {
auto ll = std::make_unique<List>(List::Orientation::VERTICAL);
ll->add_widget(create_webcam_sources());
ll->add_widget(create_webcam_body());
return std::make_unique<Subsection>("Webcam", std::move(ll), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Webcam"), std::move(ll), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
static bool audio_device_is_output(const std::string &audio_device_id) {
@@ -534,14 +535,14 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_audio_device(AudioDeviceType device_type, List *audio_input_list_ptr) {
auto audio_device_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
audio_device_list->userdata = (void*)(uintptr_t)AudioTrackType::DEVICE;
audio_device_list->add_widget(std::make_unique<Label>(&get_theme().body_font, device_type == AudioDeviceType::OUTPUT ? "Output device:" : "Input device: ", get_color_theme().text_color));
audio_device_list->add_widget(std::make_unique<Label>(&get_theme().body_font, device_type == AudioDeviceType::OUTPUT ? TR("Output device:") : TR("Input device: "), get_color_theme().text_color));
audio_device_list->add_widget(create_audio_device_selection_combobox(device_type));
audio_device_list->add_widget(create_remove_audio_device_button(audio_input_list_ptr, audio_device_list.get()));
return audio_device_list;
}
std::unique_ptr<Button> SettingsPage::create_add_audio_track_button() {
auto button = std::make_unique<Button>(&get_theme().body_font, "Add audio track", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto button = std::make_unique<Button>(&get_theme().body_font, TR("Add audio track"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
button->on_click = [this]() {
audio_track_section_list_ptr->add_widget(create_audio_track_section(audio_section_ptr));
};
@@ -566,7 +567,7 @@ namespace gsr {
switch(audio_track_type) {
case AudioTrackType::DEVICE: {
Label *label = dynamic_cast<Label*>(audio_track_line->get_child_widget_by_index(0));
const bool is_output_device = starts_with(label->get_text().c_str(), "Output device");
const bool is_output_device = starts_with(label->get_text().c_str(), TR("Output device"));
if(is_output_device)
num_output_devices++;
break;
@@ -586,7 +587,7 @@ namespace gsr {
}
std::unique_ptr<Button> SettingsPage::create_add_audio_output_device_button(List *audio_input_list_ptr) {
auto button = std::make_unique<Button>(&get_theme().body_font, "Add output device", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto button = std::make_unique<Button>(&get_theme().body_font, TR("Add output device"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
button->on_click = [this, audio_input_list_ptr]() {
audio_devices = get_audio_devices();
audio_input_list_ptr->add_widget(create_audio_device(AudioDeviceType::OUTPUT, audio_input_list_ptr));
@@ -596,7 +597,7 @@ namespace gsr {
}
std::unique_ptr<Button> SettingsPage::create_add_audio_input_device_button(List *audio_input_list_ptr) {
auto button = std::make_unique<Button>(&get_theme().body_font, "Add input device", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto button = std::make_unique<Button>(&get_theme().body_font, TR("Add input device"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
button->on_click = [this, audio_input_list_ptr]() {
audio_devices = get_audio_devices();
audio_input_list_ptr->add_widget(create_audio_device(AudioDeviceType::INPUT, audio_input_list_ptr));
@@ -610,7 +611,7 @@ namespace gsr {
for(const auto &app_audio : application_audio) {
audio_device_box->add_item(app_audio, app_audio);
}
audio_device_box->add_item("Custom...", custom_app_audio_tag);
audio_device_box->add_item(TR("Custom..."), custom_app_audio_tag);
audio_device_box->on_selection_changed = [application_audio_row, audio_device_box_ptr](const std::string&, const std::string &id) {
if(id == custom_app_audio_tag) {
@@ -626,7 +627,7 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_application_audio(List *audio_input_list_ptr) {
auto application_audio_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
application_audio_list->userdata = (void*)(uintptr_t)AudioTrackType::APPLICATION;
application_audio_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Application: ", get_color_theme().text_color));
application_audio_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Application: "), get_color_theme().text_color));
application_audio_list->add_widget(create_application_audio_selection_combobox(application_audio_list.get()));
application_audio_list->add_widget(create_remove_audio_device_button(audio_input_list_ptr, application_audio_list.get()));
return application_audio_list;
@@ -635,14 +636,14 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_custom_application_audio(List *audio_input_list_ptr) {
auto application_audio_list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
application_audio_list->userdata = (void*)(uintptr_t)AudioTrackType::APPLICATION_CUSTOM;
application_audio_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Application: ", get_color_theme().text_color));
application_audio_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Application: "), get_color_theme().text_color));
application_audio_list->add_widget(std::make_unique<Entry>(&get_theme().body_font, "", (int)(get_theme().body_font.get_character_size() * 10.0f)));
application_audio_list->add_widget(create_remove_audio_device_button(audio_input_list_ptr, application_audio_list.get()));
return application_audio_list;
}
std::unique_ptr<Button> SettingsPage::create_add_application_audio_button(List *audio_input_list_ptr) {
auto add_audio_track_button = std::make_unique<Button>(&get_theme().body_font, "Add application audio", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
auto add_audio_track_button = std::make_unique<Button>(&get_theme().body_font, TR("Add application audio"), mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
add_audio_track_button->on_click = [this, audio_input_list_ptr]() {
application_audio = get_application_audio();
if(application_audio.empty())
@@ -670,7 +671,7 @@ namespace gsr {
}
std::unique_ptr<CheckBox> SettingsPage::create_application_audio_invert_checkbox() {
auto application_audio_invert_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Record audio from all applications except the selected ones");
auto application_audio_invert_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Record audio from all applications except the selected ones"));
application_audio_invert_checkbox->set_checked(false);
application_audio_invert_checkbox->on_changed = [this](bool) {
update_application_audio_warning_visibility();
@@ -685,7 +686,7 @@ namespace gsr {
const int font_character_size = get_theme().body_font.get_character_size();
list->add_widget(std::make_unique<Image>(&get_theme().warning_texture, mgl::vec2f(font_character_size, font_character_size), Image::ScaleBehavior::SCALE));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Recording output devices and application audio may record all output audio, which is likely\nnot what you want to do. Remove the output devices.", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Recording output devices and application audio may record all output audio, which is likely\nnot what you want to do. Remove the output devices."), get_color_theme().text_color));
return list;
}
@@ -694,7 +695,7 @@ namespace gsr {
int index = 0;
audio_track_section_list_ptr->for_each_child_widget([&index](std::unique_ptr<Widget> &widget) {
char audio_track_name[32];
snprintf(audio_track_name, sizeof(audio_track_name), "Audio track #%d", 1 + index);
snprintf(audio_track_name, sizeof(audio_track_name), TR("Audio track #%d"), 1 + index);
++index;
Subsection *subsection = dynamic_cast<Subsection*>(widget.get());
@@ -723,7 +724,7 @@ namespace gsr {
std::unique_ptr<Subsection> SettingsPage::create_audio_track_section(Widget *parent_widget) {
char audio_track_name[32];
snprintf(audio_track_name, sizeof(audio_track_name), "Audio track #%d", 1 + (int)audio_track_section_list_ptr->get_num_children());
snprintf(audio_track_name, sizeof(audio_track_name), TR("Audio track #%d"), 1 + (int)audio_track_section_list_ptr->get_num_children());
auto audio_input_section = create_audio_input_section();
List *audio_input_section_ptr = audio_input_section.get();
@@ -753,7 +754,7 @@ namespace gsr {
auto audio_device_section_list = std::make_unique<List>(List::Orientation::VERTICAL);
List *audio_device_section_list_ptr = audio_device_section_list.get();
auto subsection = std::make_unique<Subsection>("Audio", std::move(audio_device_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
auto subsection = std::make_unique<Subsection>(TR("Audio"), std::move(audio_device_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
audio_section_ptr = subsection.get();
audio_device_section_list_ptr->add_widget(create_add_audio_track_button());
audio_device_section_list_ptr->add_widget(create_audio_track_section_list());
@@ -763,20 +764,20 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_video_quality_box() {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Video quality:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Video quality:"), get_color_theme().text_color));
auto video_quality_box = std::make_unique<ComboBox>(&get_theme().body_font);
if(type == Type::REPLAY || type == Type::STREAM)
video_quality_box->add_item("Constant bitrate (Recommended)", "custom");
video_quality_box->add_item(TR("Constant bitrate (Recommended)"), "custom");
else
video_quality_box->add_item("Constant bitrate", "custom");
video_quality_box->add_item("Medium", "medium");
video_quality_box->add_item("High", "high");
video_quality_box->add_item(TR("Constant bitrate"), "custom");
video_quality_box->add_item(TR("Medium"), "medium");
video_quality_box->add_item(TR("High"), "high");
if(type == Type::REPLAY || type == Type::STREAM)
video_quality_box->add_item("Very high", "very_high");
video_quality_box->add_item(TR("Very high"), "very_high");
else
video_quality_box->add_item("Very high (Recommended)", "very_high");
video_quality_box->add_item("Ultra", "ultra");
video_quality_box->add_item(TR("Very high (Recommended)"), "very_high");
video_quality_box->add_item(TR("Ultra"), "ultra");
if(type == Type::REPLAY || type == Type::STREAM)
video_quality_box->set_selected_item("custom");
@@ -814,7 +815,7 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_video_bitrate() {
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_color_theme().text_color));
video_bitrate_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Video bitrate (Kbps):"), get_color_theme().text_color));
video_bitrate_list->add_widget(create_video_bitrate_entry());
video_bitrate_list_ptr = video_bitrate_list.get();
return video_bitrate_list;
@@ -822,15 +823,15 @@ namespace gsr {
std::unique_ptr<ComboBox> SettingsPage::create_color_range_box() {
auto color_range_box = std::make_unique<ComboBox>(&get_theme().body_font);
color_range_box->add_item("Limited", "limited");
color_range_box->add_item("Full", "full");
color_range_box->add_item(TR("Limited"), "limited");
color_range_box->add_item(TR("Full"), "full");
color_range_box_ptr = color_range_box.get();
return color_range_box;
}
std::unique_ptr<List> SettingsPage::create_color_range() {
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_color_theme().text_color));
color_range_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Color range:"), get_color_theme().text_color));
color_range_list->add_widget(create_color_range_box());
color_range_list_ptr = color_range_list.get();
return color_range_list;
@@ -849,34 +850,34 @@ namespace gsr {
// TODO: Show options not supported but disable them.
// TODO: Show error if no encoders are supported.
// TODO: Show warning (once) if only software encoder is available.
video_codec_box->add_item("Auto (Recommended)", "auto");
video_codec_box->add_item(TR("Auto (Recommended)"), "auto");
if(gsr_info->supported_video_codecs.h264)
video_codec_box->add_item("H264", "h264");
video_codec_box->add_item(TR("H264"), "h264");
if(gsr_info->supported_video_codecs.hevc)
video_codec_box->add_item("HEVC", "hevc");
video_codec_box->add_item(TR("HEVC"), "hevc");
if(gsr_info->supported_video_codecs.hevc_10bit)
video_codec_box->add_item("HEVC (10 bit, reduces banding)", "hevc_10bit");
video_codec_box->add_item(TR("HEVC (10 bit, reduces banding)"), "hevc_10bit");
if(gsr_info->supported_video_codecs.hevc_hdr)
video_codec_box->add_item("HEVC (HDR)", "hevc_hdr");
video_codec_box->add_item(TR("HEVC (HDR)"), "hevc_hdr");
if(gsr_info->supported_video_codecs.av1)
video_codec_box->add_item("AV1", "av1");
video_codec_box->add_item(TR("AV1"), "av1");
if(gsr_info->supported_video_codecs.av1_10bit)
video_codec_box->add_item("AV1 (10 bit, reduces banding)", "av1_10bit");
video_codec_box->add_item(TR("AV1 (10 bit, reduces banding)"), "av1_10bit");
if(gsr_info->supported_video_codecs.av1_hdr)
video_codec_box->add_item("AV1 (HDR)", "av1_hdr");
video_codec_box->add_item(TR("AV1 (HDR)"), "av1_hdr");
if(gsr_info->supported_video_codecs.vp8)
video_codec_box->add_item("VP8", "vp8");
video_codec_box->add_item(TR("VP8"), "vp8");
if(gsr_info->supported_video_codecs.vp9)
video_codec_box->add_item("VP9", "vp9");
video_codec_box->add_item(TR("VP9"), "vp9");
if(gsr_info->supported_video_codecs.h264_software)
video_codec_box->add_item("H264 Software Encoder (Slow, not recommended)", "h264_software");
video_codec_box->add_item(TR("H264 Software Encoder (Slow, not recommended)"), "h264_software");
video_codec_box_ptr = video_codec_box.get();
return video_codec_box;
}
std::unique_ptr<List> SettingsPage::create_video_codec() {
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_color_theme().text_color));
video_codec_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Video codec:"), get_color_theme().text_color));
video_codec_list->add_widget(create_video_codec_box());
video_codec_ptr = video_codec_list.get();
return video_codec_list;
@@ -884,15 +885,15 @@ namespace gsr {
std::unique_ptr<ComboBox> SettingsPage::create_audio_codec_box() {
auto audio_codec_box = std::make_unique<ComboBox>(&get_theme().body_font);
audio_codec_box->add_item("Opus (Recommended)", "opus");
audio_codec_box->add_item("AAC", "aac");
audio_codec_box->add_item(TR("Opus (Recommended)"), "opus");
audio_codec_box->add_item(TR("AAC"), "aac");
audio_codec_box_ptr = audio_codec_box.get();
return audio_codec_box;
}
std::unique_ptr<List> SettingsPage::create_audio_codec() {
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_color_theme().text_color));
audio_codec_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Audio codec:"), get_color_theme().text_color));
audio_codec_list->add_widget(create_audio_codec_box());
audio_codec_ptr = audio_codec_list.get();
return audio_codec_list;
@@ -907,27 +908,27 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_framerate() {
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_color_theme().text_color));
framerate_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Frame rate:"), get_color_theme().text_color));
framerate_list->add_widget(create_framerate_entry());
return framerate_list;
}
std::unique_ptr<ComboBox> SettingsPage::create_framerate_mode_box() {
auto framerate_mode_box = std::make_unique<ComboBox>(&get_theme().body_font);
framerate_mode_box->add_item("Auto (Recommended)", "auto");
framerate_mode_box->add_item("Constant", "cfr");
framerate_mode_box->add_item("Variable", "vfr");
framerate_mode_box->add_item(TR("Auto (Recommended)"), "auto");
framerate_mode_box->add_item(TR("Constant"), "cfr");
framerate_mode_box->add_item(TR("Variable"), "vfr");
if(gsr_info->system_info.display_server == DisplayServer::X11)
framerate_mode_box->add_item("Sync to content", "content");
framerate_mode_box->add_item(TR("Sync to content"), "content");
else
framerate_mode_box->add_item("Sync to content (Only X11 or desktop portal capture)", "content");
framerate_mode_box->add_item(TR("Sync to content (Only X11 or desktop portal capture)"), "content");
framerate_mode_box_ptr = framerate_mode_box.get();
return framerate_mode_box;
}
std::unique_ptr<List> SettingsPage::create_framerate_mode() {
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_color_theme().text_color));
framerate_mode_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Frame rate mode:"), get_color_theme().text_color));
framerate_mode_list->add_widget(create_framerate_mode_box());
framerate_mode_list_ptr = framerate_mode_list.get();
return framerate_mode_list;
@@ -941,7 +942,7 @@ namespace gsr {
}
std::unique_ptr<Widget> SettingsPage::create_record_cursor_section() {
auto record_cursor_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Record cursor");
auto record_cursor_checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Record cursor"));
record_cursor_checkbox->set_checked(true);
record_cursor_checkbox_ptr = record_cursor_checkbox.get();
return record_cursor_checkbox;
@@ -953,7 +954,7 @@ namespace gsr {
video_section_list->add_widget(create_video_codec());
video_section_list->add_widget(create_framerate_section());
video_section_list->add_widget(create_record_cursor_section());
return std::make_unique<Subsection>("Video", std::move(video_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
return std::make_unique<Subsection>(TR("Video"), std::move(video_section_list), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f));
}
std::unique_ptr<Widget> SettingsPage::create_settings() {
@@ -1034,10 +1035,10 @@ namespace gsr {
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->on_click = [this]() {
auto select_directory_page = std::make_unique<GsrPage>("File", "Settings");
select_directory_page->add_button("Save", "save", get_color_theme().tint_color);
select_directory_page->add_button("Cancel", "cancel", get_color_theme().page_bg_color);
auto select_directory_page = std::make_unique<GsrPage>(TR("File"), "Settings");
select_directory_page->add_button(TR("Save"), "save", get_color_theme().tint_color);
select_directory_page->add_button(TR("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());
FileChooser *file_chooser_ptr = file_chooser.get();
select_directory_page->add_widget(std::move(file_chooser));
@@ -1069,7 +1070,7 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_container_section() {
auto container_list = std::make_unique<List>(List::Orientation::VERTICAL);
container_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Container:", get_color_theme().text_color));
container_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Container:"), get_color_theme().text_color));
container_list->add_widget(create_container_box());
return container_list;
}
@@ -1091,18 +1092,18 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_replay_time() {
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 duration in seconds:", get_color_theme().text_color));
replay_time_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Replay duration in seconds:"), get_color_theme().text_color));
replay_time_list->add_widget(create_replay_time_entry());
return replay_time_list;
}
std::unique_ptr<List> SettingsPage::create_replay_storage() {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Where should temporary replay data be stored?", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Where should temporary replay data be stored?"), get_color_theme().text_color));
auto replay_storage_button = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::HORIZONTAL);
replay_storage_button_ptr = replay_storage_button.get();
replay_storage_button->add_item("RAM", "ram");
replay_storage_button->add_item("Disk (Not recommended on SSDs)", "disk");
replay_storage_button->add_item(TR("RAM"), "ram");
replay_storage_button->add_item(TR("Disk (Not recommended on SSDs)"), "disk");
replay_storage_button->on_selection_changed = [this](const std::string&, const std::string &id) {
update_estimated_replay_file_size(id);
@@ -1117,33 +1118,33 @@ namespace gsr {
std::unique_ptr<RadioButton> SettingsPage::create_start_replay_automatically() {
// TODO: Support kde plasma wayland and hyprland (same ones that support getting window title)
char fullscreen_text[256];
snprintf(fullscreen_text, sizeof(fullscreen_text), "Turn on replay when starting a fullscreen application%s", gsr_info->system_info.display_server == DisplayServer::X11 ? "" : " (X11 applications only)");
snprintf(fullscreen_text, sizeof(fullscreen_text), TR("Turn on replay when starting a fullscreen application%s"), gsr_info->system_info.display_server == DisplayServer::X11 ? "" : " (X11 applications only)");
auto radiobutton = std::make_unique<RadioButton>(&get_theme().body_font, RadioButton::Orientation::VERTICAL);
radiobutton->add_item("Don't turn on replay automatically", "dont_turn_on_automatically");
radiobutton->add_item("Turn on replay when this program starts", "turn_on_at_system_startup");
radiobutton->add_item(TR("Don't turn on replay automatically"), "dont_turn_on_automatically");
radiobutton->add_item(TR("Turn on replay when this program starts"), "turn_on_at_system_startup");
radiobutton->add_item(fullscreen_text, "turn_on_at_fullscreen");
radiobutton->add_item("Turn on replay when power supply is connected", "turn_on_at_power_supply_connected");
radiobutton->add_item(TR("Turn on replay when power supply is connected"), "turn_on_at_power_supply_connected");
turn_on_replay_automatically_mode_ptr = radiobutton.get();
return radiobutton;
}
std::unique_ptr<CheckBox> SettingsPage::create_save_replay_in_game_folder() {
char text[256];
snprintf(text, sizeof(text), "Save video in a folder based on the focused applications name%s", supports_window_title ? "" : " (X11 applications only)");
snprintf(text, sizeof(text), TR("Save video in a folder based on the focused applications name%s"), supports_window_title ? "" : " (X11 applications only)");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, text);
save_replay_in_game_folder_ptr = checkbox.get();
return checkbox;
}
std::unique_ptr<CheckBox> SettingsPage::create_restart_replay_on_save() {
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Restart replay on save");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Restart replay on save"));
restart_replay_on_save = checkbox.get();
return checkbox;
}
std::unique_ptr<Label> SettingsPage::create_estimated_replay_file_size() {
auto label = std::make_unique<Label>(&get_theme().body_font, "Estimated video max file size in RAM: 57.60MB", get_color_theme().text_color);
auto label = std::make_unique<Label>(&get_theme().body_font, TR("Estimated video max file size in RAM: 57.60MB"), get_color_theme().text_color);
estimated_file_size_ptr = label.get();
return label;
}
@@ -1154,7 +1155,7 @@ namespace gsr {
const double video_filesize_mb = ((double)replay_time_seconds * (double)video_bitrate_bps) / 1000.0 / 1000.0 * 1.024;
char buffer[256];
snprintf(buffer, sizeof(buffer), "Estimated video max file size %s: %.2fMB.\nChange video bitrate or replay duration to change file size.", replay_storage_type == "ram" ? "in RAM" : "on disk", video_filesize_mb);
snprintf(buffer, sizeof(buffer), TR("Estimated video max file size %s: %.2fMB.\nChange video bitrate or replay duration to change file size."), replay_storage_type == "ram" ? TR("in RAM") : TR("on disk"), video_filesize_mb);
estimated_file_size_ptr->set_text(buffer);
}
@@ -1193,7 +1194,7 @@ namespace gsr {
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);
snprintf(label_str, sizeof(label_str), TR("Show %s status with scroll lock led"), type);
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, label_str);
checkbox->set_checked(false);
@@ -1203,7 +1204,7 @@ namespace gsr {
std::unique_ptr<CheckBox> SettingsPage::create_notifications(const char *type) {
char label_str[256];
snprintf(label_str, sizeof(label_str), "Show %s notifications", type);
snprintf(label_str, sizeof(label_str), TR("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();
@@ -1221,16 +1222,16 @@ namespace gsr {
auto list = std::make_unique<List>(List::Orientation::HORIZONTAL, List::Alignment::CENTER);
list->set_visible(gsr_info->gpu_info.vendor == GpuVendor::AMD);
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, "Record in low-power mode");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, TR("Record in low-power mode"));
low_power_mode_checkbox_ptr = checkbox.get();
list->add_widget(std::move(checkbox));
auto info = std::make_unique<Image>(&get_theme().question_mark_texture, low_power_mode_checkbox_ptr->get_size(), Image::ScaleBehavior::SCALE);
info->set_tooltip_text(
"Do not force the GPU to go into high performance mode when recording.\n"
"May affect recording performance, especially when playing a video at the same time.\n"
"If enabled then it's recommended to use sync to content frame rate mode to reduce power usage when idle."
TR("Do not force the GPU to go into high performance mode when recording.\n"
"May affect recording performance, especially when playing a video at the same time.\n"
"If enabled then it's recommended to use sync to content frame rate mode to reduce power usage when idle.")
);
Image *info_ptr = info.get();
info->on_mouse_move = [info_ptr](bool inside) {
@@ -1247,12 +1248,12 @@ namespace gsr {
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);
file_info_data_list->add_widget(create_save_directory("Directory to save replays:"));
file_info_data_list->add_widget(create_save_directory(TR("Directory to save replays:")));
file_info_data_list->add_widget(create_container_section());
file_info_data_list->add_widget(create_replay_time());
file_info_list->add_widget(std::move(file_info_data_list));
file_info_list->add_widget(create_estimated_replay_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>(TR("File info"), std::move(file_info_list), 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_replay_storage());
@@ -1261,15 +1262,15 @@ namespace gsr {
general_list->add_widget(create_restart_replay_on_save());
general_list->add_widget(create_low_power_mode());
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>("Replay indicator", create_indicator("replay"), 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)));
settings_list_ptr->add_widget(std::make_unique<Subsection>(TR("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>(TR("Replay indicator"), create_indicator("replay"), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
settings_list_ptr->add_widget(std::make_unique<Subsection>(TR("Autostart"), create_start_replay_automatically(), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
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");
view_radio_button_ptr->on_selection_changed(TR("Simple"), "simple");
replay_time_entry_ptr->on_changed = [this](const std::string&) {
update_estimated_replay_file_size(replay_storage_button_ptr->get_selected_id());
@@ -1283,14 +1284,14 @@ namespace gsr {
std::unique_ptr<CheckBox> SettingsPage::create_save_recording_in_game_folder() {
char text[256];
snprintf(text, sizeof(text), "Save video in a folder based on the focused applications name%s", supports_window_title ? "" : " (X11 applications only)");
snprintf(text, sizeof(text), TR("Save video in a folder based on the focused applications name%s"), supports_window_title ? "" : " (X11 applications only)");
auto checkbox = std::make_unique<CheckBox>(&get_theme().body_font, text);
save_recording_in_game_folder_ptr = checkbox.get();
return checkbox;
}
std::unique_ptr<Label> SettingsPage::create_estimated_record_file_size() {
auto label = std::make_unique<Label>(&get_theme().body_font, "Estimated video file size per minute (excluding audio): 345.60MB", get_color_theme().text_color);
auto label = std::make_unique<Label>(&get_theme().body_font, TR("Estimated video file size per minute (excluding audio): 345.60MB"), get_color_theme().text_color);
estimated_file_size_ptr = label.get();
return label;
}
@@ -1300,32 +1301,32 @@ namespace gsr {
const double video_filesize_mb_per_minute = (60.0 * (double)video_bitrate_bps) / 1000.0 / 1000.0 * 1.024;
char buffer[512];
snprintf(buffer, sizeof(buffer), "Estimated video file size per minute (excluding audio): %.2fMB", video_filesize_mb_per_minute);
snprintf(buffer, sizeof(buffer), TR("Estimated video file size per minute (excluding audio): %.2fMB"), video_filesize_mb_per_minute);
estimated_file_size_ptr->set_text(buffer);
}
void SettingsPage::add_record_widgets() {
auto file_info_list = std::make_unique<List>(List::Orientation::VERTICAL);
auto file_info_data_list = std::make_unique<List>(List::Orientation::HORIZONTAL);
file_info_data_list->add_widget(create_save_directory("Directory to save videos:"));
file_info_data_list->add_widget(create_save_directory(TR("Directory to save videos:")));
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>(TR("File info"), std::move(file_info_list), 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_low_power_mode());
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>("Recording indicator", create_indicator("recording"), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
settings_list_ptr->add_widget(std::make_unique<Subsection>(TR("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>(TR("Recording indicator"), create_indicator("recording"), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
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");
view_radio_button_ptr->on_selection_changed(TR("Simple"), "simple");
video_bitrate_entry_ptr->on_changed = [this](const std::string&) {
update_estimated_record_file_size();
@@ -1334,18 +1335,18 @@ namespace gsr {
std::unique_ptr<ComboBox> SettingsPage::create_streaming_service_box() {
auto streaming_service_box = std::make_unique<ComboBox>(&get_theme().body_font);
streaming_service_box->add_item("Twitch", "twitch");
streaming_service_box->add_item("YouTube", "youtube");
streaming_service_box->add_item("Rumble", "rumble");
streaming_service_box->add_item("Kick", "kick");
streaming_service_box->add_item("Custom", "custom");
streaming_service_box->add_item(TR("Twitch"), "twitch");
streaming_service_box->add_item(TR("YouTube"), "youtube");
streaming_service_box->add_item(TR("Rumble"), "rumble");
streaming_service_box->add_item(TR("Kick"), "kick");
streaming_service_box->add_item(TR("Custom"), "custom");
streaming_service_box_ptr = streaming_service_box.get();
return streaming_service_box;
}
std::unique_ptr<List> SettingsPage::create_streaming_service_section() {
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_color_theme().text_color));
streaming_service_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Stream service:"), get_color_theme().text_color));
streaming_service_list->add_widget(create_streaming_service_box());
return streaming_service_list;
}
@@ -1376,7 +1377,7 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_stream_key_section() {
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_color_theme().text_color));
stream_key_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Stream key:"), get_color_theme().text_color));
twitch_stream_key_entry_ptr = add_stream_key_entry_to_list(stream_key_list.get());
youtube_stream_key_entry_ptr = add_stream_key_entry_to_list(stream_key_list.get());
@@ -1392,7 +1393,7 @@ namespace gsr {
auto list = std::make_unique<List>(List::Orientation::VERTICAL);
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();
list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Stream URL:", get_color_theme().text_color));
list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Stream URL:"), get_color_theme().text_color));
list->add_widget(std::move(stream_url_entry));
return list;
}
@@ -1416,7 +1417,7 @@ namespace gsr {
stream_url_list->add_widget(create_stream_container());
custom_stream_list->add_widget(std::move(stream_url_list));
custom_stream_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Stream key:", get_color_theme().text_color));
custom_stream_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Stream key:"), get_color_theme().text_color));
custom_stream_list->add_widget(create_stream_custom_key());
custom_stream_list_ptr = custom_stream_list.get();
@@ -1435,7 +1436,7 @@ namespace gsr {
std::unique_ptr<List> SettingsPage::create_stream_container() {
auto container_list = std::make_unique<List>(List::Orientation::VERTICAL);
container_list->add_widget(std::make_unique<Label>(&get_theme().body_font, "Container:", get_color_theme().text_color));
container_list->add_widget(std::make_unique<Label>(&get_theme().body_font, TR("Container:"), get_color_theme().text_color));
container_list->add_widget(create_stream_container_box());
return container_list;
}
@@ -1446,13 +1447,13 @@ namespace gsr {
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)));
settings_list_ptr->add_widget(std::make_unique<Subsection>(TR("Streaming info"), std::move(streaming_info_list), 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_low_power_mode());
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>("Streaming indicator", create_indicator("streaming"), mgl::vec2f(settings_scrollable_page_ptr->get_inner_size().x, 0.0f)));
settings_list_ptr->add_widget(std::make_unique<Subsection>(TR("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>(TR("Streaming indicator"), create_indicator("streaming"), 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";
@@ -1475,7 +1476,7 @@ namespace gsr {
view_changed(id == "advanced");
return true;
};
view_radio_button_ptr->on_selection_changed("Simple", "simple");
view_radio_button_ptr->on_selection_changed(TR("Simple"), "simple");
}
void SettingsPage::on_navigate_away_from_page() {