mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-03-31 09:17:04 +09:00
Start on file chooser, page stack
This commit is contained in:
@@ -12,6 +12,13 @@
|
||||
#define CONFIG_FILE_VERSION 1
|
||||
|
||||
namespace gsr {
|
||||
static std::optional<KeyValue> parse_key_value(std::string_view line) {
|
||||
const size_t space_index = line.find(' ');
|
||||
if(space_index == std::string_view::npos)
|
||||
return std::nullopt;
|
||||
return KeyValue{line.substr(0, space_index), line.substr(space_index + 1)};
|
||||
}
|
||||
|
||||
using ConfigValue = std::variant<bool*, std::string*, int32_t*, ConfigHotkey*, std::vector<std::string>*>;
|
||||
|
||||
static std::map<std::string_view, ConfigValue> get_config_options(Config &config) {
|
||||
|
||||
@@ -4,6 +4,13 @@
|
||||
#include <string.h>
|
||||
|
||||
namespace gsr {
|
||||
static std::optional<KeyValue> parse_key_value(std::string_view line) {
|
||||
const size_t space_index = line.find('|');
|
||||
if(space_index == std::string_view::npos)
|
||||
return std::nullopt;
|
||||
return KeyValue{line.substr(0, space_index), line.substr(space_index + 1)};
|
||||
}
|
||||
|
||||
static void parse_system_info_line(GsrInfo *gsr_info, std::string_view line) {
|
||||
const std::optional<KeyValue> key_value = parse_key_value(line);
|
||||
if(!key_value)
|
||||
@@ -156,6 +163,7 @@ namespace gsr {
|
||||
if(WIFEXITED(status)) {
|
||||
switch(WEXITSTATUS(status)) {
|
||||
case 0: return GsrInfoExitStatus::OK;
|
||||
case 14: return GsrInfoExitStatus::BROKEN_DRIVERS;
|
||||
case 22: return GsrInfoExitStatus::OPENGL_FAILED;
|
||||
case 23: return GsrInfoExitStatus::NO_DRM_CARD;
|
||||
default: return GsrInfoExitStatus::FAILED_TO_RUN_COMMAND;
|
||||
@@ -180,14 +188,14 @@ namespace gsr {
|
||||
|
||||
FILE *f = popen("gpu-screen-recorder --list-audio-devices", "r");
|
||||
if(!f) {
|
||||
fprintf(stderr, "error: 'gpu-screen-recorder --info' failed\n");
|
||||
fprintf(stderr, "error: 'gpu-screen-recorder --list-audio-devices' failed\n");
|
||||
return audio_devices;
|
||||
}
|
||||
|
||||
char output[16384];
|
||||
ssize_t bytes_read = fread(output, 1, sizeof(output) - 1, f);
|
||||
if(bytes_read < 0 || ferror(f)) {
|
||||
fprintf(stderr, "error: failed to read 'gpu-screen-recorder --info' output\n");
|
||||
fprintf(stderr, "error: failed to read 'gpu-screen-recorder --list-audio-devices' output\n");
|
||||
pclose(f);
|
||||
return audio_devices;
|
||||
}
|
||||
@@ -202,4 +210,4 @@ namespace gsr {
|
||||
|
||||
return audio_devices;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
namespace gsr {
|
||||
static Theme *theme = nullptr;
|
||||
|
||||
bool init_theme(const gsr::GsrInfo &gsr_info, mgl::vec2i window_size, const std::string &resources_path) {
|
||||
bool init_theme(const GsrInfo &gsr_info, mgl::vec2i window_size, const std::string &resources_path) {
|
||||
if(theme)
|
||||
return true;
|
||||
|
||||
@@ -15,18 +15,18 @@ namespace gsr {
|
||||
theme->window_height = window_size.y;
|
||||
|
||||
switch(gsr_info.gpu_info.vendor) {
|
||||
case gsr::GpuVendor::UNKNOWN: {
|
||||
case GpuVendor::UNKNOWN: {
|
||||
break;
|
||||
}
|
||||
case gsr::GpuVendor::AMD: {
|
||||
case GpuVendor::AMD: {
|
||||
theme->tint_color = mgl::Color(221, 0, 49);
|
||||
break;
|
||||
}
|
||||
case gsr::GpuVendor::INTEL: {
|
||||
case GpuVendor::INTEL: {
|
||||
theme->tint_color = mgl::Color(8, 109, 183);
|
||||
break;
|
||||
}
|
||||
case gsr::GpuVendor::NVIDIA: {
|
||||
case GpuVendor::NVIDIA: {
|
||||
theme->tint_color = mgl::Color(118, 185, 0);
|
||||
break;
|
||||
}
|
||||
@@ -53,6 +53,9 @@ namespace gsr {
|
||||
if(!theme->settings_texture.load_from_file((resources_path + "images/settings.png").c_str(), {false, false, false}))
|
||||
goto error;
|
||||
|
||||
if(!theme->folder_texture.load_from_file((resources_path + "images/folder.png").c_str(), {false, false, false}))
|
||||
goto error;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
|
||||
@@ -22,13 +22,6 @@ namespace gsr {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<KeyValue> parse_key_value(std::string_view line) {
|
||||
const size_t space_index = line.find(' ');
|
||||
if(space_index == std::string_view::npos)
|
||||
return std::nullopt;
|
||||
return KeyValue{line.substr(0, space_index), line.substr(space_index + 1)};
|
||||
}
|
||||
|
||||
std::string get_home_dir() {
|
||||
const char *home_dir = getenv("HOME");
|
||||
if(!home_dir) {
|
||||
|
||||
@@ -70,4 +70,8 @@ namespace gsr {
|
||||
void Button::set_border_scale(float scale) {
|
||||
border_scale = scale;
|
||||
}
|
||||
|
||||
const std::string& Button::get_text() const {
|
||||
return text.get_string();
|
||||
}
|
||||
}
|
||||
@@ -146,14 +146,14 @@ namespace gsr {
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void ComboBox::set_selected_item(const std::string &id, bool trigger_event) {
|
||||
void ComboBox::set_selected_item(const std::string &id, bool trigger_event, bool trigger_event_even_if_selection_not_changed) {
|
||||
for(size_t i = 0; i < items.size(); ++i) {
|
||||
auto &item = items[i];
|
||||
if(item.id == id) {
|
||||
const size_t prev_selected_item = selected_item;
|
||||
selected_item = i;
|
||||
|
||||
if(trigger_event && selected_item != prev_selected_item && on_selection_changed)
|
||||
if(trigger_event && (trigger_event_even_if_selection_not_changed || selected_item != prev_selected_item) && on_selection_changed)
|
||||
on_selection_changed(item.text.get_string(), item.id);
|
||||
|
||||
break;
|
||||
|
||||
174
src/gui/FileChooser.cpp
Normal file
174
src/gui/FileChooser.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
#include "../../include/gui/FileChooser.hpp"
|
||||
#include "../../include/gui/Utils.hpp"
|
||||
#include "../../include/Theme.hpp"
|
||||
#include <mglpp/graphics/Rectangle.hpp>
|
||||
#include <mglpp/graphics/Sprite.hpp>
|
||||
#include <mglpp/window/Window.hpp>
|
||||
#include <mglpp/window/Event.hpp>
|
||||
#include <mglpp/system/FloatRect.hpp>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace gsr {
|
||||
static const float current_directory_padding_top_scale = 0.004629f;
|
||||
static const float current_directory_padding_bottom_scale = 0.004629f;
|
||||
static const float current_directory_padding_left_scale = 0.004629f;
|
||||
static const float current_directory_padding_right_scale = 0.004629f;
|
||||
static const float spacing_between_current_directory_and_content = 0.015f;
|
||||
static const int num_columns = 6;
|
||||
static const float content_padding_top_scale = 0.015f;
|
||||
static const float content_padding_bottom_scale = 0.015f;
|
||||
static const float content_padding_left_scale = 0.015f;
|
||||
static const float content_padding_right_scale = 0.015f;
|
||||
|
||||
FileChooser::FileChooser(const char *start_directory, mgl::vec2f content_size) :
|
||||
content_size(content_size), current_directory_text(start_directory, get_theme().body_font)
|
||||
{
|
||||
set_current_directory(start_directory);
|
||||
}
|
||||
|
||||
bool FileChooser::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
|
||||
if(!visible)
|
||||
return true;
|
||||
|
||||
if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
|
||||
if(double_click_timer.get_elapsed_time_seconds() <= get_theme().double_click_timeout_seconds) {
|
||||
++times_clicked_within_timer;
|
||||
} else {
|
||||
times_clicked_within_timer = 1;
|
||||
}
|
||||
double_click_timer.restart();
|
||||
|
||||
selected_item = mouse_over_item;
|
||||
|
||||
if(selected_item != -1 && times_clicked_within_timer > 0 && times_clicked_within_timer % 2 == 0) {
|
||||
char new_directory[PATH_MAX];
|
||||
snprintf(new_directory, sizeof(new_directory), "%s/%s", current_directory_text.get_string().c_str(), folders[selected_item].get_string().c_str());
|
||||
set_current_directory(new_directory);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void FileChooser::draw(mgl::Window &window, mgl::vec2f offset) {
|
||||
mouse_over_item = -1;
|
||||
|
||||
if(!visible)
|
||||
return;
|
||||
|
||||
const mgl::vec2f draw_pos = position + offset;
|
||||
const mgl::vec2f current_directory_padding(
|
||||
current_directory_padding_left_scale * get_theme().window_height + current_directory_padding_right_scale * get_theme().window_height,
|
||||
current_directory_padding_top_scale * get_theme().window_height + current_directory_padding_bottom_scale * get_theme().window_height
|
||||
);
|
||||
|
||||
mgl::Rectangle current_directory_background(mgl::vec2f(content_size.x, current_directory_text.get_bounds().size.y + current_directory_padding.y).floor());
|
||||
current_directory_background.set_color(mgl::Color(0, 0, 0, 120));
|
||||
current_directory_background.set_position(draw_pos.floor());
|
||||
window.draw(current_directory_background);
|
||||
|
||||
current_directory_text.set_color(get_theme().text_color);
|
||||
current_directory_text.set_position((draw_pos + mgl::vec2f(current_directory_padding.x, current_directory_background.get_size().y * 0.5f - current_directory_text.get_bounds().size.y * 0.5f)).floor());
|
||||
window.draw(current_directory_text);
|
||||
|
||||
mgl::Rectangle content_background(content_size.floor());
|
||||
content_background.set_color(mgl::Color(0, 0, 0, 120));
|
||||
content_background.set_position((draw_pos + mgl::vec2f(0.0f, current_directory_background.get_size().y + spacing_between_current_directory_and_content * get_theme().window_height)).floor());
|
||||
window.draw(content_background);
|
||||
|
||||
const mgl::vec2f mouse_pos = window.get_mouse_position().to_vec2f();
|
||||
|
||||
const int content_padding_top = content_padding_top_scale * get_theme().window_height;
|
||||
const int content_padding_bottom = content_padding_bottom_scale * get_theme().window_height;
|
||||
const int content_padding_left = content_padding_left_scale * get_theme().window_height;
|
||||
const int content_padding_right = content_padding_right_scale * get_theme().window_height;
|
||||
|
||||
const float folder_width = (int)((content_size.x - (content_padding_left + content_padding_right) * num_columns) / num_columns);
|
||||
const float width_per_item_after = content_padding_right + folder_width + content_padding_left;
|
||||
mgl::vec2f folder_pos = content_background.get_position() + mgl::vec2f(content_padding_left, content_padding_top);
|
||||
for(int i = 0; i < (int)folders.size(); ++i) {
|
||||
auto &folder_text = folders[i];
|
||||
|
||||
mgl::Sprite folder_sprite(&get_theme().folder_texture);
|
||||
folder_sprite.set_position(folder_pos.floor());
|
||||
folder_sprite.set_width((int)folder_width);
|
||||
|
||||
const mgl::vec2f item_pos = folder_pos - mgl::vec2f(content_padding_left, content_padding_top);
|
||||
const mgl::vec2f item_size = folder_sprite.get_size() + mgl::vec2f(content_padding_left + content_padding_right, content_padding_top + content_padding_bottom);
|
||||
if(i == selected_item) {
|
||||
mgl::Rectangle selected_item_background(item_size.floor());
|
||||
selected_item_background.set_position(item_pos.floor());
|
||||
selected_item_background.set_color(get_theme().tint_color);
|
||||
window.draw(selected_item_background);
|
||||
}
|
||||
if(!has_parent_with_selected_child_widget() && mouse_over_item == -1 && mgl::FloatRect(item_pos, item_size).contains(mouse_pos)) {
|
||||
// mgl::Rectangle selected_item_background(item_size.floor());
|
||||
// selected_item_background.set_position(item_pos.floor());
|
||||
// selected_item_background.set_color(mgl::Color(20, 20, 20, 150));
|
||||
// window.draw(selected_item_background);
|
||||
const float border_scale = 0.0015f;
|
||||
draw_rectangle_outline(window, item_pos.floor(), item_size.floor(), get_theme().tint_color, border_scale * get_theme().window_height);
|
||||
mouse_over_item = i;
|
||||
}
|
||||
|
||||
window.draw(folder_sprite);
|
||||
|
||||
// TODO: Dont allow text to go further left/right than item_pos (on the left side) and item_pos + item_size (on the right side).
|
||||
folder_text.set_position(folder_sprite.get_position() + mgl::vec2f(folder_sprite.get_size().x * 0.5f - folder_text.get_bounds().size.x * 0.5f, folder_sprite.get_size().y));
|
||||
window.draw(folder_text);
|
||||
|
||||
folder_pos.x += width_per_item_after;
|
||||
if(folder_pos.x + folder_width > content_background.get_position().x + content_size.x) {
|
||||
folder_pos.x = content_background.get_position().x + content_padding_left;
|
||||
folder_pos.y += content_padding_bottom + folder_sprite.get_size().y + content_padding_top;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mgl::vec2f FileChooser::get_size() {
|
||||
if(!visible)
|
||||
return {0.0f, 0.0f};
|
||||
|
||||
const mgl::vec2f current_directory_padding(
|
||||
current_directory_padding_left_scale * get_theme().window_height + current_directory_padding_right_scale * get_theme().window_height,
|
||||
current_directory_padding_top_scale * get_theme().window_height + current_directory_padding_bottom_scale * get_theme().window_height
|
||||
);
|
||||
return {content_size.x, current_directory_text.get_bounds().size.y + current_directory_padding.y + spacing_between_current_directory_and_content * get_theme().window_height + content_size.y};
|
||||
}
|
||||
|
||||
static bool is_dir(struct dirent *dir, const char *parent_directory) {
|
||||
if(dir->d_type == DT_DIR)
|
||||
return true;
|
||||
|
||||
char filepath[PATH_MAX];
|
||||
snprintf(filepath, sizeof(filepath), "%s/%s", parent_directory, dir->d_name);
|
||||
|
||||
struct stat st;
|
||||
return stat(filepath, &st) != -1 && S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
void FileChooser::set_current_directory(const char *directory) {
|
||||
folders.clear();
|
||||
selected_item = -1;
|
||||
mouse_over_item = -1;
|
||||
current_directory_text.set_string(directory);
|
||||
|
||||
DIR *d = opendir(directory);
|
||||
if(!d) {
|
||||
fprintf(stderr, "gsr-overlay error: failed to open directory: %s, error: %s\n", directory, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
struct dirent *dir = NULL;
|
||||
while((dir = readdir(d)) != NULL) {
|
||||
/* Ignore hidden files */
|
||||
if(dir->d_name[0] == '.' || !is_dir(dir, directory))
|
||||
continue;
|
||||
folders.push_back(mgl::Text(dir->d_name, get_theme().body_font));
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
}
|
||||
}
|
||||
126
src/gui/GsrPage.cpp
Normal file
126
src/gui/GsrPage.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "../../include/gui/GsrPage.hpp"
|
||||
#include "../../include/Theme.hpp"
|
||||
|
||||
#include <mglpp/graphics/Rectangle.hpp>
|
||||
#include <mglpp/graphics/Sprite.hpp>
|
||||
#include <mglpp/window/Window.hpp>
|
||||
|
||||
namespace gsr {
|
||||
GsrPage::GsrPage() :
|
||||
scrollable_body(mgl::vec2f(0.0f, 0.0f)),
|
||||
back_button(&get_theme().title_font, "Back",
|
||||
mgl::vec2f(get_theme().window_width / 10, get_theme().window_height / 15).floor(), get_theme().scrollable_page_bg_color),
|
||||
label_text("Settings", get_theme().title_font)
|
||||
{
|
||||
//set_position(content_page_position);
|
||||
const float margin = 0.02f;
|
||||
set_margins(margin, margin, margin, margin);
|
||||
back_button.set_border_scale(0.003f);
|
||||
}
|
||||
|
||||
bool GsrPage::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f) {
|
||||
if(!visible)
|
||||
return true;
|
||||
|
||||
if(!scrollable_body.on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
|
||||
return false;
|
||||
|
||||
if(!back_button.on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void GsrPage::draw(mgl::Window &window, mgl::vec2f offset) {
|
||||
if(!visible)
|
||||
return;
|
||||
|
||||
const int margin_top = margin_top_scale * get_theme().window_height;
|
||||
const int margin_left = margin_left_scale * get_theme().window_height;
|
||||
|
||||
const mgl::vec2f window_size = mgl::vec2f(get_theme().window_width, get_theme().window_height).floor();
|
||||
const mgl::vec2f content_page_size = get_size();
|
||||
const mgl::vec2f content_page_position = mgl::vec2f(window_size * 0.5f - content_page_size * 0.5f).floor();
|
||||
offset = content_page_position + mgl::vec2f(margin_left, get_border_size() + margin_top).floor();
|
||||
|
||||
mgl::Rectangle background(content_page_size);
|
||||
background.set_position(content_page_position);
|
||||
background.set_color(get_theme().scrollable_page_bg_color);
|
||||
window.draw(background);
|
||||
|
||||
mgl::Rectangle border(mgl::vec2f(content_page_size.x, get_border_size()).floor());
|
||||
border.set_position(content_page_position);
|
||||
border.set_color(get_theme().tint_color);
|
||||
window.draw(border);
|
||||
|
||||
scrollable_body.set_position(offset);
|
||||
scrollable_body.draw(window, mgl::vec2f(0.0f, 0.0f));
|
||||
|
||||
draw_page_label(window, content_page_position);
|
||||
|
||||
back_button.set_position(content_page_position + mgl::vec2f(content_page_size.x + get_horizontal_spacing(), 0.0f).floor());
|
||||
back_button.draw(window, mgl::vec2f(0.0f, 0.0f));
|
||||
}
|
||||
|
||||
void GsrPage::draw_page_label(mgl::Window &window, mgl::vec2f body_pos) {
|
||||
const mgl::vec2f window_size = mgl::vec2f(get_theme().window_width, get_theme().window_height).floor();
|
||||
|
||||
mgl::Rectangle background(mgl::vec2f(window_size.x / 10, window_size.x / 10).floor());
|
||||
background.set_position(body_pos.floor() - mgl::vec2f(background.get_size().x + get_horizontal_spacing(), 0.0f).floor());
|
||||
background.set_color(mgl::Color(0, 0, 0, 255));
|
||||
window.draw(background);
|
||||
|
||||
const int text_margin = background.get_size().y * 0.085;
|
||||
label_text.set_position((background.get_position() + mgl::vec2f(background.get_size().x * 0.5f - label_text.get_bounds().size.x * 0.5f, text_margin)).floor());
|
||||
window.draw(label_text);
|
||||
|
||||
mgl::Sprite icon(&get_theme().settings_texture);
|
||||
icon.set_height((int)(background.get_size().y * 0.5f));
|
||||
icon.set_position((background.get_position() + background.get_size() * 0.5f - icon.get_size() * 0.5f).floor());
|
||||
window.draw(icon);
|
||||
}
|
||||
|
||||
mgl::vec2f GsrPage::get_size() {
|
||||
if(!visible)
|
||||
return {0.0f, 0.0f};
|
||||
|
||||
const mgl::vec2f window_size = mgl::vec2f(get_theme().window_width, get_theme().window_height).floor();
|
||||
const mgl::vec2f content_page_size = (window_size * mgl::vec2f(0.3333f, 0.7f)).floor();
|
||||
return content_page_size;
|
||||
}
|
||||
|
||||
mgl::vec2f GsrPage::get_inner_size() {
|
||||
if(!visible)
|
||||
return {0.0f, 0.0f};
|
||||
|
||||
const int margin_top = margin_top_scale * get_theme().window_height;
|
||||
const int margin_bottom = margin_bottom_scale * get_theme().window_height;
|
||||
const int margin_left = margin_left_scale * get_theme().window_height;
|
||||
const int margin_right = margin_right_scale * get_theme().window_height;
|
||||
return get_size() - mgl::vec2f(margin_left + margin_right, margin_top + margin_bottom + get_border_size());
|
||||
}
|
||||
|
||||
void GsrPage::add_widget(std::unique_ptr<Widget> widget) {
|
||||
scrollable_body.add_widget(std::move(widget));
|
||||
}
|
||||
|
||||
void GsrPage::set_margins(float top, float bottom, float left, float right) {
|
||||
margin_top_scale = top;
|
||||
margin_bottom_scale = bottom;
|
||||
margin_left_scale = left;
|
||||
margin_right_scale = right;
|
||||
scrollable_body.set_size(get_inner_size());
|
||||
}
|
||||
|
||||
void GsrPage::set_on_back_button_click(std::function<void()> on_click_handler) {
|
||||
back_button.on_click = std::move(on_click_handler);
|
||||
}
|
||||
|
||||
float GsrPage::get_border_size() const {
|
||||
return 0.004f * get_theme().window_height;
|
||||
}
|
||||
|
||||
float GsrPage::get_horizontal_spacing() const {
|
||||
return get_theme().window_width / 50;
|
||||
}
|
||||
}
|
||||
@@ -14,55 +14,25 @@ namespace gsr {
|
||||
if(!visible)
|
||||
return true;
|
||||
|
||||
inside_event_handler = true;
|
||||
// We want to store the selected child widget since it can change in the event loop below
|
||||
Widget *selected_widget = selected_child_widget;
|
||||
if(selected_widget) {
|
||||
if(!selected_widget->on_event(event, window, mgl::vec2f(0.0f, 0.0f))) {
|
||||
inside_event_handler = false;
|
||||
if(!selected_widget->on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Process widgets by visibility (backwards)
|
||||
for(auto it = widgets.rbegin(), end = widgets.rend(); it != end; ++it) {
|
||||
return widgets.for_each_reverse([selected_widget, &event, &window](std::unique_ptr<Widget> &widget) {
|
||||
// Ignore offset because widgets are positioned with offset in ::draw, this solution is simpler
|
||||
if(it->get() != selected_widget) {
|
||||
if(!(*it)->on_event(event, window, mgl::vec2f(0.0f, 0.0f))) {
|
||||
inside_event_handler = false;
|
||||
if(widget.get() != selected_widget) {
|
||||
if(!widget->on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inside_event_handler = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Maybe call this from main on all widgets instead of from draw
|
||||
void List::update() {
|
||||
//widgets.insert(widgets.back(), std::make_move_iterator(add_queue.begin()), std::make_move_iterator(add_queue.end()));
|
||||
std::move(add_queue.begin(), add_queue.end(), std::back_inserter(widgets));
|
||||
add_queue.clear();
|
||||
|
||||
for(Widget *widget_to_remove : remove_queue) {
|
||||
remove_widget_immediate(widget_to_remove);
|
||||
}
|
||||
remove_queue.clear();
|
||||
}
|
||||
|
||||
void List::remove_widget_immediate(Widget *widget) {
|
||||
for(auto it = widgets.begin(), end = widgets.end(); it != end; ++it) {
|
||||
if(it->get() == widget) {
|
||||
widgets.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void List::draw(mgl::Window &window, mgl::vec2f offset) {
|
||||
update();
|
||||
|
||||
if(!visible)
|
||||
return;
|
||||
|
||||
@@ -140,28 +110,15 @@ namespace gsr {
|
||||
|
||||
void List::add_widget(std::unique_ptr<Widget> widget) {
|
||||
widget->parent_widget = this;
|
||||
if(inside_event_handler)
|
||||
add_queue.push_back(std::move(widget));
|
||||
else
|
||||
widgets.push_back(std::move(widget));
|
||||
widgets.push_back(std::move(widget));
|
||||
}
|
||||
|
||||
void List::remove_widget(Widget *widget) {
|
||||
for(auto it = add_queue.begin(), end = add_queue.end(); it != end; ++it) {
|
||||
if(it->get() == widget) {
|
||||
add_queue.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(inside_event_handler)
|
||||
remove_queue.push_back(widget);
|
||||
else
|
||||
remove_widget_immediate(widget);
|
||||
widgets.remove(widget);
|
||||
}
|
||||
|
||||
const std::vector<std::unique_ptr<Widget>>& List::get_child_widgets() const {
|
||||
return widgets;
|
||||
void List::for_each_child_widget(std::function<bool(std::unique_ptr<Widget> &widget)> callback) {
|
||||
widgets.for_each(callback);
|
||||
}
|
||||
|
||||
Widget* List::get_child_widget_by_index(size_t index) const {
|
||||
|
||||
58
src/gui/PageStack.cpp
Normal file
58
src/gui/PageStack.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "../../include/gui/PageStack.hpp"
|
||||
|
||||
namespace gsr {
|
||||
PageStack::PageStack() {}
|
||||
|
||||
bool PageStack::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) {
|
||||
if(!visible)
|
||||
return true;
|
||||
|
||||
offset = position + offset;
|
||||
std::unique_ptr<Page> *top_page = widget_stack.back();
|
||||
if(top_page) {
|
||||
if(!(*top_page)->on_event(event, window, offset))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PageStack::draw(mgl::Window &window, mgl::vec2f offset) {
|
||||
if(!visible)
|
||||
return;
|
||||
|
||||
offset = position + offset;
|
||||
std::unique_ptr<Page> *top_page = widget_stack.back();
|
||||
if(top_page)
|
||||
(*top_page)->draw(window, offset);
|
||||
}
|
||||
|
||||
mgl::vec2f PageStack::get_size() {
|
||||
return {0.0f, 0.0f};
|
||||
}
|
||||
|
||||
void PageStack::push(std::unique_ptr<Page> widget) {
|
||||
widget->on_navigate_to_page();
|
||||
widget_stack.push_back(std::move(widget));
|
||||
}
|
||||
|
||||
void PageStack::pop() {
|
||||
std::unique_ptr<Page> *top_page = widget_stack.back();
|
||||
if(top_page) {
|
||||
(*top_page)->on_navigate_away_from_page();
|
||||
widget_stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
Page* PageStack::top() {
|
||||
std::unique_ptr<Page> *top_page = widget_stack.back();
|
||||
if(top_page)
|
||||
return top_page->get();
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PageStack::empty() const {
|
||||
return widget_stack.empty();
|
||||
}
|
||||
}
|
||||
@@ -121,14 +121,14 @@ namespace gsr {
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void RadioButton::set_selected_item(const std::string &id, bool trigger_event) {
|
||||
void RadioButton::set_selected_item(const std::string &id, bool trigger_event, bool trigger_event_even_if_selection_not_changed) {
|
||||
for(size_t i = 0; i < items.size(); ++i) {
|
||||
auto &item = items[i];
|
||||
if(item.id == id) {
|
||||
const size_t prev_selected_item = selected_item;
|
||||
selected_item = i;
|
||||
|
||||
if(trigger_event && selected_item != prev_selected_item && on_selection_changed)
|
||||
if(trigger_event && (trigger_event_even_if_selection_not_changed || selected_item != prev_selected_item) && on_selection_changed)
|
||||
on_selection_changed(item.text.get_string(), item.id);
|
||||
|
||||
break;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "../../include/gui/ScrollablePage.hpp"
|
||||
#include "../../include/Theme.hpp"
|
||||
|
||||
#include <mglpp/graphics/Rectangle.hpp>
|
||||
#include <mglpp/window/Window.hpp>
|
||||
|
||||
namespace gsr {
|
||||
@@ -11,11 +9,8 @@ namespace gsr {
|
||||
if(!visible)
|
||||
return true;
|
||||
|
||||
const int margin_top = margin_top_scale * get_theme().window_height;
|
||||
const int margin_left = margin_left_scale * get_theme().window_height;
|
||||
|
||||
const mgl::vec2f draw_pos = position + offset;
|
||||
offset = draw_pos + mgl::vec2f(margin_left, get_border_size() + margin_top).floor();
|
||||
offset = draw_pos;
|
||||
Widget *selected_widget = selected_child_widget;
|
||||
|
||||
if(selected_widget) {
|
||||
@@ -38,21 +33,8 @@ namespace gsr {
|
||||
if(!visible)
|
||||
return;
|
||||
|
||||
const int margin_top = margin_top_scale * get_theme().window_height;
|
||||
const int margin_left = margin_left_scale * get_theme().window_height;
|
||||
|
||||
const mgl::vec2f draw_pos = position + offset;
|
||||
offset = draw_pos + mgl::vec2f(margin_left, get_border_size() + margin_top).floor();
|
||||
|
||||
mgl::Rectangle background(size.floor());
|
||||
background.set_position(draw_pos);
|
||||
background.set_color(get_theme().scrollable_page_bg_color);
|
||||
window.draw(background);
|
||||
|
||||
mgl::Rectangle border(mgl::vec2f(size.x, get_border_size()).floor());
|
||||
border.set_position(draw_pos);
|
||||
border.set_color(get_theme().tint_color);
|
||||
window.draw(border);
|
||||
offset = draw_pos;
|
||||
|
||||
mgl_scissor prev_scissor;
|
||||
mgl_window_get_scissor(window.internal_window(), &prev_scissor);
|
||||
@@ -84,25 +66,11 @@ namespace gsr {
|
||||
return size;
|
||||
}
|
||||
|
||||
mgl::vec2f ScrollablePage::get_inner_size() {
|
||||
if(!visible)
|
||||
return {0.0f, 0.0f};
|
||||
|
||||
const int margin_top = margin_top_scale * get_theme().window_height;
|
||||
const int margin_bottom = margin_bottom_scale * get_theme().window_height;
|
||||
const int margin_left = margin_left_scale * get_theme().window_height;
|
||||
const int margin_right = margin_right_scale * get_theme().window_height;
|
||||
return size - mgl::vec2f(margin_left + margin_right, margin_top + margin_bottom + get_border_size());
|
||||
void ScrollablePage::set_size(mgl::vec2f size) {
|
||||
this->size = size;
|
||||
}
|
||||
|
||||
void ScrollablePage::set_margins(float top, float bottom, float left, float right) {
|
||||
margin_top_scale = top;
|
||||
margin_bottom_scale = bottom;
|
||||
margin_left_scale = left;
|
||||
margin_right_scale = right;
|
||||
}
|
||||
|
||||
float ScrollablePage::get_border_size() const {
|
||||
return 0.004f * get_theme().window_height;
|
||||
void ScrollablePage::add_widget(std::unique_ptr<Widget> widget) {
|
||||
widgets.push_back(std::move(widget));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "../../include/gui/SettingsPage.hpp"
|
||||
#include "../../include/gui/ScrollablePage.hpp"
|
||||
#include "../../include/gui/GsrPage.hpp"
|
||||
#include "../../include/gui/Label.hpp"
|
||||
#include "../../include/gui/PageStack.hpp"
|
||||
#include "../../include/gui/FileChooser.hpp"
|
||||
#include "../../include/Theme.hpp"
|
||||
#include "../../include/GsrInfo.hpp"
|
||||
|
||||
@@ -10,20 +12,17 @@
|
||||
#include <mglpp/window/Window.hpp>
|
||||
|
||||
namespace gsr {
|
||||
SettingsPage::SettingsPage(Type type, const GsrInfo &gsr_info, const std::vector<AudioDevice> &audio_devices, std::optional<Config> &config) :
|
||||
SettingsPage::SettingsPage(Type type, const GsrInfo &gsr_info, const std::vector<AudioDevice> &audio_devices, std::optional<Config> &config, PageStack *page_stack) :
|
||||
StaticPage(mgl::vec2f(get_theme().window_width, get_theme().window_height).floor()),
|
||||
type(type),
|
||||
config(config),
|
||||
page_stack(page_stack),
|
||||
settings_title_text("Settings", get_theme().title_font)
|
||||
{
|
||||
const mgl::vec2f window_size = mgl::vec2f(get_theme().window_width, get_theme().window_height).floor();
|
||||
const mgl::vec2f content_page_size = (window_size * mgl::vec2f(0.3333f, 0.7f)).floor();
|
||||
const mgl::vec2f content_page_position = mgl::vec2f(window_size * 0.5f - content_page_size * 0.5f).floor();
|
||||
const float settings_body_margin = 0.02f;
|
||||
|
||||
auto content_page = std::make_unique<ScrollablePage>(content_page_size);
|
||||
content_page->set_position(content_page_position);
|
||||
content_page->set_margins(settings_body_margin, settings_body_margin, settings_body_margin, settings_body_margin);
|
||||
auto content_page = std::make_unique<GsrPage>();
|
||||
content_page->set_on_back_button_click([page_stack]() {
|
||||
page_stack->pop();
|
||||
});
|
||||
content_page_ptr = content_page.get();
|
||||
add_widget(std::move(content_page));
|
||||
|
||||
@@ -31,40 +30,6 @@ namespace gsr {
|
||||
add_page_specific_widgets();
|
||||
}
|
||||
|
||||
std::unique_ptr<Button> SettingsPage::create_back_button() {
|
||||
const mgl::vec2i window_size(get_theme().window_width, get_theme().window_height);
|
||||
auto back_button = std::make_unique<Button>(&get_theme().title_font, "Back", mgl::vec2f(window_size.x / 10, window_size.y / 15).floor(), get_theme().scrollable_page_bg_color);
|
||||
back_button->set_position(content_page_ptr->get_position().floor() + mgl::vec2f(content_page_ptr->get_size().x + window_size.x / 50, 0.0f).floor());
|
||||
back_button->set_border_scale(0.003f);
|
||||
back_button->on_click = [this]() {
|
||||
if(on_back_button_handler)
|
||||
on_back_button_handler();
|
||||
};
|
||||
return back_button;
|
||||
}
|
||||
|
||||
std::unique_ptr<CustomRendererWidget> SettingsPage::create_settings_icon() {
|
||||
const mgl::vec2i window_size(get_theme().window_width, get_theme().window_height);
|
||||
auto settings_icon_widget = std::make_unique<CustomRendererWidget>(mgl::vec2f(window_size.x / 10, window_size.x / 10).floor());
|
||||
settings_icon_widget->set_position(content_page_ptr->get_position().floor() - mgl::vec2f(settings_icon_widget->get_size().x + window_size.x / 50, 0.0f).floor());
|
||||
settings_icon_widget->draw_handler = [&](mgl::Window &window, mgl::vec2f pos, mgl::vec2f size) {
|
||||
mgl::Rectangle background(size);
|
||||
background.set_position(pos);
|
||||
background.set_color(mgl::Color(0, 0, 0, 255));
|
||||
window.draw(background);
|
||||
|
||||
const int text_margin = size.y * 0.085;
|
||||
settings_title_text.set_position((pos + mgl::vec2f(size.x * 0.5f - settings_title_text.get_bounds().size.x * 0.5f, text_margin)).floor());
|
||||
window.draw(settings_title_text);
|
||||
|
||||
mgl::Sprite icon(&get_theme().settings_texture);
|
||||
icon.set_height((int)(size.y * 0.5f));
|
||||
icon.set_position((pos + size * 0.5f - icon.get_size() * 0.5f).floor());
|
||||
window.draw(icon);
|
||||
};
|
||||
return settings_icon_widget;
|
||||
}
|
||||
|
||||
std::unique_ptr<RadioButton> SettingsPage::create_view_radio_button() {
|
||||
auto view_radio_button = std::make_unique<RadioButton>(&get_theme().body_font);
|
||||
view_radio_button->add_item("Simple view", "simple");
|
||||
@@ -363,8 +328,6 @@ namespace gsr {
|
||||
}
|
||||
|
||||
void SettingsPage::add_widgets(const GsrInfo &gsr_info, const std::vector<AudioDevice> &audio_devices) {
|
||||
add_widget(create_back_button());
|
||||
add_widget(create_settings_icon());
|
||||
content_page_ptr->add_widget(create_settings(gsr_info, audio_devices));
|
||||
|
||||
record_area_box_ptr->on_selection_changed = [this](const std::string &text, const std::string &id) {
|
||||
@@ -400,9 +363,20 @@ namespace gsr {
|
||||
std::unique_ptr<List> SettingsPage::create_save_directory(const char *label) {
|
||||
auto save_directory_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
||||
save_directory_list->add_widget(std::make_unique<Label>(&get_theme().body_font, label, get_theme().text_color));
|
||||
auto save_directory_entry = std::make_unique<Entry>(&get_theme().body_font, "/home/dec05eba/Videos", get_theme().body_font.get_character_size() * 20);
|
||||
save_directory_entry_ptr = save_directory_entry.get();
|
||||
save_directory_list->add_widget(std::move(save_directory_entry));
|
||||
auto save_directory_button = std::make_unique<Button>(&get_theme().body_font, "/home/dec05eba/Videos", mgl::vec2f(0.0f, 0.0f), mgl::Color(0, 0, 0, 120));
|
||||
save_directory_button->on_click = [this]() {
|
||||
auto select_directory_page = std::make_unique<GsrPage>();
|
||||
select_directory_page->set_on_back_button_click([this]() {
|
||||
page_stack->pop();
|
||||
});
|
||||
|
||||
auto file_chooser = std::make_unique<gsr::FileChooser>("/home/dec05eba", select_directory_page->get_size());
|
||||
select_directory_page->add_widget(std::move(file_chooser));
|
||||
|
||||
page_stack->push(std::move(select_directory_page));
|
||||
};
|
||||
save_directory_button_ptr = save_directory_button.get();
|
||||
save_directory_list->add_widget(std::move(save_directory_button));
|
||||
return save_directory_list;
|
||||
}
|
||||
|
||||
@@ -658,12 +632,12 @@ namespace gsr {
|
||||
|
||||
static void save_audio_tracks(std::vector<std::string> &audio_tracks, List *audio_devices_list_ptr) {
|
||||
audio_tracks.clear();
|
||||
const std::vector<std::unique_ptr<Widget>> &audio_devices_list = audio_devices_list_ptr->get_child_widgets();
|
||||
for(const std::unique_ptr<Widget> &child_widget : audio_devices_list) {
|
||||
audio_devices_list_ptr->for_each_child_widget([&audio_tracks](std::unique_ptr<Widget> &child_widget) {
|
||||
List *audio_device_line = static_cast<List*>(child_widget.get());
|
||||
ComboBox *audio_device_box = static_cast<ComboBox*>(audio_device_line->get_child_widget_by_index(0));
|
||||
audio_tracks.push_back(audio_device_box->get_selected_id());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void SettingsPage::save_common(RecordOptions &record_options) {
|
||||
@@ -705,7 +679,7 @@ namespace gsr {
|
||||
config->replay_config.show_replay_started_notifications = show_replay_started_notification_checkbox_ptr->is_checked();
|
||||
config->replay_config.show_replay_stopped_notifications = show_replay_stopped_notification_checkbox_ptr->is_checked();
|
||||
config->replay_config.show_replay_saved_notifications = show_replay_saved_notification_checkbox_ptr->is_checked();
|
||||
config->replay_config.save_directory = save_directory_entry_ptr->get_text();
|
||||
config->replay_config.save_directory = save_directory_button_ptr->get_text();
|
||||
config->replay_config.container = container_box_ptr->get_selected_id();
|
||||
config->replay_config.replay_time = atoi(replay_time_entry_ptr->get_text().c_str());
|
||||
|
||||
@@ -719,7 +693,7 @@ namespace gsr {
|
||||
save_common(config->record_config.record_options);
|
||||
config->record_config.show_recording_started_notifications = show_recording_started_notification_checkbox_ptr->is_checked();
|
||||
config->record_config.show_video_saved_notifications = show_video_saved_notification_checkbox_ptr->is_checked();
|
||||
config->record_config.save_directory = save_directory_entry_ptr->get_text();
|
||||
config->record_config.save_directory = save_directory_button_ptr->get_text();
|
||||
config->record_config.container = container_box_ptr->get_selected_id();
|
||||
}
|
||||
|
||||
|
||||
68
src/main.cpp
68
src/main.cpp
@@ -4,24 +4,17 @@
|
||||
#include "../include/gui/CustomRendererWidget.hpp"
|
||||
#include "../include/gui/SettingsPage.hpp"
|
||||
#include "../include/gui/Utils.hpp"
|
||||
#include "../include/gui/PageStack.hpp"
|
||||
#include "../include/Process.hpp"
|
||||
#include "../include/Theme.hpp"
|
||||
#include "../include/GsrInfo.hpp"
|
||||
#include "../include/window_texture.h"
|
||||
#include "../include/Config.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <optional>
|
||||
#include <signal.h>
|
||||
#include <assert.h>
|
||||
#include <stack>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/cursorfont.h>
|
||||
@@ -235,10 +228,10 @@ int main(int argc, char **argv) {
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
||||
gsr::GsrInfo gsr_info;
|
||||
// TODO:
|
||||
// TODO: Show the error in ui
|
||||
gsr::GsrInfoExitStatus gsr_info_exit_status = gsr::get_gpu_screen_recorder_info(&gsr_info);
|
||||
if(gsr_info_exit_status != gsr::GsrInfoExitStatus::OK) {
|
||||
fprintf(stderr, "error: failed to get gpu-screen-recorder info\n");
|
||||
fprintf(stderr, "error: failed to get gpu-screen-recorder info, error: %d\n", (int)gsr_info_exit_status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -331,8 +324,6 @@ int main(int argc, char **argv) {
|
||||
WindowTexture window_texture;
|
||||
bool window_texture_loaded = false;
|
||||
|
||||
mgl_texture window_texture_tex;
|
||||
memset(&window_texture_tex, 0, sizeof(window_texture_tex));
|
||||
mgl::Texture window_texture_texture;
|
||||
mgl::Sprite window_texture_sprite;
|
||||
|
||||
@@ -343,18 +334,7 @@ int main(int argc, char **argv) {
|
||||
window_texture_loaded = window_texture_init(&window_texture, display, mgl_window_get_egl_display(window.internal_window()), window_at_cursor_position, egl_funcs) == 0;
|
||||
|
||||
if(window_texture_loaded && window_texture.texture_id) {
|
||||
DrawableGeometry geometry;
|
||||
get_drawable_geometry(display, (Drawable)window_texture.pixmap, &geometry);
|
||||
|
||||
window_texture_tex.id = window_texture.texture_id;
|
||||
window_texture_tex.width = geometry.width;
|
||||
window_texture_tex.height = geometry.height;
|
||||
window_texture_tex.format = MGL_TEXTURE_FORMAT_RGB;
|
||||
window_texture_tex.max_width = 1 << 15;
|
||||
window_texture_tex.max_height = 1 << 15;
|
||||
window_texture_tex.pixel_coordinates = false;
|
||||
window_texture_tex.mipmap = false;
|
||||
window_texture_texture = mgl::Texture::reference(window_texture_tex);
|
||||
window_texture_texture = mgl::Texture(window_texture.texture_id, MGL_TEXTURE_FORMAT_RGB);
|
||||
window_texture_sprite.set_texture(&window_texture_texture);
|
||||
} else {
|
||||
XImage *img = XGetImage(display, DefaultRootWindow(display), window_pos.x, window_pos.y, window_size.x, window_size.y, AllPlanes, ZPixmap);
|
||||
@@ -376,33 +356,14 @@ int main(int argc, char **argv) {
|
||||
mgl::Rectangle bg_screenshot_overlay(window_size.to_vec2f());
|
||||
bg_screenshot_overlay.set_color(bg_color);
|
||||
|
||||
gsr::StaticPage front_page(window_size.to_vec2f());
|
||||
auto front_page = std::make_unique<gsr::StaticPage>(window_size.to_vec2f());
|
||||
gsr::StaticPage *front_page_ptr = front_page.get();
|
||||
|
||||
std::stack<gsr::Page*> page_stack;
|
||||
page_stack.push(&front_page);
|
||||
|
||||
const auto settings_back_button_callback = [&] {
|
||||
page_stack.top()->on_navigate_away_from_page();
|
||||
page_stack.pop();
|
||||
};
|
||||
gsr::PageStack page_stack;
|
||||
page_stack.push(std::move(front_page));
|
||||
|
||||
std::optional<gsr::Config> config = gsr::read_config();
|
||||
|
||||
gsr::SettingsPage replay_settings_page(gsr::SettingsPage::Type::REPLAY, gsr_info, audio_devices, config);
|
||||
replay_settings_page.on_back_button_handler = settings_back_button_callback;
|
||||
|
||||
gsr::SettingsPage record_settings_page(gsr::SettingsPage::Type::RECORD, gsr_info, audio_devices, config);
|
||||
record_settings_page.on_back_button_handler = settings_back_button_callback;
|
||||
|
||||
gsr::SettingsPage stream_settings_page(gsr::SettingsPage::Type::STREAM, gsr_info, audio_devices, config);
|
||||
stream_settings_page.on_back_button_handler = settings_back_button_callback;
|
||||
|
||||
if(!config) {
|
||||
replay_settings_page.save();
|
||||
record_settings_page.save();
|
||||
stream_settings_page.save();
|
||||
}
|
||||
|
||||
struct MainButton {
|
||||
gsr::DropdownButton* button;
|
||||
gsr::GsrMode mode;
|
||||
@@ -444,7 +405,7 @@ int main(int argc, char **argv) {
|
||||
button->add_item("Start", "start");
|
||||
button->add_item("Settings", "settings");
|
||||
gsr::DropdownButton *button_ptr = button.get();
|
||||
front_page.add_widget(std::move(button));
|
||||
front_page_ptr->add_widget(std::move(button));
|
||||
|
||||
MainButton main_button = {
|
||||
button_ptr,
|
||||
@@ -488,7 +449,8 @@ int main(int argc, char **argv) {
|
||||
// Replay
|
||||
main_buttons[0].button->on_click = [&](const std::string &id) {
|
||||
if(id == "settings") {
|
||||
page_stack.push(&replay_settings_page);
|
||||
auto replay_settings_page = std::make_unique<gsr::SettingsPage>(gsr::SettingsPage::Type::REPLAY, gsr_info, audio_devices, config, &page_stack);
|
||||
page_stack.push(std::move(replay_settings_page));
|
||||
return;
|
||||
}
|
||||
/*
|
||||
@@ -513,7 +475,8 @@ int main(int argc, char **argv) {
|
||||
// Record
|
||||
main_buttons[1].button->on_click = [&](const std::string &id) {
|
||||
if(id == "settings") {
|
||||
page_stack.push(&record_settings_page);
|
||||
auto record_settings_page = std::make_unique<gsr::SettingsPage>(gsr::SettingsPage::Type::RECORD, gsr_info, audio_devices, config, &page_stack);
|
||||
page_stack.push(std::move(record_settings_page));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -598,7 +561,8 @@ int main(int argc, char **argv) {
|
||||
// Stream
|
||||
main_buttons[2].button->on_click = [&](const std::string &id) {
|
||||
if(id == "settings") {
|
||||
page_stack.push(&stream_settings_page);
|
||||
auto stream_settings_page = std::make_unique<gsr::SettingsPage>(gsr::SettingsPage::Type::STREAM, gsr_info, audio_devices, config, &page_stack);
|
||||
page_stack.push(std::move(stream_settings_page));
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -733,6 +697,8 @@ int main(int argc, char **argv) {
|
||||
|
||||
quit:
|
||||
fprintf(stderr, "shutting down!\n");
|
||||
XUngrabKeyboard(display, CurrentTime);
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
if(window_texture_loaded)
|
||||
window_texture_deinit(&window_texture);
|
||||
gsr::deinit_theme();
|
||||
|
||||
Reference in New Issue
Block a user