mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-03-31 09:17:04 +09:00
Make checkbox nicer
This commit is contained in:
6
TODO
6
TODO
@@ -32,3 +32,9 @@ Move hotkey to gsr-overlay-daemon which should execute gpu-screen-recorder --inf
|
|||||||
should read that tmp file. gsr-overlay should remove show/hide functions for overlay and run show on startup.
|
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 stream_button_texture;
|
||||||
mgl::Texture close_texture;
|
mgl::Texture close_texture;
|
||||||
mgl::Texture logo_texture;
|
mgl::Texture logo_texture;
|
||||||
|
mgl::Texture checkbox_circle_texture;
|
||||||
|
mgl::Texture checkbox_background_texture;
|
||||||
|
|
||||||
double double_click_timeout_seconds = 0.4;
|
double double_click_timeout_seconds = 0.4;
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <mglpp/graphics/Color.hpp>
|
#include <mglpp/graphics/Color.hpp>
|
||||||
#include <mglpp/graphics/Text.hpp>
|
#include <mglpp/graphics/Text.hpp>
|
||||||
|
#include <mglpp/graphics/Sprite.hpp>
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
class CheckBox : public Widget {
|
class CheckBox : public Widget {
|
||||||
@@ -17,12 +18,16 @@ namespace gsr {
|
|||||||
|
|
||||||
mgl::vec2f get_size() override;
|
mgl::vec2f get_size() override;
|
||||||
|
|
||||||
void set_checked(bool checked);
|
void set_checked(bool checked, bool animated = false);
|
||||||
bool is_checked() const;
|
bool is_checked() const;
|
||||||
private:
|
private:
|
||||||
|
void apply_animation();
|
||||||
mgl::vec2f get_checkbox_size();
|
mgl::vec2f get_checkbox_size();
|
||||||
private:
|
private:
|
||||||
mgl::Text text;
|
mgl::Text text;
|
||||||
|
mgl::Sprite background_sprite;
|
||||||
|
mgl::Sprite circle_sprite;
|
||||||
bool checked = false;
|
bool checked = false;
|
||||||
|
float toggle_animation_value = 0.0f;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,10 @@ namespace gsr {
|
|||||||
|
|
||||||
void reset_scroll();
|
void reset_scroll();
|
||||||
private:
|
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;
|
float get_scrollbar_width() const;
|
||||||
private:
|
private:
|
||||||
mgl::vec2f size;
|
mgl::vec2f size;
|
||||||
|
|||||||
@@ -483,7 +483,7 @@ namespace gsr {
|
|||||||
ButtonMotionMask,
|
ButtonMotionMask,
|
||||||
GrabModeAsync, GrabModeAsync, None, default_cursor, CurrentTime);
|
GrabModeAsync, GrabModeAsync, None, default_cursor, CurrentTime);
|
||||||
// TODO: This breaks global hotkeys
|
// 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);
|
XSetInputFocus(display, window.get_system_handle(), RevertToParent, CurrentTime);
|
||||||
XFlush(display);
|
XFlush(display);
|
||||||
@@ -508,7 +508,7 @@ namespace gsr {
|
|||||||
default_cursor = 0;
|
default_cursor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//XUngrabKeyboard(display, CurrentTime);
|
XUngrabKeyboard(display, CurrentTime);
|
||||||
XUngrabPointer(display, CurrentTime);
|
XUngrabPointer(display, CurrentTime);
|
||||||
XFlush(display);
|
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()))
|
if(!theme->logo_texture.load_from_file((resources_path + "images/gpu_screen_recorder_logo.png").c_str()))
|
||||||
goto error;
|
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;
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|||||||
@@ -8,11 +8,32 @@
|
|||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
static const float spacing_scale = 0.005f;
|
static const float spacing_scale = 0.005f;
|
||||||
static const float checked_margin_scale = 0.003f;
|
static const float check_animation_speed = 10.0f;
|
||||||
static const float border_scale = 0.001f;
|
|
||||||
|
|
||||||
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) {
|
bool CheckBox::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
|
||||||
@@ -32,31 +53,36 @@ namespace gsr {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const mgl::vec2f draw_pos = position + offset;
|
const mgl::vec2f draw_pos = position + offset;
|
||||||
|
|
||||||
const mgl::vec2f checkbox_size = get_checkbox_size();
|
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) {
|
apply_animation();
|
||||||
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);
|
const mgl::Color background_color_unchecked(0, 0, 0, 120);
|
||||||
background.set_position(draw_pos.floor() + mgl::vec2f(side_margin, side_margin).floor());
|
const mgl::Color background_color_checked = color_multiply(get_theme().tint_color, 0.7f);
|
||||||
background.set_color(get_theme().tint_color);
|
background_sprite.set_color(interpolate_color(background_color_unchecked, background_color_checked, checked ? 1.0f : 0.0f));
|
||||||
window.draw(background);
|
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;
|
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());
|
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);
|
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();
|
void CheckBox::apply_animation() {
|
||||||
if(mouse_inside) {
|
if(checked)
|
||||||
const int border_size = std::max(1.0f, border_scale * get_theme().window_height);
|
toggle_animation_value += (get_frame_delta_seconds() * check_animation_speed);
|
||||||
const mgl::Color border_color = get_theme().tint_color;
|
else
|
||||||
draw_rectangle_outline(window, draw_pos, checkbox_size, border_color, border_size);
|
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() {
|
mgl::vec2f CheckBox::get_size() {
|
||||||
@@ -71,12 +97,14 @@ namespace gsr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mgl::vec2f CheckBox::get_checkbox_size() {
|
mgl::vec2f CheckBox::get_checkbox_size() {
|
||||||
const mgl::vec2f text_bounds = text.get_bounds().size;
|
background_sprite.set_height((int)text.get_bounds().size.y);
|
||||||
return mgl::vec2f(text_bounds.y, text_bounds.y).floor();
|
return background_sprite.get_size().floor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckBox::set_checked(bool checked) {
|
void CheckBox::set_checked(bool checked, bool animated) {
|
||||||
this->checked = checked;
|
this->checked = checked;
|
||||||
|
if(!animated)
|
||||||
|
toggle_animation_value = checked ? 1.0f : 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckBox::is_checked() const {
|
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));
|
// bottom_d.set_position(mgl::vec2f(offset.x, page_scroll_start.y + size.y - 5));
|
||||||
// window.draw(bottom_d);
|
// window.draw(bottom_d);
|
||||||
|
|
||||||
// Scroll animation
|
apply_animation();
|
||||||
const double scroll_diff = scroll_target_y - scroll_y;
|
limit_scroll(child_height);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
mgl_window_set_scissor(window.internal_window(), &prev_scissor);
|
mgl_window_set_scissor(window.internal_window(), &prev_scissor);
|
||||||
|
|
||||||
@@ -179,7 +163,33 @@ namespace gsr {
|
|||||||
scrollbar_rect.size = scrollbar.get_size();
|
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) {
|
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 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;
|
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);
|
scroll_y = scrollbar_move_cursor_scroll_y_start - scroll_amount * (child_height - size.y);
|
||||||
|
|||||||
Reference in New Issue
Block a user