Added more settings and actions to phone version
This commit is contained in:
parent
fd2ce71db6
commit
1b99c64c1b
21 changed files with 388 additions and 179 deletions
1
assets/data/icons/RemixIcon/image-add-line.svg
Normal file
1
assets/data/icons/RemixIcon/image-add-line.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M21 15V18H24V20H21V23H19V20H16V18H19V15H21ZM21.0082 3C21.556 3 22 3.44495 22 3.9934V13H20V5H4V18.999L14 9L17 12V14.829L14 11.8284L6.827 19H14V21H2.9918C2.44405 21 2 20.5551 2 20.0066V3.9934C2 3.44476 2.45531 3 2.9918 3H21.0082ZM8 7C9.10457 7 10 7.89543 10 9C10 10.1046 9.10457 11 8 11C6.89543 11 6 10.1046 6 9C6 7.89543 6.89543 7 8 7Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 438 B |
|
|
@ -719,6 +719,8 @@ void DrawingProgram::add_file_to_canvas_by_path(const std::filesystem::path& fil
|
|||
CanvasComponentContainer* newContainer = new CanvasComponentContainer(world.netObjMan, CanvasComponentType::IMAGE);
|
||||
ImageCanvasComponent& img = static_cast<ImageCanvasComponent&>(newContainer->get_comp());
|
||||
newContainer->coords = world.drawData.cam.c;
|
||||
if(world.main.g.gui.io.isTouchDevice)
|
||||
newContainer->coords.scale_about_double(world.drawData.cam.c.from_space(dropPos), 1.0 / world.main.get_scale_and_density_factor_gui());
|
||||
float imWidth = imTrueDim.x() / (imTrueDim.x() + imTrueDim.y());
|
||||
float imHeight = imTrueDim.y() / (imTrueDim.x() + imTrueDim.y());
|
||||
Vector2f imDim = Vector2f{world.main.window.size.x() * imWidth, world.main.window.size.x() * imHeight} * display->get_dimension_scale();
|
||||
|
|
|
|||
|
|
@ -404,7 +404,7 @@ void TextBoxEditTool::phone_bottom_toolbar_gui(PhoneDrawingProgramScreen& t) {
|
|||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
dropdown_many_element_popup_layout(gui, "Font Picker Popup", DropDownPopupLayout{
|
||||
.button = fontPickerButton,
|
||||
.isOpen = &fontPickerIsOpen,
|
||||
.clickAwayCallback = [&] { fontPickerIsOpen = false; },
|
||||
.entrySize = {200.0f, BIG_BUTTON_SIZE},
|
||||
.entryCount = FontPicker::sorted_font_list(gui).size(),
|
||||
.entryLayout = [&](size_t i) {
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ void ScreenshotTool::gui_toolbox(Toolbar& t) {
|
|||
take_screenshot("a" + controls.typeSelections[screenshotConfig.selectedType], screenshotConfig.selectedType);
|
||||
#else
|
||||
// We can't actually use the extension from the callback, so we have to set the extension of choice beforehand
|
||||
Toolbar::ExtensionFilter setExtensionFilter;
|
||||
Screen::ExtensionFilter setExtensionFilter;
|
||||
switch(screenshotConfig.selectedType) {
|
||||
case WorldScreenshotInfo::ScreenshotType::JPG:
|
||||
setExtensionFilter = {"JPEG", "jpg;jpeg"};
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void TextBoxTool::input_mouse_button_on_canvas_callback(const InputManager::Mous
|
|||
newTextBox.d.editing = true;
|
||||
newContainer->coords = drawP.world.drawData.cam.c;
|
||||
if(drawP.world.main.g.gui.io.isTouchDevice)
|
||||
newContainer->coords.scale_about_double(drawP.world.drawData.cam.c.from_space(startAt), 1.0 / drawP.world.main.g.final_gui_scale());
|
||||
newContainer->coords.scale_about_double(drawP.world.drawData.cam.c.from_space(startAt), 1.0 / drawP.world.main.get_scale_and_density_factor_gui());
|
||||
objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newContainer);
|
||||
}
|
||||
else if(!button.down && objInfoBeingEdited) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "ButtonHelpers.hpp"
|
||||
#include "../Elements/SVGIcon.hpp"
|
||||
#include "../Elements/LayoutElement.hpp"
|
||||
#include "Helpers/ConvertVec.hpp"
|
||||
#include "TextLabelHelpers.hpp"
|
||||
|
||||
namespace GUIStuff { namespace ElementHelpers {
|
||||
|
|
@ -37,7 +38,7 @@ void text_button(GUIManager& gui, const char* id, std::string_view text, const T
|
|||
};
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = options.wide ? CLAY_SIZING_GROW(0) : CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0) },
|
||||
.sizing = {.width = options.wide ? CLAY_SIZING_GROW(0) : CLAY_SIZING_FIT(0), .height = options.growHeight ? CLAY_SIZING_GROW(0) : CLAY_SIZING_FIT(0) },
|
||||
.childAlignment = {.x = options.centered ? CLAY_ALIGN_X_CENTER : CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
}
|
||||
}) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ struct TextButtonOptions {
|
|||
bool isSelected = false;
|
||||
bool instantResponse = false;
|
||||
bool wide = false;
|
||||
bool growHeight = false;
|
||||
bool centered = true;
|
||||
|
||||
std::function<void()> onClick;
|
||||
|
|
|
|||
|
|
@ -18,12 +18,14 @@
|
|||
|
||||
#pragma once
|
||||
#include "../GUIManager.hpp"
|
||||
#include "Helpers/ConvertVec.hpp"
|
||||
#include "TextBoxHelpers.hpp"
|
||||
#include "../Elements/ColorPicker.hpp"
|
||||
|
||||
namespace GUIStuff { namespace ElementHelpers {
|
||||
|
||||
struct ColorPickerItemsOptions {
|
||||
bool forceAspectRatioOnColorPicker = true;
|
||||
bool hasAlpha = true;
|
||||
std::function<void()> onEdit;
|
||||
std::function<void()> onSelect;
|
||||
|
|
@ -40,26 +42,28 @@ template <typename T> void color_picker_items(GUIManager& gui, const char* id, T
|
|||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}
|
||||
},
|
||||
.aspectRatio = {1.0f}
|
||||
.aspectRatio = {options.forceAspectRatioOnColorPicker ? 1.0f : 0.0f}
|
||||
}) {
|
||||
gui.element<ColorPicker<T>>("c", val, options.hasAlpha, ColorPickerData{ .onChange = fullOnEdit, .onHold = options.onSelect, .onRelease = options.onDeselect });
|
||||
}
|
||||
left_to_right_line_layout(gui, [&]() {
|
||||
text_label(gui, "R");
|
||||
input_color_component_255(gui, "r", &(*val)[0], { .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
text_label(gui, "G");
|
||||
input_color_component_255(gui, "g", &(*val)[1], { .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
text_label(gui, "B");
|
||||
input_color_component_255(gui, "b", &(*val)[2], { .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
if(options.hasAlpha) {
|
||||
text_label(gui, "A");
|
||||
input_color_component_255(gui, "a", &(*val)[3], { .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
}
|
||||
});
|
||||
left_to_right_line_layout(gui, [&]() {
|
||||
text_label(gui, "Hex");
|
||||
input_color_hex(gui, "h", val, { .hasAlpha = options.hasAlpha, .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
});
|
||||
if(!gui.io.isTouchDevice) {
|
||||
left_to_right_line_layout(gui, [&]() {
|
||||
text_label(gui, "R");
|
||||
input_color_component_255(gui, "r", &(*val)[0], { .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
text_label(gui, "G");
|
||||
input_color_component_255(gui, "g", &(*val)[1], { .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
text_label(gui, "B");
|
||||
input_color_component_255(gui, "b", &(*val)[2], { .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
if(options.hasAlpha) {
|
||||
text_label(gui, "A");
|
||||
input_color_component_255(gui, "a", &(*val)[3], { .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
}
|
||||
});
|
||||
left_to_right_line_layout(gui, [&]() {
|
||||
text_label(gui, "Hex");
|
||||
input_color_hex(gui, "h", val, { .hasAlpha = options.hasAlpha, .onEdit = fullOnEdit, .onSelect = options.onSelect, .onDeselect = options.onDeselect });
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ void bottom_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingEle
|
|||
floatConfig = {
|
||||
.offset = {
|
||||
.x = xOffset,
|
||||
.y = bb.max.y() + d.dropdownOffset
|
||||
.y = bb.max.y() + d.popupOffset
|
||||
},
|
||||
.zIndex = gui.get_z_index(),
|
||||
.attachPoints = {
|
||||
|
|
@ -255,7 +255,7 @@ void bottom_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingEle
|
|||
.attachTo = CLAY_ATTACH_TO_ROOT
|
||||
};
|
||||
|
||||
maxHeight = std::max(gui.io.safeWindowRect.max.y() - bb.max.y() - d.dropdownOffset, 0.0f);
|
||||
maxHeight = std::max(gui.io.safeWindowRect.max.y() - bb.max.y() - d.popupOffset, 0.0f);
|
||||
}
|
||||
|
||||
void top_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingElementConfig& floatConfig, float& maxHeight, const DropDownPopupLayout& d) {
|
||||
|
|
@ -271,7 +271,7 @@ void top_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingElemen
|
|||
floatConfig = {
|
||||
.offset = {
|
||||
.x = xOffset,
|
||||
.y = bb.min.y() - d.dropdownOffset
|
||||
.y = bb.min.y() - d.popupOffset
|
||||
},
|
||||
.zIndex = gui.get_z_index(),
|
||||
.attachPoints = {
|
||||
|
|
@ -281,7 +281,7 @@ void top_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingElemen
|
|||
.attachTo = CLAY_ATTACH_TO_ROOT
|
||||
};
|
||||
|
||||
maxHeight = std::max(bb.min.y() - gui.io.safeWindowRect.min.y() - d.dropdownOffset, 0.0f);
|
||||
maxHeight = std::max(bb.min.y() - gui.io.safeWindowRect.min.y() - d.popupOffset, 0.0f);
|
||||
}
|
||||
|
||||
void left_right_offset_setup(GUIManager& gui, float dropdownHeight, Clay_FloatingElementConfig& floatConfig, float& maxHeight, bool isRightSide, const DropDownPopupLayout& d) {
|
||||
|
|
@ -293,9 +293,9 @@ void left_right_offset_setup(GUIManager& gui, float dropdownHeight, Clay_Floatin
|
|||
offsetY -= (offsetY + dropdownHeight) - gui.io.safeWindowRect.max.y();
|
||||
float offsetX = 0.0f;
|
||||
if(isRightSide)
|
||||
offsetX = bb.max.x() + d.dropdownOffset;
|
||||
offsetX = bb.max.x() + d.popupOffset;
|
||||
else
|
||||
offsetX = bb.min.x() - d.entrySize.x() - d.dropdownOffset;
|
||||
offsetX = bb.min.x() - d.entrySize.x() - d.popupOffset;
|
||||
floatConfig = {
|
||||
.offset = {
|
||||
.x = offsetX,
|
||||
|
|
@ -314,9 +314,9 @@ void left_right_offset_setup(GUIManager& gui, float dropdownHeight, Clay_Floatin
|
|||
void dropdown_many_element_popup_layout(GUIManager& gui, const char* id, DropDownPopupLayout d) {
|
||||
if(!d.button->get_bb().has_value())
|
||||
return;
|
||||
d.entrySize.x() = std::min(d.entrySize.x(), gui.io.windowSize.x());
|
||||
d.entrySize.x() = std::min(d.entrySize.x(), gui.io.safeWindowRect.width());
|
||||
gui.element<LayoutElement>(id, [&](LayoutElement* l, const Clay_ElementId& lId) {
|
||||
float dropdownHeight = d.entrySize.y() * d.entryCount + d.dropdownOffset;
|
||||
float dropdownHeight = d.entrySize.y() * d.entryCount + d.popupOffset;
|
||||
Clay_FloatingElementConfig floatConfig;
|
||||
float maxHeight = gui.io.safeWindowRect.height();
|
||||
auto& buttonBB = d.button->get_bb().value();
|
||||
|
|
@ -356,9 +356,88 @@ void dropdown_many_element_popup_layout(GUIManager& gui, const char* id, DropDow
|
|||
}
|
||||
}, LayoutElement::Callbacks {
|
||||
.onClick = [&, d](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& m) {
|
||||
if(!l->mouseHovering && !l->childMouseHovering && m.down && !d.button->mouseHovering && d.isOpen) {
|
||||
*d.isOpen = false;
|
||||
gui.set_to_layout();
|
||||
if(!l->mouseHovering && !l->childMouseHovering && !d.button->mouseHovering) {
|
||||
if(m.down && d.clickAwayCallback) {
|
||||
d.clickAwayCallback();
|
||||
gui.set_to_layout();
|
||||
}
|
||||
if(!m.down && d.clickUpAwayCallback) {
|
||||
d.clickUpAwayCallback();
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void attach_to_button_popup_layout(GUIManager& gui, const char* id, AttachToButtonPopupLayout d) {
|
||||
if(!d.button->get_bb().has_value())
|
||||
return;
|
||||
d.popupSize.x() = std::min(d.popupSize.x(), std::abs(gui.io.safeWindowRect.width() - 10.0f));
|
||||
d.popupSize.y() = std::min(d.popupSize.y(), std::abs(gui.io.safeWindowRect.height() - 10.0f));
|
||||
float maxHeight = d.popupSize.y();
|
||||
gui.element<LayoutElement>(id, [&](LayoutElement* l, const Clay_ElementId& lId) {
|
||||
Clay_FloatingElementConfig floatConfig;
|
||||
auto& buttonBB = d.button->get_bb().value();
|
||||
if(buttonBB.max.y() + d.popupSize.y() > gui.io.safeWindowRect.max.y()) {
|
||||
float rightSideWidth = gui.io.safeWindowRect.max.x() - buttonBB.max.x();
|
||||
float leftSideWidth = buttonBB.min.x() - gui.io.safeWindowRect.min.x();
|
||||
if(rightSideWidth > d.popupSize.x() || leftSideWidth > d.popupSize.x())
|
||||
left_right_offset_setup(gui, d.popupSize.y(), floatConfig, maxHeight, rightSideWidth >= leftSideWidth, {
|
||||
.popupOffset = d.popupOffset,
|
||||
.button = d.button,
|
||||
.entrySize = d.popupSize
|
||||
});
|
||||
else {
|
||||
if(gui.io.safeWindowRect.max.y() - buttonBB.max.y() >= buttonBB.min.y() - gui.io.safeWindowRect.min.y())
|
||||
bottom_offset_setup(gui, d.popupSize.y(), floatConfig, maxHeight, {
|
||||
.popupOffset = d.popupOffset,
|
||||
.button = d.button,
|
||||
.entrySize = d.popupSize
|
||||
});
|
||||
else
|
||||
top_offset_setup(gui, d.popupSize.y(), floatConfig, maxHeight, {
|
||||
.popupOffset = d.popupOffset,
|
||||
.button = d.button,
|
||||
.entrySize = d.popupSize
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
bottom_offset_setup(gui, d.popupSize.y(), floatConfig, maxHeight, {
|
||||
.popupOffset = d.popupOffset,
|
||||
.button = d.button,
|
||||
.entrySize = d.popupSize
|
||||
});
|
||||
|
||||
if(maxHeight < d.popupSize.y())
|
||||
d.popupSize.y() = maxHeight;
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(d.popupSize.x()), .height = CLAY_SIZING_FIXED(d.popupSize.y())},
|
||||
.childGap = 0
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
.floating = floatConfig,
|
||||
.border = {
|
||||
.color = convert_vec4<Clay_Color>(gui.io.theme->fillColor2),
|
||||
.width = CLAY_BORDER_OUTSIDE(1)
|
||||
}
|
||||
}) {
|
||||
d.innerLayout();
|
||||
}
|
||||
}, LayoutElement::Callbacks {
|
||||
.onClick = [&, d](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& m) {
|
||||
if(!l->mouseHovering && !l->childMouseHovering && !d.button->mouseHovering) {
|
||||
if(m.down && d.clickAwayCallback) {
|
||||
d.clickAwayCallback();
|
||||
gui.set_to_layout();
|
||||
}
|
||||
if(!m.down && d.clickUpAwayCallback) {
|
||||
d.clickUpAwayCallback();
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -42,14 +42,25 @@ void window_fill_side_bar(GUIManager& gui, const WindowFillSideBarConfig& config
|
|||
void window_gap_side_bar(GUIManager& gui, const WindowFillSideBarConfig::Direction& dir);
|
||||
|
||||
struct DropDownPopupLayout {
|
||||
float dropdownOffset = 4.0f;
|
||||
float popupOffset = 4.0f;
|
||||
Element* button = nullptr;
|
||||
bool* isOpen;
|
||||
std::function<void()> clickAwayCallback;
|
||||
std::function<void()> clickUpAwayCallback;
|
||||
Vector2f entrySize;
|
||||
size_t entryCount;
|
||||
std::function<void(size_t i)> entryLayout;
|
||||
};
|
||||
|
||||
struct AttachToButtonPopupLayout {
|
||||
float popupOffset = 4.0f;
|
||||
Element* button = nullptr;
|
||||
std::function<void()> clickAwayCallback;
|
||||
std::function<void()> clickUpAwayCallback;
|
||||
Vector2f popupSize;
|
||||
std::function<void()> innerLayout;
|
||||
};
|
||||
|
||||
void attach_to_button_popup_layout(GUIManager& gui, const char* id, AttachToButtonPopupLayout d);
|
||||
void dropdown_many_element_popup_layout(GUIManager& gui, const char* id, DropDownPopupLayout d);
|
||||
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "../ElementHelpers/ColorPickerItemsHelpers.hpp"
|
||||
#include "../ElementHelpers/ButtonHelpers.hpp"
|
||||
#include "../ElementHelpers/LayoutHelpers.hpp"
|
||||
#include "Helpers/ConvertVec.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
|
|
@ -28,7 +29,7 @@ template <typename T> ColorPickerButton<T>::ColorPickerButton(GUIManager& gui):
|
|||
template <typename T> void ColorPickerButton<T>::layout(const Clay_ElementId& id, T* val, const ColorPickerButtonData& d) {
|
||||
this->data = d;
|
||||
|
||||
GUIStuff::ElementHelpers::color_button(gui, "Color Picker Button", val, {
|
||||
Element* button = GUIStuff::ElementHelpers::color_button(gui, "Color Picker Button", val, {
|
||||
.isSelected = isOpen,
|
||||
.hasAlpha = data.hasAlpha,
|
||||
.onClick = [&]{
|
||||
|
|
@ -38,18 +39,26 @@ template <typename T> void ColorPickerButton<T>::layout(const Clay_ElementId& id
|
|||
});
|
||||
if(isOpen) {
|
||||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
ElementHelpers::top_to_bottom_window_popup_layout(gui, "Color Picker", CLAY_SIZING_FIT(300), CLAY_SIZING_FIT(0), [&, val, data = data](LayoutElement*) {
|
||||
ElementHelpers::color_picker_items(gui, "c", val, {
|
||||
.hasAlpha = data.hasAlpha,
|
||||
.onEdit = data.onEdit,
|
||||
.onSelect = data.onSelect,
|
||||
.onDeselect = data.onDeselect
|
||||
});
|
||||
}, {
|
||||
.mouseButton = [&](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(!l->mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) {
|
||||
isOpen = false;
|
||||
gui.set_to_layout();
|
||||
ElementHelpers::attach_to_button_popup_layout(gui, "Color Picker", {
|
||||
.button = button,
|
||||
.clickAwayCallback = [&] { isOpen = false; },
|
||||
.popupSize = {300.0f, 300.0f},
|
||||
.innerLayout = [&] {
|
||||
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,
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
}) {
|
||||
ElementHelpers::color_picker_items(gui, "c", val, {
|
||||
.forceAspectRatioOnColorPicker = false,
|
||||
.hasAlpha = data.hasAlpha,
|
||||
.onEdit = data.onEdit,
|
||||
.onSelect = data.onSelect,
|
||||
.onDeselect = data.onDeselect
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ template <typename T> class DropDown : public Element {
|
|||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
dropdown_many_element_popup_layout(gui, "DROPDOWN", {
|
||||
.button = this,
|
||||
.isOpen = &isOpen,
|
||||
.clickAwayCallback = [&] { isOpen = false; },
|
||||
.entrySize = boundingBox.value().dim(),
|
||||
.entryCount = selections.size(),
|
||||
.entryLayout = [&](size_t i) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
DesktopDrawingProgramScreen::DesktopDrawingProgramScreen(MainProgram& m):
|
||||
DrawingProgramScreen(m),
|
||||
toolbar(m)
|
||||
toolbar(m, *this)
|
||||
{}
|
||||
|
||||
void DesktopDrawingProgramScreen::update() {
|
||||
|
|
@ -76,3 +76,10 @@ void DesktopDrawingProgramScreen::input_text_key_callback(const InputManager::Ke
|
|||
}
|
||||
DrawingProgramScreen::input_text_key_callback(key);
|
||||
}
|
||||
|
||||
void DesktopDrawingProgramScreen::open_file_selector(const std::string& filePickerName, const std::vector<ExtensionFilter>& extensionFilters, OpenFileSelectorCallback postSelectionFunc, const std::string& fileName, bool isSaving) {
|
||||
if(main.conf.useNativeFilePicker)
|
||||
Screen::open_file_selector(filePickerName, extensionFilters, postSelectionFunc, fileName, isSaving);
|
||||
else
|
||||
toolbar.open_file_selector_non_native(filePickerName, extensionFilters, postSelectionFunc, fileName, isSaving);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ class DesktopDrawingProgramScreen : public DrawingProgramScreen {
|
|||
virtual bool app_close_requested() override;
|
||||
virtual void input_key_callback(const InputManager::KeyCallbackArgs& key) override;
|
||||
virtual void input_text_key_callback(const InputManager::KeyCallbackArgs& key) override;
|
||||
virtual void open_file_selector(const std::string& filePickerName, const std::vector<ExtensionFilter>& extensionFilters, OpenFileSelectorCallback postSelectionFunc, const std::string& fileName = "", bool isSaving = false) override;
|
||||
|
||||
private:
|
||||
Toolbar toolbar;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@
|
|||
#include "../GUIStuff/Elements/SVGIcon.hpp"
|
||||
#include "../GUIStuff/Elements/TextParagraph.hpp"
|
||||
#include "../GUIStuff/ElementHelpers/LayoutHelpers.hpp"
|
||||
#include "../GUIStuff/ElementHelpers/ColorPickerHelpers.hpp"
|
||||
#include "../GUIStuff/ElementHelpers/CheckBoxHelpers.hpp"
|
||||
#include "../GUIStuff/Elements/PositionAdjustingPopupMenu.hpp"
|
||||
#include "../World.hpp"
|
||||
#include "Helpers/StringHelpers.hpp"
|
||||
|
|
@ -181,15 +183,17 @@ void FileSelectScreen::main_display() {
|
|||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
},
|
||||
}) {
|
||||
file_view();
|
||||
switch(selectedMenu) {
|
||||
case SelectedMenu::FILES:
|
||||
file_view();
|
||||
if(!editMode)
|
||||
create_file_button();
|
||||
break;
|
||||
case SelectedMenu::TRASH:
|
||||
file_view();
|
||||
break;
|
||||
case SelectedMenu::SETTINGS:
|
||||
settings_view();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -479,51 +483,71 @@ void FileSelectScreen::title_bar() {
|
|||
}
|
||||
});
|
||||
if(moreButton->get_bb().has_value() && moreOptionsMenu != MoreOptionsMenu::CLOSED) {
|
||||
size_t elemCount = 0;
|
||||
if(moreOptionsMenu == MoreOptionsMenu::MAIN)
|
||||
elemCount = 2;
|
||||
else if(moreOptionsMenu == MoreOptionsMenu::VIEW)
|
||||
elemCount = 4;
|
||||
gui.set_z_index(gui.get_z_index() + 10, [&] {
|
||||
gui.element<PositionAdjustingPopupMenu>("more options popup", moreButton->get_bb().value().top_right(), [&] {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(200), .height = CLAY_SIZING_FIT(0)},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4)
|
||||
}) {
|
||||
dropdown_many_element_popup_layout(gui, "more options popup", {
|
||||
.button = moreButton,
|
||||
.clickUpAwayCallback = [&] {
|
||||
gui.set_post_callback_func_high_priority([&] { // Cancel actions on other buttons
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
main.g.gui.set_to_layout();
|
||||
});
|
||||
},
|
||||
.entrySize = {200.0f, 30.0f},
|
||||
.entryCount = elemCount,
|
||||
.entryLayout = [&] (size_t i) {
|
||||
if(moreOptionsMenu == MoreOptionsMenu::MAIN) {
|
||||
text_transparent_option_button("Edit", "Edit", [&] {
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
start_edit_mode();
|
||||
});
|
||||
text_transparent_option_button("View", "View", [&] {
|
||||
moreOptionsMenu = MoreOptionsMenu::VIEW;
|
||||
});
|
||||
switch(i) {
|
||||
case 0: {
|
||||
text_transparent_option_button("Edit", "Edit", [&] {
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
start_edit_mode();
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
text_transparent_option_button("View", "View", [&] {
|
||||
moreOptionsMenu = MoreOptionsMenu::VIEW;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(moreOptionsMenu == MoreOptionsMenu::VIEW) {
|
||||
text_transparent_option_button("Large Grid", "Large Grid", [&] {
|
||||
fileViewType = FileViewType::LARGE_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
text_transparent_option_button("Medium Grid", "Medium Grid", [&] {
|
||||
fileViewType = FileViewType::MEDIUM_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
text_transparent_option_button("Small Grid", "Small Grid", [&] {
|
||||
fileViewType = FileViewType::SMALL_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
text_transparent_option_button("List", "List", [&] {
|
||||
fileViewType = FileViewType::LIST;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
}
|
||||
}
|
||||
}, LayoutElement::Callbacks{
|
||||
.onClick = [&](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& m) {
|
||||
if(!l->mouseHovering && !m.down) {
|
||||
gui.set_post_callback_func_high_priority([&] { // Cancel actions on other buttons
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
main.g.gui.set_to_layout();
|
||||
});
|
||||
switch(i) {
|
||||
case 0: {
|
||||
text_transparent_option_button("Large Grid", "Large Grid", [&] {
|
||||
fileViewType = FileViewType::LARGE_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
text_transparent_option_button("Medium Grid", "Medium Grid", [&] {
|
||||
fileViewType = FileViewType::MEDIUM_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
text_transparent_option_button("Small Grid", "Small Grid", [&] {
|
||||
fileViewType = FileViewType::SMALL_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
text_transparent_option_button("List", "List", [&] {
|
||||
fileViewType = FileViewType::LIST;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -541,6 +565,7 @@ void FileSelectScreen::text_transparent_option_button(const char* id, const char
|
|||
text_button(gui, id, text, {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.wide = true,
|
||||
.growHeight = true,
|
||||
.centered = false,
|
||||
.onClick = onClick
|
||||
});
|
||||
|
|
@ -569,7 +594,7 @@ void FileSelectScreen::main_menu() {
|
|||
gui.element<LayoutElement>("inner main menu element", [&] (LayoutElement*, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(300.0f * mainMenuOpenAnim->get_val()), .height = CLAY_SIZING_GROW(0)},
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(200.0f * mainMenuOpenAnim->get_val()), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
},
|
||||
|
|
@ -579,18 +604,18 @@ void FileSelectScreen::main_menu() {
|
|||
selectedMenu = SelectedMenu::FILES;
|
||||
update_file_list(fileList, savePath, false);
|
||||
mainMenuOpenAnim->animation_trigger_reverse();
|
||||
if(fileViewScrollArea) fileViewScrollArea->reset_scroll();
|
||||
if(mainViewScrollArea) mainViewScrollArea->reset_scroll();
|
||||
});
|
||||
icon_text_transparent_option_selected_button("Trash", "data/icons/trash.svg", "Trash", selectedMenu == SelectedMenu::TRASH, [&] {
|
||||
selectedMenu = SelectedMenu::TRASH;
|
||||
update_file_list(fileList, trashPath, true);
|
||||
mainMenuOpenAnim->animation_trigger_reverse();
|
||||
if(fileViewScrollArea) fileViewScrollArea->reset_scroll();
|
||||
if(mainViewScrollArea) mainViewScrollArea->reset_scroll();
|
||||
});
|
||||
icon_text_transparent_option_selected_button("Settings", "data/icons/RemixIcon/settings-3-line.svg", "Settings", selectedMenu == SelectedMenu::SETTINGS, [&] {
|
||||
selectedMenu = SelectedMenu::SETTINGS;
|
||||
mainMenuOpenAnim->animation_trigger_reverse();
|
||||
if(fileViewScrollArea) fileViewScrollArea->reset_scroll();
|
||||
if(mainViewScrollArea) mainViewScrollArea->reset_scroll();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -602,11 +627,6 @@ void FileSelectScreen::main_menu() {
|
|||
}
|
||||
|
||||
void FileSelectScreen::file_view() {
|
||||
if(selectedMenu == SelectedMenu::SETTINGS) {
|
||||
fileViewScrollArea = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
auto& gui = main.g.gui;
|
||||
std::filesystem::path folderPath = (selectedMenu == SelectedMenu::TRASH) ? trashPath : savePath;
|
||||
|
||||
|
|
@ -615,14 +635,21 @@ void FileSelectScreen::file_view() {
|
|||
gui.element<SelectableButton>("file button", SelectableButton::Data{
|
||||
.isSelected = editMode && fileList[i].selected,
|
||||
.onClick = [&, filePath, i] {
|
||||
if(editMode)
|
||||
if(selectedMenu == SelectedMenu::TRASH) {
|
||||
if(!editMode)
|
||||
start_edit_mode();
|
||||
fileList[i].selected = !fileList[i].selected;
|
||||
}
|
||||
else {
|
||||
CustomEvents::emit_event<CustomEvents::OpenInfiniPaintFileEvent>({
|
||||
.isClient = false,
|
||||
.saveThumbnail = true,
|
||||
.filePathSource = filePath
|
||||
});
|
||||
if(editMode)
|
||||
fileList[i].selected = !fileList[i].selected;
|
||||
else {
|
||||
CustomEvents::emit_event<CustomEvents::OpenInfiniPaintFileEvent>({
|
||||
.isClient = false,
|
||||
.saveThumbnail = true,
|
||||
.filePathSource = filePath
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
.innerContent = [&](const SelectableButton::InnerContentCallbackParameters& c){
|
||||
|
|
@ -701,7 +728,7 @@ void FileSelectScreen::file_view() {
|
|||
};
|
||||
|
||||
if(fileViewType == FileViewType::LIST) {
|
||||
fileViewScrollArea = gui.element<ManyElementScrollArea>("File selector list", ManyElementScrollArea::Options{
|
||||
mainViewScrollArea = gui.element<ManyElementScrollArea>("File selector list", ManyElementScrollArea::Options{
|
||||
.entryHeight = 150.0f,
|
||||
.entryCount = fileList.size(),
|
||||
.clipHorizontal = true,
|
||||
|
|
@ -730,7 +757,7 @@ void FileSelectScreen::file_view() {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
fileViewScrollArea = gui.element<GridScrollArea>("File selector grid", GridScrollArea::Options{
|
||||
mainViewScrollArea = gui.element<GridScrollArea>("File selector grid", GridScrollArea::Options{
|
||||
.entryWidth = entrySize.x(),
|
||||
.childAlignmentX = CLAY_ALIGN_X_LEFT,
|
||||
.entryHeight = entrySize.y(),
|
||||
|
|
@ -743,6 +770,40 @@ void FileSelectScreen::file_view() {
|
|||
}
|
||||
}
|
||||
|
||||
void FileSelectScreen::settings_view() {
|
||||
auto& gui = main.g.gui;
|
||||
|
||||
mainViewScrollArea = gui.element<ScrollArea>("settings scroll area", ScrollArea::Options{
|
||||
.scrollVertical = true,
|
||||
.clipVertical = true,
|
||||
.scrollbarY = ScrollArea::ScrollbarType::NORMAL,
|
||||
.innerContent = [&] (auto&) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT
|
||||
},
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0, 300), .height = CLAY_SIZING_GROW(0)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
}) {
|
||||
color_picker_button_field(gui, "defaultCanvasBackgroundColor", "Default canvas background color", &main.conf.defaultCanvasBackgroundColor, { .hasAlpha = false });
|
||||
input_scalar_field(gui, "Max GUI Scale", "Max GUI Scale", &main.conf.guiScale, 1.0f, 2.0f, {
|
||||
.decimalPrecision = 1,
|
||||
.onEdit = [&] { main.g.window_update(); }
|
||||
});
|
||||
input_scalar_field(gui, "jump transition time", "Jump transition time", &main.conf.jumpTransitionTime, 0.01f, 1000.0f, {.decimalPrecision = 2});
|
||||
checkbox_boolean_field(gui, "make all tools share same size", "Make all tools share size", &main.toolConfig.globalConf.useGlobalRelativeWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FileSelectScreen::menu_black_box() {
|
||||
auto& gui = main.g.gui;
|
||||
if(!mainMenuOpenAnim->is_at_start()) {
|
||||
|
|
|
|||
|
|
@ -63,11 +63,12 @@ class FileSelectScreen : public Screen {
|
|||
GUIStuff::GUIFloatAnimation* mainMenuOpenAnim = nullptr;
|
||||
GUIStuff::GUIFloatAnimation* actionBarOpenAnim = nullptr;
|
||||
|
||||
GUIStuff::ScrollArea* fileViewScrollArea = nullptr;
|
||||
GUIStuff::ScrollArea* mainViewScrollArea = nullptr;
|
||||
|
||||
void main_display();
|
||||
void main_menu();
|
||||
void file_view();
|
||||
void settings_view();
|
||||
void create_file_button();
|
||||
void file_view_edit();
|
||||
void menu_black_box();
|
||||
|
|
|
|||
|
|
@ -174,6 +174,20 @@ void PhoneDrawingProgramScreen::top_toolbar_remaining_area() {
|
|||
void PhoneDrawingProgramScreen::top_toolbar_hidden_button_popup(GUIStuff::Element* b, std::vector<TopToolbarRemainingAreaButton> l) {
|
||||
auto& gui = main.g.gui;
|
||||
|
||||
l.emplace_back(TopToolbarRemainingAreaButton{
|
||||
.name = "Add Image",
|
||||
.svgPath = "data/icons/RemixIcon/image-add-line.svg",
|
||||
.onClick = [&] {
|
||||
open_file_selector("Open File", {{"Any File", "*"}}, [&](const std::filesystem::path& p, const auto& e) {
|
||||
CustomEvents::emit_event<CustomEvents::AddFileToCanvasEvent>({
|
||||
.type = CustomEvents::AddFileToCanvasEvent::Type::PATH,
|
||||
.filePath = p,
|
||||
.pos = main.window.size.cast<float>() / 2.0f
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
l.emplace_back(TopToolbarRemainingAreaButton{
|
||||
.name = "Canvas Color",
|
||||
.svgPath = "data/icons/RemixIcon/settings-3-line.svg",
|
||||
|
|
@ -191,7 +205,7 @@ void PhoneDrawingProgramScreen::top_toolbar_hidden_button_popup(GUIStuff::Elemen
|
|||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
dropdown_many_element_popup_layout(gui, "top toolbar hidden button popup", {
|
||||
.button = b,
|
||||
.isOpen = &topToolbarButtonPopupOpen,
|
||||
.clickAwayCallback = [&] { topToolbarButtonPopupOpen = false; },
|
||||
.entrySize = {150.0f, 30.0f},
|
||||
.entryCount = l.size(),
|
||||
.entryLayout = [&] (size_t i) {
|
||||
|
|
|
|||
|
|
@ -17,11 +17,45 @@
|
|||
*/
|
||||
|
||||
#include "Screen.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
|
||||
Screen::Screen(MainProgram& m):
|
||||
main(m)
|
||||
{}
|
||||
|
||||
Screen::NativeFilePicker Screen::nativeFilePicker;
|
||||
|
||||
// You can't trust that filter wont be -1 on the platform youre on, so dont use the extension from the callback
|
||||
void Screen::sdl_open_file_dialog_callback(void* userData, const char * const * fileList, int filter) {
|
||||
if(!fileList) {
|
||||
nativeFilePicker.isOpen = false;
|
||||
return;
|
||||
}
|
||||
if(!(*fileList)) {
|
||||
nativeFilePicker.isOpen = false;
|
||||
return;
|
||||
}
|
||||
ExtensionFilter e;
|
||||
if(filter >= 0)
|
||||
e = nativeFilePicker.extensionFiltersComplete[filter];
|
||||
nativeFilePicker.postSelectionFunc(fileList[0], e);
|
||||
nativeFilePicker.isOpen = false;
|
||||
}
|
||||
|
||||
void Screen::open_file_selector(const std::string& filePickerName, const std::vector<ExtensionFilter>& extensionFilters, OpenFileSelectorCallback postSelectionFunc, const std::string& fileName, bool isSaving) {
|
||||
if(!nativeFilePicker.isOpen) {
|
||||
nativeFilePicker.postSelectionFunc = postSelectionFunc;
|
||||
nativeFilePicker.extensionFiltersComplete = extensionFilters;
|
||||
nativeFilePicker.sdlFileFilters.clear();
|
||||
for(auto& e : nativeFilePicker.extensionFiltersComplete)
|
||||
nativeFilePicker.sdlFileFilters.emplace_back(e.name.c_str(), e.extensions.c_str());
|
||||
if(isSaving)
|
||||
SDL_ShowSaveFileDialog(sdl_open_file_dialog_callback, nullptr, main.window.sdlWindow, nativeFilePicker.sdlFileFilters.data(), nativeFilePicker.sdlFileFilters.size(), nullptr);
|
||||
else
|
||||
SDL_ShowOpenFileDialog(sdl_open_file_dialog_callback, nullptr, main.window.sdlWindow, nativeFilePicker.sdlFileFilters.data(), nativeFilePicker.sdlFileFilters.size(), nullptr, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Screen::update() {}
|
||||
void Screen::gui_layout_run() {}
|
||||
bool Screen::app_close_requested() { return true; }
|
||||
|
|
|
|||
|
|
@ -25,6 +25,20 @@ class Screen {
|
|||
virtual void update();
|
||||
virtual void draw(SkCanvas* canvas) = 0;
|
||||
|
||||
struct ExtensionFilter {
|
||||
std::string name;
|
||||
std::string extensions;
|
||||
};
|
||||
|
||||
typedef std::function<void(const std::filesystem::path&, const ExtensionFilter& extensionSelected)> OpenFileSelectorCallback;
|
||||
struct NativeFilePicker {
|
||||
std::atomic<bool> isOpen = false;
|
||||
std::vector<ExtensionFilter> extensionFiltersComplete;
|
||||
std::vector<SDL_DialogFileFilter> sdlFileFilters;
|
||||
OpenFileSelectorCallback postSelectionFunc;
|
||||
};
|
||||
static NativeFilePicker nativeFilePicker;
|
||||
|
||||
virtual void gui_layout_run();
|
||||
virtual bool app_close_requested();
|
||||
virtual void input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile);
|
||||
|
|
@ -53,7 +67,11 @@ class Screen {
|
|||
virtual void input_app_about_to_go_to_background_callback();
|
||||
virtual std::optional<InputManager::TextBoxStartInfo> get_text_box_start_info();
|
||||
|
||||
virtual void open_file_selector(const std::string& filePickerName, const std::vector<ExtensionFilter>& extensionFilters, OpenFileSelectorCallback postSelectionFunc, const std::string& fileName = "", bool isSaving = false);
|
||||
|
||||
virtual ~Screen();
|
||||
protected:
|
||||
static void sdl_open_file_dialog_callback(void* userData, const char * const * fileList, int filter);
|
||||
|
||||
MainProgram& main;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@
|
|||
#include "GUIStuff/Elements/MovableTabList.hpp"
|
||||
#include "GUIStuff/Elements/TextParagraph.hpp"
|
||||
|
||||
#include "Screens/DesktopDrawingProgramScreen.hpp"
|
||||
|
||||
#define UPDATE_DOWNLOAD_URL "https://infinipaint.com/download.html"
|
||||
#define UPDATE_NOTIFICATION_URL "https://infinipaint.com/updateNotificationVersion.txt"
|
||||
|
||||
|
|
@ -78,60 +80,31 @@
|
|||
#include <EmscriptenHelpers/emscripten_browser_file.h>
|
||||
#endif
|
||||
|
||||
Toolbar::NativeFilePicker Toolbar::nativeFilePicker;
|
||||
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
Toolbar::Toolbar(MainProgram& initMain):
|
||||
main(initMain)
|
||||
Toolbar::Toolbar(MainProgram& initMain, DesktopDrawingProgramScreen& initDrawScreen):
|
||||
main(initMain),
|
||||
drawScreen(initDrawScreen)
|
||||
{}
|
||||
|
||||
// You can't trust that filter wont be -1 on the platform youre on, so dont use the extension from the callback
|
||||
void Toolbar::sdl_open_file_dialog_callback(void* userData, const char * const * fileList, int filter) {
|
||||
if(!fileList) {
|
||||
nativeFilePicker.isOpen = false;
|
||||
return;
|
||||
}
|
||||
if(!(*fileList)) {
|
||||
nativeFilePicker.isOpen = false;
|
||||
return;
|
||||
}
|
||||
ExtensionFilter e;
|
||||
if(filter >= 0)
|
||||
e = nativeFilePicker.extensionFiltersComplete[filter];
|
||||
nativeFilePicker.postSelectionFunc(fileList[0], e);
|
||||
nativeFilePicker.isOpen = false;
|
||||
void Toolbar::open_file_selector(const std::string& filePickerName, const std::vector<Screen::ExtensionFilter>& extensionFilters, Screen::OpenFileSelectorCallback postSelectionFunc, const std::string& fileName, bool isSaving) {
|
||||
drawScreen.open_file_selector(filePickerName, extensionFilters, postSelectionFunc, fileName, isSaving);
|
||||
}
|
||||
|
||||
void Toolbar::open_file_selector(const std::string& filePickerName, const std::vector<ExtensionFilter>& extensionFilters, OpenFileSelectorCallback postSelectionFunc, const std::string& fileName, bool isSaving) {
|
||||
if(main.conf.useNativeFilePicker) {
|
||||
if(!nativeFilePicker.isOpen) {
|
||||
nativeFilePicker.postSelectionFunc = postSelectionFunc;
|
||||
nativeFilePicker.extensionFiltersComplete = extensionFilters;
|
||||
nativeFilePicker.sdlFileFilters.clear();
|
||||
for(auto& e : nativeFilePicker.extensionFiltersComplete)
|
||||
nativeFilePicker.sdlFileFilters.emplace_back(e.name.c_str(), e.extensions.c_str());
|
||||
if(isSaving)
|
||||
SDL_ShowSaveFileDialog(sdl_open_file_dialog_callback, nullptr, main.window.sdlWindow, nativeFilePicker.sdlFileFilters.data(), nativeFilePicker.sdlFileFilters.size(), nullptr);
|
||||
else
|
||||
SDL_ShowOpenFileDialog(sdl_open_file_dialog_callback, nullptr, main.window.sdlWindow, nativeFilePicker.sdlFileFilters.data(), nativeFilePicker.sdlFileFilters.size(), nullptr, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
filePicker.isOpen = true;
|
||||
filePicker.extensionFiltersComplete = extensionFilters;
|
||||
filePicker.extensionFilters.clear();
|
||||
for(auto& [name, exList] : extensionFilters)
|
||||
filePicker.extensionFilters.emplace_back(exList);
|
||||
filePicker.extensionSelected = extensionFilters.size() - 1;
|
||||
filePicker.filePickerWindowName = filePickerName;
|
||||
filePicker.postSelectionFunc = postSelectionFunc;
|
||||
filePicker.fileName = "";
|
||||
filePicker.isSaving = isSaving;
|
||||
filePicker.entriesScrollArea = nullptr;
|
||||
file_picker_gui_refresh_entries();
|
||||
}
|
||||
void Toolbar::open_file_selector_non_native(const std::string& filePickerName, const std::vector<Screen::ExtensionFilter>& extensionFilters, Screen::OpenFileSelectorCallback postSelectionFunc, const std::string& fileName, bool isSaving) {
|
||||
filePicker.isOpen = true;
|
||||
filePicker.extensionFiltersComplete = extensionFilters;
|
||||
filePicker.extensionFilters.clear();
|
||||
for(auto& [name, exList] : extensionFilters)
|
||||
filePicker.extensionFilters.emplace_back(exList);
|
||||
filePicker.extensionSelected = extensionFilters.size() - 1;
|
||||
filePicker.filePickerWindowName = filePickerName;
|
||||
filePicker.postSelectionFunc = postSelectionFunc;
|
||||
filePicker.fileName = "";
|
||||
filePicker.isSaving = isSaving;
|
||||
filePicker.entriesScrollArea = nullptr;
|
||||
file_picker_gui_refresh_entries();
|
||||
}
|
||||
|
||||
void Toolbar::color_button_left(const char* id, Vector4f* color, const ColorSelectorButtonData& colorSelectorData) {
|
||||
|
|
@ -1781,10 +1754,11 @@ void Toolbar::general_settings_inner_gui() {
|
|||
if(!themeData.selectedThemeIndex)
|
||||
reload_theme_list();
|
||||
|
||||
CLAY_AUTO_ID({.layout = {
|
||||
.childGap = io.theme->childGap1,
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER},
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
CLAY_AUTO_ID({.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0)},
|
||||
.childGap = io.theme->childGap1,
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER},
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
}
|
||||
}) {
|
||||
text_label(gui, "Theme: ");
|
||||
|
|
|
|||
|
|
@ -27,8 +27,10 @@
|
|||
#include <Helpers/Serializers.hpp>
|
||||
#include <SDL3/SDL_dialog.h>
|
||||
#include <Helpers/VersionNumber.hpp>
|
||||
#include "Screens/Screen.hpp"
|
||||
|
||||
class MainProgram;
|
||||
class DesktopDrawingProgramScreen;
|
||||
|
||||
class Toolbar {
|
||||
public:
|
||||
|
|
@ -44,14 +46,9 @@ class Toolbar {
|
|||
TimePoint time;
|
||||
};
|
||||
|
||||
struct ExtensionFilter {
|
||||
std::string name;
|
||||
std::string extensions;
|
||||
};
|
||||
|
||||
std::string chatMessageInput;
|
||||
|
||||
Toolbar(MainProgram& initMain);
|
||||
Toolbar(MainProgram& initMain, DesktopDrawingProgramScreen& initDrawScreen);
|
||||
void update();
|
||||
void layout_run();
|
||||
|
||||
|
|
@ -74,8 +71,8 @@ class Toolbar {
|
|||
|
||||
void paint_popup(Vector2f popupPos);
|
||||
|
||||
typedef std::function<void(const std::filesystem::path&, const ExtensionFilter& extensionSelected)> OpenFileSelectorCallback;
|
||||
void open_file_selector(const std::string& filePickerName, const std::vector<ExtensionFilter>& extensionFilters, OpenFileSelectorCallback postSelectionFunc, const std::string& fileName = "", bool isSaving = false);
|
||||
void open_file_selector(const std::string& filePickerName, const std::vector<Screen::ExtensionFilter>& extensionFilters, Screen::OpenFileSelectorCallback postSelectionFunc, const std::string& fileName = "", bool isSaving = false);
|
||||
void open_file_selector_non_native(const std::string& filePickerName, const std::vector<Screen::ExtensionFilter>& extensionFilters, Screen::OpenFileSelectorCallback postSelectionFunc, const std::string& fileName = "", bool isSaving = false);
|
||||
void save_func();
|
||||
void save_as_func();
|
||||
|
||||
|
|
@ -203,7 +200,7 @@ class Toolbar {
|
|||
struct FilePicker {
|
||||
bool isOpen = false;
|
||||
std::string filePickerWindowName;
|
||||
std::vector<ExtensionFilter> extensionFiltersComplete;
|
||||
std::vector<Screen::ExtensionFilter> extensionFiltersComplete;
|
||||
std::vector<std::string> extensionFilters;
|
||||
std::vector<std::filesystem::path> entries;
|
||||
std::filesystem::path currentSelectedPath;
|
||||
|
|
@ -211,17 +208,9 @@ class Toolbar {
|
|||
bool isSaving = false;
|
||||
size_t extensionSelected;
|
||||
GUIStuff::ScrollArea* entriesScrollArea = nullptr;
|
||||
OpenFileSelectorCallback postSelectionFunc;
|
||||
Screen::OpenFileSelectorCallback postSelectionFunc;
|
||||
} filePicker;
|
||||
|
||||
struct NativeFilePicker {
|
||||
std::atomic<bool> isOpen = false;
|
||||
std::vector<ExtensionFilter> extensionFiltersComplete;
|
||||
std::vector<SDL_DialogFileFilter> sdlFileFilters;
|
||||
OpenFileSelectorCallback postSelectionFunc;
|
||||
};
|
||||
static NativeFilePicker nativeFilePicker;
|
||||
|
||||
RichText::TextData build_paragraph_from_chat_message(const ChatMessage& message, float alpha);
|
||||
|
||||
void load_icons_at(const std::filesystem::path& pathToLoad);
|
||||
|
|
@ -230,4 +219,5 @@ class Toolbar {
|
|||
std::string serverLocalID;
|
||||
|
||||
MainProgram& main;
|
||||
DesktopDrawingProgramScreen& drawScreen;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue