From 45aa5ed1b4b4acb75f710a6de1256bdc53292bf1 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Sun, 3 May 2026 19:40:34 +0300 Subject: [PATCH] Slight changes to phone color selector UI --- src/GUIStuff/Elements/DropDown.hpp | 24 +++--- src/GUIStuff/Elements/TreeListing.cpp | 7 +- src/Screens/PhoneDrawingProgramScreen.cpp | 95 +++++++++++++---------- 3 files changed, 71 insertions(+), 55 deletions(-) diff --git a/src/GUIStuff/Elements/DropDown.hpp b/src/GUIStuff/Elements/DropDown.hpp index 92ee38c..d07d7d2 100644 --- a/src/GUIStuff/Elements/DropDown.hpp +++ b/src/GUIStuff/Elements/DropDown.hpp @@ -65,14 +65,14 @@ template class DropDown : public Element { gui.element("DROPDOWN", [&](LayoutElement* l, const Clay_ElementId& lId) { float dropdownHeight = ENTRY_HEIGHT * selections.size() + DROPDOWN_OFFSET; Clay_FloatingElementConfig floatConfig; - float maxHeight = gui.io.windowSize.y(); - if(buttonBB.max.y() + dropdownHeight > gui.io.windowSize.y()) { - float rightSideWidth = gui.io.windowSize.x() - buttonBB.max.x(); - float leftSideWidth = buttonBB.min.x(); + float maxHeight = gui.io.safeWindowRect.height(); + if(buttonBB.max.y() + dropdownHeight > 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 > buttonBB.width() || leftSideWidth > buttonBB.width()) vertical_offset_setup(dropdownHeight, floatConfig, maxHeight, rightSideWidth >= leftSideWidth); else { - if(gui.io.windowSize.y() - buttonBB.max.y() >= buttonBB.min.y()) + if(gui.io.safeWindowRect.max.y() - buttonBB.max.y() >= buttonBB.min.y() - gui.io.safeWindowRect.min.y()) bottom_offset_setup(dropdownHeight, floatConfig, maxHeight); else top_offset_setup(dropdownHeight, floatConfig, maxHeight); @@ -132,7 +132,7 @@ template class DropDown : public Element { .attachTo = CLAY_ATTACH_TO_PARENT }; // This function might be used even when boundingBox isnt determined yet - maxHeight = boundingBox.has_value() ? std::max(gui.io.windowSize.y() - boundingBox.value().max.y() - DROPDOWN_OFFSET, 0.0f) : 0.0f; + maxHeight = boundingBox.has_value() ? std::max(gui.io.safeWindowRect.max.y() - boundingBox.value().max.y() - DROPDOWN_OFFSET, 0.0f) : 0.0f; } void top_offset_setup(float dropdownHeight, Clay_FloatingElementConfig& floatConfig, float& maxHeight) { @@ -147,16 +147,16 @@ template class DropDown : public Element { }, .attachTo = CLAY_ATTACH_TO_PARENT }; - maxHeight = std::max(boundingBox.value().min.y() - DROPDOWN_OFFSET, 0.0f); + maxHeight = std::max(boundingBox.value().min.y() - gui.io.safeWindowRect.min.y() - DROPDOWN_OFFSET, 0.0f); } void vertical_offset_setup(float dropdownHeight, Clay_FloatingElementConfig& floatConfig, float& maxHeight, bool isRightSide) { auto& bb = boundingBox.value(); float offsetY = bb.center().y() - dropdownHeight * 0.5f; - if(dropdownHeight >= gui.io.windowSize.y() || offsetY < 0.0f) - offsetY = 0.0f; - else if(offsetY + dropdownHeight > gui.io.windowSize.y()) - offsetY -= (offsetY + dropdownHeight) - gui.io.windowSize.y(); + if(dropdownHeight >= gui.io.safeWindowRect.height() || offsetY < gui.io.safeWindowRect.min.y()) + offsetY = gui.io.safeWindowRect.min.y(); + else if(offsetY + dropdownHeight > gui.io.safeWindowRect.max.y()) + offsetY -= (offsetY + dropdownHeight) - gui.io.safeWindowRect.max.y(); floatConfig = { .offset = { .x = isRightSide ? bb.max.x() + DROPDOWN_OFFSET : bb.min.x() - bb.width() - DROPDOWN_OFFSET, @@ -169,7 +169,7 @@ template class DropDown : public Element { }, .attachTo = CLAY_ATTACH_TO_ROOT }; - maxHeight = gui.io.windowSize.y(); + maxHeight = gui.io.safeWindowRect.height(); } void text_transparent_option_button(const char* id, const char* text, const std::function& onClick) { diff --git a/src/GUIStuff/Elements/TreeListing.cpp b/src/GUIStuff/Elements/TreeListing.cpp index 9534070..25a5710 100644 --- a/src/GUIStuff/Elements/TreeListing.cpp +++ b/src/GUIStuff/Elements/TreeListing.cpp @@ -122,7 +122,8 @@ void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) { } }, LayoutElement::Callbacks { .onClick = [&, i] (LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) { - if(l->mouseHovering && button.button == InputManager::MouseButton::LEFT && button.down) { + bool hovering = l->mouseHovering || (l->childMouseHovering && button.deviceType == InputManager::MouseDeviceType::TOUCH); + if(hovering && button.button == InputManager::MouseButton::LEFT && button.down) { gui.set_post_callback_func([&, i, button, l]{ auto& objIndex = flattenedIndexList[i].objIndex; if(d.selectedIndices) { @@ -149,7 +150,7 @@ void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) { d.selectedIndices->emplace(objIndex); if(d.onSelectChange) d.onSelectChange(); } - isDragging = true; + isDragging = button.deviceType != InputManager::MouseDeviceType::TOUCH || l->childMouseHovering; dragIndexStart = dragIndexEnd = i; dragFromTop = button.pos.y() - l->get_bb().value().min.y() < ENTRY_HEIGHT * 0.5f; } @@ -161,7 +162,7 @@ void TreeListing::layout(const Clay_ElementId& id, const Data& newDisplayData) { } }, .onMotion = [&, i] (LayoutElement* l, const InputManager::MouseMotionCallbackArgs& motion) { - if(isDragging && l->mouseHovering) { + if(isDragging && (l->mouseHovering || l->childMouseHovering)) { size_t newDragIndexEnd = i; bool newDragFromTop = motion.pos.y() - l->get_bb().value().min.y() < ENTRY_HEIGHT * 0.5f; if(dragIndexEnd != newDragIndexEnd || dragFromTop != newDragFromTop) { diff --git a/src/Screens/PhoneDrawingProgramScreen.cpp b/src/Screens/PhoneDrawingProgramScreen.cpp index 31719e6..b1468a1 100644 --- a/src/Screens/PhoneDrawingProgramScreen.cpp +++ b/src/Screens/PhoneDrawingProgramScreen.cpp @@ -257,6 +257,21 @@ void PhoneDrawingProgramScreen::color_settings_popup(Vector4f* color) { bool extraSettingsOpen = colorPickerPopupData.screenType == ColorPickerPopupData::ScreenType::EXTRA; bool extraColorButtons = extraSettingsOpen && colorPickerPopupData.selectedPalette != 0; + + auto paletteColorPickerGridColorButton = [&](size_t i){ + auto newC = std::make_shared(palette.colors[i].x(), palette.colors[i].y(), palette.colors[i].z()); + color_button(gui, "c", newC.get(), { + .isSelected = newC->x() == color->x() && newC->y() == color->y() && newC->z() == color->z(), + .hasAlpha = false, + .onClick = [newC, color] { + // We want to keep the old color's alpha + color->x() = newC->x(); + color->y() = newC->y(); + color->z() = newC->z(); + } + }); + }; + auto paletteColorPickerGrid = [&] { gui.element("color selector grid", GridScrollArea::Options{ .entryWidth = BIG_BUTTON_SIZE, @@ -265,24 +280,34 @@ void PhoneDrawingProgramScreen::color_settings_popup(Vector4f* color) { .entryCount = palette.colors.size() + (extraColorButtons ? 3 : 1), .scrollbar = ScrollArea::ScrollbarType::NORMAL, .elementContent = [&](size_t i) { - if(i < palette.colors.size()) { - auto newC = std::make_shared(palette.colors[i].x(), palette.colors[i].y(), palette.colors[i].z()); - color_button(gui, "c", newC.get(), { - .isSelected = newC->x() == color->x() && newC->y() == color->y() && newC->z() == color->z(), - .hasAlpha = false, - .onClick = [newC, color] { - // We want to keep the old color's alpha - color->x() = newC->x(); - color->y() = newC->y(); - color->z() = newC->z(); - } - }); + if(colorPickerPopupData.screenType == ColorPickerPopupData::ScreenType::NORMAL) { + if(i < palette.colors.size()) + paletteColorPickerGridColorButton(i); + else { + svg_icon_button(gui, "extra color settings", "data/icons/RemixIcon/more-fill.svg", { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, + .onClick = [&] { + colorPickerPopupData.screenType = ColorPickerPopupData::ScreenType::EXTRA; + } + }); + } } else { - if(extraColorButtons) { - switch(i - palette.colors.size()) { + if(i == 0) { + svg_icon_button(gui, "extra color settings", "data/icons/RemixIcon/arrow-left-s-line.svg", { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, + .onClick = [&] { + colorPickerPopupData.screenType = ColorPickerPopupData::ScreenType::NORMAL; + } + }); + } + else if((i - 1) < palette.colors.size()) + paletteColorPickerGridColorButton(i - 1); + else if(extraColorButtons) { + switch(i - palette.colors.size() - 1) { case 0: svg_icon_button(gui, "addcolor", "data/icons/plus.svg", { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, .onClick = [&, color] { std::erase(palette.colors, Vector3f{color->x(), color->y(), color->z()}); palette.colors.emplace_back(color->x(), color->y(), color->z()); @@ -291,37 +316,14 @@ void PhoneDrawingProgramScreen::color_settings_popup(Vector4f* color) { break; case 1: svg_icon_button(gui, "deletecolor", "data/icons/close.svg", { + .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, .onClick = [&, color] { std::erase(palette.colors, Vector3f{color->x(), color->y(), color->z()}); } }); break; - case 2: - svg_icon_button(gui, "extra color settings", "data/icons/RemixIcon/more-fill.svg", { - .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, - .isSelected = extraSettingsOpen, - .onClick = [&] { - if(colorPickerPopupData.screenType == ColorPickerPopupData::ScreenType::NORMAL) - colorPickerPopupData.screenType = ColorPickerPopupData::ScreenType::EXTRA; - else - colorPickerPopupData.screenType = ColorPickerPopupData::ScreenType::NORMAL; - } - }); - break; } } - else { - svg_icon_button(gui, "extra color settings", "data/icons/RemixIcon/more-fill.svg", { - .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, - .isSelected = extraSettingsOpen, - .onClick = [&] { - if(colorPickerPopupData.screenType == ColorPickerPopupData::ScreenType::NORMAL) - colorPickerPopupData.screenType = ColorPickerPopupData::ScreenType::EXTRA; - else - colorPickerPopupData.screenType = ColorPickerPopupData::ScreenType::NORMAL; - } - }); - } } } }); @@ -336,7 +338,11 @@ void PhoneDrawingProgramScreen::color_settings_popup(Vector4f* color) { }, .aspectRatio = {1.0f} }) { - gui.element>("color picker element", color, true); + gui.element>("color picker element", color, true, ColorPickerData{ + .onChange = [&] { + gui.set_to_layout(); + } + }); } CLAY_AUTO_ID({ .layout = { @@ -350,7 +356,7 @@ void PhoneDrawingProgramScreen::color_settings_popup(Vector4f* color) { for(auto& p : main.conf.palettes) paletteNames.emplace_back(p.name); gui.element>("paletteselector", &colorPickerPopupData.selectedPalette, paletteNames); - svg_icon_button(gui, "paletteadd", "data/icons/RemixIcon/more-fill.svg", { + svg_icon_button(gui, "paletteadd", "data/icons/pencil.svg", { .onClick = [&] { reset_color_picker_popup_data(); colorPickerPopupData.screenType = ColorPickerPopupData::ScreenType::PALETTES; @@ -406,6 +412,15 @@ void PhoneDrawingProgramScreen::color_settings_popup(Vector4f* color) { }) { text_label(gui, main.conf.palettes[objIndex.back()].name); } + if(gui.io.isTouchDevice) { + gui.set_z_index_keep_clipping_region(gui.get_z_index() + 1, [&] { + CLAY_AUTO_ID({ + .layout = {.sizing = {.width = CLAY_SIZING_FIXED(TreeListing::ENTRY_HEIGHT), .height = CLAY_SIZING_FIXED(TreeListing::ENTRY_HEIGHT)}} + }) { + gui.element("touch screen holder", "data/icons/menu.svg"); + } + }); + } gui.set_z_index_keep_clipping_region(gui.get_z_index() + 1, [&] { svg_icon_button(gui, "edit button", "data/icons/pencil.svg", { .drawType = SelectableButton::DrawType::TRANSPARENT_ALL,