GUI now (mostly) reacts on tap (left click release) instead of left clicks

This commit is contained in:
Yousef Khadadeh 2026-03-04 13:50:15 +03:00
parent 911b7bc91d
commit 167108db7d
14 changed files with 66 additions and 37 deletions

View file

@ -11,7 +11,7 @@ void CheckBox::update(UpdateInputData& io, bool newIsTicked, const std::function
},
.custom = { .customData = this }
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
if(isTicked != newIsTicked) {
hoverAnimation2 = selection.hovered ? CHECKBOX_ANIMATION_TIME : 0.0f;
isTicked = newIsTicked;

View file

@ -29,7 +29,7 @@ template <typename T> class ColorPicker : public Element {
.aspectRatio = {1.0f},
.custom = { .customData = this }
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
if(selection.clicked && data) {
float svSelectionAreaSize = get_sv_selection_area_size();
modifyingSv = SCollision::collide(SCollision::AABB<float>(bb.min, bb.min + Vector2f{svSelectionAreaSize, svSelectionAreaSize}), io.mouse.pos);

View file

@ -1,4 +1,6 @@
#include "Element.hpp"
#include "Helpers/MathExtras.hpp"
#include <chrono>
namespace GUIStuff {
SkFont get_setup_skfont() {
@ -35,24 +37,31 @@ namespace GUIStuff {
return {{command->boundingBox.x, command->boundingBox.y}, {command->boundingBox.x + command->boundingBox.width, command->boundingBox.y + command->boundingBox.height}};
}
void SelectionHelper::update(bool isHovering, bool isLeftClick, bool isLeftHeld) {
void SelectionHelper::update(bool isHovering, bool isLeftClick, bool isLeftHeld, const Vector2f& cursorPos) {
hovered = isHovering;
clicked = false;
tapped = false;
justUnselected = false;
bool oldSelected = selected;
if(isLeftClick) {
if(hovered) {
selected = true;
clicked = true;
held = true;
clicked = true;
timeClicked = std::chrono::steady_clock::now();
clickPos = cursorPos;
}
else
selected = false;
}
else if(!isLeftHeld)
else if(!isLeftHeld) {
if(held && hovered && (std::chrono::steady_clock::now() - timeClicked) < std::chrono::milliseconds(250) && vec_distance_sqrd(clickPos, cursorPos) < (25 * 25)) {
selected = true;
tapped = true;
}
held = false;
}
if(!selected && oldSelected)
justUnselected = true;

View file

@ -119,12 +119,15 @@ struct UpdateInputData {
class SelectionHelper {
public:
void update(bool isHovering, bool isLeftClick, bool isLeftHeld);
void update(bool isHovering, bool isLeftClick, bool isLeftHeld, const Vector2f& cursorPos);
bool held = false;
bool hovered = false;
bool selected = false;
bool clicked = false;
bool justUnselected = false;
bool tapped = false;
Vector2f clickPos;
std::chrono::steady_clock::time_point timeClicked;
};
class Element {

View file

@ -24,7 +24,7 @@ void MovableTabList::update(UpdateInputData& io, const std::vector<std::pair<std
},
.clip = {.horizontal = true, .childOffset = Clay_GetScrollOffset()}
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
if(elemUpdate)
elemUpdate();
for(size_t i = 0; i < buttons.size(); i++) {

View file

@ -17,7 +17,7 @@ template <typename T> class NumberSlider : public Element {
},
.custom = { .customData = this }
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
if(selection.held && data) {
float fracPosOnSlider = (io.mouse.pos.x() - bb.min.x()) / bb.width();
*data = static_cast<T>(std::clamp<double>(std::lerp<double>(min, max, fracPosOnSlider), min, max)); // Clamp as double then cast so that unsigned types dont wrap on clamp

View file

@ -22,7 +22,7 @@ void PaintCircleMenu::update(GUIManager& gui, const Data& data, const std::funct
Vector2f vecFromCenter = (io.mouse.pos - bb.center()).normalized();
float distFromCenter = vec_distance(io.mouse.pos, bb.center());
if(data.newRotationAngle) {
rotateBarSelect.update(isHoveredNoObstruction && distFromCenter > ROTATE_START && distFromCenter < CIRCLE_END, io.mouse.leftClick, io.mouse.leftHeld);
rotateBarSelect.update(isHoveredNoObstruction && distFromCenter > ROTATE_START && distFromCenter < CIRCLE_END, io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
if(rotateBarSelect.held) {
double& newRotationAngle = *data.newRotationAngle;
newRotationAngle = std::atan2(vecFromCenter.y(), -vecFromCenter.x()) + std::numbers::pi;
@ -41,7 +41,7 @@ void PaintCircleMenu::update(GUIManager& gui, const Data& data, const std::funct
*data.newRotationAngle = data.currentRotationAngle;
}
if(!data.palette.empty() && data.selectedColor) {
colorBarSelect.update(isHoveredNoObstruction && distFromCenter > PALETTE_START && distFromCenter < ROTATE_START, io.mouse.leftClick, io.mouse.leftHeld);
colorBarSelect.update(isHoveredNoObstruction && distFromCenter > PALETTE_START && distFromCenter < ROTATE_START, io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
if(colorBarSelect.hovered) {
Vector4f& selectedColor = *data.selectedColor;
double selectionAngle = std::atan2(-vecFromCenter.y(), -vecFromCenter.x()) + std::numbers::pi;

View file

@ -9,7 +9,7 @@ void RadioButton::update(UpdateInputData& io, bool newIsTicked, const std::funct
},
.custom = { .customData = this }
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
if(isTicked != newIsTicked) {
hoverAnimation2 = RADIOBUTTON_ANIMATION_TIME;
isTicked = newIsTicked;

View file

@ -18,7 +18,7 @@ void RotateWheel::update(UpdateInputData& io, double* newRotationAnglePtr, const
},
.custom = { .customData = this }
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
Vector2f vecFromCenter = (io.mouse.pos - bb.center()).normalized();
float distFromCenter = vec_distance(io.mouse.pos, bb.center());
wheelHovered = selection.hovered && distFromCenter > wheel_start() && distFromCenter < wheel_end();

View file

@ -49,7 +49,7 @@ void SelectableButton::update(UpdateInputData& io, DrawType drawType, const std:
.backgroundColor = convert_vec4<Clay_Color>(backgroundColorHighlight),
.cornerRadius = CLAY_CORNER_RADIUS(4)
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
elemUpdate(selection, isSelected);
}
}

View file

@ -29,7 +29,7 @@ template <typename T> class TextBox : public Element {
},
.custom = { .customData = this }
}) {
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld);
selection.update(Clay_Hovered(), io.mouse.leftClick, io.mouse.leftHeld, io.mouse.pos);
if(data && selection.selected) {
io.richTextBoxToEdit = textbox;
io.richTextBoxToEditCursor = cur;