Default UI looks maybe better now.

This commit is contained in:
Kapendev 2025-01-04 11:53:37 +02:00
parent 4cb892672f
commit 900bf6513d
9 changed files with 79 additions and 37 deletions

View file

@ -17,8 +17,7 @@ void ready() {
bool update(float dt) {
// Create the drawing options for the map and tile.
auto mapOptions = DrawOptions(Hook.center);
mapOptions.scale = Vec2(2);
auto mapOptions = DrawOptions(Vec2(2));
auto tileOptions = mapOptions;
tileOptions.flip = tileFlip;
if (wasd.x > 0) tileFlip = Flip.x;
@ -26,14 +25,14 @@ bool update(float dt) {
// Move the tile and the camera.
tile.position += wasd * Vec2(120 * dt);
camera.position = tile.position;
camera.position = tile.position + tile.size * Vec2(0.5f);
// Check for collisions between the tile and the map and resolve the collision.
foreach (position; map.gridPositions(camera.area, mapOptions)) {
if (map[position] < 0) continue;
auto area = Rect(map.worldPosition(position, mapOptions), map.tileSize * mapOptions.scale);
while (area.hasIntersection(Rect(tile.position, tile.size * mapOptions.scale).area(mapOptions.hook))) {
while (area.hasIntersection(Rect(tile.position, tile.size * mapOptions.scale))) {
tile.position -= wasd * Vec2(dt);
camera.position = tile.position;
camera.position = tile.position + tile.size * Vec2(0.5f);
}
}

View file

@ -27,7 +27,6 @@ void ready() {
bool update(float dt) {
prepareUi();
setUiFocus(0);
setUiMargin(2);
setUiStartPoint(Vec2(8));
if (myButton("My Button 1")) println("Boom 1!");
if (myButton("My Button 2")) println("Boom 2!");

View file

@ -14,7 +14,7 @@ bool update(float dt) {
setUiFocus(0);
setUiStartPoint(Vec2(8));
// Toggle the limit of the drag handle.
if (uiButton(Vec2(100, 30), "Limit: {}".format(handleOptions.dragLimit))) {
if (uiButton(Vec2(120, 24), "Limit: {}".format(handleOptions.dragLimit))) {
if (handleOptions.dragLimit) handleOptions.dragLimit = UiDragLimit.none;
else handleOptions.dragLimit = UiDragLimit.viewport;
}

View file

@ -2,7 +2,7 @@
import parin;
auto textSize = Vec2(80, 20);
auto textSize = Vec2(90, 24);
auto buttonSize = Vec2(20);
void ready() {
@ -12,8 +12,6 @@ void ready() {
bool update(float dt) {
prepareUi();
setUiFocus(0);
// Set the margin between subsequent UI items.
setUiMargin(2);
setUiStartPoint(Vec2(8));
// Create a horizontal layout for arranging subsequent UI items.
useUiLayout(Layout.h);

View file

@ -2,7 +2,7 @@
import parin;
auto buttonSize = Vec2(60, 20);
auto buttonSize = Vec2(70, 24);
auto activeMenu = 0;
IStr[4] mainMenu = [
@ -31,7 +31,6 @@ void ready() {
bool update(float dt) {
prepareUi();
setUiFocus(0);
setUiMargin(2);
// Get the current menu.
auto menu = mainMenu[];
if (activeMenu == 1) menu = continueMenu[];

39
examples/ui/playground.d Normal file
View file

@ -0,0 +1,39 @@
/// This example shows almost every UI item of Parin.
import parin;
char[20] textFieldBuffer;
Str textFieldText;
auto handleSize = Vec2(140, 7);
auto buttonSize = Vec2(60, 20);
auto textSize = Vec2(140, 12);
auto uiPoint = Vec2();
void ready() {
lockResolution(320, 180);
}
bool update(float dt) {
prepareUi();
setUiFocus(0);
if (Keyboard.f11.isPressed) toggleIsFullscreen();
useUiLayout(Layout.h);
uiDragHandle(handleSize, uiPoint);
useUiLayout(Layout.h);
if (uiButton(buttonSize, "Button")) println("Button");
useUiLayout(Layout.h);
uiText(textSize, "Hello world!");
useUiLayout(Layout.h);
uiTextField(textSize, textFieldText, textFieldBuffer);
return false;
}
void finish() { }
mixin runGame!(ready, update, finish);

View file

@ -17,13 +17,10 @@ bool update(float dt) {
// Set the viewport state for subsequent UI items.
setUiViewportState(viewportPosition, viewport.size, viewportScale);
viewport.attach();
setUiMargin(2);
setUiStartPoint(Vec2(8));
foreach (i; 0 .. 4) {
if (uiButton(Vec2(14), i.toStr())) println(i);
foreach (i; 0 .. 3) {
if (uiButton(Vec2(19), i.toStr())) println(i);
}
viewport.detach();
drawViewport(viewport, viewportPosition, DrawOptions(viewportScale));
return false;

View file

@ -256,11 +256,11 @@ struct TileMap {
bool empty() {
return position.x > last.x || position.y > last.y;
}
IVec2 front() {
return position;
}
void popFront() {
position.x += 1;
if (position.x >= colCount) {

View file

@ -17,10 +17,12 @@ UiState uiState;
UiState uiPreviousState;
enum defaultUiAlpha = 220;
enum defaultUiDisabledColor = 0x202020.toRgb().alpha(defaultUiAlpha);
enum defaultUiIdleColor = 0x414141.toRgb().alpha(defaultUiAlpha);
enum defaultUiHotColor = 0x818181.toRgb().alpha(defaultUiAlpha);
enum defaultUiActiveColor = 0xBABABA.toRgb().alpha(defaultUiAlpha);
enum defaultUiBorderThickness = 1;
enum defaultUiMargin = 1;
enum defaultUiDisabledColor = 0x202020.toRgb();
enum defaultUiIdleColor = 0x414141.toRgb();
enum defaultUiHotColor = 0x818181.toRgb();
enum defaultUiActiveColor = 0xBABABA.toRgb();
/// A type representing the constraints on drag movement.
enum UiDragLimit: ubyte {
@ -36,8 +38,8 @@ enum UiDragLimit: ubyte {
struct UiOptions {
FontId font = FontId();
Alignment alignment = Alignment.center;
short alignmentOffset = 0;
UiDragLimit dragLimit = UiDragLimit.none;
short alignmentOffset = defaultUiBorderThickness;
UiDragLimit dragLimit = UiDragLimit.viewport;
Vec2 dragLimitX = Vec2(-100000.0f, 100000.0f);
Vec2 dragLimitY = Vec2(-100000.0f, 100000.0f);
bool isDisabled = false;
@ -48,7 +50,7 @@ struct UiOptions {
this.isDisabled = isDisabled;
}
this(Alignment alignment, short alignmentOffset = 0) {
this(Alignment alignment, short alignmentOffset = defaultUiBorderThickness) {
this.alignment = alignment;
this.alignmentOffset = alignmentOffset;
}
@ -69,7 +71,7 @@ struct UiState {
Vec2 viewportScale = Vec2(1.0f);
Vec2 startPoint;
short margin;
short margin = defaultUiMargin;
Layout layout;
Vec2 layoutStartPoint;
@ -107,7 +109,7 @@ int findSpaceInTextField(IStr text) {
void prepareUi() {
setUiViewportState(Vec2(), resolution, Vec2(1.0f));
uiState.startPoint = Vec2();
uiState.margin = 0;
uiState.margin = defaultUiMargin;
uiState.layout = Layout.v;
uiState.layoutStartPoint = Vec2();
@ -181,6 +183,8 @@ void setUiMargin(short value) {
uiState.margin = value;
}
// TODO: THERE IS A WEIRD BUG WITH SPACING IF YOU DON"T PUT USE AT THE START OF EVERY GROUP. FIX IT.
// TODO: MAYBE ALSO MAKE THIS POOOOOOP MORE SIMPLE.
void useUiLayout(Layout value) {
if (uiState.layoutStartPointOffest) {
final switch (value) {
@ -213,7 +217,7 @@ Vec2 uiLayoutStartPoint() {
}
Vec2 uiLayoutPoint() {
return uiState.layoutStartPoint + uiState.layoutStartPointOffest;
return (uiState.layoutStartPoint + uiState.layoutStartPointOffest);
}
Vec2 uiItemPoint() {
@ -358,10 +362,11 @@ void drawUiText(Vec2 size, IStr text, Vec2 point, UiOptions options = UiOptions(
case Alignment.center: break;
case Alignment.right: textPoint.x -= options.alignmentOffset; break;
}
textPoint = textPoint.round();
auto textOptions = DrawOptions(options.alignment, cast(int) size.x.round());
textOptions.hook = Hook.center;
if (options.isDisabled) textOptions.color.a = defaultUiAlpha;
drawText(font, text, textPoint.round(), textOptions);
drawText(font, text, textPoint, textOptions);
}
void uiText(Vec2 size, IStr text, UiOptions options = UiOptions()) {
@ -400,7 +405,7 @@ bool updateUiButton(Vec2 size, IStr text, UiOptions options = UiOptions()) {
if (uiState.keyboardClickAction.isDown || uiState.gamepadClickAction.isDown) isActive = true;
if (uiState.keyboardClickAction.isPressed || uiState.gamepadClickAction.isPressed) isClicked = true;
}
updateUiState(point, size, isHot, isActive, isClicked);
updateUiState(area.position, area.size, isHot, isActive, isClicked);
return isClicked;
}
@ -411,6 +416,7 @@ void drawUiButton(Vec2 size, IStr text, Vec2 point, bool isHot, bool isActive, U
else if (isActive) drawRect(area, defaultUiActiveColor);
else if (isHot) drawRect(area, defaultUiHotColor);
else drawRect(area, defaultUiIdleColor);
if (!options.isDisabled) drawHollowRect(area, defaultUiBorderThickness, defaultUiDisabledColor.alpha(defaultUiAlpha));
drawUiText(size, text, point, options);
}
@ -477,6 +483,9 @@ bool updateUiDragHandle(Vec2 size, ref Vec2 point, UiOptions options = UiOptions
void drawUiDragHandle(Vec2 size, Vec2 point, bool isHot, bool isActive, UiOptions options = UiOptions()) {
drawUiButton(size, "", point, isHot, isActive, options);
if (!options.isDisabled) {
drawHollowRect(Rect(point, size), defaultUiBorderThickness, defaultUiDisabledColor.alpha(defaultUiAlpha));
}
}
bool uiDragHandle(Vec2 size, ref Vec2 point, UiOptions options = UiOptions()) {
@ -495,7 +504,7 @@ bool updateUiTextField(Vec2 size, ref Str text, Str textBuffer, UiOptions option
} else if (Keyboard.backspace.isPressed && text.length > 0) {
if (Keyboard.ctrl.isDown || Keyboard.alt.isDown) {
auto spaceIndex = findSpaceInTextField(text);
while (spaceIndex == text.length - 1) {
while (text.length > 0 && spaceIndex == text.length - 1) {
text = text[0 .. $ - 1];
spaceIndex = findSpaceInTextField(text);
}
@ -579,11 +588,13 @@ void drawUiTextField(Vec2 size, Str text, Vec2 point, UiOptions options = UiOpti
case Alignment.right: textPoint.x = point.x + size.x - options.alignmentOffset; textSize.x = 0.0f; break;
}
if (!options.isDisabled) {
auto rect = Rect(textPoint.x + textSize.x + 1.0f, textPoint.y, font.size * 0.08f, font.size).area(Hook.center);
rect.subTopBottom(rect.size.y * 0.1f);
rect = rect.round();
if (rect.size.x == 0.0f) rect.size.x = 1.0f;
drawRect(rect, defaultUiDisabledColor);
auto rect = Rect(
round(textPoint.x + textSize.x + 2.0f),
round(textPoint.y),
font.size * 0.08f, font.size).area(Hook.center,
);
if (rect.size.x <= 1.0f) rect.size.x = 1.0f;
drawRect(rect, defaultUiDisabledColor.alpha(defaultUiAlpha));
}
}