Separate UI code into own file
This commit is contained in:
parent
5cd7239c8a
commit
e90b31de55
@ -129,6 +129,7 @@
|
||||
<ClCompile Include="src\Platform.c" />
|
||||
<ClCompile Include="src\Renderer.c" />
|
||||
<ClCompile Include="src\Shader.c" />
|
||||
<ClCompile Include="src\UserInterface.c" />
|
||||
<ClCompile Include="src\WorldTraveller.c" />
|
||||
<ClCompile Include="src\Texture.c" />
|
||||
</ItemGroup>
|
||||
@ -153,6 +154,7 @@
|
||||
<ClInclude Include="src\include\Dengine\Renderer.h" />
|
||||
<ClInclude Include="src\include\Dengine\Shader.h" />
|
||||
<ClInclude Include="src\include\Dengine\Texture.h" />
|
||||
<ClInclude Include="src\include\Dengine\UserInterface.h" />
|
||||
<ClInclude Include="src\include\Dengine\WorldTraveller.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
@ -48,6 +48,9 @@
|
||||
<ClCompile Include="src\dengine.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\UserInterface.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="data\shaders\default.vert.glsl" />
|
||||
@ -101,5 +104,8 @@
|
||||
<ClInclude Include="src\include\Dengine\WorldTraveller.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\include\Dengine\UserInterface.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -36,7 +36,8 @@ AudioVorbis *asset_getVorbis(AssetManager *assetManager,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Texture *asset_getTexture(AssetManager *assetManager, const enum TexList type)
|
||||
Texture *asset_getTexture(AssetManager *const assetManager,
|
||||
const enum TexList type)
|
||||
{
|
||||
if (type < texlist_count)
|
||||
return &assetManager->textures[type];
|
||||
|
@ -168,7 +168,7 @@ INTERNAL v2 mapWorldToCameraSpace(v2 worldPos, v4 cameraBounds)
|
||||
return posInCameraSpace;
|
||||
}
|
||||
|
||||
RenderTex renderer_createNullRenderTex(AssetManager *assetManager)
|
||||
RenderTex renderer_createNullRenderTex(AssetManager *const assetManager)
|
||||
{
|
||||
Texture *emptyTex = asset_getTexture(assetManager, texlist_empty);
|
||||
RenderTex result = {emptyTex, V4(0, 1, 1, 0)};
|
||||
|
295
src/UserInterface.c
Normal file
295
src/UserInterface.c
Normal file
@ -0,0 +1,295 @@
|
||||
#include "Dengine/UserInterface.h"
|
||||
#include "Dengine/Assets.h"
|
||||
#include "Dengine/Renderer.h"
|
||||
|
||||
i32 userInterface_button(UiState *const uiState,
|
||||
AssetManager *const assetManager,
|
||||
Renderer *const renderer, const KeyInput input,
|
||||
const i32 id, const Rect rect)
|
||||
{
|
||||
if (math_pointInRect(rect, input.mouseP))
|
||||
{
|
||||
uiState->hotItem = id;
|
||||
if (uiState->activeItem == 0 && input.keys[keycode_mouseLeft].endedDown)
|
||||
uiState->activeItem = id;
|
||||
}
|
||||
|
||||
RenderTex renderTex = renderer_createNullRenderTex(assetManager);
|
||||
|
||||
/* If no widget has keyboard focus, take it */
|
||||
if (uiState->kbdItem == 0)
|
||||
uiState->kbdItem = id;
|
||||
|
||||
/* If we have keyboard focus, show it */
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
// Draw outline
|
||||
renderer_staticRect(renderer, v2_add(V2(-6, -6), rect.pos),
|
||||
v2_add(V2(20, 20), rect.size), V2(0, 0), 0, renderTex,
|
||||
V4(1.0f, 0, 0, 1));
|
||||
}
|
||||
|
||||
// Draw shadow
|
||||
renderer_staticRect(renderer, v2_add(V2(8, 8), rect.pos), rect.size,
|
||||
V2(0, 0), 0, renderTex, V4(0, 0, 0, 1));
|
||||
|
||||
if (uiState->hotItem == id)
|
||||
{
|
||||
if (uiState->activeItem == id)
|
||||
{
|
||||
renderer_staticRect(renderer, v2_add(V2(2, 2), rect.pos), rect.size,
|
||||
V2(0, 0), 0, renderTex, V4(1, 1, 1, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer_staticRect(renderer, v2_add(V2(0, 0), rect.pos), rect.size,
|
||||
V2(0, 0), 0, renderTex, V4(1, 1, 1, 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer_staticRect(renderer, v2_add(V2(0, 0), rect.pos), rect.size,
|
||||
V2(0, 0), 0, renderTex, V4(0.5f, 0.5f, 0.5f, 1));
|
||||
}
|
||||
|
||||
// After renderering before click check, see if we need to process keys
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
switch (uiState->keyEntered)
|
||||
{
|
||||
case keycode_tab:
|
||||
// Set focus to nothing and let next widget get focus
|
||||
uiState->kbdItem = 0;
|
||||
if (uiState->keyMod == keycode_leftShift)
|
||||
uiState->kbdItem = uiState->lastWidget;
|
||||
|
||||
// Clear key state so next widget doesn't auto grab
|
||||
uiState->keyEntered = keycode_null;
|
||||
break;
|
||||
case keycode_enter:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uiState->lastWidget = id;
|
||||
|
||||
if (!input.keys[keycode_mouseLeft].endedDown &&
|
||||
uiState->hotItem == id &&
|
||||
uiState->activeItem == id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
i32 userInterface_scrollBar(UiState *const uiState,
|
||||
AssetManager *const assetManager,
|
||||
Renderer *const renderer, const KeyInput input,
|
||||
const i32 id, const Rect scrollBarRect,
|
||||
i32 *const value, const i32 maxValue)
|
||||
{
|
||||
#ifdef DENGINE_DEBUG
|
||||
ASSERT(*value <= maxValue);
|
||||
#endif
|
||||
|
||||
if (math_pointInRect(scrollBarRect, input.mouseP))
|
||||
{
|
||||
uiState->hotItem = id;
|
||||
if (uiState->activeItem == 0 && input.keys[keycode_mouseLeft].endedDown)
|
||||
uiState->activeItem = id;
|
||||
}
|
||||
|
||||
RenderTex renderTex = renderer_createNullRenderTex(assetManager);
|
||||
|
||||
/* If no widget has keyboard focus, take it */
|
||||
if (uiState->kbdItem == 0)
|
||||
uiState->kbdItem = id;
|
||||
|
||||
/* If we have keyboard focus, show it */
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
// Draw outline
|
||||
renderer_staticRect(renderer, v2_add(V2(-6, -6), scrollBarRect.pos),
|
||||
v2_add(V2(20, 20), scrollBarRect.size), V2(0, 0), 0,
|
||||
renderTex, V4(1.0f, 0, 0, 1));
|
||||
}
|
||||
|
||||
// Render scroll bar background
|
||||
renderer_staticRect(renderer, scrollBarRect.pos, scrollBarRect.size,
|
||||
V2(0, 0), 0, renderTex, V4(0.75f, 0.5f, 0.5f, 1));
|
||||
|
||||
// Render scroll bar slider
|
||||
v2 sliderSize = V2(16, 16);
|
||||
v4 sliderColor = V4(0, 0, 0, 1);
|
||||
|
||||
f32 sliderPercentageOffset = (CAST(f32) *value / CAST(f32) maxValue);
|
||||
f32 sliderYOffsetToBar =
|
||||
(scrollBarRect.size.h - sliderSize.h) * sliderPercentageOffset;
|
||||
v2 sliderPos = v2_add(scrollBarRect.pos, V2(0, sliderYOffsetToBar));
|
||||
|
||||
if (uiState->hotItem == id || uiState->activeItem == id)
|
||||
sliderColor = V4(1.0f, 0, 0, 1);
|
||||
else
|
||||
sliderColor = V4(0.0f, 1.0f, 0, 1);
|
||||
|
||||
renderer_staticRect(renderer, sliderPos, sliderSize, V2(0, 0), 0, renderTex,
|
||||
sliderColor);
|
||||
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
switch (uiState->keyEntered)
|
||||
{
|
||||
case keycode_tab:
|
||||
uiState->kbdItem = 0;
|
||||
if (uiState->keyMod == keycode_leftShift)
|
||||
uiState->kbdItem = uiState->lastWidget;
|
||||
|
||||
// Clear key state so next widget doesn't auto grab
|
||||
uiState->keyEntered = keycode_null;
|
||||
break;
|
||||
case keycode_up:
|
||||
// TODO(doyle): Fix input for this to work, i.e. proper rate limited input poll
|
||||
if (*value < maxValue)
|
||||
{
|
||||
(*value)++;
|
||||
return 1;
|
||||
}
|
||||
case keycode_down:
|
||||
if (*value > 0)
|
||||
{
|
||||
(*value)--;
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uiState->lastWidget = id;
|
||||
|
||||
if (uiState->activeItem == id)
|
||||
{
|
||||
f32 mouseYRelToRect = input.mouseP.y - scrollBarRect.pos.y;
|
||||
|
||||
// Bounds check
|
||||
if (mouseYRelToRect < 0)
|
||||
mouseYRelToRect = 0;
|
||||
else if (mouseYRelToRect > scrollBarRect.size.h)
|
||||
mouseYRelToRect = scrollBarRect.size.h;
|
||||
|
||||
f32 newSliderPercentOffset =
|
||||
(CAST(f32) mouseYRelToRect / scrollBarRect.size.h);
|
||||
|
||||
i32 newValue = CAST(i32)(newSliderPercentOffset * CAST(f32)maxValue);
|
||||
if (newValue != *value)
|
||||
{
|
||||
*value = newValue;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
i32 userInterface_textField(UiState *const uiState, MemoryArena *arena,
|
||||
AssetManager *const assetManager,
|
||||
Renderer *const renderer, Font *const font,
|
||||
KeyInput input, const i32 id, v2 pos,
|
||||
char *const string)
|
||||
{
|
||||
i32 strLen = common_strlen(string);
|
||||
b32 changed = FALSE;
|
||||
|
||||
Rect textRect = {0};
|
||||
textRect.pos = pos;
|
||||
textRect.size = V2(30 * font->maxSize.w, font->maxSize.h);
|
||||
if (math_pointInRect(textRect, input.mouseP))
|
||||
{
|
||||
uiState->hotItem = id;
|
||||
if (uiState->activeItem == 0 && input.keys[keycode_mouseLeft].endedDown)
|
||||
{
|
||||
uiState->activeItem = id;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no widget has keyboard focus, take it */
|
||||
if (uiState->kbdItem == 0)
|
||||
uiState->kbdItem = id;
|
||||
|
||||
RenderTex renderTex = renderer_createNullRenderTex(assetManager);
|
||||
/* If we have keyboard focus, show it */
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
// Draw outline
|
||||
renderer_staticRect(renderer, v2_add(V2(-4, -4), textRect.pos),
|
||||
v2_add(V2(16, 16), textRect.size), V2(0, 0), 0,
|
||||
renderTex, V4(1.0f, 0, 0, 1));
|
||||
}
|
||||
|
||||
// Render text field
|
||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
||||
renderTex, V4(0.75f, 0.5f, 0.5f, 1));
|
||||
|
||||
if (uiState->activeItem == id || uiState->hotItem == id)
|
||||
{
|
||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
||||
renderTex, V4(0.75f, 0.75f, 0.0f, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
||||
renderTex, V4(0.5f, 0.5f, 0.5f, 1));
|
||||
}
|
||||
|
||||
// TODO(doyle): Figure out why we need to offset text ..
|
||||
v2 strPos = v2_add(textRect.pos, V2(0, -font->maxSize.h));
|
||||
|
||||
renderer_staticString(renderer, arena, font, string, strPos, V2(0, 0), 0,
|
||||
V4(0, 0, 0, 1));
|
||||
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
switch (uiState->keyEntered)
|
||||
{
|
||||
case keycode_tab:
|
||||
uiState->kbdItem = 0;
|
||||
if (uiState->keyMod == keycode_leftShift)
|
||||
uiState->kbdItem = uiState->lastWidget;
|
||||
|
||||
uiState->keyEntered = keycode_null;
|
||||
break;
|
||||
|
||||
case keycode_backspace:
|
||||
if (strLen > 0)
|
||||
{
|
||||
string[--strLen] = 0;
|
||||
changed = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiState->keyChar >= keycode_space &&
|
||||
uiState->keyChar <= keycode_tilda && strLen < 30)
|
||||
{
|
||||
string[strLen++] = uiState->keyChar + ' ';
|
||||
string[strLen] = 0;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!input.keys[keycode_mouseLeft].endedDown &&
|
||||
uiState->hotItem == id &&
|
||||
uiState->activeItem == id)
|
||||
{
|
||||
uiState->kbdItem = id;
|
||||
}
|
||||
|
||||
uiState->lastWidget = id;
|
||||
return changed;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "Dengine/Debug.h"
|
||||
#include "Dengine/Entity.h"
|
||||
#include "Dengine/Platform.h"
|
||||
#include "Dengine/UserInterface.h"
|
||||
|
||||
enum State
|
||||
{
|
||||
@ -1001,289 +1002,6 @@ INTERNAL void sortWorldEntityList(World *world, i32 numDeadEntities)
|
||||
world->freeEntityIndex -= numDeadEntities;
|
||||
}
|
||||
|
||||
INTERNAL i32 button(UiState *uiState, AssetManager *assetManager,
|
||||
Renderer *renderer, KeyInput input, i32 id, Rect rect)
|
||||
{
|
||||
if (math_pointInRect(rect, input.mouseP))
|
||||
{
|
||||
uiState->hotItem = id;
|
||||
if (uiState->activeItem == 0 && input.keys[keycode_mouseLeft].endedDown)
|
||||
uiState->activeItem = id;
|
||||
}
|
||||
|
||||
RenderTex renderTex = renderer_createNullRenderTex(assetManager);
|
||||
|
||||
/* If no widget has keyboard focus, take it */
|
||||
if (uiState->kbdItem == 0)
|
||||
uiState->kbdItem = id;
|
||||
|
||||
/* If we have keyboard focus, show it */
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
// Draw outline
|
||||
renderer_staticRect(renderer, v2_add(V2(-6, -6), rect.pos),
|
||||
v2_add(V2(20, 20), rect.size), V2(0, 0), 0, renderTex,
|
||||
V4(1.0f, 0, 0, 1));
|
||||
}
|
||||
|
||||
// Draw shadow
|
||||
renderer_staticRect(renderer, v2_add(V2(8, 8), rect.pos), rect.size,
|
||||
V2(0, 0), 0, renderTex, V4(0, 0, 0, 1));
|
||||
|
||||
if (uiState->hotItem == id)
|
||||
{
|
||||
if (uiState->activeItem == id)
|
||||
{
|
||||
renderer_staticRect(renderer, v2_add(V2(2, 2), rect.pos), rect.size,
|
||||
V2(0, 0), 0, renderTex, V4(1, 1, 1, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer_staticRect(renderer, v2_add(V2(0, 0), rect.pos), rect.size,
|
||||
V2(0, 0), 0, renderTex, V4(1, 1, 1, 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer_staticRect(renderer, v2_add(V2(0, 0), rect.pos), rect.size,
|
||||
V2(0, 0), 0, renderTex, V4(0.5f, 0.5f, 0.5f, 1));
|
||||
}
|
||||
|
||||
// After renderering before click check, see if we need to process keys
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
switch (uiState->keyEntered)
|
||||
{
|
||||
case keycode_tab:
|
||||
// Set focus to nothing and let next widget get focus
|
||||
uiState->kbdItem = 0;
|
||||
if (uiState->keyMod == keycode_leftShift)
|
||||
uiState->kbdItem = uiState->lastWidget;
|
||||
|
||||
// Clear key state so next widget doesn't auto grab
|
||||
uiState->keyEntered = keycode_null;
|
||||
break;
|
||||
case keycode_enter:
|
||||
return 1;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uiState->lastWidget = id;
|
||||
|
||||
if (!input.keys[keycode_mouseLeft].endedDown &&
|
||||
uiState->hotItem == id &&
|
||||
uiState->activeItem == id)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INTERNAL i32 scrollBar(UiState *uiState, AssetManager *assetManager,
|
||||
Renderer *renderer, KeyInput input, i32 id,
|
||||
Rect scrollBarRect, i32 *value, i32 maxValue)
|
||||
{
|
||||
#ifdef DENGINE_DEBUG
|
||||
ASSERT(*value <= maxValue);
|
||||
#endif
|
||||
|
||||
if (math_pointInRect(scrollBarRect, input.mouseP))
|
||||
{
|
||||
uiState->hotItem = id;
|
||||
if (uiState->activeItem == 0 && input.keys[keycode_mouseLeft].endedDown)
|
||||
uiState->activeItem = id;
|
||||
}
|
||||
|
||||
RenderTex renderTex = renderer_createNullRenderTex(assetManager);
|
||||
|
||||
/* If no widget has keyboard focus, take it */
|
||||
if (uiState->kbdItem == 0)
|
||||
uiState->kbdItem = id;
|
||||
|
||||
/* If we have keyboard focus, show it */
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
// Draw outline
|
||||
renderer_staticRect(renderer, v2_add(V2(-6, -6), scrollBarRect.pos),
|
||||
v2_add(V2(20, 20), scrollBarRect.size), V2(0, 0), 0,
|
||||
renderTex, V4(1.0f, 0, 0, 1));
|
||||
}
|
||||
|
||||
// Render scroll bar background
|
||||
renderer_staticRect(renderer, scrollBarRect.pos, scrollBarRect.size,
|
||||
V2(0, 0), 0, renderTex, V4(0.75f, 0.5f, 0.5f, 1));
|
||||
|
||||
// Render scroll bar slider
|
||||
v2 sliderSize = V2(16, 16);
|
||||
v4 sliderColor = V4(0, 0, 0, 1);
|
||||
|
||||
f32 sliderPercentageOffset = (CAST(f32) *value / CAST(f32) maxValue);
|
||||
f32 sliderYOffsetToBar =
|
||||
(scrollBarRect.size.h - sliderSize.h) * sliderPercentageOffset;
|
||||
v2 sliderPos = v2_add(scrollBarRect.pos, V2(0, sliderYOffsetToBar));
|
||||
|
||||
if (uiState->hotItem == id || uiState->activeItem == id)
|
||||
sliderColor = V4(1.0f, 0, 0, 1);
|
||||
else
|
||||
sliderColor = V4(0.0f, 1.0f, 0, 1);
|
||||
|
||||
renderer_staticRect(renderer, sliderPos, sliderSize, V2(0, 0), 0, renderTex,
|
||||
sliderColor);
|
||||
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
switch (uiState->keyEntered)
|
||||
{
|
||||
case keycode_tab:
|
||||
uiState->kbdItem = 0;
|
||||
if (uiState->keyMod == keycode_leftShift)
|
||||
uiState->kbdItem = uiState->lastWidget;
|
||||
|
||||
// Clear key state so next widget doesn't auto grab
|
||||
uiState->keyEntered = keycode_null;
|
||||
break;
|
||||
case keycode_up:
|
||||
// TODO(doyle): Fix input for this to work, i.e. proper rate limited input poll
|
||||
if (*value < maxValue)
|
||||
{
|
||||
(*value)++;
|
||||
return 1;
|
||||
}
|
||||
case keycode_down:
|
||||
if (*value > 0)
|
||||
{
|
||||
(*value)--;
|
||||
return 1;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uiState->lastWidget = id;
|
||||
|
||||
if (uiState->activeItem == id)
|
||||
{
|
||||
f32 mouseYRelToRect = input.mouseP.y - scrollBarRect.pos.y;
|
||||
|
||||
// Bounds check
|
||||
if (mouseYRelToRect < 0)
|
||||
mouseYRelToRect = 0;
|
||||
else if (mouseYRelToRect > scrollBarRect.size.h)
|
||||
mouseYRelToRect = scrollBarRect.size.h;
|
||||
|
||||
f32 newSliderPercentOffset =
|
||||
(CAST(f32) mouseYRelToRect / scrollBarRect.size.h);
|
||||
|
||||
i32 newValue = CAST(i32)(newSliderPercentOffset * CAST(f32)maxValue);
|
||||
if (newValue != *value)
|
||||
{
|
||||
*value = newValue;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
INTERNAL i32 textField(UiState *const uiState, MemoryArena *arena,
|
||||
AssetManager *const assetManager,
|
||||
Renderer *const renderer, Font *const font,
|
||||
KeyInput input, const i32 id, v2 pos, char *const string)
|
||||
{
|
||||
i32 strLen = common_strlen(string);
|
||||
b32 changed = FALSE;
|
||||
|
||||
Rect textRect = {0};
|
||||
textRect.pos = pos;
|
||||
textRect.size = V2(30 * font->maxSize.w, font->maxSize.h);
|
||||
if (math_pointInRect(textRect, input.mouseP))
|
||||
{
|
||||
uiState->hotItem = id;
|
||||
if (uiState->activeItem == 0 && input.keys[keycode_mouseLeft].endedDown)
|
||||
{
|
||||
uiState->activeItem = id;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no widget has keyboard focus, take it */
|
||||
if (uiState->kbdItem == 0)
|
||||
uiState->kbdItem = id;
|
||||
|
||||
RenderTex renderTex = renderer_createNullRenderTex(assetManager);
|
||||
/* If we have keyboard focus, show it */
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
// Draw outline
|
||||
renderer_staticRect(renderer, v2_add(V2(-4, -4), textRect.pos),
|
||||
v2_add(V2(16, 16), textRect.size), V2(0, 0), 0,
|
||||
renderTex, V4(1.0f, 0, 0, 1));
|
||||
}
|
||||
|
||||
// Render
|
||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
||||
renderTex, V4(0.75f, 0.5f, 0.5f, 1));
|
||||
|
||||
if (uiState->activeItem == id || uiState->hotItem == id)
|
||||
{
|
||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
||||
renderTex, V4(0.75f, 0.75f, 0.0f, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
renderer_staticRect(renderer, textRect.pos, textRect.size, V2(0, 0), 0,
|
||||
renderTex, V4(0.5f, 0.5f, 0.5f, 1));
|
||||
}
|
||||
|
||||
renderer_staticString(renderer, arena, font, string, textRect.pos, V2(0, 0),
|
||||
0, V4(0, 0, 0, 1));
|
||||
|
||||
if (uiState->kbdItem == id)
|
||||
{
|
||||
switch (uiState->keyEntered)
|
||||
{
|
||||
case keycode_tab:
|
||||
uiState->kbdItem = 0;
|
||||
if (uiState->keyMod == keycode_leftShift)
|
||||
uiState->kbdItem = uiState->lastWidget;
|
||||
|
||||
uiState->keyEntered = keycode_null;
|
||||
break;
|
||||
|
||||
case keycode_backspace:
|
||||
if (strLen > 0)
|
||||
{
|
||||
string[--strLen] = 0;
|
||||
changed = TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (uiState->keyChar >= keycode_space &&
|
||||
uiState->keyChar <= keycode_tilda && strLen < 30)
|
||||
{
|
||||
string[strLen++] = uiState->keyChar + ' ';
|
||||
string[strLen] = 0;
|
||||
changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!input.keys[keycode_mouseLeft].endedDown &&
|
||||
uiState->hotItem == id &&
|
||||
uiState->activeItem == id)
|
||||
{
|
||||
uiState->kbdItem = id;
|
||||
}
|
||||
|
||||
uiState->lastWidget = id;
|
||||
return changed;
|
||||
}
|
||||
|
||||
void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
||||
{
|
||||
if (dt >= 1.0f) dt = 1.0f;
|
||||
@ -1535,25 +1253,26 @@ void worldTraveller_gameUpdateAndRender(GameState *state, f32 dt)
|
||||
|
||||
/* Draw ui */
|
||||
Rect buttonRectA = {V2(300, 500), V2(100, 50)};
|
||||
button(&state->uiState, assetManager, renderer, state->input, 1,
|
||||
buttonRectA);
|
||||
userInterface_button(&state->uiState, assetManager, renderer, state->input,
|
||||
1, buttonRectA);
|
||||
|
||||
Rect buttonRectB = {V2(500, 500), V2(100, 50)};
|
||||
button(&state->uiState, assetManager, renderer, state->input, 2,
|
||||
buttonRectB);
|
||||
userInterface_button(&state->uiState, assetManager, renderer, state->input,
|
||||
2, buttonRectB);
|
||||
|
||||
Rect buttonRectC = {V2(700, 500), V2(100, 50)};
|
||||
button(&state->uiState, assetManager, renderer, state->input, 3,
|
||||
buttonRectC);
|
||||
userInterface_button(&state->uiState, assetManager, renderer, state->input,
|
||||
3, buttonRectC);
|
||||
|
||||
LOCAL_PERSIST i32 scrollValue = 30;
|
||||
Rect scrollRectA = {V2(900, 500), V2(16, 255)};
|
||||
scrollBar(&state->uiState, assetManager, renderer, state->input, 4,
|
||||
scrollRectA, &scrollValue, 160);
|
||||
userInterface_scrollBar(&state->uiState, assetManager, renderer,
|
||||
state->input, 4, scrollRectA, &scrollValue, 160);
|
||||
|
||||
LOCAL_PERSIST char fieldString[80] = "Hello world";
|
||||
textField(&state->uiState, &state->arena, assetManager, renderer, font,
|
||||
state->input, 5, V2(1000, 500), fieldString);
|
||||
userInterface_textField(&state->uiState, &state->arena, assetManager,
|
||||
renderer, font, state->input, 5, V2(1000, 500),
|
||||
fieldString);
|
||||
|
||||
// RESET IMGUI
|
||||
if (!state->input.keys[keycode_mouseLeft].endedDown)
|
||||
|
@ -22,7 +22,8 @@ typedef struct AssetManager
|
||||
|
||||
AudioVorbis *asset_getVorbis(AssetManager *assetManager,
|
||||
const enum AudioList type);
|
||||
Texture *asset_getTexture(AssetManager *assetManager, const enum TexList type);
|
||||
Texture *asset_getTexture(AssetManager *const assetManager,
|
||||
const enum TexList type);
|
||||
Shader *asset_getShader(AssetManager *assetManager, const enum ShaderList type);
|
||||
TexAtlas *asset_getTextureAtlas(AssetManager *assetManager,
|
||||
const enum TexList type);
|
||||
|
@ -28,7 +28,7 @@ typedef struct RenderTex
|
||||
v4 texRect;
|
||||
} RenderTex;
|
||||
|
||||
RenderTex renderer_createNullRenderTex(AssetManager *assetManager);
|
||||
RenderTex renderer_createNullRenderTex(AssetManager *const assetManager);
|
||||
|
||||
// TODO(doyle): Clean up lines
|
||||
// Renderer::~Renderer() { glDeleteVertexArrays(1, &this->quadVAO); }
|
||||
|
43
src/include/Dengine/UserInterface.h
Normal file
43
src/include/Dengine/UserInterface.h
Normal file
@ -0,0 +1,43 @@
|
||||
#ifndef DENGINE_USER_INTERFACE_H
|
||||
#define DENGINE_USER_INTERFACE_H
|
||||
|
||||
#include "Dengine/Common.h"
|
||||
#include "Dengine/Math.h"
|
||||
#include "Dengine/Platform.h"
|
||||
|
||||
/* Forward Declaration */
|
||||
typedef struct AssetManager AssetManager;
|
||||
typedef struct Font Font;
|
||||
typedef struct MemoryArena MemoryArena;
|
||||
typedef struct Renderer Renderer;
|
||||
|
||||
typedef struct UiState
|
||||
{
|
||||
i32 hotItem;
|
||||
i32 activeItem;
|
||||
|
||||
i32 kbdItem;
|
||||
enum KeyCode keyEntered;
|
||||
enum KeyCode keyMod;
|
||||
enum KeyCode keyChar;
|
||||
|
||||
i32 lastWidget;
|
||||
} UiState;
|
||||
|
||||
i32 userInterface_button(UiState *const uiState,
|
||||
AssetManager *const assetManager,
|
||||
Renderer *const renderer, const KeyInput input,
|
||||
const i32 id, const Rect rect);
|
||||
|
||||
i32 userInterface_textField(UiState *const uiState, MemoryArena *arena,
|
||||
AssetManager *const assetManager,
|
||||
Renderer *const renderer, Font *const font,
|
||||
KeyInput input, const i32 id, v2 pos,
|
||||
char *const string);
|
||||
|
||||
i32 userInterface_scrollBar(UiState *const uiState,
|
||||
AssetManager *const assetManager,
|
||||
Renderer *const renderer, const KeyInput input,
|
||||
const i32 id, const Rect scrollBarRect,
|
||||
i32 *const value, const i32 maxValue);
|
||||
#endif
|
@ -4,27 +4,17 @@
|
||||
#include "Dengine/AssetManager.h"
|
||||
#include "Dengine/Audio.h"
|
||||
#include "Dengine/Common.h"
|
||||
#include "Dengine/Entity.h"
|
||||
#include "Dengine/Math.h"
|
||||
#include "Dengine/MemoryArena.h"
|
||||
#include "Dengine/Platform.h"
|
||||
#include "Dengine/Renderer.h"
|
||||
#include "Dengine/UserInterface.h"
|
||||
|
||||
#define NUM_KEYS 1024
|
||||
#define METERS_TO_PIXEL 240
|
||||
|
||||
typedef struct UiState
|
||||
{
|
||||
i32 hotItem;
|
||||
i32 activeItem;
|
||||
|
||||
i32 kbdItem;
|
||||
enum KeyCode keyEntered;
|
||||
enum KeyCode keyMod;
|
||||
enum KeyCode keyChar;
|
||||
|
||||
i32 lastWidget;
|
||||
} UiState;
|
||||
/* Forward declaration */
|
||||
typedef struct Entity Entity;
|
||||
|
||||
typedef struct World
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user