mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-01-31 01:13:04 +09:00
Make checkbox nicer
This commit is contained in:
8
TODO
8
TODO
@@ -31,4 +31,10 @@ Make hotkeys configurable.
|
||||
Move hotkey to gsr-overlay-daemon which should execute gpu-screen-recorder --info on start, write that output to /tmp/blabla (or $XDG_RUNTIME_DIR) and gsr-overlay
|
||||
should read that tmp file. gsr-overlay should remove show/hide functions for overlay and run show on startup.
|
||||
|
||||
Combobox shouldn't show all items if its the combobox at the bottom and scrolling is needed to show them all.
|
||||
Combobox shouldn't show all items if its the combobox at the bottom and scrolling is needed to show them all.
|
||||
|
||||
Filechooser should have the option to select list view, search bar and common folders/mounted drives on the left side for quick navigation.
|
||||
|
||||
Start recording/replay/streaming with correct data from settings.
|
||||
Save recording/replay/streaming status to file.
|
||||
Save gsr info data to file to quick re-open.
|
||||
BIN
images/checkbox_background.png
Normal file
BIN
images/checkbox_background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 982 B |
BIN
images/checkbox_circle.png
Normal file
BIN
images/checkbox_circle.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 727 B |
@@ -37,6 +37,8 @@ namespace gsr {
|
||||
mgl::Texture stream_button_texture;
|
||||
mgl::Texture close_texture;
|
||||
mgl::Texture logo_texture;
|
||||
mgl::Texture checkbox_circle_texture;
|
||||
mgl::Texture checkbox_background_texture;
|
||||
|
||||
double double_click_timeout_seconds = 0.4;
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <mglpp/graphics/Color.hpp>
|
||||
#include <mglpp/graphics/Text.hpp>
|
||||
#include <mglpp/graphics/Sprite.hpp>
|
||||
|
||||
namespace gsr {
|
||||
class CheckBox : public Widget {
|
||||
@@ -17,12 +18,16 @@ namespace gsr {
|
||||
|
||||
mgl::vec2f get_size() override;
|
||||
|
||||
void set_checked(bool checked);
|
||||
void set_checked(bool checked, bool animated = false);
|
||||
bool is_checked() const;
|
||||
private:
|
||||
void apply_animation();
|
||||
mgl::vec2f get_checkbox_size();
|
||||
private:
|
||||
mgl::Text text;
|
||||
mgl::Sprite background_sprite;
|
||||
mgl::Sprite circle_sprite;
|
||||
bool checked = false;
|
||||
float toggle_animation_value = 0.0f;
|
||||
};
|
||||
}
|
||||
@@ -24,6 +24,10 @@ namespace gsr {
|
||||
|
||||
void reset_scroll();
|
||||
private:
|
||||
void apply_animation();
|
||||
void limit_scroll(double child_height);
|
||||
void limit_scroll_cursor(mgl::Window &window, double child_height, double scrollbar_empty_space);
|
||||
void draw_scrollbar();
|
||||
float get_scrollbar_width() const;
|
||||
private:
|
||||
mgl::vec2f size;
|
||||
|
||||
@@ -483,7 +483,7 @@ namespace gsr {
|
||||
ButtonMotionMask,
|
||||
GrabModeAsync, GrabModeAsync, None, default_cursor, CurrentTime);
|
||||
// TODO: This breaks global hotkeys
|
||||
//XGrabKeyboard(display, window.get_system_handle(), True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
XGrabKeyboard(display, window.get_system_handle(), True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||
|
||||
XSetInputFocus(display, window.get_system_handle(), RevertToParent, CurrentTime);
|
||||
XFlush(display);
|
||||
@@ -508,7 +508,7 @@ namespace gsr {
|
||||
default_cursor = 0;
|
||||
}
|
||||
|
||||
//XUngrabKeyboard(display, CurrentTime);
|
||||
XUngrabKeyboard(display, CurrentTime);
|
||||
XUngrabPointer(display, CurrentTime);
|
||||
XFlush(display);
|
||||
|
||||
|
||||
@@ -82,6 +82,12 @@ namespace gsr {
|
||||
if(!theme->logo_texture.load_from_file((resources_path + "images/gpu_screen_recorder_logo.png").c_str()))
|
||||
goto error;
|
||||
|
||||
if(!theme->checkbox_circle_texture.load_from_file((resources_path + "images/checkbox_circle.png").c_str()))
|
||||
goto error;
|
||||
|
||||
if(!theme->checkbox_background_texture.load_from_file((resources_path + "images/checkbox_background.png").c_str()))
|
||||
goto error;
|
||||
|
||||
return true;
|
||||
|
||||
error:
|
||||
|
||||
@@ -8,11 +8,32 @@
|
||||
|
||||
namespace gsr {
|
||||
static const float spacing_scale = 0.005f;
|
||||
static const float checked_margin_scale = 0.003f;
|
||||
static const float border_scale = 0.001f;
|
||||
static const float check_animation_speed = 10.0f;
|
||||
|
||||
CheckBox::CheckBox(mgl::Font *font, const char *text) : text(text, *font) {
|
||||
static mgl::Color color_multiply(mgl::Color color, float multiply) {
|
||||
return mgl::Color(color.r * multiply, color.g * multiply, color.b * multiply, color.a);
|
||||
}
|
||||
|
||||
static float linear_interpolation(float source, float destination, float interpolation) {
|
||||
return source + (destination - source) * interpolation;
|
||||
}
|
||||
|
||||
static mgl::Color interpolate_color(mgl::Color source, mgl::Color destination, float interpolation) {
|
||||
mgl::Color color;
|
||||
color.r = linear_interpolation(source.r, destination.r, interpolation);
|
||||
color.g = linear_interpolation(source.g, destination.g, interpolation);
|
||||
color.b = linear_interpolation(source.b, destination.b, interpolation);
|
||||
color.a = linear_interpolation(source.a, destination.a, interpolation);
|
||||
return color;
|
||||
}
|
||||
|
||||
CheckBox::CheckBox(mgl::Font *font, const char *text) :
|
||||
text(text, *font),
|
||||
background_sprite(&get_theme().checkbox_background_texture),
|
||||
circle_sprite(&get_theme().checkbox_circle_texture)
|
||||
{
|
||||
background_sprite.set_color(get_theme().tint_color);
|
||||
circle_sprite.set_color(get_theme().tint_color);
|
||||
}
|
||||
|
||||
bool CheckBox::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
|
||||
@@ -32,31 +53,36 @@ namespace gsr {
|
||||
return;
|
||||
|
||||
const mgl::vec2f draw_pos = position + offset;
|
||||
|
||||
const mgl::vec2f checkbox_size = get_checkbox_size();
|
||||
mgl::Rectangle background(get_checkbox_size());
|
||||
background.set_position(draw_pos.floor());
|
||||
background.set_color(mgl::Color(0, 0, 0, 120));
|
||||
window.draw(background);
|
||||
|
||||
if(checked) {
|
||||
const float side_margin = checked_margin_scale * get_theme().window_height;
|
||||
mgl::Rectangle background(get_checkbox_size() - mgl::vec2f(side_margin, side_margin).floor() * 2.0f);
|
||||
background.set_position(draw_pos.floor() + mgl::vec2f(side_margin, side_margin).floor());
|
||||
background.set_color(get_theme().tint_color);
|
||||
window.draw(background);
|
||||
}
|
||||
apply_animation();
|
||||
|
||||
const mgl::Color background_color_unchecked(0, 0, 0, 120);
|
||||
const mgl::Color background_color_checked = color_multiply(get_theme().tint_color, 0.7f);
|
||||
background_sprite.set_color(interpolate_color(background_color_unchecked, background_color_checked, checked ? 1.0f : 0.0f));
|
||||
background_sprite.set_position(draw_pos.floor());
|
||||
window.draw(background_sprite);
|
||||
|
||||
circle_sprite.set_height((int)background_sprite.get_size().y);
|
||||
const float circle_animation_x = linear_interpolation(0.0f, background_sprite.get_size().x - circle_sprite.get_size().x, toggle_animation_value);
|
||||
circle_sprite.set_position((draw_pos + mgl::vec2f(circle_animation_x, 0.0f)).floor());
|
||||
window.draw(circle_sprite);
|
||||
|
||||
const mgl::vec2f text_bounds = text.get_bounds().size;
|
||||
text.set_position((draw_pos + mgl::vec2f(checkbox_size.x + spacing_scale * get_theme().window_height, checkbox_size.y * 0.5f - text_bounds.y * 0.5f)).floor());
|
||||
window.draw(text);
|
||||
}
|
||||
|
||||
const bool mouse_inside = mgl::FloatRect(draw_pos, get_size()).contains(window.get_mouse_position().to_vec2f()) && !has_parent_with_selected_child_widget();
|
||||
if(mouse_inside) {
|
||||
const int border_size = std::max(1.0f, border_scale * get_theme().window_height);
|
||||
const mgl::Color border_color = get_theme().tint_color;
|
||||
draw_rectangle_outline(window, draw_pos, checkbox_size, border_color, border_size);
|
||||
}
|
||||
void CheckBox::apply_animation() {
|
||||
if(checked)
|
||||
toggle_animation_value += (get_frame_delta_seconds() * check_animation_speed);
|
||||
else
|
||||
toggle_animation_value -= (get_frame_delta_seconds() * check_animation_speed);
|
||||
|
||||
if(toggle_animation_value < 0.0f)
|
||||
toggle_animation_value = 0.0f;
|
||||
else if(toggle_animation_value > 1.0f)
|
||||
toggle_animation_value = 1.0f;
|
||||
}
|
||||
|
||||
mgl::vec2f CheckBox::get_size() {
|
||||
@@ -71,12 +97,14 @@ namespace gsr {
|
||||
}
|
||||
|
||||
mgl::vec2f CheckBox::get_checkbox_size() {
|
||||
const mgl::vec2f text_bounds = text.get_bounds().size;
|
||||
return mgl::vec2f(text_bounds.y, text_bounds.y).floor();
|
||||
background_sprite.set_height((int)text.get_bounds().size.y);
|
||||
return background_sprite.get_size().floor();
|
||||
}
|
||||
|
||||
void CheckBox::set_checked(bool checked) {
|
||||
void CheckBox::set_checked(bool checked, bool animated) {
|
||||
this->checked = checked;
|
||||
if(!animated)
|
||||
toggle_animation_value = checked ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
bool CheckBox::is_checked() const {
|
||||
|
||||
@@ -132,24 +132,8 @@ namespace gsr {
|
||||
// bottom_d.set_position(mgl::vec2f(offset.x, page_scroll_start.y + size.y - 5));
|
||||
// window.draw(bottom_d);
|
||||
|
||||
// Scroll animation
|
||||
const double scroll_diff = scroll_target_y - scroll_y;
|
||||
if(std::abs(scroll_diff) < 0.1) {
|
||||
scroll_y = scroll_target_y;
|
||||
} else {
|
||||
const double frame_scroll_speed = std::min(1.0, get_frame_delta_seconds() * scroll_update_speed);
|
||||
scroll_y += (scroll_diff * frame_scroll_speed);
|
||||
}
|
||||
|
||||
// Top and bottom limit
|
||||
const double scroll_bottom_limit = child_height - size.y;
|
||||
if(scroll_y > 0.001 || child_height < size.y) {
|
||||
scroll_y = 0;
|
||||
scroll_target_y = 0;
|
||||
} else if(scroll_y < -scroll_bottom_limit) {
|
||||
scroll_y = -scroll_bottom_limit;
|
||||
scroll_target_y = -scroll_bottom_limit;
|
||||
}
|
||||
apply_animation();
|
||||
limit_scroll(child_height);
|
||||
|
||||
mgl_window_set_scissor(window.internal_window(), &prev_scissor);
|
||||
|
||||
@@ -179,7 +163,33 @@ namespace gsr {
|
||||
scrollbar_rect.size = scrollbar.get_size();
|
||||
}
|
||||
|
||||
limit_scroll_cursor(window, child_height, scrollbar_empty_space);
|
||||
}
|
||||
|
||||
void ScrollablePage::apply_animation() {
|
||||
const double scroll_diff = scroll_target_y - scroll_y;
|
||||
if(std::abs(scroll_diff) < 0.1) {
|
||||
scroll_y = scroll_target_y;
|
||||
} else {
|
||||
const double frame_scroll_speed = std::min(1.0, get_frame_delta_seconds() * scroll_update_speed);
|
||||
scroll_y += (scroll_diff * frame_scroll_speed);
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollablePage::limit_scroll(double child_height) {
|
||||
const double scroll_bottom_limit = child_height - size.y;
|
||||
if(scroll_y > 0.001 || child_height < size.y) {
|
||||
scroll_y = 0;
|
||||
scroll_target_y = 0;
|
||||
} else if(scroll_y < -scroll_bottom_limit) {
|
||||
scroll_y = -scroll_bottom_limit;
|
||||
scroll_target_y = -scroll_bottom_limit;
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollablePage::limit_scroll_cursor(mgl::Window &window, double child_height, double scrollbar_empty_space) {
|
||||
if(moving_scrollbar_with_cursor) {
|
||||
const double scroll_bottom_limit = child_height - size.y;
|
||||
const mgl::vec2f scrollbar_move_diff = window.get_mouse_position().to_vec2f() - scrollbar_move_cursor_start_pos;
|
||||
const double scroll_amount = scrollbar_move_diff.y / scrollbar_empty_space;
|
||||
scroll_y = scrollbar_move_cursor_scroll_y_start - scroll_amount * (child_height - size.y);
|
||||
|
||||
Reference in New Issue
Block a user