Added options in file selector screen main menu
This commit is contained in:
parent
06dd550067
commit
1fb8aa4409
7 changed files with 240 additions and 46 deletions
1
assets/data/icons/RemixIcon/settings-3-line.svg
Normal file
1
assets/data/icons/RemixIcon/settings-3-line.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M3.33946 17.0002C2.90721 16.2515 2.58277 15.4702 2.36133 14.6741C3.3338 14.1779 3.99972 13.1668 3.99972 12.0002C3.99972 10.8345 3.3348 9.824 2.36353 9.32741C2.81025 7.71651 3.65857 6.21627 4.86474 4.99001C5.7807 5.58416 6.98935 5.65534 7.99972 5.072C9.01009 4.48866 9.55277 3.40635 9.4962 2.31604C11.1613 1.8846 12.8847 1.90004 14.5031 2.31862C14.4475 3.40806 14.9901 4.48912 15.9997 5.072C17.0101 5.65532 18.2187 5.58416 19.1346 4.99007C19.7133 5.57986 20.2277 6.25151 20.66 7.00021C21.0922 7.7489 21.4167 8.53025 21.6381 9.32628C20.6656 9.82247 19.9997 10.8336 19.9997 12.0002C19.9997 13.166 20.6646 14.1764 21.6359 14.673C21.1892 16.2839 20.3409 17.7841 19.1347 19.0104C18.2187 18.4163 17.0101 18.3451 15.9997 18.9284C14.9893 19.5117 14.4467 20.5941 14.5032 21.6844C12.8382 22.1158 11.1148 22.1004 9.49633 21.6818C9.55191 20.5923 9.00929 19.5113 7.99972 18.9284C6.98938 18.3451 5.78079 18.4162 4.86484 19.0103C4.28617 18.4205 3.77172 17.7489 3.33946 17.0002ZM8.99972 17.1964C10.0911 17.8265 10.8749 18.8227 11.2503 19.9659C11.7486 20.0133 12.2502 20.014 12.7486 19.9675C13.1238 18.8237 13.9078 17.8268 14.9997 17.1964C16.0916 16.5659 17.347 16.3855 18.5252 16.6324C18.8146 16.224 19.0648 15.7892 19.2729 15.334C18.4706 14.4373 17.9997 13.2604 17.9997 12.0002C17.9997 10.74 18.4706 9.5632 19.2729 8.6665C19.1688 8.4405 19.0538 8.21822 18.9279 8.00021C18.802 7.78219 18.667 7.57148 18.5233 7.36842C17.3457 7.61476 16.0911 7.43414 14.9997 6.80405C13.9083 6.17395 13.1246 5.17768 12.7491 4.03455C12.2509 3.98714 11.7492 3.98646 11.2509 4.03292C10.8756 5.17671 10.0916 6.17364 8.99972 6.80405C7.9078 7.43447 6.65245 7.61494 5.47428 7.36803C5.18485 7.77641 4.93463 8.21117 4.72656 8.66637C5.52881 9.56311 5.99972 10.74 5.99972 12.0002C5.99972 13.2604 5.52883 14.4372 4.72656 15.3339C4.83067 15.5599 4.94564 15.7822 5.07152 16.0002C5.19739 16.2182 5.3324 16.4289 5.47612 16.632C6.65377 16.3857 7.90838 16.5663 8.99972 17.1964ZM11.9997 15.0002C10.3429 15.0002 8.99972 13.6571 8.99972 12.0002C8.99972 10.3434 10.3429 9.00021 11.9997 9.00021C13.6566 9.00021 14.9997 10.3434 14.9997 12.0002C14.9997 13.6571 13.6566 15.0002 11.9997 15.0002ZM11.9997 13.0002C12.552 13.0002 12.9997 12.5525 12.9997 12.0002C12.9997 11.4479 12.552 11.0002 11.9997 11.0002C11.4474 11.0002 10.9997 11.4479 10.9997 12.0002C10.9997 12.5525 11.4474 13.0002 11.9997 13.0002Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
|
|
@ -1,5 +1,6 @@
|
|||
#include "ButtonHelpers.hpp"
|
||||
#include "../Elements/SVGIcon.hpp"
|
||||
#include "../Elements/LayoutElement.hpp"
|
||||
#include "TextLabelHelpers.hpp"
|
||||
|
||||
namespace GUIStuff { namespace ElementHelpers {
|
||||
|
|
@ -26,6 +27,51 @@ void text_button(GUIManager& gui, const char* id, std::string_view text, const T
|
|||
}
|
||||
}
|
||||
|
||||
void text_button_with_icon(GUIManager& gui, const char* id, const std::string& svgPath, std::string_view text, const TextButtonOptions& options) {
|
||||
gui.new_id(id, [&] {
|
||||
SelectableButton::Data d = selectable_button_options_to_data(options);
|
||||
d.innerContent = [&gui, svgPath, text, centered = options.centered] (const SelectableButton::InnerContentCallbackParameters&) {
|
||||
gui.element<LayoutElement>("layoutelem", [&] (LayoutElement* l, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) },
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
}
|
||||
}) {
|
||||
if(l->get_bb().has_value()) {
|
||||
float iconSize = l->get_bb().value().height();
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(iconSize), .height = CLAY_SIZING_FIXED(iconSize)},
|
||||
},
|
||||
.aspectRatio = {.aspectRatio = 1.0f}
|
||||
}) {
|
||||
gui.element<SVGIcon>("icon", svgPath, false);
|
||||
}
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0) },
|
||||
.childAlignment = {.x = centered ? CLAY_ALIGN_X_CENTER : CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
}
|
||||
}) {
|
||||
text_label(gui, text);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = options.wide ? CLAY_SIZING_GROW(0) : CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0) },
|
||||
.childAlignment = {.x = options.centered ? CLAY_ALIGN_X_CENTER : CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
}
|
||||
}) {
|
||||
gui.element<SelectableButton>("button", d);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void text_button_sized(GUIManager& gui, const char* id, std::string_view text, Clay_SizingAxis x, Clay_SizingAxis y, const TextButtonOptions& options) {
|
||||
SelectableButton::Data d = selectable_button_options_to_data(options);
|
||||
d.innerContent = [&gui, text] (const SelectableButton::InnerContentCallbackParameters&) {
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ struct FixedSizeColorButtonOptions {
|
|||
};
|
||||
|
||||
void text_button(GUIManager& gui, const char* id, std::string_view text, const TextButtonOptions& options = {});
|
||||
void text_button_with_icon(GUIManager& gui, const char* id, const std::string& svgPath, std::string_view text, const TextButtonOptions& options = {});
|
||||
void text_button_sized(GUIManager& gui, const char* id, std::string_view text, Clay_SizingAxis x, Clay_SizingAxis y, const TextButtonOptions& options = {});
|
||||
SelectableButton* svg_icon_button(GUIManager& gui, const char* id, const std::string& svgPath, const SVGButtonOptions& options = {});
|
||||
|
||||
|
|
|
|||
|
|
@ -12,11 +12,13 @@ void GridScrollArea::layout(const Clay_ElementId& id, const Options& o) {
|
|||
|
||||
options = o;
|
||||
|
||||
if(boundingBox.has_value())
|
||||
rowWidth = boundingBox.value().width(); // Use grid element bounding box instead of inner content width because row width will decide whether a scroll bar appears or not, which will change the inner content width (circular dependency)
|
||||
|
||||
ScrollBarManyEntriesOptions opts;
|
||||
opts.clipHorizontal = true;
|
||||
opts.entryHeight = options.entryHeight;
|
||||
opts.innerContentExtraCallback = [&, extraCallback = options.innerContentExtraCallback] (const ScrollArea::InnerContentParameters& contParams) {
|
||||
rowWidth = std::fabs(contParams.containerDimensions.x());
|
||||
if(extraCallback) extraCallback(contParams);
|
||||
};
|
||||
size_t entriesPerRow = std::max<size_t>(rowWidth / options.entryWidth, 1);
|
||||
|
|
|
|||
|
|
@ -258,9 +258,11 @@ void GUIManager::draw(SkCanvas* c, bool skiaAA) {
|
|||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_SCISSOR_END: {
|
||||
canvas->restore();
|
||||
clipRectStack.pop_back();
|
||||
clip_rect_transform(canvas, clipRectStack, clipRect, clipNoDraw);
|
||||
if(!clipRectStack.empty()) {
|
||||
canvas->restore();
|
||||
clipRectStack.pop_back();
|
||||
clip_rect_transform(canvas, clipRectStack, clipRect, clipNoDraw);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CLAY_RENDER_COMMAND_TYPE_CUSTOM: {
|
||||
|
|
|
|||
|
|
@ -6,75 +6,204 @@
|
|||
#include "Helpers/ConvertVec.hpp"
|
||||
#include "../GUIStuff/Elements/GridScrollArea.hpp"
|
||||
#include "../GUIStuff/Elements/ImageDisplay.hpp"
|
||||
#include "../GUIStuff/Elements/LayoutElement.hpp"
|
||||
#include "../World.hpp"
|
||||
#include "Helpers/StringHelpers.hpp"
|
||||
#include <SDL3/SDL_timer.h>
|
||||
|
||||
#define MAIN_MENU_SIZE 300
|
||||
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
FileSelectScreen::FileSelectScreen(MainProgram& m): Screen(m) {}
|
||||
|
||||
void FileSelectScreen::gui_layout_run() {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
auto& gui = main.g.gui;
|
||||
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
},
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
if(mainMenuOpen)
|
||||
main_menu();
|
||||
if(!(mainMenuOpen && main_menu_fills_screen())) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(gui.io.windowSize.x()), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
},
|
||||
}) {
|
||||
switch(selectedMenu) {
|
||||
case SelectedMenu::FILES:
|
||||
title_bar("Files");
|
||||
file_view();
|
||||
break;
|
||||
case SelectedMenu::TRASH:
|
||||
title_bar("Trash");
|
||||
file_view();
|
||||
break;
|
||||
case SelectedMenu::SETTINGS:
|
||||
title_bar("Settings");
|
||||
break;
|
||||
}
|
||||
menu_black_box();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool FileSelectScreen::main_menu_fills_screen() {
|
||||
return main.g.gui.io.windowSize.x() < MAIN_MENU_SIZE + 50;
|
||||
}
|
||||
|
||||
void FileSelectScreen::title_bar(std::string_view title) {
|
||||
auto& gui = main.g.gui;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(40)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER },
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
}
|
||||
}) {
|
||||
svg_icon_button(gui, "main settings button", "data/icons/menu.svg", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.onClick = [&] {
|
||||
mainMenuOpen = true;
|
||||
}
|
||||
});
|
||||
text_label(gui, title);
|
||||
}
|
||||
}
|
||||
|
||||
void FileSelectScreen::main_menu() {
|
||||
auto& gui = main.g.gui;
|
||||
gui.element<LayoutElement>("main menu popup", [&] (LayoutElement*, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(40)},
|
||||
.sizing = {.width = CLAY_SIZING_GROW(static_cast<float>(main_menu_fills_screen() ? 0 : 300)), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER },
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
}
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
},
|
||||
}) {
|
||||
svg_icon_button(gui, "main settings button", "data/icons/menu.svg", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL
|
||||
text_button_with_icon(gui, "Files", "data/icons/folder.svg", "Files", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.isSelected = selectedMenu == SelectedMenu::FILES,
|
||||
.wide = true,
|
||||
.centered = false,
|
||||
.onClick = [&] {
|
||||
selectedMenu = SelectedMenu::FILES;
|
||||
fileListOptional.reset();
|
||||
mainMenuOpen = false;
|
||||
}
|
||||
});
|
||||
text_button_with_icon(gui, "Trash", "data/icons/trash.svg", "Trash", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.isSelected = selectedMenu == SelectedMenu::TRASH,
|
||||
.wide = true,
|
||||
.centered = false,
|
||||
.onClick = [&] {
|
||||
selectedMenu = SelectedMenu::TRASH;
|
||||
fileListOptional.reset();
|
||||
mainMenuOpen = false;
|
||||
}
|
||||
});
|
||||
text_button_with_icon(gui, "Settings", "data/icons/RemixIcon/settings-3-line.svg", "Settings", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.isSelected = selectedMenu == SelectedMenu::SETTINGS,
|
||||
.wide = true,
|
||||
.centered = false,
|
||||
.onClick = [&] {
|
||||
selectedMenu = SelectedMenu::SETTINGS;
|
||||
mainMenuOpen = false;
|
||||
}
|
||||
});
|
||||
text_label(gui, "File selector");
|
||||
}
|
||||
auto& fileList = get_file_list();
|
||||
gui.element<GridScrollArea>("File selector grid", GridScrollArea::Options{
|
||||
.entryWidth = 200.0f,
|
||||
.childAlignmentX = CLAY_ALIGN_X_LEFT,
|
||||
.entryHeight = 220.0f,
|
||||
.entryCount = fileList.size(),
|
||||
.elementContent = [&](size_t i) {
|
||||
CLAY_AUTO_ID({
|
||||
});
|
||||
}
|
||||
|
||||
void FileSelectScreen::file_view() {
|
||||
auto& gui = main.g.gui;
|
||||
bool isTrash = selectedMenu == SelectedMenu::TRASH;
|
||||
std::string folder = isTrash ? "trash" : "saves";
|
||||
auto& fileList = get_file_list(folder);
|
||||
gui.element<GridScrollArea>("File selector grid", GridScrollArea::Options{
|
||||
.entryWidth = 180.0f,
|
||||
.childAlignmentX = CLAY_ALIGN_X_LEFT,
|
||||
.entryHeight = 200.0f,
|
||||
.entryCount = fileList.size(),
|
||||
.elementContent = [&](size_t i) {
|
||||
gui.element<SelectableButton>("file button", SelectableButton::Data{
|
||||
.onClick = [&] {
|
||||
},
|
||||
.innerContent = [&](const SelectableButton::InnerContentCallbackParameters& c){
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = 6,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
}
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .sizing = {.width = CLAY_SIZING_FIXED(130), .height = CLAY_SIZING_FIXED(130) }},
|
||||
}) {
|
||||
gui.element<ImageDisplay>("ico", ImageDisplay::Data{
|
||||
.imgPath = main.conf.configPath / folder / (fileList[i].fileName + ".jpg"),
|
||||
.radius = 20
|
||||
});
|
||||
}
|
||||
text_label(gui, fileList[i].fileName);
|
||||
text_label_light(gui, fileList[i].lastModifyDate);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FileSelectScreen::menu_black_box() {
|
||||
auto& gui = main.g.gui;
|
||||
if(mainMenuOpen) {
|
||||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
gui.element<LayoutElement>("file list disable fill", [&] (LayoutElement* l, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = { .width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = 6,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
},
|
||||
.backgroundColor = {0.0f, 0.0f, 0.0f, 0.6f},
|
||||
.floating = {
|
||||
.zIndex = gui.get_z_index(),
|
||||
.attachPoints = {
|
||||
.element = CLAY_ATTACH_POINT_LEFT_TOP,
|
||||
.parent = CLAY_ATTACH_POINT_LEFT_TOP
|
||||
},
|
||||
.attachTo = CLAY_ATTACH_TO_PARENT
|
||||
}
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .sizing = {.width = CLAY_SIZING_FIXED(150), .height = CLAY_SIZING_FIXED(150) }},
|
||||
}) {
|
||||
gui.element<ImageDisplay>("ico", ImageDisplay::Data{
|
||||
.imgPath = main.conf.configPath / "saveThumbnails" / (fileList[i].fileName + ".jpg"),
|
||||
.radius = 20
|
||||
});
|
||||
}
|
||||
text_label(gui, fileList[i].fileName);
|
||||
text_label_light(gui, fileList[i].lastModifyDate);
|
||||
}
|
||||
}
|
||||
}, LayoutElement::Callbacks{
|
||||
.mouseButton = [&] (LayoutElement* l, const InputManager::MouseButtonCallbackArgs& m) {
|
||||
if(m.down && m.button == InputManager::MouseButton::LEFT && l->mouseHovering) {
|
||||
mainMenuOpen = false;
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<FileSelectScreen::FileInfo>& FileSelectScreen::get_file_list() {
|
||||
const std::vector<FileSelectScreen::FileInfo>& FileSelectScreen::get_file_list(const std::string& folder) {
|
||||
if(!fileListOptional.has_value()) {
|
||||
std::filesystem::path savePath = main.conf.configPath / "saves";
|
||||
std::filesystem::path savePath = main.conf.configPath / folder;
|
||||
fileListOptional = std::vector<FileInfo>();
|
||||
auto& fL = fileListOptional.value();
|
||||
int globCount;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,19 @@ class FileSelectScreen : public Screen {
|
|||
SDL_Time lastModifyTime;
|
||||
std::string lastModifyDate;
|
||||
};
|
||||
const std::vector<FileInfo>& get_file_list();
|
||||
const std::vector<FileInfo>& get_file_list(const std::string& folder);
|
||||
std::optional<std::vector<FileInfo>> fileListOptional;
|
||||
|
||||
void main_menu();
|
||||
void file_view();
|
||||
bool main_menu_fills_screen();
|
||||
void menu_black_box();
|
||||
void title_bar(std::string_view title);
|
||||
|
||||
enum class SelectedMenu {
|
||||
FILES,
|
||||
TRASH,
|
||||
SETTINGS
|
||||
} selectedMenu = SelectedMenu::FILES;
|
||||
bool mainMenuOpen = false;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue