Search lister improvements.

This commit is contained in:
Peter Slattery 2019-09-21 13:19:02 -07:00
parent 594e4257e0
commit eb22ebf1ea
10 changed files with 168 additions and 111 deletions

View File

@ -351,7 +351,13 @@ RELOAD_STATIC_DATA(ReloadStaticData)
RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_A, false, KeyCode_Invalid, OpenNodeLister);
RegisterKeyPressCommand(&State->InputCommandRegistry, KeyCode_Tab, false, KeyCode_Invalid, ToggleNodeDisplay);
InitializeTextInputCommands(&State->TextEntryCommandRegistry, State->Permanent);
// Node Lister
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_DownArrow, false, KeyCode_Invalid, SearchListerNextItem);
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_UpArrow, false, KeyCode_Invalid, SearchListerPrevItem);
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_Enter, false, KeyCode_Invalid, SelectAndCloseSearchLister);
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_MouseLeftButton, false, KeyCode_Invalid, CloseSearchLister);
RegisterKeyPressCommand(&State->NodeListerCommandRegistry, KeyCode_Esc, false, KeyCode_Invalid, CloseSearchLister);
InitializeTextInputCommands(&State->NodeListerCommandRegistry, State->Permanent);
}
}
@ -367,7 +373,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
InitMemoryArena(&State->SACNMemory, 0, 0, Context.PlatformAlloc);
InitializeInputCommandRegistry(&State->InputCommandRegistry, 32, State->Permanent);
InitializeInputCommandRegistry(&State->TextEntryCommandRegistry, 32, State->Permanent);
InitializeInputCommandRegistry(&State->NodeListerCommandRegistry, 32, State->Permanent);
State->ActiveCommands = &State->InputCommandRegistry;
State->ActiveTextEntry.Buffer = MakeString(PushArray(State->Permanent, char, 256), 0, 256);
@ -447,15 +453,14 @@ INITIALIZE_APPLICATION(InitializeApplication)
State->Camera.Far = 100.0f;
State->Camera.Position = v3{0, 0, -250};
State->Camera.LookAt = v3{0, 0, 0};
State->Camera_StartDragPos = V4(State->Camera.Position, 1);
#if 1
char Path[] = "radialumia.fold";
LoadAssembly(State, Context, Path);
#endif
State->InterfaceYMax = 200;
State->PixelsToWorldScale = .01f;
State->Camera_StartDragPos = {};
State->UniverseOutputDisplayOffset = v2{0, 0};
State->UniverseOutputDisplayZoom = 1.0f;
@ -489,7 +494,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
// incorrect to clear the arena, and then access the memory later.
ClearArena(State->Transient);
if (State->ActiveCommands == &State->TextEntryCommandRegistry)
if (State->ActiveCommands == &State->NodeListerCommandRegistry)
{
AppendInputToEntryString(&State->ActiveTextEntry, Input.New->StringInput, Input.New->StringInputUsed);
}
@ -504,7 +509,6 @@ UPDATE_AND_RENDER(UpdateAndRender)
State->LEDBufferList->Count,
Context.DeltaTime);
}
ClearTransientNodeColorBuffers(State->NodeList);
{
@ -768,7 +772,9 @@ UPDATE_AND_RENDER(UpdateAndRender)
SetTextInputDestinationToFloat(&State->ActiveTextEntry, &Connection->R32Value);
}
State->NodeInteraction = NewEmptyNodeInteraction();
State->ActiveCommands = &State->TextEntryCommandRegistry;
// TODO(Peter): This is wrong, should be something to do with capturing text input
State->ActiveCommands = &State->NodeListerCommandRegistry;
}
else // This is the case where you dragged the value
{
@ -796,15 +802,6 @@ UPDATE_AND_RENDER(UpdateAndRender)
if (State->InterfaceShowNodeList)
{
if (KeyTransitionedDown(Input, KeyCode_DownArrow))
{
SearchListerNextItem(State, Input);
}
if (KeyTransitionedDown(Input, KeyCode_UpArrow))
{
SearchListerPrevItem(State, Input);
}
v2 TopLeft = State->NodeListMenuPosition;
v2 Dimension = v2{300, 30};
@ -817,23 +814,6 @@ UPDATE_AND_RENDER(UpdateAndRender)
State->ActiveTextEntry.CursorPosition,
State->Font, State->Interface, Input);
State->GeneralPurposeSearchHotItem = NodeListResult.HotItem;
if (KeyTransitionedDown(Input, KeyCode_Enter))
{
NodeListResult.SelectedItem = NodeListResult.HotItem;
}
if (NodeListResult.SelectedItem >= 0)
{
PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[NodeListResult.SelectedItem],
MousePos, State->NodeRenderSettings, State->Permanent);
CloseSearchLister(State, Input);
}
else if (KeyTransitionedDown(Input, KeyCode_MouseLeftButton) ||
KeyTransitionedDown(Input, KeyCode_Esc))
{
CloseSearchLister(State, Input);
}
}
}
@ -851,7 +831,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
DrawDebugInterface(RenderBuffer, 25,
State->Interface, Context.WindowWidth, Context.WindowHeight - TopBarHeight,
Context.DeltaTime, State->Camera, Input, State->Transient);
Context.DeltaTime, State, State->Camera, Input, State->Transient);
}
EndDebugFrame(GlobalDebugServices);

View File

@ -48,7 +48,7 @@ struct assembly
typedef struct app_state app_state;
#include "foldhaus_debug_visuals.h"
#include "foldhaus_command_dispatch.h"
@ -56,6 +56,7 @@ typedef struct app_state app_state;
#include "foldhaus_default_nodes.h"
#include "generated/foldhaus_nodes_generated.cpp"
#include "foldhaus_search_lister.h"
struct app_state
{
@ -66,9 +67,9 @@ struct app_state
camera Camera;
input_command_registry InputCommandRegistry;
input_command_registry TextEntryCommandRegistry;
input_command_registry NodeListerCommandRegistry;
input_command_registry* ActiveCommands;
text_input ActiveTextEntry;
text_entry ActiveTextEntry;
streaming_acn SACN;
s32 TotalLEDsCount;
@ -84,7 +85,6 @@ struct app_state
bitmap_font* Font;
interface_config Interface;
r32 InterfaceYMax;
r32 PixelsToWorldScale;
v4 Camera_StartDragPos;
@ -107,9 +107,10 @@ struct app_state
};
#include "foldhaus_search_lister.h"
#include "foldhaus_debug_visuals.h"
#include "foldhaus_sacn_view.cpp"
#include "foldhaus_command_dispatch.cpp"
#include "foldhaus_node.cpp"
#include "foldhaus_text_entry.cpp"
#include "foldhaus_interface.cpp"
#include "foldhaus_search_lister.cpp"

View File

@ -1,5 +1,5 @@
internal void
DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_config Interface, r32 WindowWidth, r32 WindowHeight, r32 DeltaTime, camera Camera, input Input, memory_arena* Transient)
DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_config Interface, r32 WindowWidth, r32 WindowHeight, r32 DeltaTime, app_state* State, camera Camera, input Input, memory_arena* Transient)
{
DEBUG_TRACK_SCOPE(DrawDebugInterface);
@ -19,9 +19,22 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
}
r32 FramesPerSecond = 1.0f / DeltaTime;
PrintF(&DebugString, "Framerate: %.*f s %d fps",
string InputCommands = MakeStringLiteral("Default Input Registry - HI KALAN");
string NodeListerCommands = MakeStringLiteral("Node Lister Input Registry - HI KALAN");
string ActiveInputRegistry = {};
if (State->ActiveCommands == &State->InputCommandRegistry)
{
ActiveInputRegistry = InputCommands;
}
else if (State->ActiveCommands == &State->NodeListerCommandRegistry)
{
ActiveInputRegistry = NodeListerCommands;
}
PrintF(&DebugString, "Framerate: %.*f s %d fps | Input: %s",
5, DeltaTime,
(u32)FramesPerSecond);
(u32)FramesPerSecond,
ActiveInputRegistry.Memory);
DrawString(RenderBuffer, DebugString, Interface.Font, Interface.FontSize, TopOfScreenLinePos, WhiteV4);
v2 ButtonDim = v2{200, (r32)NewLineYOffset(*Interface.Font) + 10};

View File

@ -7,7 +7,11 @@ FOLDHAUS_INPUT_COMMAND_PROC(CameraMouseControl)
State->Camera_StartDragPos = V4(State->Camera.Position, 1);
}
if (Input.MouseDownY > State->InterfaceYMax)
if (KeyTransitionedUp(Input, KeyCode_MouseLeftButton))
{
State->Camera_StartDragPos = V4(State->Camera.Position, 1);
}
else
{
if (!State->DrawUniverseOutputDisplay)
{
@ -55,7 +59,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
State->InterfaceShowNodeList = true;
State->NodeListMenuPosition = v2{(r32)Input.New->MouseX, (r32)Input.New->MouseY};
SetTextInputDestinationToString(&State->ActiveTextEntry, &State->GeneralPurposeSearchString);
State->ActiveCommands = &State->TextEntryCommandRegistry;
State->ActiveCommands = &State->NodeListerCommandRegistry;
}
FOLDHAUS_INPUT_COMMAND_PROC(ToggleNodeDisplay)

View File

@ -0,0 +1,74 @@
internal string*
GetStringAtIndex (search_lister Lister, s32 Index)
{
string* Result = 0;
Assert(Index >= 0 && Index < Lister.ListLength);
u8* Element = Lister.ListMemory + (Lister.ElementStride * Index);
Result = (string*)(Element + Lister.OffsetToStringInElement);
return Result;
}
#define InitializeSearchLister(SearchLister, List, ListLength, StringFieldName) \
s32 ElementStride = (u8*)(List + 1) - (u8*)(List); \
s32 OffsetToString = (u8*)(List->#StringFieldName) - (u8*)(List); \
InitializeSearchLister_((u8*)List, ListLength, ElementStride, OffsetToString); \
internal void
InitializeSearchLister_(search_lister* Lister,
u8* ListMemory,
s32 ListLength,
s32 ElementStride,
s32 OffsetToString)
{
Lister->ListLength = ListLength;
Lister->ListMemory = ListMemory;
Lister->OffsetToStringInElement = OffsetToString;
Lister->ElementStride = ElementStride;
Lister->Filter.Length = 0;
}
internal s32
GetNextHotItemIndex (s32 CurrentHotItem, s32 ListLength)
{
s32 Result = GSMin(CurrentHotItem + 1, ListLength - 1);
return Result;
}
internal s32
GetPrevHotItemIndex (s32 CurrentHotItem)
{
s32 Result = GSMax(0, CurrentHotItem - 1);
return Result;
}
FOLDHAUS_INPUT_COMMAND_PROC(SearchListerNextItem)
{
State->GeneralPurposeSearchHotItem = GetNextHotItemIndex(State->GeneralPurposeSearchHotItem, NodeSpecificationsCount);
}
FOLDHAUS_INPUT_COMMAND_PROC(SearchListerPrevItem)
{
State->GeneralPurposeSearchHotItem = GetPrevHotItemIndex(State->GeneralPurposeSearchHotItem);
}
FOLDHAUS_INPUT_COMMAND_PROC(CloseSearchLister)
{
// TODO(Peter): This is to show the node list. Generalize to just a lister
State->InterfaceShowNodeList = false;
// TODO(Peter): This also assumes we know where we came from. Probably need to implement
// push/pop functionality for the activecommands.
State->ActiveCommands = &State->InputCommandRegistry;
State->GeneralPurposeSearchHotItem = -1;
}
FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseSearchLister)
{
s32 HotItem = State->GeneralPurposeSearchHotItem;
v2 MousePos = v2{(r32)Input.New->MouseX, (r32)Input.New->MouseY};
PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[HotItem],
MousePos, State->NodeRenderSettings, State->Permanent);
CloseSearchLister(State, Input);
}

View File

@ -1,33 +1,9 @@
internal s32
GetNextHotItem (s32 CurrentHotItem, s32 ListLength)
struct search_lister
{
s32 Result = GSMin(CurrentHotItem + 1, ListLength - 1);
return Result;
}
internal s32
GetPrevHotItem (s32 CurrentHotItem)
{
s32 Result = GSMax(0, CurrentHotItem - 1);
return Result;
}
FOLDHAUS_INPUT_COMMAND_PROC(SearchListerNextItem)
{
State->GeneralPurposeSearchHotItem = GetNextHotItem(State->GeneralPurposeSearchHotItem, NodeSpecificationsCount);
}
FOLDHAUS_INPUT_COMMAND_PROC(SearchListerPrevItem)
{
State->GeneralPurposeSearchHotItem = GetPrevHotItem(State->GeneralPurposeSearchHotItem);
}
FOLDHAUS_INPUT_COMMAND_PROC(CloseSearchLister)
{
// TODO(Peter): This is to show the node list. Generalize to just a lister
State->InterfaceShowNodeList = false;
// TODO(Peter): This also assumes we know where we came from. Probably need to implement
// push/pop functionality for the activecommands.
State->ActiveCommands = &State->InputCommandRegistry;
State->GeneralPurposeSearchHotItem = -1;
}
s32 ListLength;
u8* ListMemory;
s32 OffsetToStringInElement;
s32 ElementStride;
string Filter;
};

View File

@ -1,12 +1,12 @@
internal void
ResetTextInput (text_input* Input)
ResetTextInput (text_entry* Input)
{
Input->CursorPosition = 0;
Input->Buffer.Length = 0;
}
internal void
PipeSearchStringToDestination (text_input* Input)
PipeSearchStringToDestination (text_entry* Input)
{
switch (Input->Destination.Type)
{
@ -25,18 +25,19 @@ PipeSearchStringToDestination (text_input* Input)
}
}
FOLDHAUS_INPUT_COMMAND_PROC(RemoveCharacterFromEntryString)
internal void
RemoveCharacterAtCursor (text_entry* TextEntry)
{
if (State->ActiveTextEntry.CursorPosition > 0)
if (TextEntry->CursorPosition > 0)
{
RemoveCharAt(&State->ActiveTextEntry.Buffer,
State->ActiveTextEntry.CursorPosition - 1);
State->ActiveTextEntry.CursorPosition--;
RemoveCharAt(&TextEntry->Buffer,
TextEntry->CursorPosition - 1);
TextEntry->CursorPosition--;
}
}
internal void
SetTextInputDestinationToString (text_input* TextInput, string* DestinationString)
SetTextInputDestinationToString (text_entry* TextInput, string* DestinationString)
{
ResetTextInput(TextInput);
TextInput->Destination.Type = TextTranslateTo_String;
@ -45,7 +46,7 @@ SetTextInputDestinationToString (text_input* TextInput, string* DestinationStrin
}
internal void
SetTextInputDestinationToFloat (text_input* TextInput, r32* DestinationFloat)
SetTextInputDestinationToFloat (text_entry* TextInput, r32* DestinationFloat)
{
ResetTextInput(TextInput);
TextInput->Destination.Type = TextTranslateTo_R32;
@ -59,7 +60,7 @@ SetTextInputDestinationToFloat (text_input* TextInput, r32* DestinationFloat)
}
internal void
AppendInputToEntryString (text_input* EntryString, char* InputString, s32 InputStringLength)
AppendInputToEntryString (text_entry* EntryString, char* InputString, s32 InputStringLength)
{
if (InputStringLength > 0)
{
@ -72,33 +73,41 @@ AppendInputToEntryString (text_input* EntryString, char* InputString, s32 InputS
PipeSearchStringToDestination(EntryString);
}
internal void
MoveCursorRight (text_entry* TextEntry)
{
TextEntry->CursorPosition = GSMin(TextEntry->Buffer.Length,
TextEntry->CursorPosition + 1);
}
internal void
MoveCursorLeft (text_entry* TextEntry)
{
TextEntry->CursorPosition = GSMax(0, TextEntry->CursorPosition - 1);
}
FOLDHAUS_INPUT_COMMAND_PROC(RemoveCharacterFromEntryString)
{
RemoveCharacterAtCursor(&State->ActiveTextEntry);
}
FOLDHAUS_INPUT_COMMAND_PROC(TextEntryMoveCursorRight)
{
State->ActiveTextEntry.CursorPosition = GSMin(State->ActiveTextEntry.Buffer.Length,
State->ActiveTextEntry.CursorPosition + 1);
MoveCursorRight(&State->ActiveTextEntry);
}
FOLDHAUS_INPUT_COMMAND_PROC(TextEntryMoveCursorLeft)
{
State->ActiveTextEntry.CursorPosition = GSMax(0,
State->ActiveTextEntry.CursorPosition - 1);
}
FOLDHAUS_INPUT_COMMAND_PROC(LeaveTextEntryMode)
{
// TODO(Peter): Make this more flexible. Should return to whatever came before
State->ActiveCommands = &State->InputCommandRegistry;
MoveCursorLeft(&State->ActiveTextEntry);
}
internal void
InitializeTextInputCommands (input_command_registry* SearchCommands, memory_arena* PermanentStorage)
InitializeTextInputCommands (input_command_registry* Commands, memory_arena* PermanentStorage)
{
if (SearchCommands->Size > 0)
if (Commands->Size > 0)
{
RegisterKeyPressCommand(SearchCommands, KeyCode_Backspace, false, KeyCode_Invalid, RemoveCharacterFromEntryString);
RegisterKeyPressCommand(SearchCommands, KeyCode_LeftArrow, false, KeyCode_Invalid, TextEntryMoveCursorLeft);
RegisterKeyPressCommand(SearchCommands, KeyCode_RightArrow, false, KeyCode_Invalid, TextEntryMoveCursorRight);
RegisterKeyPressCommand(SearchCommands, KeyCode_Enter, false, KeyCode_Invalid,
LeaveTextEntryMode);
RegisterKeyPressCommand(Commands, KeyCode_Backspace, false, KeyCode_Invalid, RemoveCharacterFromEntryString);
RegisterKeyPressCommand(Commands, KeyCode_LeftArrow, false, KeyCode_Invalid, TextEntryMoveCursorLeft);
RegisterKeyPressCommand(Commands, KeyCode_RightArrow, false, KeyCode_Invalid, TextEntryMoveCursorRight);
}
}

View File

@ -6,7 +6,7 @@ enum text_translation_type
TextTranslateTo_U32,
};
struct text_input_destination
struct text_entry_destination
{
text_translation_type Type;
union {
@ -17,10 +17,10 @@ struct text_input_destination
};
};
struct text_input
struct text_entry
{
string Buffer;
s32 CursorPosition;
text_input_destination Destination;
text_entry_destination Destination;
};

View File

@ -579,7 +579,6 @@ EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimens
search_lister_result Result = {};
Result.ShouldRemainOpen = true;
Result.HotItem = HotItem;
Result.SelectedItem = -1;
// Title Bar
PushRenderQuad2D(RenderBuffer, v2{TopLeft.x, TopLeft.y - 30}, v2{TopLeft.x + 300, TopLeft.y}, v4{.3f, .3f, .3f, 1.f});

View File

@ -1,13 +1,14 @@
TODO FOLDHAUS
Hardening
- more robust windows input layer
- memory visualization
- separate rendering thread
- cache led positions. Only update if they are moving
- input context changes
- x don't type into the search bar when its not open
- x don't type into the search bar when you press a to open it
- x type into text boxes
- - shift drag to 10x drag speed
- select nodes -> delete nodes
- open add node menu, click off to the side, it still adds a node.
- remove node connections
Name
- Splash screen (like blender) (thisll be fun)