mirror of
https://github.com/Kapendev/parin.git
synced 2025-04-26 04:59:54 +03:00
UI colors and replaced layout with RectCut method.
This commit is contained in:
parent
b89bec38e1
commit
5a3d3133d9
9 changed files with 104 additions and 251 deletions
|
@ -1,21 +1,21 @@
|
|||
/// This example shows how to create custom UI items.
|
||||
/// This example shows how to create a custom UI button.
|
||||
|
||||
import parin;
|
||||
|
||||
auto atlas = TextureId();
|
||||
|
||||
bool myButton(IStr text) {
|
||||
bool myButton(Rect area, IStr text) {
|
||||
// Create a button without drawing anything.
|
||||
auto result = updateUiButton(Vec2(80, 30), text);
|
||||
auto result = updateUiButton(area, text);
|
||||
// Draw the button above.
|
||||
if (isUiItemActive) {
|
||||
drawTextureArea(atlas, Rect(uiItemSize), uiItemPoint, DrawOptions(gray3));
|
||||
drawTextureArea(atlas, Rect(area.size), area.position, DrawOptions(gray3));
|
||||
} else if (isUiItemHot) {
|
||||
drawTextureArea(atlas, Rect(uiItemSize), uiItemPoint, DrawOptions(gray2));
|
||||
drawTextureArea(atlas, Rect(area.size), area.position, DrawOptions(gray2));
|
||||
} else {
|
||||
drawTextureArea(atlas, Rect(uiItemSize), uiItemPoint, DrawOptions(gray1));
|
||||
drawTextureArea(atlas, Rect(area.size), area.position, DrawOptions(gray1));
|
||||
}
|
||||
drawUiText(uiItemSize, text, uiItemPoint, UiOptions(Alignment.left, 6));
|
||||
drawUiText(area, text, UiOptions(Alignment.left, 4));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,7 @@ void ready() {
|
|||
bool update(float dt) {
|
||||
prepareUi();
|
||||
setUiFocus(0);
|
||||
setUiStartPoint(Vec2(8));
|
||||
if (myButton("My Button 1")) println("Boom 1!");
|
||||
if (myButton("My Button 2")) println("Boom 2!");
|
||||
if (myButton(Rect(8, 8, 100, 25), "My Button")) println("Boom!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
import parin;
|
||||
|
||||
char[32] textBuffer;
|
||||
Str text;
|
||||
char[32] textBuffer;
|
||||
|
||||
void ready() {
|
||||
lockResolution(320, 180);
|
||||
|
@ -12,12 +12,8 @@ void ready() {
|
|||
bool update(float dt) {
|
||||
prepareUi();
|
||||
setUiFocus(0);
|
||||
setUiStartPoint(Vec2());
|
||||
// Create the text field and print if enter is pressed.
|
||||
// Text field combos: ctrl+backspace, ctrl+x
|
||||
if (uiTextField(resolution, text, textBuffer)) {
|
||||
println(text);
|
||||
}
|
||||
// Create the text field and print if enter is pressed. Combos: ctrl+backspace, ctrl+x
|
||||
if (uiTextField(Rect(resolution), text, textBuffer)) println(text);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import parin;
|
||||
|
||||
auto handlePosition = Vec2(120, 60);
|
||||
auto handleArea = Rect(40, 60, 60, 60);
|
||||
auto handleOptions = UiOptions();
|
||||
|
||||
void ready() {
|
||||
|
@ -12,15 +12,13 @@ void ready() {
|
|||
bool update(float dt) {
|
||||
prepareUi();
|
||||
setUiFocus(0);
|
||||
setUiStartPoint(Vec2(8));
|
||||
// Toggle the limit of the drag handle.
|
||||
if (uiButton(Vec2(120, 24), "Limit: {}".format(handleOptions.dragLimit))) {
|
||||
if (handleOptions.dragLimit) handleOptions.dragLimit = UiDragLimit.none;
|
||||
else handleOptions.dragLimit = UiDragLimit.viewport;
|
||||
if (uiButton(Rect(8, 8, 120, 25), handleOptions.dragLimit.toStr())) {
|
||||
handleOptions.dragLimit = handleOptions.dragLimit ? UiDragLimit.none : UiDragLimit.viewport;
|
||||
}
|
||||
// Create the drag handle and print if it is dragged.
|
||||
if (uiDragHandle(Vec2(60), handlePosition, handleOptions)) {
|
||||
println(handlePosition);
|
||||
if (uiDragHandle(handleArea, handleOptions)) {
|
||||
println(handleArea.position);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
import parin;
|
||||
|
||||
auto buttonText = "Hello world!";
|
||||
|
||||
void ready() {
|
||||
lockResolution(320, 180);
|
||||
}
|
||||
|
@ -13,12 +11,8 @@ bool update(float dt) {
|
|||
prepareUi();
|
||||
// Disable the UI focus for this frame. Focus is only needed for UIs that support keyboard controls.
|
||||
setUiFocus(0);
|
||||
// Set the starting point for subsequent UI items.
|
||||
setUiStartPoint(Vec2(8));
|
||||
// Create a button and print if it is clicked.
|
||||
if (uiButton(Vec2(80, 30), buttonText)) {
|
||||
println(buttonText);
|
||||
}
|
||||
if (uiButton(Rect(8, 8, 100, 25), "Hello world!")) println("World: Hi!");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
import parin;
|
||||
|
||||
auto textSize = Vec2(90, 24);
|
||||
auto buttonSize = Vec2(20);
|
||||
auto groupHeight = 20;
|
||||
auto groupMargin = 2;
|
||||
auto buttonWidth = 20;
|
||||
auto textWidth = 90;
|
||||
|
||||
void ready() {
|
||||
lockResolution(320, 180);
|
||||
|
@ -12,15 +14,19 @@ void ready() {
|
|||
bool update(float dt) {
|
||||
prepareUi();
|
||||
setUiFocus(0);
|
||||
setUiStartPoint(Vec2(8));
|
||||
// Create a horizontal layout for arranging subsequent UI items.
|
||||
useUiLayout(Layout.h);
|
||||
uiText(textSize, "Cool Button", UiOptions(Alignment.left));
|
||||
if (uiButton(buttonSize, "")) println("Cool");
|
||||
// Create a new horizontal layout under the previous layout.
|
||||
useUiLayout(Layout.h);
|
||||
uiText(textSize, "Super Button", UiOptions(Alignment.left));
|
||||
if (uiButton(buttonSize, "")) println("Super");
|
||||
// Create an area for arranging UI items.
|
||||
auto area = Rect(Vec2(8), resolution - Vec2(8));
|
||||
auto group = Rect();
|
||||
// Group 1.
|
||||
group = area.subTop(groupHeight);
|
||||
uiText(group.subLeft(textWidth), "Cool Button", UiOptions(Alignment.left));
|
||||
if (uiButton(group.subLeft(buttonWidth), "")) println("Cool");
|
||||
// Margin.
|
||||
area.subTop(groupMargin);
|
||||
// Group 2.
|
||||
group = area.subTop(groupHeight);
|
||||
uiText(group.subLeft(textWidth), "Super Button", UiOptions(Alignment.left));
|
||||
if (uiButton(group.subLeft(buttonWidth), "")) println("Super");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
import parin;
|
||||
|
||||
auto buttonSize = Vec2(70, 24);
|
||||
auto activeMenu = 0;
|
||||
auto buttonWidth = 70;
|
||||
auto buttonHeight = 25;
|
||||
auto buttonMargin = 2;
|
||||
|
||||
IStr[4] mainMenu = [
|
||||
"Start",
|
||||
|
@ -12,9 +14,8 @@ IStr[4] mainMenu = [
|
|||
"Quit",
|
||||
];
|
||||
|
||||
IStr[3] continueMenu = [
|
||||
IStr[2] continueMenu = [
|
||||
"Save 1",
|
||||
"Save 2",
|
||||
"Back",
|
||||
];
|
||||
|
||||
|
@ -36,18 +37,20 @@ bool update(float dt) {
|
|||
if (activeMenu == 1) menu = continueMenu[];
|
||||
else if (activeMenu == 2) menu = settingsMenu[];
|
||||
// Draw the menu.
|
||||
auto menuPoint = resolution * Vec2(0.5);
|
||||
menuPoint.x -= buttonSize.x * 0.5;
|
||||
menuPoint.y -= (buttonSize.y * menu.length + uiMargin * (menu.length - 1)) * 0.5;
|
||||
setUiStartPoint(menuPoint);
|
||||
auto area = Rect(
|
||||
resolution * Vec2(0.5),
|
||||
buttonWidth,
|
||||
buttonHeight * menu.length + buttonMargin * (menu.length - 1),
|
||||
).area(Hook.center);
|
||||
foreach (item; menu) {
|
||||
if (uiButton(buttonSize, item)) {
|
||||
if (uiButton(area.subTop(buttonHeight), item)) {
|
||||
println(item);
|
||||
if (activeMenu == 0 && item == "Continue") activeMenu = 1;
|
||||
if (activeMenu == 0 && item == "Settings") activeMenu = 2;
|
||||
if (item == "Back") activeMenu = 0;
|
||||
if (item == "Quit") return true;
|
||||
}
|
||||
area.subTop(buttonMargin);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
/// 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);
|
|
@ -17,9 +17,8 @@ bool update(float dt) {
|
|||
// Set the viewport state for subsequent UI items.
|
||||
setUiViewportState(viewportPosition, viewport.size, viewportScale);
|
||||
viewport.attach();
|
||||
setUiStartPoint(Vec2(8));
|
||||
foreach (i; 0 .. 3) {
|
||||
if (uiButton(Vec2(19), i.toStr())) println(i);
|
||||
if (uiButton(Rect(8, 8 + i * 22, 20, 20), i.toStr())) println(i);
|
||||
}
|
||||
viewport.detach();
|
||||
drawViewport(viewport, viewportPosition, DrawOptions(viewportScale));
|
||||
|
|
|
@ -18,9 +18,7 @@ import parin.engine;
|
|||
UiState uiState;
|
||||
UiState uiPreviousState;
|
||||
|
||||
enum defaultUiAlpha = 220;
|
||||
enum defaultUiMargin = 1;
|
||||
enum defaultUiBorderThickness = 1;
|
||||
enum defaultUiAlpha = 200;
|
||||
enum defaultUiDisabledColor = 0x202020.toRgb();
|
||||
enum defaultUiIdleColor = 0x414141.toRgb();
|
||||
enum defaultUiHotColor = 0x818181.toRgb();
|
||||
|
@ -39,8 +37,13 @@ enum UiDragLimit: ubyte {
|
|||
|
||||
struct UiOptions {
|
||||
FontId font = FontId();
|
||||
Color disabledColor = defaultUiDisabledColor;
|
||||
Color idleColor = defaultUiIdleColor;
|
||||
Color hotColor = defaultUiHotColor;
|
||||
Color activeColor = defaultUiActiveColor;
|
||||
|
||||
Alignment alignment = Alignment.center;
|
||||
short alignmentOffset = defaultUiBorderThickness;
|
||||
short alignmentOffset = 0;
|
||||
UiDragLimit dragLimit = UiDragLimit.viewport;
|
||||
Vec2 dragLimitX = Vec2(-100000.0f, 100000.0f);
|
||||
Vec2 dragLimitY = Vec2(-100000.0f, 100000.0f);
|
||||
|
@ -52,7 +55,7 @@ struct UiOptions {
|
|||
this.isDisabled = isDisabled;
|
||||
}
|
||||
|
||||
this(Alignment alignment, short alignmentOffset = defaultUiBorderThickness) {
|
||||
this(Alignment alignment, short alignmentOffset = 0) {
|
||||
this.alignment = alignment;
|
||||
this.alignmentOffset = alignmentOffset;
|
||||
}
|
||||
|
@ -72,18 +75,8 @@ struct UiState {
|
|||
Vec2 viewportSize;
|
||||
Vec2 viewportScale = Vec2(1.0f);
|
||||
|
||||
Vec2 startPoint;
|
||||
short margin = defaultUiMargin;
|
||||
|
||||
Layout layout;
|
||||
Vec2 layoutStartPoint;
|
||||
Vec2 layoutStartPointOffest;
|
||||
Vec2 layoutMaxItemSize;
|
||||
|
||||
Vec2 mousePressedPoint;
|
||||
Vec2 itemDragOffset;
|
||||
Vec2 itemPoint;
|
||||
Vec2 itemSize;
|
||||
short itemId;
|
||||
short hotItemId;
|
||||
short activeItemId;
|
||||
|
@ -110,16 +103,6 @@ int findSpaceInTextField(IStr text) {
|
|||
|
||||
void prepareUi() {
|
||||
setUiViewportState(Vec2(), resolution, Vec2(1.0f));
|
||||
uiState.startPoint = Vec2();
|
||||
uiState.margin = defaultUiMargin;
|
||||
|
||||
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;
|
||||
|
@ -165,75 +148,10 @@ void setUiViewportState(Vec2 point, Vec2 size, Vec2 scale) {
|
|||
}
|
||||
}
|
||||
|
||||
Vec2 uiStartPoint() {
|
||||
return uiState.startPoint;
|
||||
}
|
||||
|
||||
void setUiStartPoint(Vec2 value) {
|
||||
uiState.startPoint = value;
|
||||
uiState.itemSize = Vec2();
|
||||
uiState.layoutStartPoint = value;
|
||||
uiState.layoutStartPointOffest = Vec2();
|
||||
uiState.layoutMaxItemSize = Vec2();
|
||||
}
|
||||
|
||||
short uiMargin() {
|
||||
return uiState.margin;
|
||||
}
|
||||
|
||||
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) {
|
||||
case Layout.v:
|
||||
if (uiState.layoutStartPointOffest.x > uiState.layoutMaxItemSize.x) {
|
||||
uiState.layoutStartPoint.x = uiState.layoutStartPoint.x + uiState.layoutStartPointOffest.x + uiState.margin;
|
||||
} else {
|
||||
uiState.layoutStartPoint.x += uiState.layoutMaxItemSize.x + uiState.margin;
|
||||
}
|
||||
uiState.layoutStartPointOffest = Vec2();
|
||||
uiState.layoutMaxItemSize.x = 0.0f;
|
||||
break;
|
||||
case Layout.h:
|
||||
uiState.layoutStartPoint.x = uiState.startPoint.x;
|
||||
if (uiState.layoutStartPointOffest.y > uiState.layoutMaxItemSize.y) {
|
||||
uiState.layoutStartPoint.y = uiState.layoutStartPoint.y + uiState.layoutStartPointOffest.y + uiState.margin;
|
||||
} else {
|
||||
uiState.layoutStartPoint.y += uiState.layoutMaxItemSize.y + uiState.margin;
|
||||
}
|
||||
uiState.layoutStartPointOffest = Vec2();
|
||||
uiState.layoutMaxItemSize.y = 0.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
uiState.layout = value;
|
||||
}
|
||||
|
||||
Vec2 uiLayoutStartPoint() {
|
||||
return uiState.layoutStartPoint;
|
||||
}
|
||||
|
||||
Vec2 uiLayoutPoint() {
|
||||
return uiState.layoutStartPoint + uiState.layoutStartPointOffest;
|
||||
}
|
||||
|
||||
short uiItemId() {
|
||||
return uiState.itemId;
|
||||
}
|
||||
|
||||
Vec2 uiItemPoint() {
|
||||
return uiState.itemPoint;
|
||||
}
|
||||
|
||||
Vec2 uiItemSize() {
|
||||
return uiState.itemSize;
|
||||
}
|
||||
|
||||
bool isUiItemHot() {
|
||||
return uiState.itemId == uiState.hotItemId;
|
||||
}
|
||||
|
@ -326,17 +244,9 @@ void wrapUiFocus(short step, Sz length) {
|
|||
uiState.focusedItemId = wrap(cast(short) (uiState.focusedItemId + step), min, cast(short) (max + 1));
|
||||
}
|
||||
|
||||
void updateUiState(Vec2 itemPoint, Vec2 itemSize, bool isHot, bool isActive, bool isClicked) {
|
||||
void updateUiState(Rect area, bool isHot, bool isActive, bool isClicked) {
|
||||
uiPreviousState = uiState;
|
||||
uiState.itemPoint = itemPoint;
|
||||
uiState.itemSize = itemSize;
|
||||
uiState.itemId += 1;
|
||||
if (itemSize.x > uiState.layoutMaxItemSize.x) uiState.layoutMaxItemSize.x = itemSize.x;
|
||||
if (itemSize.y > uiState.layoutMaxItemSize.y) uiState.layoutMaxItemSize.y = itemSize.y;
|
||||
final switch (uiState.layout) {
|
||||
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;
|
||||
}
|
||||
|
@ -347,7 +257,7 @@ void updateUiState(Vec2 itemPoint, Vec2 itemSize, bool isHot, bool isActive, boo
|
|||
if (isClicked) uiState.clickedItemId = uiState.itemId;
|
||||
if (uiState.mouseClickAction.isPressed && uiState.itemId == uiState.activeItemId) {
|
||||
auto m = uiMouse;
|
||||
uiState.itemDragOffset = uiState.itemPoint - m;
|
||||
uiState.itemDragOffset = area.position - m;
|
||||
uiState.draggedItemId = uiState.itemId;
|
||||
}
|
||||
if (uiState.draggedItemId) {
|
||||
|
@ -355,13 +265,12 @@ void updateUiState(Vec2 itemPoint, Vec2 itemSize, bool isHot, bool isActive, boo
|
|||
}
|
||||
}
|
||||
|
||||
void updateUiText(Vec2 size, IStr text, UiOptions options = UiOptions()) {
|
||||
updateUiState(uiLayoutPoint, size, false, false, false);
|
||||
void updateUiText(Rect area, IStr text, UiOptions options = UiOptions()) {
|
||||
updateUiState(area, false, false, false);
|
||||
}
|
||||
|
||||
void drawUiText(Vec2 size, IStr text, Vec2 point, UiOptions options = UiOptions()) {
|
||||
void drawUiText(Rect area, IStr text, UiOptions options = UiOptions()) {
|
||||
auto font = options.font.isValid ? options.font.get() : engineFont;
|
||||
auto area = Rect(point, size);
|
||||
auto textPoint = area.centerPoint;
|
||||
final switch (options.alignment) {
|
||||
case Alignment.left: textPoint.x += options.alignmentOffset; break;
|
||||
|
@ -369,23 +278,21 @@ void drawUiText(Vec2 size, IStr text, Vec2 point, UiOptions options = UiOptions(
|
|||
case Alignment.right: textPoint.x -= options.alignmentOffset; break;
|
||||
}
|
||||
textPoint = textPoint.round();
|
||||
auto textOptions = DrawOptions(options.alignment, cast(int) size.x.round());
|
||||
auto textOptions = DrawOptions(options.alignment, cast(int) area.size.x.round());
|
||||
textOptions.hook = Hook.center;
|
||||
if (options.isDisabled) textOptions.color.a = defaultUiAlpha;
|
||||
drawText(font, text, textPoint, textOptions);
|
||||
}
|
||||
|
||||
void uiText(Vec2 size, IStr text, UiOptions options = UiOptions()) {
|
||||
updateUiText(size, text, options);
|
||||
drawUiText(uiItemSize, text, uiItemPoint, options);
|
||||
void uiText(Rect area, IStr text, UiOptions options = UiOptions()) {
|
||||
updateUiText(area, text, options);
|
||||
drawUiText(area, text, options);
|
||||
}
|
||||
|
||||
bool updateUiButton(Vec2 size, IStr text, UiOptions options = UiOptions()) {
|
||||
bool updateUiButton(Rect area, IStr text, UiOptions options = UiOptions()) {
|
||||
auto font = options.font.isValid ? options.font.get() : engineFont;
|
||||
auto m = uiMouse;
|
||||
auto id = uiState.itemId + 1;
|
||||
auto point = uiLayoutPoint;
|
||||
auto area = Rect(point, size);
|
||||
auto isHot = area.hasPointInclusive(m);
|
||||
if (isHot) {
|
||||
uiState.previousMaxHotItemIdBuffer = cast(short) id;
|
||||
|
@ -411,28 +318,26 @@ 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(area.position, area.size, isHot, isActive, isClicked);
|
||||
updateUiState(area, isHot, isActive, isClicked);
|
||||
return isClicked;
|
||||
}
|
||||
|
||||
void drawUiButton(Vec2 size, IStr text, Vec2 point, bool isHot, bool isActive, UiOptions options = UiOptions()) {
|
||||
void drawUiButton(Rect area, IStr text, bool isHot, bool isActive, UiOptions options = UiOptions()) {
|
||||
auto font = options.font.isValid ? options.font.get() : engineFont;
|
||||
auto area = Rect(point, size);
|
||||
if (options.isDisabled) drawRect(area, defaultUiDisabledColor);
|
||||
else if (isActive) drawRect(area, defaultUiActiveColor);
|
||||
else if (isHot) drawRect(area, defaultUiHotColor);
|
||||
else drawRect(area, defaultUiIdleColor);
|
||||
drawHollowRect(area, defaultUiBorderThickness, defaultUiDisabledColor.alpha(defaultUiAlpha));
|
||||
drawUiText(size, text, point, options);
|
||||
if (options.isDisabled) drawRect(area, options.disabledColor);
|
||||
else if (isActive) drawRect(area, options.activeColor);
|
||||
else if (isHot) drawRect(area, options.hotColor);
|
||||
else drawRect(area, options.idleColor);
|
||||
drawUiText(area, text, options);
|
||||
}
|
||||
|
||||
bool uiButton(Vec2 size, IStr text, UiOptions options = UiOptions()) {
|
||||
auto result = updateUiButton(size, text, options);
|
||||
drawUiButton(uiItemSize, text, uiItemPoint, isUiItemHot, isUiItemActive, options);
|
||||
bool uiButton(Rect area, IStr text, UiOptions options = UiOptions()) {
|
||||
auto result = updateUiButton(area, text, options);
|
||||
drawUiButton(area, text, isUiItemHot, isUiItemActive, options);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool updateUiDragHandle(Vec2 size, ref Vec2 point, UiOptions options = UiOptions()) {
|
||||
bool updateUiDragHandle(ref Rect area, UiOptions options = UiOptions()) {
|
||||
auto dragLimitX = Vec2(-100000.0f, 100000.0f);
|
||||
auto dragLimitY = Vec2(-100000.0f, 100000.0f);
|
||||
// NOTE: There is a potential bug here when size is bigger than the limit/viewport. I will ignore it for now.
|
||||
|
@ -443,13 +348,13 @@ bool updateUiDragHandle(Vec2 size, ref Vec2 point, UiOptions options = UiOptions
|
|||
dragLimitY = Vec2(0.0f, uiState.viewportSize.y);
|
||||
break;
|
||||
case UiDragLimit.viewportAndX:
|
||||
point.y = clamp(point.y, 0.0f, uiState.viewportSize.y - size.y);
|
||||
area.position.y = clamp(area.position.y, 0.0f, uiState.viewportSize.y - area.size.y);
|
||||
dragLimitX = Vec2(0.0f, uiState.viewportSize.x);
|
||||
dragLimitY = Vec2(point.y, point.y + size.y);
|
||||
dragLimitY = Vec2(area.position.y, area.position.y + area.size.y);
|
||||
break;
|
||||
case UiDragLimit.viewportAndY:
|
||||
point.x = clamp(point.x, 0.0f, uiState.viewportSize.x - size.x);
|
||||
dragLimitX = Vec2(point.x, point.x + size.x);
|
||||
area.position.x = clamp(area.position.x, 0.0f, uiState.viewportSize.x - area.size.x);
|
||||
dragLimitX = Vec2(area.position.x, area.position.x + area.size.x);
|
||||
dragLimitY = Vec2(0.0f, uiState.viewportSize.y);
|
||||
break;
|
||||
case UiDragLimit.custom:
|
||||
|
@ -457,51 +362,45 @@ bool updateUiDragHandle(Vec2 size, ref Vec2 point, UiOptions options = UiOptions
|
|||
dragLimitY = options.dragLimitY;
|
||||
break;
|
||||
case UiDragLimit.customAndX:
|
||||
point.y = clamp(point.y, 0.0f, options.dragLimitY.y - size.y);
|
||||
area.position.y = clamp(area.position.y, 0.0f, options.dragLimitY.y - area.size.y);
|
||||
dragLimitX = options.dragLimitX;
|
||||
dragLimitY = Vec2(point.y, point.y + size.y);
|
||||
dragLimitY = Vec2(area.position.y, area.position.y + area.size.y);
|
||||
break;
|
||||
case UiDragLimit.customAndY:
|
||||
point.x = clamp(point.x, 0.0f, options.dragLimitX.y - size.x);
|
||||
dragLimitX = Vec2(point.x, point.x + size.x);
|
||||
area.position.x = clamp(area.position.x, 0.0f, options.dragLimitX.y - area.size.x);
|
||||
dragLimitX = Vec2(area.position.x, area.position.x + area.size.x);
|
||||
dragLimitY = options.dragLimitY;
|
||||
break;
|
||||
}
|
||||
|
||||
size.x = clamp(size.x, 0.0f, dragLimitX.y - dragLimitX.x);
|
||||
size.y = clamp(size.y, 0.0f, dragLimitY.y - dragLimitY.x);
|
||||
point.x = clamp(point.x, dragLimitX.x, dragLimitX.y - size.x);
|
||||
point.y = clamp(point.y, dragLimitY.x, dragLimitY.y - size.y);
|
||||
setUiStartPoint(point);
|
||||
updateUiButton(size, "", options);
|
||||
area.position.x = clamp(area.position.x, dragLimitX.x, dragLimitX.y - area.size.x);
|
||||
area.position.y = clamp(area.position.y, dragLimitY.x, dragLimitY.y - area.size.y);
|
||||
updateUiButton(area, "", options);
|
||||
if (isUiItemDragged) {
|
||||
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);
|
||||
area.position.y = clamp(m.y + uiDragOffset.y, dragLimitY.x, dragLimitY.y - area.size.y);
|
||||
area.position.x = clamp(m.x + uiDragOffset.x, dragLimitX.x, dragLimitX.y - area.size.x);
|
||||
uiState = uiPreviousState;
|
||||
setUiStartPoint(point);
|
||||
updateUiButton(size, "", options);
|
||||
updateUiButton(area, "", options);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void drawUiDragHandle(Vec2 size, Vec2 point, bool isHot, bool isActive, UiOptions options = UiOptions()) {
|
||||
drawUiButton(size, "", point, isHot, isActive, options);
|
||||
drawHollowRect(Rect(point, size), defaultUiBorderThickness, defaultUiDisabledColor.alpha(defaultUiAlpha));
|
||||
void drawUiDragHandle(Rect area, bool isHot, bool isActive, UiOptions options = UiOptions()) {
|
||||
drawUiButton(area, "", isHot, isActive, options);
|
||||
}
|
||||
|
||||
bool uiDragHandle(Vec2 size, ref Vec2 point, UiOptions options = UiOptions()) {
|
||||
auto result = updateUiDragHandle(size, point, options);
|
||||
drawUiDragHandle(uiItemSize, uiItemPoint, isUiItemHot, isUiItemActive, options);
|
||||
bool uiDragHandle(ref Rect area, UiOptions options = UiOptions()) {
|
||||
auto result = updateUiDragHandle(area, options);
|
||||
drawUiDragHandle(area, isUiItemHot, isUiItemActive, options);
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: Add support for right-to-left text.
|
||||
@trusted
|
||||
bool updateUiTextField(Vec2 size, ref Str text, Str textBuffer, UiOptions options = UiOptions()) {
|
||||
auto point = uiLayoutPoint;
|
||||
bool updateUiTextField(Rect area, ref Str text, Str textBuffer, UiOptions options = UiOptions()) {
|
||||
if (options.isDisabled) {
|
||||
// Look, I am funny.
|
||||
} else if (Keyboard.x.isPressed && (Keyboard.ctrl.isDown || Keyboard.alt.isDown)) {
|
||||
|
@ -575,22 +474,21 @@ bool updateUiTextField(Vec2 size, ref Str text, Str textBuffer, UiOptions option
|
|||
}
|
||||
}
|
||||
}
|
||||
updateUiState(point, size, false, false, false);
|
||||
updateUiState(area, false, false, false);
|
||||
return uiState.keyboardClickAction.isPressed;
|
||||
}
|
||||
|
||||
// TODO: Add support for right-to-left text.
|
||||
void drawUiTextField(Vec2 size, Str text, Vec2 point, UiOptions options = UiOptions()) {
|
||||
void drawUiTextField(Rect area, Str text, UiOptions options = UiOptions()) {
|
||||
auto font = options.font.isValid ? options.font.get() : engineFont;
|
||||
drawUiText(size, text, point, options);
|
||||
drawUiText(area, text, options);
|
||||
// TODO: Make that text thing a function doood.
|
||||
auto area = Rect(point, size);
|
||||
auto textPoint = area.centerPoint;
|
||||
auto textSize = measureTextSize(font, text);
|
||||
final switch (options.alignment) {
|
||||
case Alignment.left: textPoint.x = point.x + options.alignmentOffset; break;
|
||||
case Alignment.left: textPoint.x = area.position.x + options.alignmentOffset; break;
|
||||
case Alignment.center: textSize.x *= 0.5f; break;
|
||||
case Alignment.right: textPoint.x = point.x + size.x - options.alignmentOffset; textSize.x = 0.0f; break;
|
||||
case Alignment.right: textPoint.x = area.position.x + area.size.x - options.alignmentOffset; textSize.x = 0.0f; break;
|
||||
}
|
||||
if (!options.isDisabled) {
|
||||
auto rect = Rect(
|
||||
|
@ -599,15 +497,15 @@ void drawUiTextField(Vec2 size, Str text, Vec2 point, UiOptions options = UiOpti
|
|||
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));
|
||||
drawRect(rect, options.disabledColor.alpha(defaultUiAlpha));
|
||||
}
|
||||
}
|
||||
|
||||
// Combos:
|
||||
// ctrl|alt + backsapce : Remove word.
|
||||
// ctrl|alt + x : Remove everything.
|
||||
bool uiTextField(Vec2 size, ref Str text, Str textBuffer, UiOptions options = UiOptions()) {
|
||||
auto result = updateUiTextField(size, text, textBuffer, options);
|
||||
drawUiTextField(uiItemSize, text, uiItemPoint, options);
|
||||
bool uiTextField(Rect area, ref Str text, Str textBuffer, UiOptions options = UiOptions()) {
|
||||
auto result = updateUiTextField(area, text, textBuffer, options);
|
||||
drawUiTextField(area, text, options);
|
||||
return result;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue