Overlapping ui items work now.

This commit is contained in:
Kapendev 2024-12-19 05:22:03 +02:00
parent 2603bf6d76
commit a24b98b26f
3 changed files with 41 additions and 12 deletions

View file

@ -15,11 +15,11 @@ bool update(float dt) {
// Set the margin between subsequent UI items.
setUiMargin(2);
setUiStartPoint(Vec2(8));
// Create a layout for arranging subsequent UI items.
// Create a horizontal layout for arranging subsequent UI items.
useUiLayout(Layout.h);
uiText(textSize, "Cool Button", UiButtonOptions(Alignment.left));
if (uiButton(buttonSize, "")) println("Cool");
// Create a new layout under the previous layout.
// Create a new horizontal layout under the previous layout.
useUiLayout(Layout.h);
uiText(textSize, "Super Button", UiButtonOptions(Alignment.left));
if (uiButton(buttonSize, "")) println("Super");

View file

@ -2335,7 +2335,7 @@ void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOpt
textOffsetY += font.lineSpacing;
codepointIndex += 1; // Adding the new line.
}
codepointIndex -= text[$ - 1] != '\n'; // Removing one extra new line.
// codepointIndex -= text[$ - 1] != '\n'; // Removing one extra new line.
rl.rlPopMatrix();
}

View file

@ -6,8 +6,7 @@
// Version: v0.0.29
// ---
// TODO: Think about overlapping UI items.
// TODO: Add way to get item point for some stuff. This is nice when making lists.
// TODO: Think about theming and other ui item types.
/// The `ui` module functions as a immediate mode UI library.
module parin.ui;
@ -73,8 +72,10 @@ struct UiState {
Vec2 viewportPoint;
Vec2 viewportSize;
Vec2 viewportScale = Vec2(1.0f);
Vec2 startPoint;
short margin;
Layout layout;
Vec2 layoutStartPoint;
Vec2 layoutStartPointOffest;
@ -90,22 +91,27 @@ struct UiState {
short clickedItemId;
short draggedItemId;
short focusedItemId;
short previousMaxHotItemId;
short previousMaxHotItemIdBuffer;
}
void prepareUi() {
setUiViewportState(Vec2(), resolution, Vec2(1.0f));
uiState.startPoint = Vec2();
uiState.margin = 0;
uiState.layout = Layout.v;
uiState.layoutStartPoint = Vec2();
uiState.layoutStartPointOffest = Vec2();
uiState.layoutMaxItemSize = Vec2();
uiState.itemPoint = Vec2();
uiState.itemSize = Vec2();
uiState.itemId = 0;
uiState.hotItemId = 0;
uiState.activeItemId = 0;
uiState.clickedItemId = 0;
uiState.previousMaxHotItemId = uiState.previousMaxHotItemIdBuffer;
}
Vec2 uiMouse() {
@ -141,7 +147,6 @@ void setUiViewportState(Vec2 point, Vec2 size, Vec2 scale) {
uiState.viewportPoint = point;
uiState.viewportSize = size;
uiState.viewportScale = scale;
if (uiState.mouseClickAction.isPressed) {
uiState.mousePressedPoint = uiMouse;
}
@ -152,8 +157,8 @@ Vec2 uiStartPoint() {
}
void setUiStartPoint(Vec2 value) {
uiState.itemSize = Vec2();
uiState.startPoint = value;
uiState.itemSize = Vec2();
uiState.layoutStartPoint = value;
uiState.layoutStartPointOffest = Vec2();
uiState.layoutMaxItemSize = Vec2();
@ -194,6 +199,14 @@ void useUiLayout(Layout value) {
uiState.layout = value;
}
Vec2 uiLayoutStartPoint() {
return uiState.layoutStartPoint;
}
Vec2 uiLayoutPoint() {
return uiState.layoutStartPoint + uiState.layoutStartPointOffest;
}
bool isUiItemHot() {
return uiState.itemId == uiState.hotItemId;
}
@ -230,7 +243,15 @@ Vec2 uiDragOffset() {
return uiState.itemDragOffset;
}
int uiFocus() {
bool isUiItemFocused() {
return uiState.itemId == uiState.focusedItemId;
}
bool isUiFocused() {
return uiState.focusedItemId > 0;
}
short uiFocus() {
return uiState.focusedItemId;
}
@ -289,7 +310,9 @@ void updateUiState(Vec2 itemPoint, Vec2 itemSize, bool isHot, bool isActive, boo
case Layout.v: uiState.layoutStartPointOffest.y += uiState.itemSize.y + uiState.margin; break;
case Layout.h: uiState.layoutStartPointOffest.x += uiState.itemSize.x + uiState.margin; break;
}
if (isHot) uiState.hotItemId = uiState.itemId;
if (isHot) {
uiState.hotItemId = uiState.itemId;
}
if (isActive) {
uiState.activeItemId = uiState.itemId;
uiState.focusedItemId = uiState.itemId;
@ -307,7 +330,7 @@ void updateUiState(Vec2 itemPoint, Vec2 itemSize, bool isHot, bool isActive, boo
void updateUiText(Vec2 size, IStr text, UiButtonOptions options = UiButtonOptions()) {
if (options.font.isEmpty) options.font = engineFont;
auto point = uiState.layoutStartPoint + uiState.layoutStartPointOffest;
auto point = uiLayoutPoint;
auto maxSize = measureTextSize(options.font, text);
if (maxSize.x < size.x) maxSize.x = size.x;
if (maxSize.y < size.y) maxSize.y = size.y;
@ -333,7 +356,7 @@ bool updateUiButton(Vec2 size, IStr text, UiButtonOptions options = UiButtonOpti
if (options.font.isEmpty) options.font = engineFont;
auto m = uiMouse;
auto id = uiState.itemId + 1;
auto point = uiState.layoutStartPoint + uiState.layoutStartPointOffest;
auto point = uiLayoutPoint;
auto maxSize = measureTextSize(options.font, text);
if (maxSize.x < size.x) maxSize.x = size.x;
if (maxSize.y < size.y) maxSize.y = size.y;
@ -343,6 +366,12 @@ bool updateUiButton(Vec2 size, IStr text, UiButtonOptions options = UiButtonOpti
m.x < point.x + maxSize.x &&
m.y >= point.y &&
m.y < point.y + maxSize.y;
if (isHot) {
uiState.previousMaxHotItemIdBuffer = cast(short) id;
}
if (uiState.previousMaxHotItemId) {
isHot = isHot && id == uiState.previousMaxHotItemId;
}
auto isActive = isHot && uiState.mouseClickAction.isDown;
auto isClicked = isHot;
if (uiState.isActOnPress) {
@ -435,7 +464,7 @@ bool uiDragHandle(Vec2 size, ref Vec2 point, UiButtonOptions options = UiButtonO
auto m = (mouse - uiState.viewportPoint) / uiState.viewportScale; // NOTE: Maybe this should be a function?
point.y = clamp(m.y + uiDragOffset.y, dragLimitY.x, dragLimitY.y - size.y);
point.x = clamp(m.x + uiDragOffset.x, dragLimitX.x, dragLimitX.y - size.x);
uiState = uiPreviousState;
uiState = uiPreviousState;
setUiStartPoint(point);
updateUiButton(size, "", options);
drawUiButton(size, "", uiState.itemPoint, isUiItemHot, isUiItemActive, options);