aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2024-08-03 23:36:11 +0200
committerdec05eba <dec05eba@protonmail.com>2024-08-03 23:36:11 +0200
commit3a20c417cbf7d5db1d9d26abfbda388e58f96c18 (patch)
treea7552bff0a5164446eaade0dde570cd6111e474d /src
parentc080342fcd358561af7edc64cea2222880923b93 (diff)
Align list items, dont process selected item twice if changed in event loop, mouse button events should only occur when pressing left mouse button
Diffstat (limited to 'src')
-rw-r--r--src/GsrInfo.cpp2
-rw-r--r--src/gui/Button.cpp2
-rw-r--r--src/gui/ComboBox.cpp10
-rw-r--r--src/gui/DropdownButton.cpp2
-rw-r--r--src/gui/Entry.cpp2
-rw-r--r--src/gui/List.cpp36
-rw-r--r--src/gui/ScrollablePage.cpp14
-rw-r--r--src/gui/StaticPage.cpp14
-rw-r--r--src/main.cpp53
9 files changed, 83 insertions, 52 deletions
diff --git a/src/GsrInfo.cpp b/src/GsrInfo.cpp
index 6aa1c17..f147ecb 100644
--- a/src/GsrInfo.cpp
+++ b/src/GsrInfo.cpp
@@ -54,6 +54,8 @@ namespace gsr {
static void parse_video_codecs_line(GsrInfo *gsr_info, const std::string &line) {
if(line == "h264")
gsr_info->supported_video_codecs.h264 = true;
+ else if(line == "h264_software")
+ gsr_info->supported_video_codecs.h264_software = true;
else if(line == "hevc")
gsr_info->supported_video_codecs.hevc = true;
else if(line == "av1")
diff --git a/src/gui/Button.cpp b/src/gui/Button.cpp
index b530004..eb5932b 100644
--- a/src/gui/Button.cpp
+++ b/src/gui/Button.cpp
@@ -14,7 +14,7 @@ namespace gsr {
bool Button::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
if(event.type == mgl::Event::MouseMoved) {
mouse_inside = mgl::FloatRect(position + offset, size).contains({ (float)event.mouse_move.x, (float)event.mouse_move.y });
- } else if(event.type == mgl::Event::MouseButtonPressed) {
+ } else if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
const bool clicked_inside = mouse_inside;
if(clicked_inside && on_click)
on_click();
diff --git a/src/gui/ComboBox.cpp b/src/gui/ComboBox.cpp
index 03e66bd..3aa4439 100644
--- a/src/gui/ComboBox.cpp
+++ b/src/gui/ComboBox.cpp
@@ -46,7 +46,6 @@ namespace gsr {
set_widget_as_selected_in_parent();
else
remove_widget_as_selected_in_parent();
- return false;
} else {
show_dropdown = false;
remove_widget_as_selected_in_parent();
@@ -118,6 +117,15 @@ namespace gsr {
dirty = true;
}
+ void ComboBox::set_selected_item(const std::string &id) {
+ for(size_t i = 0; i < items.size(); ++i) {
+ if(items[i].id == id) {
+ selected_item = i;
+ break;
+ }
+ }
+ }
+
void ComboBox::update_if_dirty() {
if(!dirty)
return;
diff --git a/src/gui/DropdownButton.cpp b/src/gui/DropdownButton.cpp
index 1d7374b..fa51aac 100644
--- a/src/gui/DropdownButton.cpp
+++ b/src/gui/DropdownButton.cpp
@@ -30,7 +30,7 @@ namespace gsr {
const mgl::vec2f draw_pos = position + offset;
const mgl::vec2f collision_margin(1.0f, 1.0f); // Makes sure that multiple buttons that are next to each other wont activate at the same time when the cursor is right between them
mouse_inside = mgl::FloatRect(draw_pos + collision_margin, size - collision_margin).contains({ (float)event.mouse_move.x, (float)event.mouse_move.y });
- } else if(event.type == mgl::Event::MouseButtonPressed) {
+ } else if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
const bool clicked_inside = mouse_inside;
if(show_dropdown && clicked_inside && mouse_inside_item == -1) {
diff --git a/src/gui/Entry.cpp b/src/gui/Entry.cpp
index 09ec167..bf0f1ad 100644
--- a/src/gui/Entry.cpp
+++ b/src/gui/Entry.cpp
@@ -20,7 +20,7 @@ namespace gsr {
}
bool Entry::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
- if(event.type == mgl::Event::MouseButtonPressed) {
+ if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
selected = mgl::FloatRect(position + offset, get_size()).contains({ (float)event.mouse_button.x, (float)event.mouse_button.y });
} else if(event.type == mgl::Event::KeyPressed && selected) {
if(event.key.code == mgl::Keyboard::Backspace && !text.get_string().empty()) {
diff --git a/src/gui/List.cpp b/src/gui/List.cpp
index 10be76f..4a74f62 100644
--- a/src/gui/List.cpp
+++ b/src/gui/List.cpp
@@ -1,22 +1,28 @@
#include "../../include/gui/List.hpp"
+static float floor(float f) {
+ return (int)f;
+}
+
namespace gsr {
// TODO: Make this modifiable, multiple by window size.
// TODO: Add homogeneous option, using a specified max size of this list.
static const mgl::vec2f spacing(30.0f, 10.0f);
- List::List(Orientation orientation) : orientation(orientation) {}
+ List::List(Orientation orientation, Alignment content_alignment) : orientation(orientation), content_alignment(content_alignment) {}
bool List::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f) {
- if(selected_child_widget) {
- if(!selected_child_widget->on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
+ // 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)))
return false;
}
// Process widgets by visibility (backwards)
for(auto it = widgets.rbegin(), end = widgets.rend(); it != end; ++it) {
// Ignore offset because widgets are positioned with offset in ::draw, this solution is simpler
- if(it->get() != selected_child_widget) {
+ if(it->get() != selected_widget) {
if(!(*it)->on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
return false;
}
@@ -27,13 +33,19 @@ namespace gsr {
void List::draw(mgl::Window &window, mgl::vec2f offset) {
mgl::vec2f draw_pos = position + offset;
+ offset = {0.0f, 0.0f};
+ Widget *selected_widget = selected_child_widget;
+
+ // TODO: Handle start/end alignment
+ const mgl::vec2f size = get_size();
- // TODO: Do same vertical/horizontal alignment for items
switch(orientation) {
case Orientation::VERTICAL: {
for(auto &widget : widgets) {
- widget->set_position(draw_pos);
- if(widget.get() != selected_child_widget)
+ if(content_alignment == Alignment::CENTER)
+ offset.x = floor(size.x * 0.5f - widget->get_size().x * 0.5f);
+ widget->set_position(draw_pos + offset);
+ if(widget.get() != selected_widget)
widget->draw(window, mgl::vec2f(0.0f, 0.0f));
draw_pos.y += widget->get_size().y + spacing.y;
}
@@ -41,8 +53,10 @@ namespace gsr {
}
case Orientation::HORIZONTAL: {
for(auto &widget : widgets) {
- widget->set_position(draw_pos);
- if(widget.get() != selected_child_widget)
+ if(content_alignment == Alignment::CENTER)
+ offset.y = floor(size.y * 0.5f - widget->get_size().y * 0.5f);
+ widget->set_position(draw_pos + offset);
+ if(widget.get() != selected_widget)
widget->draw(window, mgl::vec2f(0.0f, 0.0f));
draw_pos.x += widget->get_size().x + spacing.x;
}
@@ -50,8 +64,8 @@ namespace gsr {
}
}
- if(selected_child_widget)
- selected_child_widget->draw(window, mgl::vec2f(0.0f, 0.0f));
+ if(selected_widget)
+ selected_widget->draw(window, mgl::vec2f(0.0f, 0.0f));
}
void List::add_widget(std::unique_ptr<Widget> widget) {
diff --git a/src/gui/ScrollablePage.cpp b/src/gui/ScrollablePage.cpp
index de036b9..73b445e 100644
--- a/src/gui/ScrollablePage.cpp
+++ b/src/gui/ScrollablePage.cpp
@@ -10,15 +10,16 @@ namespace gsr {
bool ScrollablePage::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) {
const mgl::vec2f draw_pos = position + offset;
offset = draw_pos + mgl::vec2f(0.0f, get_border_size(window)).floor();
+ Widget *selected_widget = selected_child_widget;
- if(selected_child_widget) {
- if(!selected_child_widget->on_event(event, window, offset))
+ if(selected_widget) {
+ if(!selected_widget->on_event(event, window, offset))
return false;
}
// Process widgets by visibility (backwards)
for(auto it = widgets.rbegin(), end = widgets.rend(); it != end; ++it) {
- if(it->get() != selected_child_widget) {
+ if(it->get() != selected_widget) {
if(!(*it)->on_event(event, window, offset))
return false;
}
@@ -30,6 +31,7 @@ namespace gsr {
void ScrollablePage::draw(mgl::Window &window, mgl::vec2f offset) {
const mgl::vec2f draw_pos = position + offset;
offset = draw_pos + mgl::vec2f(0.0f, get_border_size(window)).floor();
+ Widget *selected_widget = selected_child_widget;
mgl_scissor prev_scissor;
mgl_window_get_scissor(window.internal_window(), &prev_scissor);
@@ -51,12 +53,12 @@ namespace gsr {
window.draw(border);
for(auto &widget : widgets) {
- if(widget.get() != selected_child_widget)
+ if(widget.get() != selected_widget)
widget->draw(window, offset);
}
- if(selected_child_widget)
- selected_child_widget->draw(window, offset);
+ if(selected_widget)
+ selected_widget->draw(window, offset);
mgl_window_set_scissor(window.internal_window(), &prev_scissor);
}
diff --git a/src/gui/StaticPage.cpp b/src/gui/StaticPage.cpp
index 1194d0f..a6d9b64 100644
--- a/src/gui/StaticPage.cpp
+++ b/src/gui/StaticPage.cpp
@@ -8,15 +8,16 @@ namespace gsr {
bool StaticPage::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) {
const mgl::vec2f draw_pos = position + offset;
offset = draw_pos;
+ Widget *selected_widget = selected_child_widget;
- if(selected_child_widget) {
- if(!selected_child_widget->on_event(event, window, offset))
+ if(selected_widget) {
+ if(!selected_widget->on_event(event, window, offset))
return false;
}
// Process widgets by visibility (backwards)
for(auto it = widgets.rbegin(), end = widgets.rend(); it != end; ++it) {
- if(it->get() != selected_child_widget) {
+ if(it->get() != selected_widget) {
if(!(*it)->on_event(event, window, offset))
return false;
}
@@ -28,6 +29,7 @@ namespace gsr {
void StaticPage::draw(mgl::Window &window, mgl::vec2f offset) {
const mgl::vec2f draw_pos = position + offset;
offset = draw_pos;
+ Widget *selected_widget = selected_child_widget;
mgl_scissor prev_scissor;
mgl_window_get_scissor(window.internal_window(), &prev_scissor);
@@ -39,12 +41,12 @@ namespace gsr {
mgl_window_set_scissor(window.internal_window(), &new_scissor);
for(auto &widget : widgets) {
- if(widget.get() != selected_child_widget)
+ if(widget.get() != selected_widget)
widget->draw(window, offset);
}
- if(selected_child_widget)
- selected_child_widget->draw(window, offset);
+ if(selected_widget)
+ selected_widget->draw(window, offset);
mgl_window_set_scissor(window.internal_window(), &prev_scissor);
}
diff --git a/src/main.cpp b/src/main.cpp
index f8a40e3..07aca20 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -99,16 +99,6 @@ static Bool set_window_wm_state(Display *display, Window window, Atom atom) {
return True;
}
-static Bool make_window_always_on_top(Display* display, Window window) {
- Atom net_wm_state_above_atom = XInternAtom(display, "_NET_WM_STATE_ABOVE", False);
- if(!net_wm_state_above_atom) {
- fprintf(stderr, "Error: failed to find atom _NET_WM_STATE_ABOVE\n");
- return False;
- }
-
- return set_window_wm_state(display, window, net_wm_state_above_atom);
-}
-
static Bool make_window_sticky(Display* display, Window window) {
Atom net_wm_state_sticky_atom = XInternAtom(display, "_NET_WM_STATE_STICKY", False);
if(!net_wm_state_sticky_atom) {
@@ -232,20 +222,35 @@ auto back_button = std::make_unique<gsr::Button>(&title_font, "Back", mgl::vec2f
}
if(gsr_info.supported_capture_options.portal)
record_area_box->add_item("Desktop portal", "portal");
+
+ if(!gsr_info.supported_capture_options.monitors.empty())
+ record_area_box->set_selected_item(gsr_info.supported_capture_options.monitors.front().name);
+ else if(gsr_info.supported_capture_options.portal)
+ record_area_box->set_selected_item("portal");
+
record_area_list->add_widget(std::move(record_area_box));
}
settings_list->add_widget(std::move(record_area_list));
- auto audio_devices_list = std::make_unique<gsr::List>(gsr::List::Orientation::VERTICAL);
+ auto audio_device_section_list = std::make_unique<gsr::List>(gsr::List::Orientation::VERTICAL);
{
- audio_devices_list->add_widget(std::make_unique<gsr::Label>(&title_font, "Audio:", gsr::get_theme().text_color));
- auto audio_device_box = std::make_unique<gsr::ComboBox>(&title_font);
- for(const auto &audio_device : audio_devices) {
- audio_device_box->add_item(audio_device.description, audio_device.name);
+ audio_device_section_list->add_widget(std::make_unique<gsr::Label>(&title_font, "Audio:", gsr::get_theme().text_color));
+ auto audio_devices_list = std::make_unique<gsr::List>(gsr::List::Orientation::VERTICAL);
+ for(int i = 0; i < 3; ++i) {
+ auto audio_device_list = std::make_unique<gsr::List>(gsr::List::Orientation::HORIZONTAL, gsr::List::Alignment::CENTER);
+ {
+ audio_device_list->add_widget(std::make_unique<gsr::Label>(&title_font, (std::to_string(1 + i) + ":").c_str(), gsr::get_theme().text_color));
+ auto audio_device_box = std::make_unique<gsr::ComboBox>(&title_font);
+ for(const auto &audio_device : audio_devices) {
+ audio_device_box->add_item(audio_device.description, audio_device.name);
+ }
+ audio_device_list->add_widget(std::move(audio_device_box));
+ }
+ audio_devices_list->add_widget(std::move(audio_device_list));
}
- audio_devices_list->add_widget(std::move(audio_device_box));
+ audio_device_section_list->add_widget(std::move(audio_devices_list));
}
- settings_list->add_widget(std::move(audio_devices_list));
+ settings_list->add_widget(std::move(audio_device_section_list));
auto quality_list = std::make_unique<gsr::List>(gsr::List::Orientation::HORIZONTAL);
{
@@ -257,6 +262,7 @@ auto back_button = std::make_unique<gsr::Button>(&title_font, "Back", mgl::vec2f
video_quality_box->add_item("High (Recommended for live streaming)", "high");
video_quality_box->add_item("Very high (Recommended)", "very_high");
video_quality_box->add_item("Ultra", "ultra");
+ video_quality_box->set_selected_item("very_high");
video_quality_list->add_widget(std::move(video_quality_box));
}
quality_list->add_widget(std::move(video_quality_list));
@@ -274,7 +280,6 @@ auto back_button = std::make_unique<gsr::Button>(&title_font, "Back", mgl::vec2f
auto framerate_list = std::make_unique<gsr::List>(gsr::List::Orientation::VERTICAL);
{
framerate_list->add_widget(std::make_unique<gsr::Label>(&title_font, "Frame rate:", gsr::get_theme().text_color));
- //create_entry_validator_integer_in_range
auto framerate_entry = std::make_unique<gsr::Entry>(&title_font, "60", title_font.get_character_size() * 2);
framerate_entry->validate_handler = gsr::create_entry_validator_integer_in_range(1, 500);
framerate_list->add_widget(std::move(framerate_entry));
@@ -302,7 +307,8 @@ auto back_button = std::make_unique<gsr::Button>(&title_font, "Back", mgl::vec2f
if(gsr_info.supported_video_codecs.vp9)
video_codec_box->add_item("VP9", "vp9");
// TODO: Add hdr options
- video_codec_box->add_item("H264 Software Encoder (Slow, not recommended)", "h264_software");
+ if(gsr_info.supported_video_codecs.h264_software)
+ video_codec_box->add_item("H264 Software Encoder (Slow, not recommended)", "h264_software");
video_codec_list->add_widget(std::move(video_codec_box));
}
codec_list->add_widget(std::move(video_codec_list));
@@ -335,10 +341,8 @@ auto back_button = std::make_unique<gsr::Button>(&title_font, "Back", mgl::vec2f
auto save_directory_list = std::make_unique<gsr::List>(gsr::List::Orientation::VERTICAL);
{
save_directory_list->add_widget(std::make_unique<gsr::Label>(&title_font, "Directory to save the video:", gsr::get_theme().text_color));
- auto directory_selection_box = std::make_unique<gsr::ComboBox>(&title_font);
// TODO:
- directory_selection_box->add_item("/home/dec05eba/Videos", "mp4");
- save_directory_list->add_widget(std::move(directory_selection_box));
+ save_directory_list->add_widget(std::make_unique<gsr::Entry>(&title_font, "/home/dec05eba/Videos", title_font.get_character_size() * 20));
}
file_list->add_widget(std::move(save_directory_list));
@@ -402,10 +406,10 @@ int main(int argc, char **argv) {
window_create_params.max_size = window_size;
window_create_params.position = window_pos;
window_create_params.hidden = true;
- //window_create_params.override_redirect = true;
+ window_create_params.override_redirect = true;
window_create_params.background_color = bg_color;
window_create_params.support_alpha = true;
- window_create_params.window_type = MGL_WINDOW_TYPE_DIALOG;
+ window_create_params.window_type = MGL_WINDOW_TYPE_NOTIFICATION;
mgl::Window window;
if(!window.create("gsr overlay", window_create_params))
@@ -700,7 +704,6 @@ int main(int argc, char **argv) {
update_overlay_shape();
window.set_visible(true);
- make_window_always_on_top(display, window.get_system_handle());
make_window_sticky(display, window.get_system_handle());
Cursor default_cursor = XCreateFontCursor(display, XC_arrow);