Move ui element rendering to window rendering
This commit is contained in:
parent
70a3032155
commit
4e585a4939
@ -4,70 +4,6 @@
|
|||||||
#include "Dengine/Renderer.h"
|
#include "Dengine/Renderer.h"
|
||||||
#include "Dengine/Debug.h"
|
#include "Dengine/Debug.h"
|
||||||
|
|
||||||
i32 userInterface_window(UiState *const uiState, MemoryArena *const arena,
|
|
||||||
AssetManager *const assetManager,
|
|
||||||
Renderer *const renderer, Font *const font,
|
|
||||||
const KeyInput input, WindowState *window)
|
|
||||||
{
|
|
||||||
if (math_pointInRect(window->rect, input.mouseP))
|
|
||||||
{
|
|
||||||
uiState->hotItem = window->id;
|
|
||||||
if (uiState->activeItem == 0 && input.keys[keycode_mouseLeft].endedDown)
|
|
||||||
uiState->activeItem = window->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect rect = window->rect;
|
|
||||||
RenderTex nullRenderTex = renderer_createNullRenderTex(assetManager);
|
|
||||||
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
|
|
||||||
nullRenderTex, V4(0.25f, 0.25f, 0.5f, 0.5f));
|
|
||||||
|
|
||||||
v2 menuTitleP = v2_add(rect.pos, V2(0, rect.size.h - 10));
|
|
||||||
renderer_staticString(renderer, arena, font, window->title, menuTitleP,
|
|
||||||
V2(0, 0), 0, V4(0, 0, 0, 1));
|
|
||||||
|
|
||||||
// NOTE(doyle): activeItem captures mouse click within the UI bounds, but if
|
|
||||||
// the user drags the mouse outside the bounds quicker than the game updates
|
|
||||||
// then we use a second flag which only "unclicks" when the mouse is let go
|
|
||||||
if (uiState->activeItem == window->id) window->windowHeld = TRUE;
|
|
||||||
|
|
||||||
if (window->windowHeld)
|
|
||||||
{
|
|
||||||
if (!input.keys[keycode_mouseLeft].endedDown)
|
|
||||||
{
|
|
||||||
window->windowHeld = FALSE;
|
|
||||||
window->prevFrameWindowHeld = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (window->windowHeld)
|
|
||||||
{
|
|
||||||
// NOTE(doyle): If this is the first window click we don't process
|
|
||||||
// movement and store the current position to delta from next cycle
|
|
||||||
if (window->prevFrameWindowHeld)
|
|
||||||
{
|
|
||||||
// NOTE(doyle): Window clicked and held
|
|
||||||
v2 deltaP = v2_sub(input.mouseP, window->prevMouseP);
|
|
||||||
DEBUG_PUSH_VAR("Delta Pos %4.2f, %4.2f", deltaP, "v2");
|
|
||||||
window->rect.pos = v2_add(deltaP, window->rect.pos);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
window->prevFrameWindowHeld = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
window->prevMouseP = input.mouseP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!input.keys[keycode_mouseLeft].endedDown &&
|
|
||||||
uiState->hotItem == window->id &&
|
|
||||||
uiState->activeItem == window->id)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
i32 userInterface_button(UiState *const uiState,
|
i32 userInterface_button(UiState *const uiState,
|
||||||
MemoryArena *const arena,
|
MemoryArena *const arena,
|
||||||
AssetManager *const assetManager,
|
AssetManager *const assetManager,
|
||||||
@ -194,13 +130,13 @@ i32 userInterface_button(UiState *const uiState,
|
|||||||
uiState->hotItem == id &&
|
uiState->hotItem == id &&
|
||||||
uiState->activeItem == id)
|
uiState->activeItem == id)
|
||||||
{
|
{
|
||||||
return 1;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
i32 userInterface_scrollBar(UiState *const uiState,
|
i32 userInterface_scrollbar(UiState *const uiState,
|
||||||
AssetManager *const assetManager,
|
AssetManager *const assetManager,
|
||||||
Renderer *const renderer, const KeyInput input,
|
Renderer *const renderer, const KeyInput input,
|
||||||
const i32 id, const Rect scrollBarRect,
|
const i32 id, const Rect scrollBarRect,
|
||||||
@ -277,13 +213,13 @@ i32 userInterface_scrollBar(UiState *const uiState,
|
|||||||
if (*value < maxValue)
|
if (*value < maxValue)
|
||||||
{
|
{
|
||||||
(*value)++;
|
(*value)++;
|
||||||
return 1;
|
return id;
|
||||||
}
|
}
|
||||||
case keycode_down:
|
case keycode_down:
|
||||||
if (*value > 0)
|
if (*value > 0)
|
||||||
{
|
{
|
||||||
(*value)--;
|
(*value)--;
|
||||||
return 1;
|
return id;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -309,7 +245,7 @@ i32 userInterface_scrollBar(UiState *const uiState,
|
|||||||
if (newValue != *value)
|
if (newValue != *value)
|
||||||
{
|
{
|
||||||
*value = newValue;
|
*value = newValue;
|
||||||
return 1;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,17 +255,13 @@ i32 userInterface_scrollBar(UiState *const uiState,
|
|||||||
i32 userInterface_textField(UiState *const uiState, MemoryArena *const arena,
|
i32 userInterface_textField(UiState *const uiState, MemoryArena *const arena,
|
||||||
AssetManager *const assetManager,
|
AssetManager *const assetManager,
|
||||||
Renderer *const renderer, Font *const font,
|
Renderer *const renderer, Font *const font,
|
||||||
KeyInput input, const i32 id, v2 pos,
|
KeyInput input, const i32 id, const Rect rect,
|
||||||
char *const string)
|
char *const string)
|
||||||
{
|
{
|
||||||
i32 strLen = common_strlen(string);
|
i32 strLen = common_strlen(string);
|
||||||
b32 changed = FALSE;
|
b32 changed = FALSE;
|
||||||
|
|
||||||
Rect textRect = {0};
|
if (math_pointInRect(rect, input.mouseP))
|
||||||
textRect.pos = pos;
|
|
||||||
textRect.size = V2(30 * font->maxSize.w, font->maxSize.h);
|
|
||||||
|
|
||||||
if (math_pointInRect(textRect, input.mouseP))
|
|
||||||
{
|
{
|
||||||
uiState->hotItem = id;
|
uiState->hotItem = id;
|
||||||
if (uiState->activeItem == uiState->statWindow.id ||
|
if (uiState->activeItem == uiState->statWindow.id ||
|
||||||
@ -352,28 +284,27 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena *const arena,
|
|||||||
if (uiState->kbdItem == id)
|
if (uiState->kbdItem == id)
|
||||||
{
|
{
|
||||||
// Draw outline
|
// Draw outline
|
||||||
renderer_staticRect(renderer, v2_add(V2(-2, -2), textRect.pos),
|
renderer_staticRect(renderer, v2_add(V2(-2, -2), rect.pos),
|
||||||
v2_add(V2(4, 4), textRect.size), V2(0, 0), 0,
|
v2_add(V2(4, 4), rect.size), V2(0, 0), 0,
|
||||||
renderTex, V4(1.0f, 0, 0, 1));
|
renderTex, V4(1.0f, 0, 0, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render text field
|
// Render text field
|
||||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
|
||||||
renderTex, V4(0.75f, 0.5f, 0.5f, 1));
|
renderTex, V4(0.75f, 0.5f, 0.5f, 1));
|
||||||
|
|
||||||
if (uiState->activeItem == id || uiState->hotItem == id)
|
if (uiState->activeItem == id || uiState->hotItem == id)
|
||||||
{
|
{
|
||||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
|
||||||
renderTex, V4(0.75f, 0.75f, 0.0f, 1));
|
renderTex, V4(0.75f, 0.75f, 0.0f, 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
|
||||||
renderTex, V4(0.5f, 0.5f, 0.5f, 1));
|
renderTex, V4(0.5f, 0.5f, 0.5f, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
v2 strPos = textRect.pos;
|
v2 strPos = rect.pos;
|
||||||
|
|
||||||
renderer_staticString(renderer, arena, font, string, strPos, V2(0, 0), 0,
|
renderer_staticString(renderer, arena, font, string, strPos, V2(0, 0), 0,
|
||||||
V4(0, 0, 0, 1));
|
V4(0, 0, 0, 1));
|
||||||
|
|
||||||
@ -417,6 +348,138 @@ i32 userInterface_textField(UiState *const uiState, MemoryArena *const arena,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uiState->lastWidget = id;
|
uiState->lastWidget = id;
|
||||||
return changed;
|
|
||||||
|
if (changed) return id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
i32 userInterface_window(UiState *const uiState, MemoryArena *const arena,
|
||||||
|
AssetManager *const assetManager,
|
||||||
|
Renderer *const renderer, Font *const font,
|
||||||
|
const KeyInput input, WindowState *window)
|
||||||
|
{
|
||||||
|
if (math_pointInRect(window->rect, input.mouseP))
|
||||||
|
{
|
||||||
|
uiState->hotItem = window->id;
|
||||||
|
if (uiState->activeItem == 0 && input.keys[keycode_mouseLeft].endedDown)
|
||||||
|
uiState->activeItem = window->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect rect = window->rect;
|
||||||
|
RenderTex nullRenderTex = renderer_createNullRenderTex(assetManager);
|
||||||
|
renderer_staticRect(renderer, rect.pos, rect.size, V2(0, 0), 0,
|
||||||
|
nullRenderTex, V4(0.25f, 0.25f, 0.5f, 0.5f));
|
||||||
|
|
||||||
|
v2 menuTitleP = v2_add(rect.pos, V2(0, rect.size.h - 10));
|
||||||
|
renderer_staticString(renderer, arena, font, window->title, menuTitleP,
|
||||||
|
V2(0, 0), 0, V4(0, 0, 0, 1));
|
||||||
|
|
||||||
|
// NOTE(doyle): activeItem captures mouse click within the UI bounds, but if
|
||||||
|
// the user drags the mouse outside the bounds quicker than the game updates
|
||||||
|
// then we use a second flag which only "unclicks" when the mouse is let go
|
||||||
|
if (uiState->activeItem == window->id) window->windowHeld = TRUE;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for (i32 i = 0; i < window->numChildItems; i++)
|
||||||
|
{
|
||||||
|
if (uiState->activeItem == window->childUiId[i])
|
||||||
|
{
|
||||||
|
window->windowHeld = FALSE;
|
||||||
|
window->prevFrameWindowHeld = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (window->windowHeld)
|
||||||
|
{
|
||||||
|
if (!input.keys[keycode_mouseLeft].endedDown)
|
||||||
|
{
|
||||||
|
window->windowHeld = FALSE;
|
||||||
|
window->prevFrameWindowHeld = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window->windowHeld)
|
||||||
|
{
|
||||||
|
// NOTE(doyle): If this is the first window click we don't process
|
||||||
|
// movement and store the current position to delta from next cycle
|
||||||
|
if (window->prevFrameWindowHeld)
|
||||||
|
{
|
||||||
|
// NOTE(doyle): Window clicked and held
|
||||||
|
v2 deltaP = v2_sub(input.mouseP, window->prevMouseP);
|
||||||
|
|
||||||
|
for (i32 i = 0; i < window->numChildUiItems; i++)
|
||||||
|
{
|
||||||
|
UiItem *childUi = &window->childUiItems[i];
|
||||||
|
childUi->rect.pos = v2_add(deltaP, childUi->rect.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_PUSH_VAR("Delta Pos %4.2f, %4.2f", deltaP, "v2");
|
||||||
|
window->rect.pos = v2_add(deltaP, window->rect.pos);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->prevFrameWindowHeld = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->prevMouseP = input.mouseP;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Draw window elements */
|
||||||
|
i32 firstActiveChildId = -1;
|
||||||
|
for (i32 i = 0; i < window->numChildUiItems; i++)
|
||||||
|
{
|
||||||
|
UiItem *childUi = &window->childUiItems[i];
|
||||||
|
|
||||||
|
// TODO(doyle): Redundant? If we can only have 1 active child at a time
|
||||||
|
// What about overlapping elements?
|
||||||
|
i32 getChildActiveState = -1;
|
||||||
|
switch(childUi->type)
|
||||||
|
{
|
||||||
|
case uitype_button:
|
||||||
|
// TODO(doyle): Bug in font rendering once button reaches 700-800+
|
||||||
|
// pixels
|
||||||
|
getChildActiveState = userInterface_button(
|
||||||
|
uiState, arena, assetManager, renderer, font, input,
|
||||||
|
childUi->id, childUi->rect, childUi->label);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case uitype_scrollbar:
|
||||||
|
// TODO(doyle): window steals scrollbar focus
|
||||||
|
getChildActiveState = userInterface_scrollbar(
|
||||||
|
uiState, assetManager, renderer, input, childUi->id,
|
||||||
|
childUi->rect, &childUi->value, childUi->maxValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case uitype_textField:
|
||||||
|
getChildActiveState = userInterface_textField(
|
||||||
|
uiState, arena, assetManager, renderer, font, input,
|
||||||
|
childUi->id, childUi->rect, childUi->string);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
DEBUG_LOG(
|
||||||
|
"userInterface_window() warning: Enum uitype unrecognised");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(doyle): Capture only the first active id, but keep loop going to
|
||||||
|
// render the rest of the window ui
|
||||||
|
if (firstActiveChildId == -1 && getChildActiveState > 0)
|
||||||
|
firstActiveChildId = getChildActiveState;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstActiveChildId != -1)
|
||||||
|
return firstActiveChildId;
|
||||||
|
|
||||||
|
if (!input.keys[keycode_mouseLeft].endedDown &&
|
||||||
|
uiState->hotItem == window->id &&
|
||||||
|
uiState->activeItem == window->id)
|
||||||
|
{
|
||||||
|
return window->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,6 +323,56 @@ INTERNAL void entityInit(GameState *state, v2 windowSize)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
INTERNAL v2 getPosRelativeToRect(Rect rect, v2 offset,
|
||||||
|
enum RectBaseline baseline)
|
||||||
|
{
|
||||||
|
#ifdef DENGINE_DEBUG
|
||||||
|
ASSERT(baseline < rectbaseline_count);
|
||||||
|
#endif
|
||||||
|
v2 result = {0};
|
||||||
|
|
||||||
|
v2 posToOffsetFrom = rect.pos;
|
||||||
|
switch (baseline)
|
||||||
|
{
|
||||||
|
case rectbaseline_top:
|
||||||
|
posToOffsetFrom.y += (rect.size.h);
|
||||||
|
posToOffsetFrom.x += (rect.size.w * 0.5f);
|
||||||
|
break;
|
||||||
|
case rectbaseline_topLeft:
|
||||||
|
posToOffsetFrom.y += (rect.size.h);
|
||||||
|
break;
|
||||||
|
case rectbaseline_topRight:
|
||||||
|
posToOffsetFrom.y += (rect.size.h);
|
||||||
|
posToOffsetFrom.x += (rect.size.w);
|
||||||
|
break;
|
||||||
|
case rectbaseline_bottom:
|
||||||
|
posToOffsetFrom.x += (rect.size.w * 0.5f);
|
||||||
|
break;
|
||||||
|
case rectbaseline_bottomRight:
|
||||||
|
posToOffsetFrom.x += (rect.size.w);
|
||||||
|
break;
|
||||||
|
case rectbaseline_left:
|
||||||
|
posToOffsetFrom.y += (rect.size.h * 0.5f);
|
||||||
|
break;
|
||||||
|
case rectbaseline_right:
|
||||||
|
posToOffsetFrom.x += (rect.size.w);
|
||||||
|
posToOffsetFrom.y += (rect.size.h * 0.5f);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case rectbaseline_bottomLeft:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
#ifdef DENGINE_DEBUG
|
||||||
|
DEBUG_LOG(
|
||||||
|
"getPosRelativeToRect() warning: baseline enum not recognised");
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = v2_add(posToOffsetFrom, offset);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(doyle): Remove and implement own random generator!
|
// TODO(doyle): Remove and implement own random generator!
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -339,6 +389,8 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize)
|
|||||||
state->state = state_active;
|
state->state = state_active;
|
||||||
state->currWorldIndex = 0;
|
state->currWorldIndex = 0;
|
||||||
state->tileSize = 64;
|
state->tileSize = 64;
|
||||||
|
|
||||||
|
state->uiState.uniqueId = 1;
|
||||||
state->uiState.keyEntered = keycode_null;
|
state->uiState.keyEntered = keycode_null;
|
||||||
state->uiState.keyMod = keycode_null;
|
state->uiState.keyMod = keycode_null;
|
||||||
state->uiState.keyChar = keycode_null;
|
state->uiState.keyChar = keycode_null;
|
||||||
@ -351,18 +403,63 @@ void worldTraveller_gameInit(GameState *state, v2 windowSize)
|
|||||||
state->uiState.statWindow.prevFrameWindowHeld = FALSE;
|
state->uiState.statWindow.prevFrameWindowHeld = FALSE;
|
||||||
state->uiState.statWindow.windowHeld = FALSE;
|
state->uiState.statWindow.windowHeld = FALSE;
|
||||||
|
|
||||||
common_strncpy(state->uiState.debugWindow.title, "Debug Menu",
|
WindowState *debugWindow = &state->uiState.debugWindow;
|
||||||
|
common_strncpy(debugWindow->title, "Debug Menu",
|
||||||
common_strlen("Debug Menu"));
|
common_strlen("Debug Menu"));
|
||||||
state->uiState.debugWindow.id = 98;
|
debugWindow->id = 98;
|
||||||
state->uiState.debugWindow.rect.pos = V2(800, 400);
|
debugWindow->numChildUiItems = 0;
|
||||||
state->uiState.debugWindow.rect.size = V2(750, 400);
|
debugWindow->rect.pos = V2(800, 400);
|
||||||
state->uiState.debugWindow.prevFrameWindowHeld = FALSE;
|
debugWindow->rect.size = V2(750, 400);
|
||||||
state->uiState.debugWindow.windowHeld = FALSE;
|
debugWindow->prevFrameWindowHeld = FALSE;
|
||||||
|
debugWindow->windowHeld = FALSE;
|
||||||
|
|
||||||
|
UiItem *audioBtn =
|
||||||
|
(debugWindow->childUiItems) + debugWindow->numChildUiItems++;
|
||||||
|
common_strncpy(audioBtn->label, "Toggle Music",
|
||||||
|
common_strlen("Toggle Music"));
|
||||||
|
audioBtn->id = userInterface_generateId(&state->uiState);
|
||||||
|
audioBtn->rect.size = V2(100, 50);
|
||||||
|
audioBtn->rect.pos = getPosRelativeToRect(debugWindow->rect, V2(10, -65.0f),
|
||||||
|
rectbaseline_topLeft);
|
||||||
|
audioBtn->type = uitype_button;
|
||||||
|
|
||||||
|
UiItem *debugBtn =
|
||||||
|
(debugWindow->childUiItems) + debugWindow->numChildUiItems++;
|
||||||
|
common_strncpy(debugBtn->label, "Toggle Debug",
|
||||||
|
common_strlen("Toggle Debug"));
|
||||||
|
debugBtn->id = userInterface_generateId(&state->uiState);
|
||||||
|
debugBtn->rect.size = V2(100, 50);
|
||||||
|
debugBtn->rect.pos = getPosRelativeToRect(audioBtn->rect, V2(25, 0),
|
||||||
|
rectbaseline_bottomRight);
|
||||||
|
debugBtn->type = uitype_button;
|
||||||
|
|
||||||
|
UiItem *scrollbar =
|
||||||
|
(debugWindow->childUiItems) + debugWindow->numChildUiItems++;
|
||||||
|
scrollbar->id = userInterface_generateId(&state->uiState);
|
||||||
|
|
||||||
|
scrollbar->rect.size = V2(16, debugWindow->rect.size.h);
|
||||||
|
scrollbar->rect.pos =
|
||||||
|
getPosRelativeToRect(debugWindow->rect, V2(-scrollbar->rect.size.w, 0),
|
||||||
|
rectbaseline_bottomRight);
|
||||||
|
scrollbar->value = 0;
|
||||||
|
scrollbar->maxValue = 160;
|
||||||
|
scrollbar->type = uitype_scrollbar;
|
||||||
|
|
||||||
|
UiItem *textField =
|
||||||
|
(debugWindow->childUiItems) + debugWindow->numChildUiItems++;
|
||||||
|
textField->id = userInterface_generateId(&state->uiState);
|
||||||
|
textField->rect.size = V2(200, 20);
|
||||||
|
textField->rect.pos = getPosRelativeToRect(
|
||||||
|
audioBtn->rect, V2(0, -textField->rect.size.h - 10),
|
||||||
|
rectbaseline_bottomLeft);
|
||||||
|
|
||||||
|
common_strncpy(textField->string, "Hello world",
|
||||||
|
common_strlen("Hello world"));
|
||||||
|
textField->type = uitype_textField;
|
||||||
|
|
||||||
state->config.playWorldAudio = FALSE;
|
state->config.playWorldAudio = FALSE;
|
||||||
state->config.showDebugDisplay = TRUE;
|
state->config.showDebugDisplay = TRUE;
|
||||||
|
|
||||||
|
|
||||||
assetInit(state);
|
assetInit(state);
|
||||||
rendererInit(state, windowSize);
|
rendererInit(state, windowSize);
|
||||||
entityInit(state, windowSize);
|
entityInit(state, windowSize);
|
||||||
@ -1039,70 +1136,6 @@ typedef struct BattleState
|
|||||||
|
|
||||||
GLOBAL_VAR BattleState battleState = {0};
|
GLOBAL_VAR BattleState battleState = {0};
|
||||||
|
|
||||||
enum RectBaseline
|
|
||||||
{
|
|
||||||
rectbaseline_top,
|
|
||||||
rectbaseline_topLeft,
|
|
||||||
rectbaseline_topRight,
|
|
||||||
rectbaseline_bottom,
|
|
||||||
rectbaseline_bottomRight,
|
|
||||||
rectbaseline_bottomLeft,
|
|
||||||
rectbaseline_left,
|
|
||||||
rectbaseline_right,
|
|
||||||
rectbaseline_center,
|
|
||||||
rectbaseline_count,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
INTERNAL v2 getPosRelativeToRect(Rect rect, v2 offset,
|
|
||||||
enum RectBaseline baseline)
|
|
||||||
{
|
|
||||||
#ifdef DENGINE_DEBUG
|
|
||||||
ASSERT(baseline < rectbaseline_count);
|
|
||||||
#endif
|
|
||||||
v2 result = {0};
|
|
||||||
|
|
||||||
v2 posToOffsetFrom = rect.pos;
|
|
||||||
switch (baseline)
|
|
||||||
{
|
|
||||||
case rectbaseline_top:
|
|
||||||
posToOffsetFrom.y += (rect.size.h);
|
|
||||||
posToOffsetFrom.x += (rect.size.w * 0.5f);
|
|
||||||
break;
|
|
||||||
case rectbaseline_topLeft:
|
|
||||||
posToOffsetFrom.y += (rect.size.h);
|
|
||||||
break;
|
|
||||||
case rectbaseline_topRight:
|
|
||||||
posToOffsetFrom.y += (rect.size.h);
|
|
||||||
posToOffsetFrom.x += (rect.size.w);
|
|
||||||
break;
|
|
||||||
case rectbaseline_bottom:
|
|
||||||
posToOffsetFrom.x += (rect.size.w * 0.5f);
|
|
||||||
break;
|
|
||||||
case rectbaseline_bottomRight:
|
|
||||||
posToOffsetFrom.x += (rect.size.w);
|
|
||||||
break;
|
|
||||||
case rectbaseline_left:
|
|
||||||
posToOffsetFrom.y += (rect.size.h * 0.5f);
|
|
||||||
break;
|
|
||||||
case rectbaseline_right:
|
|
||||||
posToOffsetFrom.x += (rect.size.w);
|
|
||||||
posToOffsetFrom.y += (rect.size.h * 0.5f);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case rectbaseline_bottomLeft:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
#ifdef DENGINE_DEBUG
|
|
||||||
DEBUG_LOG(
|
|
||||||
"getPosRelativeToRect() warning: baseline enum not recognised");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = v2_add(posToOffsetFrom, offset);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
||||||
{
|
{
|
||||||
@ -1412,53 +1445,22 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
|||||||
|
|
||||||
/* Draw debug window */
|
/* Draw debug window */
|
||||||
WindowState *debugWindow = &state->uiState.debugWindow;
|
WindowState *debugWindow = &state->uiState.debugWindow;
|
||||||
userInterface_window(&state->uiState, &state->arena, assetManager, renderer,
|
i32 activeId =
|
||||||
font, state->input, debugWindow);
|
userInterface_window(&state->uiState, &state->arena, assetManager,
|
||||||
|
renderer, font, state->input, debugWindow);
|
||||||
|
|
||||||
// TODO(doyle): Bug in font rendering once button reaches 700-800+ pixels
|
// TODO(doyle): Name lookup to user interface id
|
||||||
Rect toggleAudioButtonRect = {0};
|
if (activeId == 1)
|
||||||
toggleAudioButtonRect.size = V2(100, 50);
|
|
||||||
toggleAudioButtonRect.pos = getPosRelativeToRect(
|
|
||||||
debugWindow->rect, V2(10, -65.0f), rectbaseline_topLeft);
|
|
||||||
|
|
||||||
b32 toggleAudioClicked = userInterface_button(
|
|
||||||
&state->uiState, &state->arena, assetManager, renderer, font,
|
|
||||||
state->input, 1, toggleAudioButtonRect, "Toggle Music");
|
|
||||||
|
|
||||||
if (toggleAudioClicked)
|
|
||||||
{
|
{
|
||||||
state->config.playWorldAudio =
|
state->config.playWorldAudio =
|
||||||
(state->config.playWorldAudio == TRUE) ? FALSE : TRUE;
|
(state->config.playWorldAudio == TRUE) ? FALSE : TRUE;
|
||||||
}
|
}
|
||||||
|
else if (activeId == 2)
|
||||||
Rect toggleDebugButtonRect = {0};
|
|
||||||
toggleDebugButtonRect.size = V2(100, 50);
|
|
||||||
toggleDebugButtonRect.pos = getPosRelativeToRect(
|
|
||||||
toggleAudioButtonRect, V2(25, 0), rectbaseline_bottomRight);
|
|
||||||
b32 toggleDebugClicked = userInterface_button(
|
|
||||||
&state->uiState, &state->arena, assetManager, renderer, font,
|
|
||||||
state->input, 2, toggleDebugButtonRect, "Toggle Debug Display");
|
|
||||||
|
|
||||||
if (toggleDebugClicked)
|
|
||||||
{
|
{
|
||||||
state->config.showDebugDisplay =
|
state->config.showDebugDisplay =
|
||||||
(state->config.showDebugDisplay == TRUE) ? FALSE : TRUE;
|
(state->config.showDebugDisplay == TRUE) ? FALSE : TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCAL_PERSIST i32 scrollValue = 30;
|
|
||||||
Rect scrollRectA = {V2(0, 0), V2(16, 255)};
|
|
||||||
scrollRectA.pos = getPosRelativeToRect(debugWindow->rect, V2(-20, -260),
|
|
||||||
rectbaseline_topRight);
|
|
||||||
userInterface_scrollBar(&state->uiState, assetManager, renderer,
|
|
||||||
state->input, 3, scrollRectA, &scrollValue, 160);
|
|
||||||
|
|
||||||
LOCAL_PERSIST char fieldString[80] = "Hello world";
|
|
||||||
v2 textFieldP = getPosRelativeToRect(toggleAudioButtonRect, V2(0, -20),
|
|
||||||
rectbaseline_bottomLeft);
|
|
||||||
userInterface_textField(&state->uiState, &state->arena, assetManager,
|
|
||||||
renderer, font, state->input, 4, textFieldP,
|
|
||||||
fieldString);
|
|
||||||
|
|
||||||
// RESET IMGUI
|
// RESET IMGUI
|
||||||
if (!state->input.keys[keycode_mouseLeft].endedDown)
|
if (!state->input.keys[keycode_mouseLeft].endedDown)
|
||||||
state->uiState.activeItem = 0;
|
state->uiState.activeItem = 0;
|
||||||
|
@ -15,7 +15,7 @@ enum UiType
|
|||||||
{
|
{
|
||||||
uitype_button,
|
uitype_button,
|
||||||
uitype_scrollbar,
|
uitype_scrollbar,
|
||||||
uitype_textfield,
|
uitype_textField,
|
||||||
uitype_string,
|
uitype_string,
|
||||||
uitype_count,
|
uitype_count,
|
||||||
};
|
};
|
||||||
@ -23,14 +23,24 @@ enum UiType
|
|||||||
typedef struct UiItem
|
typedef struct UiItem
|
||||||
{
|
{
|
||||||
i32 id;
|
i32 id;
|
||||||
Rect rect;
|
char label[64];
|
||||||
enum UiType type;
|
enum UiType type;
|
||||||
|
|
||||||
|
Rect rect;
|
||||||
|
|
||||||
|
// TODO(doyle): ECS this? Not all elements need
|
||||||
|
i32 value;
|
||||||
|
i32 maxValue;
|
||||||
|
char string[80];
|
||||||
} UiItem;
|
} UiItem;
|
||||||
|
|
||||||
typedef struct WindowState
|
typedef struct WindowState
|
||||||
{
|
{
|
||||||
i32 id;
|
|
||||||
char title[64];
|
char title[64];
|
||||||
|
i32 id;
|
||||||
|
|
||||||
|
UiItem childUiItems[16];
|
||||||
|
i32 numChildUiItems;
|
||||||
|
|
||||||
Rect rect;
|
Rect rect;
|
||||||
// TODO(doyle): Store this in the input data not window?
|
// TODO(doyle): Store this in the input data not window?
|
||||||
@ -42,6 +52,8 @@ typedef struct WindowState
|
|||||||
|
|
||||||
typedef struct UiState
|
typedef struct UiState
|
||||||
{
|
{
|
||||||
|
i32 uniqueId;
|
||||||
|
|
||||||
UiItem uiList[128];
|
UiItem uiList[128];
|
||||||
i32 numItems;
|
i32 numItems;
|
||||||
|
|
||||||
@ -58,10 +70,11 @@ typedef struct UiState
|
|||||||
WindowState debugWindow;
|
WindowState debugWindow;
|
||||||
} UiState;
|
} UiState;
|
||||||
|
|
||||||
i32 userInterface_window(UiState *const uiState, MemoryArena *const arena,
|
inline i32 userInterface_generateId(UiState *const uiState)
|
||||||
AssetManager *const assetManager,
|
{
|
||||||
Renderer *const renderer, Font *const font,
|
i32 result = uiState->uniqueId++;
|
||||||
const KeyInput input, WindowState *window);
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
i32 userInterface_button(UiState *const uiState,
|
i32 userInterface_button(UiState *const uiState,
|
||||||
MemoryArena *const arena,
|
MemoryArena *const arena,
|
||||||
@ -76,12 +89,17 @@ i32 userInterface_textField(UiState *const uiState,
|
|||||||
MemoryArena *const arena,
|
MemoryArena *const arena,
|
||||||
AssetManager *const assetManager,
|
AssetManager *const assetManager,
|
||||||
Renderer *const renderer, Font *const font,
|
Renderer *const renderer, Font *const font,
|
||||||
KeyInput input, const i32 id, v2 pos,
|
KeyInput input, const i32 id, const Rect rect,
|
||||||
char *const string);
|
char *const string);
|
||||||
|
|
||||||
i32 userInterface_scrollBar(UiState *const uiState,
|
i32 userInterface_scrollbar(UiState *const uiState,
|
||||||
AssetManager *const assetManager,
|
AssetManager *const assetManager,
|
||||||
Renderer *const renderer, const KeyInput input,
|
Renderer *const renderer, const KeyInput input,
|
||||||
const i32 id, const Rect scrollBarRect,
|
const i32 id, const Rect scrollBarRect,
|
||||||
i32 *const value, const i32 maxValue);
|
i32 *const value, const i32 maxValue);
|
||||||
|
|
||||||
|
i32 userInterface_window(UiState *const uiState, MemoryArena *const arena,
|
||||||
|
AssetManager *const assetManager,
|
||||||
|
Renderer *const renderer, Font *const font,
|
||||||
|
const KeyInput input, WindowState *window);
|
||||||
#endif
|
#endif
|
||||||
|
@ -16,6 +16,21 @@
|
|||||||
/* Forward declaration */
|
/* Forward declaration */
|
||||||
typedef struct Entity Entity;
|
typedef struct Entity Entity;
|
||||||
|
|
||||||
|
enum RectBaseline
|
||||||
|
{
|
||||||
|
rectbaseline_top,
|
||||||
|
rectbaseline_topLeft,
|
||||||
|
rectbaseline_topRight,
|
||||||
|
rectbaseline_bottom,
|
||||||
|
rectbaseline_bottomRight,
|
||||||
|
rectbaseline_bottomLeft,
|
||||||
|
rectbaseline_left,
|
||||||
|
rectbaseline_right,
|
||||||
|
rectbaseline_center,
|
||||||
|
rectbaseline_count,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct Config
|
typedef struct Config
|
||||||
{
|
{
|
||||||
b32 playWorldAudio;
|
b32 playWorldAudio;
|
||||||
|
Loading…
Reference in New Issue
Block a user