mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-08 17:57:02 +08:00
feat(screenshot-ui): add newest/oldest sort selector
Add a combo button to the screenshot gallery to sort files by modification time (newest or oldest first). Store timestamp per image and rebuild layout when sort order changes. Include translations for en_US and zh_CN.
This commit is contained in:
@@ -49,5 +49,8 @@
|
|||||||
"item.water.name": "water",
|
"item.water.name": "water",
|
||||||
"item.pig_spawn_egg.name": "pig spawn egg",
|
"item.pig_spawn_egg.name": "pig spawn egg",
|
||||||
"screenshot.no_screenshot": "No Screenshot",
|
"screenshot.no_screenshot": "No Screenshot",
|
||||||
"button.show_in_file_manager": "Show In File Manager"
|
"button.show_in_file_manager": "Show In File Manager",
|
||||||
|
"file.sort_type": "File Sort Type: {type}",
|
||||||
|
"file.newest_first": "Newest First",
|
||||||
|
"file.oldest_first": "Oldest First"
|
||||||
}
|
}
|
||||||
@@ -49,5 +49,8 @@
|
|||||||
"item.water.name": "水",
|
"item.water.name": "水",
|
||||||
"item.pig_spawn_egg.name": "猪猪刷怪蛋",
|
"item.pig_spawn_egg.name": "猪猪刷怪蛋",
|
||||||
"screenshot.no_screenshot": "没有截图",
|
"screenshot.no_screenshot": "没有截图",
|
||||||
"button.show_in_file_manager": "在文件管理器中显示"
|
"button.show_in_file_manager": "在文件管理器中显示",
|
||||||
|
"file.sort_type": "文件排序方式:{type}",
|
||||||
|
"file.newest_first": "最新在前",
|
||||||
|
"file.oldest_first": "最旧在前"
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "Cubed/ui/image.hpp"
|
#include "Cubed/ui/image.hpp"
|
||||||
#include "Cubed/ui/ui_manager.hpp"
|
#include "Cubed/ui/ui_manager.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
namespace Cubed {
|
namespace Cubed {
|
||||||
class Texture;
|
class Texture;
|
||||||
class ScreenshotScene;
|
class ScreenshotScene;
|
||||||
@@ -20,16 +22,22 @@ public:
|
|||||||
void update_layout(int width, int height);
|
void update_layout(int width, int height);
|
||||||
|
|
||||||
void open_lightbox(const Texture* image);
|
void open_lightbox(const Texture* image);
|
||||||
|
void update(float dt) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ImageInfo {
|
struct ImageInfo {
|
||||||
const Texture* texture = nullptr;
|
const Texture* texture = nullptr;
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
|
std::chrono::nanoseconds time{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class SortType { NEWEST_FIRST, OLDEST_FIRST };
|
||||||
|
|
||||||
ScreenshotScene& m_scene;
|
ScreenshotScene& m_scene;
|
||||||
std::vector<ImageInfo> m_image_infos;
|
std::vector<ImageInfo> m_image_infos;
|
||||||
|
SortType m_sort_type = SortType::NEWEST_FIRST;
|
||||||
|
bool m_need_rebuild = false;
|
||||||
Widget* m_lightbox = nullptr;
|
Widget* m_lightbox = nullptr;
|
||||||
Image* m_lightbox_image = nullptr;
|
Image* m_lightbox_image = nullptr;
|
||||||
bool handle_window_resize_event(const WindowResizeEvent& e) override;
|
bool handle_window_resize_event(const WindowResizeEvent& e) override;
|
||||||
|
|||||||
@@ -7,12 +7,14 @@
|
|||||||
#include "Cubed/tools/file_utils.hpp"
|
#include "Cubed/tools/file_utils.hpp"
|
||||||
#include "Cubed/ui/button.hpp"
|
#include "Cubed/ui/button.hpp"
|
||||||
#include "Cubed/ui/column_layout.hpp"
|
#include "Cubed/ui/column_layout.hpp"
|
||||||
|
#include "Cubed/ui/combo_button.hpp"
|
||||||
#include "Cubed/ui/row_layout.hpp"
|
#include "Cubed/ui/row_layout.hpp"
|
||||||
#include "Cubed/ui/scroll_view.hpp"
|
#include "Cubed/ui/scroll_view.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
namespace {
|
namespace {
|
||||||
constexpr std::array<std::string_view, 4> IMAGE_EXT{".jpg", ".jpeg", ".png",
|
constexpr std::array<std::string_view, 4> IMAGE_EXT{".jpg", ".jpeg", ".png",
|
||||||
@@ -61,6 +63,17 @@ void ScreenshotUI::update_layout(int width, int height) {
|
|||||||
info.texture->set_linear();
|
info.texture->set_linear();
|
||||||
info.height = info.texture->height() * IMAGE_SCALE;
|
info.height = info.texture->height() * IMAGE_SCALE;
|
||||||
info.width = info.texture->width() * IMAGE_SCALE;
|
info.width = info.texture->width() * IMAGE_SCALE;
|
||||||
|
std::error_code ec;
|
||||||
|
auto ftime = fs::last_write_time(entry, ec);
|
||||||
|
if (!ec) {
|
||||||
|
auto sys_time =
|
||||||
|
std::chrono::clock_cast<std::chrono::system_clock>(ftime);
|
||||||
|
info.time =
|
||||||
|
std::chrono::time_point_cast<std::chrono::nanoseconds>(
|
||||||
|
sys_time)
|
||||||
|
.time_since_epoch();
|
||||||
|
}
|
||||||
|
|
||||||
m_image_infos.emplace_back(std::move(info));
|
m_image_infos.emplace_back(std::move(info));
|
||||||
}
|
}
|
||||||
constexpr int PADDING = 50;
|
constexpr int PADDING = 50;
|
||||||
@@ -88,6 +101,18 @@ void ScreenshotUI::update_layout(int width, int height) {
|
|||||||
row->set_spacing(SPACING);
|
row->set_spacing(SPACING);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::sort(m_image_infos.begin(), m_image_infos.end(),
|
||||||
|
[this](const ImageInfo& a, const ImageInfo& b) {
|
||||||
|
switch (m_sort_type) {
|
||||||
|
case SortType::NEWEST_FIRST:
|
||||||
|
return a.time > b.time;
|
||||||
|
case SortType::OLDEST_FIRST:
|
||||||
|
return a.time < b.time;
|
||||||
|
default:
|
||||||
|
return a.time > b.time;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
for (auto& image : m_image_infos) {
|
for (auto& image : m_image_infos) {
|
||||||
if (!row) {
|
if (!row) {
|
||||||
create_row();
|
create_row();
|
||||||
@@ -111,14 +136,47 @@ void ScreenshotUI::update_layout(int width, int height) {
|
|||||||
.set_color(Color::WHITE)
|
.set_color(Color::WHITE)
|
||||||
.set_anchor(Anchor::CENTER);
|
.set_anchor(Anchor::CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto& combo = bg->add_child<ComboButton>();
|
||||||
|
combo.set_anchor(Anchor::TOP_RIGHT);
|
||||||
|
combo.set_offset(title.get_offset());
|
||||||
|
|
||||||
|
switch (m_sort_type) {
|
||||||
|
case SortType::NEWEST_FIRST:
|
||||||
|
combo.set_index(0);
|
||||||
|
break;
|
||||||
|
case SortType::OLDEST_FIRST:
|
||||||
|
combo.set_index(1);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
combo.set_index(0);
|
||||||
|
}
|
||||||
|
combo.set_combo_text("file.sort_type", "type");
|
||||||
|
std::vector<ComboPair> combos;
|
||||||
|
|
||||||
|
combos.emplace_back(tr("file.newest_first"), [this]() {
|
||||||
|
m_sort_type = SortType::NEWEST_FIRST;
|
||||||
|
m_need_rebuild = true;
|
||||||
|
});
|
||||||
|
combos.emplace_back(tr("file.oldest_first"), [this]() {
|
||||||
|
m_sort_type = SortType::OLDEST_FIRST;
|
||||||
|
m_need_rebuild = true;
|
||||||
|
});
|
||||||
|
combo.set_default_image(texture_manager);
|
||||||
|
combo.set_combos(combos);
|
||||||
|
}
|
||||||
|
|
||||||
auto& bottom_row = bg->add_child<RowLayout>();
|
auto& bottom_row = bg->add_child<RowLayout>();
|
||||||
bottom_row.set_spacing(10);
|
bottom_row.set_spacing(10);
|
||||||
bottom_row.set_anchor(Anchor::BOTTOM_CENTER).set_offset({0, -30});
|
bottom_row.set_anchor(Anchor::BOTTOM_CENTER).set_offset({0, -30});
|
||||||
|
|
||||||
auto& open_file = bottom_row.add_child<Button>();
|
auto& open_file = bottom_row.add_child<Button>();
|
||||||
open_file.set_default_image(texture_manager)
|
open_file.set_default_image(texture_manager)
|
||||||
.set_text(tr("button.show_in_file_manager"))
|
.set_text(tr("button.show_in_file_manager"))
|
||||||
.set_clicked(
|
.set_clicked(
|
||||||
[]() { Tools::open_file_manager(Renderer::SCREENSHOT_PATH); });
|
[]() { Tools::open_file_manager(Renderer::SCREENSHOT_PATH); });
|
||||||
|
|
||||||
auto& return_button = bottom_row.add_child<Button>();
|
auto& return_button = bottom_row.add_child<Button>();
|
||||||
return_button.set_default_image(texture_manager);
|
return_button.set_default_image(texture_manager);
|
||||||
return_button.set_text(tr("button.return"));
|
return_button.set_text(tr("button.return"));
|
||||||
@@ -164,6 +222,15 @@ void ScreenshotUI::open_lightbox(const Texture* image) {
|
|||||||
m_lightbox->set_visible(true);
|
m_lightbox->set_visible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScreenshotUI::update(float dt) {
|
||||||
|
|
||||||
|
if (m_need_rebuild) {
|
||||||
|
m_need_rebuild = false;
|
||||||
|
update_layout(Widget::get_window_width(), Widget::get_window_height());
|
||||||
|
}
|
||||||
|
UIManager::update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
bool ScreenshotUI::handle_window_resize_event(const WindowResizeEvent& e) {
|
bool ScreenshotUI::handle_window_resize_event(const WindowResizeEvent& e) {
|
||||||
update_layout(e.width, e.height);
|
update_layout(e.width, e.height);
|
||||||
return UIManager::handle_window_resize_event(e);
|
return UIManager::handle_window_resize_event(e);
|
||||||
|
|||||||
Reference in New Issue
Block a user