mirror of
https://repo.dec05eba.com/gpu-screen-recorder-ui
synced 2026-03-31 09:17:04 +09:00
File chooser navigation
This commit is contained in:
Submodule depends/mglpp updated: 61b2725ef1...685cd2d470
Binary file not shown.
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 7.1 KiB |
BIN
images/up_arrow.png
Normal file
BIN
images/up_arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
@@ -31,6 +31,7 @@ namespace gsr {
|
|||||||
mgl::Texture combobox_arrow_texture;
|
mgl::Texture combobox_arrow_texture;
|
||||||
mgl::Texture settings_texture;
|
mgl::Texture settings_texture;
|
||||||
mgl::Texture folder_texture;
|
mgl::Texture folder_texture;
|
||||||
|
mgl::Texture up_arrow_texture;
|
||||||
|
|
||||||
double double_click_timeout_seconds = 0.4;
|
double double_click_timeout_seconds = 0.4;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,4 +25,8 @@ namespace gsr {
|
|||||||
std::string get_videos_dir();
|
std::string get_videos_dir();
|
||||||
int create_directory_recursive(char *path);
|
int create_directory_recursive(char *path);
|
||||||
bool file_get_content(const char *filepath, std::string &file_content);
|
bool file_get_content(const char *filepath, std::string &file_content);
|
||||||
|
|
||||||
|
// Returns the path to the parent directory (ignoring trailing /)
|
||||||
|
// of "." if there is no parent directory and the directory path is relative
|
||||||
|
std::string get_parent_directory(std::string_view directory);
|
||||||
}
|
}
|
||||||
@@ -22,6 +22,7 @@ namespace gsr {
|
|||||||
void set_border_scale(float scale);
|
void set_border_scale(float scale);
|
||||||
|
|
||||||
const std::string& get_text() const;
|
const std::string& get_text() const;
|
||||||
|
void set_text(std::string str);
|
||||||
|
|
||||||
std::function<void()> on_click;
|
std::function<void()> on_click;
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,16 +1,51 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Widget.hpp"
|
#include "Widget.hpp"
|
||||||
|
#include "ScrollablePage.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <mglpp/graphics/Text.hpp>
|
#include <mglpp/graphics/Text.hpp>
|
||||||
|
#include <mglpp/graphics/Sprite.hpp>
|
||||||
#include <mglpp/system/Clock.hpp>
|
#include <mglpp/system/Clock.hpp>
|
||||||
|
|
||||||
// This currently only supports displaying folders
|
// This currently only supports displaying folders
|
||||||
// TODO: Support files as well
|
// TODO: Support files as well
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
|
class FileChooser;
|
||||||
|
|
||||||
|
class FileChooserBody : public Widget {
|
||||||
|
friend class FileChooser;
|
||||||
|
public:
|
||||||
|
FileChooserBody(FileChooser *file_chooser, mgl::vec2f size);
|
||||||
|
FileChooserBody(const FileChooserBody&) = delete;
|
||||||
|
FileChooserBody& operator=(const FileChooserBody&) = delete;
|
||||||
|
|
||||||
|
bool on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) override;
|
||||||
|
void draw(mgl::Window &window, mgl::vec2f offset) override;
|
||||||
|
|
||||||
|
mgl::vec2f get_size() override;
|
||||||
|
mgl::vec2f get_inner_size() override;
|
||||||
|
void set_size(mgl::vec2f size);
|
||||||
|
private:
|
||||||
|
void set_current_directory(const char *directory);
|
||||||
|
private:
|
||||||
|
struct Folder {
|
||||||
|
mgl::Text text;
|
||||||
|
time_t last_modified_seconds = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
FileChooser *file_chooser = nullptr;
|
||||||
|
mgl::vec2f size;
|
||||||
|
mgl::vec2f inner_size;
|
||||||
|
std::vector<Folder> folders;
|
||||||
|
int mouse_over_item = -1;
|
||||||
|
int selected_item = -1;
|
||||||
|
mgl::Clock double_click_timer;
|
||||||
|
int times_clicked_within_timer = 0;
|
||||||
|
};
|
||||||
|
|
||||||
class FileChooser : public Widget {
|
class FileChooser : public Widget {
|
||||||
public:
|
public:
|
||||||
FileChooser(const char *start_directory, mgl::vec2f size);
|
FileChooser(const char *start_directory, mgl::vec2f size);
|
||||||
@@ -23,6 +58,9 @@ namespace gsr {
|
|||||||
mgl::vec2f get_size() override;
|
mgl::vec2f get_size() override;
|
||||||
|
|
||||||
void set_current_directory(const char *directory);
|
void set_current_directory(const char *directory);
|
||||||
|
void open_subdirectory(const char *name);
|
||||||
|
void open_parent_directory();
|
||||||
|
const std::string& get_current_directory() const;
|
||||||
private:
|
private:
|
||||||
struct Folder {
|
struct Folder {
|
||||||
mgl::Text text;
|
mgl::Text text;
|
||||||
@@ -31,10 +69,8 @@ namespace gsr {
|
|||||||
|
|
||||||
mgl::vec2f size;
|
mgl::vec2f size;
|
||||||
mgl::Text current_directory_text;
|
mgl::Text current_directory_text;
|
||||||
int mouse_over_item = -1;
|
mgl::Sprite up_arrow_sprite;
|
||||||
int selected_item = -1;
|
ScrollablePage scrollable_page;
|
||||||
std::vector<Folder> folders;
|
FileChooserBody *file_chooser_body_ptr = nullptr;
|
||||||
mgl::Clock double_click_timer;
|
|
||||||
int times_clicked_within_timer = 0;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "Page.hpp"
|
#include "Page.hpp"
|
||||||
#include "Button.hpp"
|
#include "Button.hpp"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <mglpp/graphics/Text.hpp>
|
#include <mglpp/graphics/Text.hpp>
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
@@ -19,9 +20,12 @@ namespace gsr {
|
|||||||
mgl::vec2f get_inner_size() override;
|
mgl::vec2f get_inner_size() override;
|
||||||
|
|
||||||
void set_margins(float top, float bottom, float left, float right);
|
void set_margins(float top, float bottom, float left, float right);
|
||||||
void set_on_back_button_click(std::function<void()> on_click_handler);
|
void add_button(const std::string &text, const std::string &id, mgl::Color color);
|
||||||
|
|
||||||
|
std::function<void(const std::string &id)> on_click;
|
||||||
private:
|
private:
|
||||||
void draw_page_label(mgl::Window &window, mgl::vec2f body_pos);
|
void draw_page_label(mgl::Window &window, mgl::vec2f body_pos);
|
||||||
|
void draw_buttons(mgl::Window &window, mgl::vec2f body_pos, mgl::vec2f body_size);
|
||||||
void draw_children(mgl::Window &window, mgl::vec2f position);
|
void draw_children(mgl::Window &window, mgl::vec2f position);
|
||||||
|
|
||||||
float get_border_size() const;
|
float get_border_size() const;
|
||||||
@@ -29,11 +33,16 @@ namespace gsr {
|
|||||||
mgl::vec2f get_content_position();
|
mgl::vec2f get_content_position();
|
||||||
mgl::vec2f get_content_position_with_margin();
|
mgl::vec2f get_content_position_with_margin();
|
||||||
private:
|
private:
|
||||||
|
struct ButtonItem {
|
||||||
|
std::unique_ptr<Button> button;
|
||||||
|
std::string id;
|
||||||
|
};
|
||||||
|
|
||||||
float margin_top_scale = 0.0f;
|
float margin_top_scale = 0.0f;
|
||||||
float margin_bottom_scale = 0.0f;
|
float margin_bottom_scale = 0.0f;
|
||||||
float margin_left_scale = 0.0f;
|
float margin_left_scale = 0.0f;
|
||||||
float margin_right_scale = 0.0f;
|
float margin_right_scale = 0.0f;
|
||||||
Button back_button;
|
|
||||||
mgl::Text label_text;
|
mgl::Text label_text;
|
||||||
|
std::vector<ButtonItem> buttons;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -18,8 +18,12 @@ namespace gsr {
|
|||||||
void set_size(mgl::vec2f size);
|
void set_size(mgl::vec2f size);
|
||||||
|
|
||||||
void add_widget(std::unique_ptr<Widget> widget);
|
void add_widget(std::unique_ptr<Widget> widget);
|
||||||
|
|
||||||
|
void reset_scroll();
|
||||||
private:
|
private:
|
||||||
mgl::vec2f size;
|
mgl::vec2f size;
|
||||||
SafeVector<std::unique_ptr<Widget>> widgets;
|
SafeVector<std::unique_ptr<Widget>> widgets;
|
||||||
|
int scroll_target_y = 0;
|
||||||
|
double scroll_y = 0.0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -13,4 +13,6 @@ namespace mgl {
|
|||||||
namespace gsr {
|
namespace gsr {
|
||||||
// Inner border
|
// Inner border
|
||||||
void draw_rectangle_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size, mgl::Color color, float border_size);
|
void draw_rectangle_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size, mgl::Color color, float border_size);
|
||||||
|
double get_frame_delta_seconds();
|
||||||
|
void set_frame_delta_seconds(double frame_delta);
|
||||||
}
|
}
|
||||||
@@ -56,6 +56,9 @@ namespace gsr {
|
|||||||
if(!theme->folder_texture.load_from_file((resources_path + "images/folder.png").c_str(), {false, false, false}))
|
if(!theme->folder_texture.load_from_file((resources_path + "images/folder.png").c_str(), {false, false, false}))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
if(!theme->up_arrow_texture.load_from_file((resources_path + "images/up_arrow.png").c_str(), {false, false, false}))
|
||||||
|
goto error;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
|||||||
@@ -166,4 +166,22 @@ namespace gsr {
|
|||||||
fclose(file);
|
fclose(file);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string get_parent_directory(std::string_view directory) {
|
||||||
|
std::string result;
|
||||||
|
|
||||||
|
while(directory.size() > 1 && directory.back() == '/') {
|
||||||
|
directory.remove_suffix(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t prev_slash_index = directory.rfind('/');
|
||||||
|
if(prev_slash_index == 0) {
|
||||||
|
result = "/";
|
||||||
|
} else if(prev_slash_index == std::string_view::npos) {
|
||||||
|
result = ".";
|
||||||
|
} else {
|
||||||
|
result = directory.substr(0, prev_slash_index);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -23,8 +23,9 @@ namespace gsr {
|
|||||||
const mgl::vec2f item_size = get_size().floor();
|
const mgl::vec2f item_size = get_size().floor();
|
||||||
if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
|
if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
|
||||||
const bool clicked_inside = mgl::FloatRect(position + offset, item_size).contains({ (float)event.mouse_button.x, (float)event.mouse_button.y });
|
const bool clicked_inside = mgl::FloatRect(position + offset, item_size).contains({ (float)event.mouse_button.x, (float)event.mouse_button.y });
|
||||||
if(clicked_inside && on_click) {
|
if(clicked_inside) {
|
||||||
on_click();
|
if(on_click)
|
||||||
|
on_click();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,4 +77,8 @@ namespace gsr {
|
|||||||
const std::string& Button::get_text() const {
|
const std::string& Button::get_text() const {
|
||||||
return text.get_string();
|
return text.get_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Button::set_text(std::string str) {
|
||||||
|
text.set_string(std::move(str));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "../../include/gui/FileChooser.hpp"
|
#include "../../include/gui/FileChooser.hpp"
|
||||||
#include "../../include/gui/Utils.hpp"
|
#include "../../include/gui/Utils.hpp"
|
||||||
|
#include "../../include/Utils.hpp"
|
||||||
#include "../../include/Theme.hpp"
|
#include "../../include/Theme.hpp"
|
||||||
|
|
||||||
#include <mglpp/graphics/Rectangle.hpp>
|
#include <mglpp/graphics/Rectangle.hpp>
|
||||||
@@ -25,14 +26,12 @@ namespace gsr {
|
|||||||
static const float content_padding_bottom_scale = 0.03f;
|
static const float content_padding_bottom_scale = 0.03f;
|
||||||
static const float content_padding_left_scale = 0.03f;
|
static const float content_padding_left_scale = 0.03f;
|
||||||
static const float content_padding_right_scale = 0.03f;
|
static const float content_padding_right_scale = 0.03f;
|
||||||
|
static const float up_button_spacing_scale = 0.01f;
|
||||||
|
|
||||||
FileChooser::FileChooser(const char *start_directory, mgl::vec2f size) :
|
FileChooserBody::FileChooserBody(FileChooser *file_chooser, mgl::vec2f size) :
|
||||||
size(size), current_directory_text(start_directory, get_theme().body_font)
|
file_chooser(file_chooser), size(size), inner_size(size) {}
|
||||||
{
|
|
||||||
set_current_directory(start_directory);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FileChooser::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f offset) {
|
bool FileChooserBody::on_event(mgl::Event &event, mgl::Window&, mgl::vec2f) {
|
||||||
if(!visible)
|
if(!visible)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@@ -44,45 +43,29 @@ namespace gsr {
|
|||||||
}
|
}
|
||||||
double_click_timer.restart();
|
double_click_timer.restart();
|
||||||
|
|
||||||
|
const int prev_selected_item = selected_item;
|
||||||
selected_item = mouse_over_item;
|
selected_item = mouse_over_item;
|
||||||
|
const bool item_changed = selected_item != prev_selected_item;
|
||||||
|
if(item_changed)
|
||||||
|
times_clicked_within_timer = 1;
|
||||||
|
|
||||||
if(selected_item != -1 && times_clicked_within_timer > 0 && times_clicked_within_timer % 2 == 0) {
|
if(selected_item != -1 && times_clicked_within_timer > 0 && times_clicked_within_timer % 2 == 0) {
|
||||||
char new_directory[PATH_MAX];
|
file_chooser->open_subdirectory(folders[selected_item].text.get_string().c_str());
|
||||||
snprintf(new_directory, sizeof(new_directory), "%s/%s", current_directory_text.get_string().c_str(), folders[selected_item].text.get_string().c_str());
|
|
||||||
set_current_directory(new_directory);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileChooser::draw(mgl::Window &window, mgl::vec2f offset) {
|
void FileChooserBody::draw(mgl::Window &window, mgl::vec2f offset) {
|
||||||
mouse_over_item = -1;
|
mouse_over_item = -1;
|
||||||
|
|
||||||
if(!visible)
|
if(!visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const mgl::vec2f draw_pos_start = position + offset;
|
mgl_scissor scissor;
|
||||||
mgl::vec2f draw_pos = draw_pos_start;
|
mgl_window_get_scissor(window.internal_window(), &scissor);
|
||||||
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(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);
|
|
||||||
|
|
||||||
draw_pos += mgl::vec2f(0.0f, current_directory_background.get_size().y + spacing_between_current_directory_and_content * get_theme().window_height);
|
|
||||||
mgl::Rectangle content_background(mgl::vec2f(size.x, size.y - (draw_pos.y - draw_pos_start.y)).floor());
|
|
||||||
content_background.set_color(mgl::Color(0, 0, 0, 120));
|
|
||||||
content_background.set_position(draw_pos.floor());
|
|
||||||
window.draw(content_background);
|
|
||||||
|
|
||||||
|
const mgl::vec2f draw_pos = position + offset;
|
||||||
const mgl::vec2f mouse_pos = window.get_mouse_position().to_vec2f();
|
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_top = content_padding_top_scale * get_theme().window_height;
|
||||||
@@ -90,9 +73,11 @@ namespace gsr {
|
|||||||
const int content_padding_left = content_padding_left_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 int content_padding_right = content_padding_right_scale * get_theme().window_height;
|
||||||
|
|
||||||
const float folder_width = (int)((content_background.get_size().x - (content_padding_left + content_padding_right) * num_columns) / num_columns);
|
const float folder_width = (int)((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;
|
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);
|
mgl::vec2f folder_pos = draw_pos + mgl::vec2f(content_padding_left, content_padding_top);
|
||||||
|
bool end_is_newline = false;
|
||||||
|
|
||||||
for(int i = 0; i < (int)folders.size(); ++i) {
|
for(int i = 0; i < (int)folders.size(); ++i) {
|
||||||
auto &folder = folders[i];
|
auto &folder = folders[i];
|
||||||
|
|
||||||
@@ -118,32 +103,33 @@ namespace gsr {
|
|||||||
mouse_over_item = i;
|
mouse_over_item = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.draw(folder_sprite);
|
if(item_pos.y + item_size.y >= draw_pos.y && item_pos.y < scissor.position.y + scissor.size.y) {
|
||||||
|
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).
|
// 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));
|
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);
|
window.draw(folder.text);
|
||||||
|
}
|
||||||
|
|
||||||
folder_pos.x += width_per_item_after;
|
folder_pos.x += width_per_item_after;
|
||||||
if(folder_pos.x + folder_width > content_background.get_position().x + content_background.get_size().x) {
|
if(folder_pos.x + folder_width > draw_pos.x + size.x) {
|
||||||
folder_pos.x = content_background.get_position().x + content_padding_left;
|
folder_pos.x = draw_pos.x + content_padding_left;
|
||||||
folder_pos.y += content_padding_bottom + folder_sprite.get_size().y + content_padding_top;
|
folder_pos.y += content_padding_bottom + folder_sprite.get_size().y + content_padding_top;
|
||||||
|
if(i == (int)folders.size() - 1)
|
||||||
|
end_is_newline = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!end_is_newline)
|
||||||
|
folder_pos.y += content_padding_bottom + folder_width;
|
||||||
|
|
||||||
|
inner_size = mgl::vec2f(size.x, folder_pos.y - draw_pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
mgl::vec2f FileChooser::get_size() {
|
void FileChooserBody::set_current_directory(const char *directory) {
|
||||||
if(!visible)
|
|
||||||
return {0.0f, 0.0f};
|
|
||||||
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileChooser::set_current_directory(const char *directory) {
|
|
||||||
folders.clear();
|
folders.clear();
|
||||||
selected_item = -1;
|
selected_item = -1;
|
||||||
mouse_over_item = -1;
|
mouse_over_item = -1;
|
||||||
current_directory_text.set_string(directory);
|
|
||||||
|
|
||||||
DIR *d = opendir(directory);
|
DIR *d = opendir(directory);
|
||||||
if(!d) {
|
if(!d) {
|
||||||
@@ -176,4 +162,117 @@ namespace gsr {
|
|||||||
return folder_a.last_modified_seconds > folder_b.last_modified_seconds;
|
return folder_a.last_modified_seconds > folder_b.last_modified_seconds;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mgl::vec2f FileChooserBody::get_size() {
|
||||||
|
if(!visible)
|
||||||
|
return {0.0f, 0.0f};
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
mgl::vec2f FileChooserBody::get_inner_size() {
|
||||||
|
if(!visible)
|
||||||
|
return {0.0f, 0.0f};
|
||||||
|
|
||||||
|
return inner_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileChooserBody::set_size(mgl::vec2f size) {
|
||||||
|
this->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileChooser::FileChooser(const char *start_directory, mgl::vec2f size) :
|
||||||
|
size(size),
|
||||||
|
current_directory_text(start_directory, get_theme().body_font),
|
||||||
|
up_arrow_sprite(&get_theme().up_arrow_texture),
|
||||||
|
scrollable_page(size)
|
||||||
|
{
|
||||||
|
auto file_chooser_body = std::make_unique<FileChooserBody>(this, size);
|
||||||
|
file_chooser_body_ptr = file_chooser_body.get();
|
||||||
|
scrollable_page.add_widget(std::move(file_chooser_body));
|
||||||
|
set_current_directory(start_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FileChooser::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) {
|
||||||
|
if(!visible)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(event.type == mgl::Event::MouseButtonPressed && event.mouse_button.button == mgl::Mouse::Left) {
|
||||||
|
if(mgl::FloatRect(up_arrow_sprite.get_position(), up_arrow_sprite.get_size()).contains(mgl::vec2f(event.mouse_button.x, event.mouse_button.y))) {
|
||||||
|
open_parent_directory();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return scrollable_page.on_event(event, window, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileChooser::draw(mgl::Window &window, mgl::vec2f offset) {
|
||||||
|
if(!visible)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const mgl::vec2f draw_pos_start = position + offset;
|
||||||
|
mgl::vec2f draw_pos = draw_pos_start;
|
||||||
|
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::vec2f current_directory_background_size = mgl::vec2f(size.x, current_directory_text.get_bounds().size.y + current_directory_padding.y).floor();
|
||||||
|
|
||||||
|
up_arrow_sprite.set_height((int)(current_directory_background_size.y * 0.8f));
|
||||||
|
up_arrow_sprite.set_position((draw_pos + mgl::vec2f(size.x - up_arrow_sprite.get_size().x, current_directory_background_size.y * 0.5f - up_arrow_sprite.get_size().y * 0.5f)).floor());
|
||||||
|
const bool mouse_inside_up_arrow = mgl::FloatRect(up_arrow_sprite.get_position(), up_arrow_sprite.get_size()).contains(window.get_mouse_position().to_vec2f()) && !has_parent_with_selected_child_widget();
|
||||||
|
up_arrow_sprite.set_color(mouse_inside_up_arrow ? get_theme().tint_color : mgl::Color(255, 255, 255));
|
||||||
|
window.draw(up_arrow_sprite);
|
||||||
|
|
||||||
|
current_directory_background_size.x -= (up_arrow_sprite.get_size().x + up_button_spacing_scale * get_theme().window_height);
|
||||||
|
mgl::Rectangle current_directory_background(current_directory_background_size.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_size.y * 0.5f - current_directory_text.get_bounds().size.y * 0.5f)).floor());
|
||||||
|
window.draw(current_directory_text);
|
||||||
|
|
||||||
|
draw_pos += mgl::vec2f(0.0f, current_directory_background_size.y + spacing_between_current_directory_and_content * get_theme().window_height);
|
||||||
|
const mgl::vec2f body_size = mgl::vec2f(size.x, size.y - (draw_pos.y - draw_pos_start.y)).floor();
|
||||||
|
scrollable_page.set_size(body_size);
|
||||||
|
file_chooser_body_ptr->set_size(body_size);
|
||||||
|
|
||||||
|
mgl::Rectangle content_background(size.floor());
|
||||||
|
content_background.set_position(draw_pos.floor());
|
||||||
|
content_background.set_color(mgl::Color(0, 0, 0, 120));
|
||||||
|
window.draw(content_background);
|
||||||
|
|
||||||
|
scrollable_page.draw(window, draw_pos.floor());
|
||||||
|
}
|
||||||
|
|
||||||
|
mgl::vec2f FileChooser::get_size() {
|
||||||
|
if(!visible)
|
||||||
|
return {0.0f, 0.0f};
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileChooser::set_current_directory(const char *directory) {
|
||||||
|
current_directory_text.set_string(directory);
|
||||||
|
file_chooser_body_ptr->set_current_directory(directory);
|
||||||
|
scrollable_page.reset_scroll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileChooser::open_subdirectory(const char *name) {
|
||||||
|
char filepath[PATH_MAX];
|
||||||
|
snprintf(filepath, sizeof(filepath), "%s/%s", current_directory_text.get_string().c_str(), name);
|
||||||
|
set_current_directory(filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FileChooser::open_parent_directory() {
|
||||||
|
set_current_directory(get_parent_directory(current_directory_text.get_string()).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string& FileChooser::get_current_directory() const {
|
||||||
|
return current_directory_text.get_string();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,23 +6,24 @@
|
|||||||
#include <mglpp/window/Window.hpp>
|
#include <mglpp/window/Window.hpp>
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
|
static const float button_spacing_scale = 0.015f;
|
||||||
|
|
||||||
GsrPage::GsrPage() :
|
GsrPage::GsrPage() :
|
||||||
back_button(&get_theme().title_font, "Back",
|
|
||||||
mgl::vec2f(get_theme().window_width / 10, get_theme().window_height / 15).floor(), get_theme().page_bg_color),
|
|
||||||
label_text("Settings", get_theme().title_font)
|
label_text("Settings", get_theme().title_font)
|
||||||
{
|
{
|
||||||
//set_position(content_page_position);
|
|
||||||
const float margin = 0.02f;
|
const float margin = 0.02f;
|
||||||
set_margins(margin, margin, margin, margin);
|
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) {
|
bool GsrPage::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f) {
|
||||||
if(!visible)
|
if(!visible)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if(!back_button.on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
|
for(size_t i = 0; i < buttons.size(); ++i) {
|
||||||
return false;
|
ButtonItem &button_item = buttons[i];
|
||||||
|
if(!button_item.button->on_event(event, window, mgl::vec2f(0.0f, 0.0f)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const int margin_top = margin_top_scale * get_theme().window_height;
|
const int margin_top = margin_top_scale * get_theme().window_height;
|
||||||
const int margin_left = margin_left_scale * get_theme().window_height;
|
const int margin_left = margin_left_scale * get_theme().window_height;
|
||||||
@@ -49,8 +50,8 @@ namespace gsr {
|
|||||||
if(!visible)
|
if(!visible)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const mgl::vec2f content_page_size = get_size();
|
|
||||||
const mgl::vec2f content_page_position = get_content_position();
|
const mgl::vec2f content_page_position = get_content_position();
|
||||||
|
const mgl::vec2f content_page_size = get_size();
|
||||||
|
|
||||||
mgl::Rectangle background(content_page_size);
|
mgl::Rectangle background(content_page_size);
|
||||||
background.set_position(content_page_position);
|
background.set_position(content_page_position);
|
||||||
@@ -63,9 +64,7 @@ namespace gsr {
|
|||||||
window.draw(border);
|
window.draw(border);
|
||||||
|
|
||||||
draw_page_label(window, content_page_position);
|
draw_page_label(window, content_page_position);
|
||||||
|
draw_buttons(window, content_page_position, content_page_size);
|
||||||
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));
|
|
||||||
|
|
||||||
const int margin_top = margin_top_scale * get_theme().window_height;
|
const int margin_top = margin_top_scale * get_theme().window_height;
|
||||||
const int margin_left = margin_left_scale * get_theme().window_height;
|
const int margin_left = margin_left_scale * get_theme().window_height;
|
||||||
@@ -90,6 +89,16 @@ namespace gsr {
|
|||||||
window.draw(icon);
|
window.draw(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GsrPage::draw_buttons(mgl::Window &window, mgl::vec2f body_pos, mgl::vec2f body_size) {
|
||||||
|
float offset_y = 0.0f;
|
||||||
|
for(size_t i = 0; i < buttons.size(); ++i) {
|
||||||
|
ButtonItem &button_item = buttons[i];
|
||||||
|
button_item.button->set_position(body_pos + mgl::vec2f(body_size.x + get_horizontal_spacing(), offset_y).floor());
|
||||||
|
button_item.button->draw(window, mgl::vec2f(0.0f, 0.0f));
|
||||||
|
offset_y += button_item.button->get_size().y + (button_spacing_scale * get_theme().window_height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GsrPage::draw_children(mgl::Window &window, mgl::vec2f position) {
|
void GsrPage::draw_children(mgl::Window &window, mgl::vec2f position) {
|
||||||
Widget *selected_widget = selected_child_widget;
|
Widget *selected_widget = selected_child_widget;
|
||||||
|
|
||||||
@@ -142,8 +151,15 @@ namespace gsr {
|
|||||||
margin_right_scale = right;
|
margin_right_scale = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GsrPage::set_on_back_button_click(std::function<void()> on_click_handler) {
|
void GsrPage::add_button(const std::string &text, const std::string &id, mgl::Color color) {
|
||||||
back_button.on_click = std::move(on_click_handler);
|
auto button = std::make_unique<Button>(&get_theme().title_font, text.c_str(),
|
||||||
|
mgl::vec2f(get_theme().window_width / 10, get_theme().window_height / 15).floor(), color);
|
||||||
|
button->set_border_scale(0.003f);
|
||||||
|
button->on_click = [this, id]() {
|
||||||
|
if(on_click)
|
||||||
|
on_click(id);
|
||||||
|
};
|
||||||
|
buttons.push_back({ std::move(button), id });
|
||||||
}
|
}
|
||||||
|
|
||||||
float GsrPage::get_border_size() const {
|
float GsrPage::get_border_size() const {
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
#include "../../include/gui/ScrollablePage.hpp"
|
#include "../../include/gui/ScrollablePage.hpp"
|
||||||
|
#include "../../include/gui/Utils.hpp"
|
||||||
|
|
||||||
#include <mglpp/window/Window.hpp>
|
#include <mglpp/window/Window.hpp>
|
||||||
|
#include <mglpp/window/Event.hpp>
|
||||||
|
//#include <mglpp/graphics/Rectangle.hpp>
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
|
static const int scroll_speed = 80;
|
||||||
|
static const double scroll_update_speed = 10.0;
|
||||||
|
|
||||||
ScrollablePage::ScrollablePage(mgl::vec2f size) : size(size) {}
|
ScrollablePage::ScrollablePage(mgl::vec2f size) : size(size) {}
|
||||||
|
|
||||||
bool ScrollablePage::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) {
|
bool ScrollablePage::on_event(mgl::Event &event, mgl::Window &window, mgl::vec2f offset) {
|
||||||
if(!visible)
|
if(!visible)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const mgl::vec2f draw_pos = position + offset;
|
offset = position + offset + mgl::vec2f(0.0f, scroll_y);
|
||||||
offset = draw_pos;
|
|
||||||
Widget *selected_widget = selected_child_widget;
|
Widget *selected_widget = selected_child_widget;
|
||||||
|
|
||||||
if(selected_widget) {
|
if(selected_widget) {
|
||||||
@@ -19,21 +24,34 @@ namespace gsr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Process widgets by visibility (backwards)
|
// Process widgets by visibility (backwards)
|
||||||
return widgets.for_each_reverse([selected_widget, &window, &event, offset](std::unique_ptr<Widget> &widget) {
|
const bool continue_events = widgets.for_each_reverse([selected_widget, &window, &event, offset](std::unique_ptr<Widget> &widget) {
|
||||||
if(widget.get() != selected_widget) {
|
if(widget.get() != selected_widget) {
|
||||||
if(!widget->on_event(event, window, offset))
|
if(!widget->on_event(event, window, offset))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(!continue_events)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(event.type == mgl::Event::MouseWheelScrolled) {
|
||||||
|
const double scroll = event.mouse_wheel_scroll.delta * scroll_speed;
|
||||||
|
scroll_target_y += scroll;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScrollablePage::draw(mgl::Window &window, mgl::vec2f offset) {
|
void ScrollablePage::draw(mgl::Window &window, mgl::vec2f offset) {
|
||||||
if(!visible)
|
if(!visible || widgets.empty()) {
|
||||||
|
reset_scroll();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const mgl::vec2f draw_pos = position + offset;
|
offset = position + offset;
|
||||||
offset = draw_pos;
|
const mgl::vec2f page_scroll_start = offset;
|
||||||
|
|
||||||
mgl_scissor prev_scissor;
|
mgl_scissor prev_scissor;
|
||||||
mgl_window_get_scissor(window.internal_window(), &prev_scissor);
|
mgl_window_get_scissor(window.internal_window(), &prev_scissor);
|
||||||
@@ -46,16 +64,67 @@ namespace gsr {
|
|||||||
mgl_window_set_scissor(window.internal_window(), &new_scissor);
|
mgl_window_set_scissor(window.internal_window(), &new_scissor);
|
||||||
|
|
||||||
Widget *selected_widget = selected_child_widget;
|
Widget *selected_widget = selected_child_widget;
|
||||||
|
offset.y += scroll_y;
|
||||||
|
|
||||||
|
double child_top = 999999.0;
|
||||||
|
double child_bottom = 0.0;
|
||||||
for(size_t i = 0; i < widgets.size(); ++i) {
|
for(size_t i = 0; i < widgets.size(); ++i) {
|
||||||
auto &widget = widgets[i];
|
auto &widget = widgets[i];
|
||||||
if(widget.get() != selected_widget)
|
if(widget.get() != selected_widget) {
|
||||||
widget->draw(window, offset);
|
widget->draw(window, offset);
|
||||||
|
|
||||||
|
// TODO: Create a widget function to get the render area instead, which each widget should set (position + offset as start, and position + offset + size as end), this has to be done in the widgets to ensure that recursive rendering has correct position.
|
||||||
|
// TODO: Do these calls before drawing, so that scroll limits can be set before drawing to prevent scrolling from overflowing for 1 frame.
|
||||||
|
// To make that possible move inner_size calculation in FileChooserBody to the get_inner_size function.
|
||||||
|
// That calculation can be done without looping folders.
|
||||||
|
const mgl::vec2f widget_pos = widget->get_position() + offset;
|
||||||
|
const mgl::vec2f widget_inner_size = widget->get_inner_size();
|
||||||
|
|
||||||
|
child_top = std::min(child_top, (double)widget_pos.y);
|
||||||
|
child_bottom = std::max(child_bottom, (double)widget_pos.y + (double)widget_inner_size.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(selected_widget)
|
if(selected_widget) {
|
||||||
selected_widget->draw(window, offset);
|
selected_widget->draw(window, offset);
|
||||||
|
|
||||||
|
const mgl::vec2f widget_pos = selected_widget->get_position() + offset;
|
||||||
|
const mgl::vec2f widget_inner_size = selected_widget->get_inner_size();
|
||||||
|
|
||||||
|
child_top = std::min(child_top, (double)widget_pos.y);
|
||||||
|
child_bottom = std::max(child_bottom, (double)widget_pos.y + (double)widget_inner_size.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
const double child_height = child_bottom - child_top;
|
||||||
|
|
||||||
|
// Debug output
|
||||||
|
// mgl::Rectangle bottom(mgl::vec2f(size.x, 5.0f));
|
||||||
|
// bottom.set_color(mgl::Color(255, 0, 0, 255));
|
||||||
|
// bottom.set_position(mgl::vec2f(offset.x, child_bottom));
|
||||||
|
// window.draw(bottom);
|
||||||
|
|
||||||
|
// mgl::Rectangle bottom_d(mgl::vec2f(size.x, 5.0f));
|
||||||
|
// bottom_d.set_color(mgl::Color(0, 255, 0, 255));
|
||||||
|
// 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 child_draw_overflow = (page_scroll_start.y + size.y) - child_bottom;
|
||||||
|
if(scroll_y > 0.001 || child_height < size.y) {
|
||||||
|
scroll_target_y = 0;
|
||||||
|
} else if(child_draw_overflow > 0.001) {
|
||||||
|
scroll_target_y = scroll_y + child_draw_overflow;
|
||||||
|
}
|
||||||
|
|
||||||
mgl_window_set_scissor(window.internal_window(), &prev_scissor);
|
mgl_window_set_scissor(window.internal_window(), &prev_scissor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,4 +142,9 @@ namespace gsr {
|
|||||||
void ScrollablePage::add_widget(std::unique_ptr<Widget> widget) {
|
void ScrollablePage::add_widget(std::unique_ptr<Widget> widget) {
|
||||||
widgets.push_back(std::move(widget));
|
widgets.push_back(std::move(widget));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScrollablePage::reset_scroll() {
|
||||||
|
scroll_y = 0;
|
||||||
|
scroll_target_y = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -20,9 +20,11 @@ namespace gsr {
|
|||||||
settings_title_text("Settings", get_theme().title_font)
|
settings_title_text("Settings", get_theme().title_font)
|
||||||
{
|
{
|
||||||
auto content_page = std::make_unique<GsrPage>();
|
auto content_page = std::make_unique<GsrPage>();
|
||||||
content_page->set_on_back_button_click([page_stack]() {
|
content_page->add_button("Back", "back", get_theme().page_bg_color);
|
||||||
page_stack->pop();
|
content_page->on_click = [page_stack](const std::string &id) {
|
||||||
});
|
if(id == "back")
|
||||||
|
page_stack->pop();
|
||||||
|
};
|
||||||
content_page_ptr = content_page.get();
|
content_page_ptr = content_page.get();
|
||||||
add_widget(std::move(content_page));
|
add_widget(std::move(content_page));
|
||||||
|
|
||||||
@@ -363,19 +365,25 @@ namespace gsr {
|
|||||||
std::unique_ptr<List> SettingsPage::create_save_directory(const char *label) {
|
std::unique_ptr<List> SettingsPage::create_save_directory(const char *label) {
|
||||||
auto save_directory_list = std::make_unique<List>(List::Orientation::VERTICAL);
|
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));
|
save_directory_list->add_widget(std::make_unique<Label>(&get_theme().body_font, label, get_theme().text_color));
|
||||||
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));
|
auto save_directory_button = std::make_unique<Button>(&get_theme().body_font, "/home/dec05eba", 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]() {
|
save_directory_button->on_click = [this]() {
|
||||||
auto select_directory_page = std::make_unique<GsrPage>();
|
auto select_directory_page = std::make_unique<GsrPage>();
|
||||||
select_directory_page->set_on_back_button_click([this]() {
|
select_directory_page->add_button("Save", "save", get_theme().tint_color);
|
||||||
page_stack->pop();
|
select_directory_page->add_button("Cancel", "cancel", get_theme().page_bg_color);
|
||||||
});
|
|
||||||
|
|
||||||
auto file_chooser = std::make_unique<gsr::FileChooser>("/home/dec05eba", select_directory_page->get_inner_size());
|
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));
|
select_directory_page->add_widget(std::move(file_chooser));
|
||||||
|
|
||||||
|
select_directory_page->on_click = [this, file_chooser_ptr](const std::string &id) {
|
||||||
|
if(id == "save")
|
||||||
|
save_directory_button_ptr->set_text(file_chooser_ptr->get_current_directory());
|
||||||
|
page_stack->pop();
|
||||||
|
};
|
||||||
|
|
||||||
page_stack->push(std::move(select_directory_page));
|
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));
|
save_directory_list->add_widget(std::move(save_directory_button));
|
||||||
return save_directory_list;
|
return save_directory_list;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <mglpp/graphics/Rectangle.hpp>
|
#include <mglpp/graphics/Rectangle.hpp>
|
||||||
|
|
||||||
namespace gsr {
|
namespace gsr {
|
||||||
|
static double frame_delta_seconds = 1.0;
|
||||||
|
|
||||||
// TODO: Use vertices to make it one draw call
|
// TODO: Use vertices to make it one draw call
|
||||||
void draw_rectangle_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size, mgl::Color color, float border_size) {
|
void draw_rectangle_outline(mgl::Window &window, mgl::vec2f pos, mgl::vec2f size, mgl::Color color, float border_size) {
|
||||||
pos = pos.floor();
|
pos = pos.floor();
|
||||||
@@ -40,4 +42,12 @@ namespace gsr {
|
|||||||
window.draw(rect);
|
window.draw(rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double get_frame_delta_seconds() {
|
||||||
|
return frame_delta_seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_frame_delta_seconds(double frame_delta) {
|
||||||
|
frame_delta_seconds = frame_delta;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -666,7 +666,12 @@ int main(int argc, char **argv) {
|
|||||||
window.display();
|
window.display();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mgl::Clock frame_delta_clock;
|
||||||
while(window.is_open()) {
|
while(window.is_open()) {
|
||||||
|
const double frame_delta_seconds = frame_delta_clock.get_elapsed_time_seconds();
|
||||||
|
frame_delta_clock.restart();
|
||||||
|
gsr::set_frame_delta_seconds(frame_delta_seconds);
|
||||||
|
|
||||||
if(page_stack.empty() || !running) {
|
if(page_stack.empty() || !running) {
|
||||||
running = false;
|
running = false;
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|||||||
Reference in New Issue
Block a user