From a533494b3a70b2f26f15d281a3a0496ade56a5d7 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Wed, 13 May 2026 19:56:14 +0300 Subject: [PATCH] Slight changes to UI --- src/GUIStuff/ElementHelpers/ButtonHelpers.cpp | 4 +- src/GUIStuff/Elements/CheckBox.cpp | 2 +- src/GUIStuff/Elements/RadioButton.cpp | 2 +- src/GUIStuff/Elements/SVGIcon.cpp | 9 +- src/GUIStuff/Elements/SVGIcon.hpp | 3 +- src/GUIStuff/Elements/TreeListing.cpp | 4 + src/GridManager.cpp | 4 + src/Screens/FileSelectScreen.cpp | 4 +- src/Screens/PhoneDrawingProgramScreen.cpp | 103 ++++++++++++++++-- src/Screens/PhoneDrawingProgramScreen.hpp | 9 +- src/Toolbar.cpp | 4 +- src/main.cpp | 2 +- 12 files changed, 129 insertions(+), 21 deletions(-) diff --git a/src/GUIStuff/ElementHelpers/ButtonHelpers.cpp b/src/GUIStuff/ElementHelpers/ButtonHelpers.cpp index b20ca01..38e7eb4 100644 --- a/src/GUIStuff/ElementHelpers/ButtonHelpers.cpp +++ b/src/GUIStuff/ElementHelpers/ButtonHelpers.cpp @@ -108,8 +108,8 @@ void text_button_sized(GUIManager& gui, const char* id, std::string_view text, C SelectableButton* svg_icon_button(GUIManager& gui, const char* id, const std::string& svgPath, const SVGButtonOptions& options) { SelectableButton::Data d = selectable_button_options_to_data(options); - d.innerContent = [&gui, &svgPath] (const SelectableButton::InnerContentCallbackParameters& p) { - gui.element("icon", svgPath, p.isSelected || p.isHovering || p.isHeld); + d.innerContent = [&gui, &svgPath, &options] (const SelectableButton::InnerContentCallbackParameters& p) { + gui.element("icon", svgPath, p.isSelected || p.isHovering || p.isHeld, options.drawType == SelectableButton::DrawType::FILLED_INVERSE); }; SelectableButton* toRet; CLAY_AUTO_ID({.layout = {.sizing = {.width = CLAY_SIZING_FIXED(options.size), .height = CLAY_SIZING_FIXED(options.size) } } }) { diff --git a/src/GUIStuff/Elements/CheckBox.cpp b/src/GUIStuff/Elements/CheckBox.cpp index e078443..4daf224 100644 --- a/src/GUIStuff/Elements/CheckBox.cpp +++ b/src/GUIStuff/Elements/CheckBox.cpp @@ -31,7 +31,7 @@ void CheckBox::layout(const Clay_ElementId& id, const std::function& isT this->isTicked = isTicked; this->onClick = onClick; - float size = gui.io.isTouchDevice ? 25 : 15; + float size = 20; CLAY(id, { .layout = { .sizing = {.width = CLAY_SIZING_FIXED(size), .height = CLAY_SIZING_FIXED(size)} diff --git a/src/GUIStuff/Elements/RadioButton.cpp b/src/GUIStuff/Elements/RadioButton.cpp index d88f08e..5c24819 100644 --- a/src/GUIStuff/Elements/RadioButton.cpp +++ b/src/GUIStuff/Elements/RadioButton.cpp @@ -29,7 +29,7 @@ void RadioButton::layout(const Clay_ElementId& id, const std::function& this->onClick = onClick; this->isTicked = isTicked; - float size = gui.io.isTouchDevice ? 25 : 20; + float size = 20; CLAY(id, { .layout = { .sizing = {.width = CLAY_SIZING_FIXED(size), .height = CLAY_SIZING_FIXED(size)} diff --git a/src/GUIStuff/Elements/SVGIcon.cpp b/src/GUIStuff/Elements/SVGIcon.cpp index 3845469..4878042 100644 --- a/src/GUIStuff/Elements/SVGIcon.cpp +++ b/src/GUIStuff/Elements/SVGIcon.cpp @@ -29,7 +29,7 @@ namespace GUIStuff { SVGIcon::SVGIcon(GUIManager& gui): Element(gui) {} -void SVGIcon::layout(const Clay_ElementId& id, const std::string& newSvgPath, bool newIsHighlighted) { +void SVGIcon::layout(const Clay_ElementId& id, const std::string& newSvgPath, bool newIsHighlighted, bool newInverse) { bool redraw = false; auto& io = gui.io; @@ -42,7 +42,9 @@ void SVGIcon::layout(const Clay_ElementId& id, const std::string& newSvgPath, bo } redraw |= highlighted != newIsHighlighted; + redraw |= inverse != newInverse; highlighted = newIsHighlighted; + inverse = newInverse; if(redraw) gui.invalidate_draw_element(this); @@ -66,7 +68,10 @@ void SVGIcon::clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderComman SkRect r = SkRect::MakeXYWH(0.0f, 0.0f, bb.width(), bb.height()); canvas->clipRect(r); SkPaint blendingPaint; - blendingPaint.setColorFilter(SkColorFilters::Blend(highlighted ? io.theme->frontColor1 : io.theme->frontColor2, SkColorSpace::MakeSRGB(), SkBlendMode::kSrcIn)); + if(inverse) + blendingPaint.setColorFilter(SkColorFilters::Blend(highlighted ? io.theme->backColor1 : io.theme->backColor2, SkColorSpace::MakeSRGB(), SkBlendMode::kSrcIn)); + else + blendingPaint.setColorFilter(SkColorFilters::Blend(highlighted ? io.theme->frontColor1 : io.theme->frontColor2, SkColorSpace::MakeSRGB(), SkBlendMode::kSrcIn)); canvas->saveLayer(r, &blendingPaint); canvas->scale(bb.width() / svgDom->containerSize().width(), bb.height() / svgDom->containerSize().height()); svgDom->render(canvas); diff --git a/src/GUIStuff/Elements/SVGIcon.hpp b/src/GUIStuff/Elements/SVGIcon.hpp index 8480170..6c6b758 100644 --- a/src/GUIStuff/Elements/SVGIcon.hpp +++ b/src/GUIStuff/Elements/SVGIcon.hpp @@ -24,9 +24,10 @@ namespace GUIStuff { class SVGIcon : public Element { public: SVGIcon(GUIManager& gui); - void layout(const Clay_ElementId& id, const std::string& newSvgPath, bool newIsHighlighted = false); + void layout(const Clay_ElementId& id, const std::string& newSvgPath, bool newIsHighlighted = false, bool newInverse = false); virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override; private: + bool inverse; bool highlighted; sk_sp svgDom; }; diff --git a/src/GUIStuff/Elements/TreeListing.cpp b/src/GUIStuff/Elements/TreeListing.cpp index bf8709c..ca80b56 100644 --- a/src/GUIStuff/Elements/TreeListing.cpp +++ b/src/GUIStuff/Elements/TreeListing.cpp @@ -152,6 +152,10 @@ void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) { } } d.drawObjGUI(objInfo.objIndex); + // Gap for scroll bar + CLAY_AUTO_ID({ + .layout = {.sizing = {.width = CLAY_SIZING_FIT(15), .height = CLAY_SIZING_GROW(0)}} + }) {} } } }, LayoutElement::Callbacks { diff --git a/src/GridManager.cpp b/src/GridManager.cpp index 292c9bf..6bf84d3 100644 --- a/src/GridManager.cpp +++ b/src/GridManager.cpp @@ -328,6 +328,10 @@ void GridManager::setup_list_gui(const std::function& onStartModify) { list_button("delete trash", "data/icons/trash.svg", [&, i] { main.world->gridMan.remove_grid(i); }); + // Gap for scroll bar + CLAY_AUTO_ID({ + .layout = {.sizing = {.width = CLAY_SIZING_FIT(15), .height = CLAY_SIZING_GROW(0)}} + }) {} } } }, LayoutElement::Callbacks { diff --git a/src/Screens/FileSelectScreen.cpp b/src/Screens/FileSelectScreen.cpp index e56d795..be107f1 100644 --- a/src/Screens/FileSelectScreen.cpp +++ b/src/Screens/FileSelectScreen.cpp @@ -241,7 +241,7 @@ void FileSelectScreen::create_file_button() { CLAY(lId, { .layout = {.sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0)}}, .floating = { - .offset = {-5, -5}, + .offset = {-25, -25}, .zIndex = gui.get_z_index(), .attachPoints = { .element = CLAY_ATTACH_POINT_RIGHT_BOTTOM, @@ -251,6 +251,8 @@ void FileSelectScreen::create_file_button() { } }) { svg_icon_button(gui, "add button", "data/icons/plus.svg", { + .drawType = SelectableButton::DrawType::FILLED_INVERSE, + .size = 40.0f, .onClick = [&] { CustomEvents::emit_event({ .isClient = false, diff --git a/src/Screens/PhoneDrawingProgramScreen.cpp b/src/Screens/PhoneDrawingProgramScreen.cpp index cc63b55..1285750 100644 --- a/src/Screens/PhoneDrawingProgramScreen.cpp +++ b/src/Screens/PhoneDrawingProgramScreen.cpp @@ -83,17 +83,39 @@ void PhoneDrawingProgramScreen::main_display() { .layoutDirection = CLAY_TOP_TO_BOTTOM }, }) { - top_toolbar(); - top_toolbar_settings_popup(); - CLAY_AUTO_ID({ - .layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}} - }) {} - bottom_toolbar(); + if(hideGUI) + hidden_gui(); + else { + top_toolbar(); + top_toolbar_settings_popup(); + CLAY_AUTO_ID({ + .layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}} + }) {} + bottom_toolbar(); + } if(!main.world->drawProg.layerMan.is_a_layer_being_edited()) center_message("Select layer to edit message", "Select a layer to edit"); } } +void PhoneDrawingProgramScreen::hidden_gui() { + auto& gui = main.g.gui; + + window_fill_side_bar(gui, WindowFillSideBarConfig{ + .dir = WindowFillSideBarConfig::Direction::TOP + }, [&] { + CLAY_AUTO_ID({ + .layout = {.sizing = {.width = CLAY_SIZING_GROW(0)}} + }); + svg_icon_button(gui, "show gui button", "data/icons/eyeopen.svg", { + .isSelected = true, + .onClick = [&] { + hideGUI = false; + } + }); + }); +} + void PhoneDrawingProgramScreen::top_toolbar_settings_popup() { auto& gui = main.g.gui; auto& io = gui.io; @@ -183,6 +205,42 @@ void PhoneDrawingProgramScreen::top_toolbar_settings_popup() { }); break; } + case TopToolbarSettingsPopup::HOST: { + gui.set_z_index(gui.get_z_index() + 20, [&] { + gui.element("host lobby menu", [&] (LayoutElement*, const Clay_ElementId& lId) { + Vector2f popupSize = { + std::clamp(gui.io.safeWindowRect.width() - 10.0f, 20.0f, 300.0f), + std::clamp(gui.io.safeWindowRect.height() - 40.0f, 50.0f, 600.0f) + }; + CLAY(lId, { + .layout = { + .sizing = {.width = CLAY_SIZING_FIT(popupSize.x()), .height = CLAY_SIZING_FIT(0, popupSize.y()) }, + .padding = CLAY_PADDING_ALL(io.theme->padding1), + .childGap = io.theme->childGap1, + .childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP}, + .layoutDirection = CLAY_TOP_TO_BOTTOM + }, + .backgroundColor = convert_vec4(io.theme->backColor1), + .cornerRadius = CLAY_CORNER_RADIUS(io.theme->windowCorners1), + .floating = {.offset = {.x = 0, .y = static_cast(io.theme->padding1)}, .zIndex = gui.get_z_index(), .attachPoints = {.element = CLAY_ATTACH_POINT_RIGHT_TOP, .parent = CLAY_ATTACH_POINT_RIGHT_BOTTOM}, .attachTo = CLAY_ATTACH_TO_PARENT} + }) { + text_label_centered(gui, "Host"); + input_text_field(gui, "lobby", "Lobby", &serverToConnectTo, { + .immutable = true + }); + text_button(gui, "Host button", "Copy & Host", { + .wide = true, + .onClick = [&] { + main.input.set_clipboard_str(serverToConnectTo); + main.world->start_hosting(serverToConnectTo, serverLocalID); + topToolbarSettingsPopup = TopToolbarSettingsPopup::NONE; + } + }); + } + }); + }); + break; + } } } @@ -264,6 +322,14 @@ void PhoneDrawingProgramScreen::top_toolbar_remaining_area() { topToolbarSettingsPopup = topToolbarSettingsPopup == TopToolbarSettingsPopup::GRIDS ? TopToolbarSettingsPopup::NONE : TopToolbarSettingsPopup::GRIDS; } }, + TopToolbarRemainingAreaButton{ + .name = "Hide Toolbars", + .svgPath = "data/icons/eyeopen.svg", + .isSelected = false, + .onClick = [&] { + hideGUI = true; + } + }, }; gui.element("remaining area", [&](LayoutElement* l, const Clay_ElementId& lId) { CLAY(lId, { @@ -309,6 +375,7 @@ void PhoneDrawingProgramScreen::top_toolbar_remaining_area() { }); Element* e = svg_icon_button(gui, "Hidden buttons", "data/icons/RemixIcon/more-2-fill.svg", { .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, + .isSelected = topToolbarSettingsPopup == TopToolbarSettingsPopup::HIDDEN_BUTTONS, .onClick = [&] { topToolbarSettingsPopup = topToolbarSettingsPopup == TopToolbarSettingsPopup::HIDDEN_BUTTONS ? TopToolbarSettingsPopup::NONE : TopToolbarSettingsPopup::HIDDEN_BUTTONS; } @@ -351,6 +418,16 @@ void PhoneDrawingProgramScreen::top_toolbar_hidden_button_popup(GUIStuff::Elemen } }); + l.emplace_back(TopToolbarRemainingAreaButton{ + .name = "Host", + .svgPath = "data/icons/network.svg", + .onClick = [&] { + serverLocalID = NetLibrary::get_random_server_local_id(); + serverToConnectTo = NetLibrary::get_global_id() + serverLocalID; + topToolbarSettingsPopup = topToolbarSettingsPopup == TopToolbarSettingsPopup::HOST ? TopToolbarSettingsPopup::NONE : TopToolbarSettingsPopup::HOST; + } + }); + gui.set_z_index(gui.get_z_index() + 20, [&] { dropdown_many_element_popup_layout(gui, "top toolbar hidden button popup", { .button = b, @@ -935,10 +1012,16 @@ void PhoneDrawingProgramScreen::bottom_extra_toolbar_gui() { } void PhoneDrawingProgramScreen::input_global_back_button_callback() { - main.world->save_to_file(main.world->filePath); - main.set_tab_to_close(main.world.get()); - main.g.gui.set_to_layout(); - main.set_screen([&] (std::unique_ptr) { return std::make_unique(main); }); + if(hideGUI) { + hideGUI = false; + main.g.gui.set_to_layout(); + } + else { + main.world->save_to_file(main.world->filePath); + main.set_tab_to_close(main.world.get()); + main.g.gui.set_to_layout(); + main.set_screen([&] (std::unique_ptr) { return std::make_unique(main); }); + } } void PhoneDrawingProgramScreen::input_app_about_to_go_to_background_callback() { diff --git a/src/Screens/PhoneDrawingProgramScreen.hpp b/src/Screens/PhoneDrawingProgramScreen.hpp index a198100..5d2e908 100644 --- a/src/Screens/PhoneDrawingProgramScreen.hpp +++ b/src/Screens/PhoneDrawingProgramScreen.hpp @@ -72,13 +72,17 @@ class PhoneDrawingProgramScreen : public DrawingProgramScreen { HIDDEN_BUTTONS, BOOKMARKS, LAYERS, - GRIDS + GRIDS, + HOST } topToolbarSettingsPopup = TopToolbarSettingsPopup::NONE; + bool hideGUI = false; + Vector4f backgroundColorTemporary; Vector4f* colorPickerPtr = nullptr; ColorSelectorData colorPickerData; + void hidden_gui(); void center_message(const char* id, const std::string& m); void default_bottom_toolbar(); void bottom_toolbar_gui(); @@ -91,4 +95,7 @@ class PhoneDrawingProgramScreen : public DrawingProgramScreen { void bottom_toolbar(); void main_display(); void tool_settings_popup(); + + std::string serverToConnectTo; + std::string serverLocalID; }; diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index 4dc1506..acf4807 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -1428,7 +1428,9 @@ void Toolbar::options_menu() { switch(optionsMenuType) { case HOST_MENU: { center_obstructing_window_gui("host menu", CLAY_SIZING_FIT(650), CLAY_SIZING_FIT(0), [&] { - input_text_field(gui, "lobby", "Lobby", &serverToConnectTo); + input_text_field(gui, "lobby", "Lobby", &serverToConnectTo, { + .immutable = true + }); left_to_right_line_layout(gui, [&]() { text_button_wide("copy lobby address", "Copy Lobby Address", [&] { main.input.set_clipboard_str(serverToConnectTo); diff --git a/src/main.cpp b/src/main.cpp index a4652b1..2fe65f6 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -216,7 +216,7 @@ void initialize_sdl(MainStruct& mS, int wWidth, int wHeight) { SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_VERSION_STRING, VersionConstants::CURRENT_VERSION_STRING.c_str()); SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_IDENTIFIER_STRING, "com.infinipaint.infinipaint"); SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_CREATOR_STRING, "Yousef Khadadeh (ErrorAtLine0)"); - SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Copyright (c) 2026 Yousef Khadadeh"); + SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_COPYRIGHT_STRING, "Copyright (C) 2025-2026 Yousef Khadadeh"); SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_URL_STRING, "https://infinipaint.com/"); SDL_SetAppMetadataProperty(SDL_PROP_APP_METADATA_TYPE_STRING, "application");