Quickly got the search lister to use the correct index when filtering the list.

This commit is contained in:
Peter Slattery 2019-10-30 09:10:15 -07:00
parent 21d6c1740e
commit e00e90f2fd
13 changed files with 230 additions and 142 deletions

View File

@ -21,6 +21,6 @@ del *.pdb > NUL 2> NUL
REM cl %CommonCompilerFlags% ..\meta\main_meta.cpp /link %CommonLinkerFlags% user32.lib winmm.lib gdi32.lib -incremental:no
cl %CommonCompilerFlags% ..\meta\foldhaus_meta.cpp /link %CommonLinkerFlags%
C:\programs\ctime\ctime.exe -end C:\projects\foldhaus\build\win32_gs_meta_build_time.ctm %LastError%
C:\programs\ctime\ctime.exe -end C:\projects\foldhaus_meta\build\win32_gs_meta_build_time.ctm %LastError%
C:\programs\ctime\ctime.exe -stats C:\projects\foldhaus\build\win32_gs_meta_build_time.ctm
popd

View File

@ -25,7 +25,7 @@ load_paths = {
command_list = {
{ .name = "build_application",
.out = "*app compilation*", .footer_panel = false, .save_dirty_files = true,
.cmd = { { "src\\build.bat" , .os = "win" },
.cmd = { { "build.bat" , .os = "win" },
{ "./build.sh", .os = "linux" },
{ "./build.sh", .os = "mac" }, }, },
{ .name = "build_meta",

View File

@ -405,7 +405,7 @@ INITIALIZE_APPLICATION(InitializeApplication)
Font->BitmapStride = Font->BitmapWidth * Font->BitmapBytesPerPixel;
GSMemSet(Font->BitmapMemory, 0, Font->BitmapStride * Font->BitmapHeight);
platform_font_info FontInfo = Context.PlatformGetFontInfo("Anonymous Pro", FontSize);
platform_font_info FontInfo = Context.PlatformGetFontInfo("Anonymous Pro", FontSize, FontWeight_Normal, false, false, false);
Font->PixelHeight = FontInfo.PixelHeight;
Font->Ascent = FontInfo.Ascent;
Font->Descent = FontInfo.Descent;
@ -524,6 +524,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
for (s32 EventIdx = 0; EventIdx < InputQueue.QueueUsed; EventIdx++)
{
input_entry Event = InputQueue.Entries[EventIdx];
input_command* Command = FindExistingCommand(State->ActiveCommands, Event.Key, (key_code)0);
if (Command)
{
@ -857,20 +858,20 @@ UPDATE_AND_RENDER(UpdateAndRender)
{
RenderNodeList(State->NodeList, State->NodeRenderSettings, RenderBuffer);
if (State->InterfaceShowNodeList)
if (State->InterfaceShowNodeLister)
{
v2 TopLeft = State->NodeListMenuPosition;
v2 Dimension = v2{300, 30};
search_lister_result NodeListResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
MakeStringLiteral("Nodes List"),
NodeSpecificationsCount, (u8*)NodeSpecifications,
State->GeneralPurposeSearchHotItem,
NodeListerGetNodeName,
&State->ActiveTextEntry.Buffer,
State->ActiveTextEntry.CursorPosition,
State->Font, State->Interface, GuiMouse);
State->GeneralPurposeSearchHotItem = NodeListResult.HotItem;
search_lister_result NodeListerResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
MakeStringLiteral("Nodes List"),
NodeSpecificationsCount, (u8*)NodeSpecifications,
State->GeneralPurposeSearchHotItem,
NodeListerGetNodeName,
&State->ActiveTextEntry.Buffer,
State->ActiveTextEntry.CursorPosition,
State->Font, State->Interface, GuiMouse);
State->GeneralPurposeSearchHotItem = NodeListerResult.HotItem;
}
}

View File

@ -98,7 +98,7 @@ struct app_state
v2 UniverseOutputDisplayOffset;
r32 UniverseOutputDisplayZoom;
b32 InterfaceShowNodeList;
b32 InterfaceShowNodeLister;
v2 NodeListMenuPosition;
node_list* NodeList;

View File

@ -41,7 +41,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(ToggleUniverseDebugView)
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
{
State->InterfaceShowNodeList = true;
State->InterfaceShowNodeLister = true;
State->NodeListMenuPosition = Mouse.Pos;
SetTextInputDestinationToString(&State->ActiveTextEntry, &State->GeneralPurposeSearchString);
State->ActiveCommands = &State->NodeListerCommandRegistry;

View File

@ -1124,11 +1124,60 @@ ResetNodesUpdateState (node_list* NodeList)
}
}
internal char*
NodeListerGetNodeName (u8* NodeSpecificationsList, s32 NodeSpecificationsListCount, s32 Offset)
internal b32
SpecificationPassesFilter(string SpecificationName, string SearchString)
{
node_specification* Specifications = (node_specification*)NodeSpecificationsList + Offset;
char* Result = Specifications->Name;
return (SearchString.Length == 0 || StringContainsStringCaseInsensitive(SpecificationName, SearchString));
}
internal s32
NodeListerConvertHotItemToListIndex (s32 HotItem, u8* NodeSpecificationsList, s32 NodeSpecificationsListCount,
string SearchString)
{
s32 ListIndex = 0;
s32 FilteredItemsCount = 0;
for (s32 i = 0; i < NodeSpecificationsListCount; i++)
{
node_specification* Specification = (node_specification*)NodeSpecificationsList + i;
string ItemName = MakeString(Specification->Name);
b32 PassesFilter = SpecificationPassesFilter(ItemName, SearchString);
if (PassesFilter)
{
if (FilteredItemsCount == HotItem)
{
break;
}
FilteredItemsCount++;
}
ListIndex++;
}
return ListIndex;
}
internal string
NodeListerGetNodeName (u8* NodeSpecificationsList, s32 NodeSpecificationsListCount, string SearchString, s32 Offset)
{
s32 FilteredItemsCount = 0;
node_specification* Specification = (node_specification*)NodeSpecificationsList;
string Result = {};
for (s32 i = 0; i < NodeSpecificationsListCount; i++)
{
string ItemName = MakeString(Specification->Name);
b32 PassesFilter = SpecificationPassesFilter(ItemName, SearchString);
if (PassesFilter)
{
if (FilteredItemsCount == Offset)
{
Result = ItemName;
break;
}
FilteredItemsCount++;
}
Specification++;
}
return Result;
}

View File

@ -35,7 +35,21 @@ typedef CLEANUP_APPLICATION(cleanup_application);
typedef struct platform_font_info platform_font_info;
#define GET_FONT_INFO(name) platform_font_info name(char* FontName, s32 PixelHeight)
enum font_weight
{
FontWeight_Invalid = 0,
FontWeight_Thin = 100,
FontWeight_ExtraLight = 200,
FontWeight_Light = 300,
FontWeight_Normal = 400,
FontWeight_Medium = 500,
FontWeight_SemiBold = 600,
FontWeight_Bold = 700,
FontWeight_ExtraBold = 800,
FontWeight_Heavy = 900,
};
#define GET_FONT_INFO(name) platform_font_info name(char* FontName, s32 PixelHeight, font_weight FontWeight, b32 Italic, b32 Underline, b32 Strikeout)
typedef GET_FONT_INFO(platform_get_font_info);
#define DRAW_FONT_CODEPOINT(name) void name(u8* DestBuffer, s32 DestBufferWidth, s32 DestBufferHeight, u32 XOffset, u32 YOffset, char Codepoint, platform_font_info FontInfo, u32* OutWidth, u32* OutHeight)

View File

@ -57,7 +57,7 @@ FOLDHAUS_INPUT_COMMAND_PROC(SearchListerPrevItem)
FOLDHAUS_INPUT_COMMAND_PROC(CloseSearchLister)
{
// TODO(Peter): This is to show the node list. Generalize to just a lister
State->InterfaceShowNodeList = false;
State->InterfaceShowNodeLister = false;
// TODO(Peter): This also assumes we know where we came from. Probably need to implement
// push/pop functionality for the activecommands.
QueueNextFrameCommandRegistry(&State->InputCommandRegistry, State);
@ -67,7 +67,11 @@ FOLDHAUS_INPUT_COMMAND_PROC(CloseSearchLister)
FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseSearchLister)
{
s32 HotItem = State->GeneralPurposeSearchHotItem;
PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[HotItem],
s32 ListIndexFromHotItem = NodeListerConvertHotItemToListIndex(HotItem,
(u8*)NodeSpecifications,
NodeSpecificationsCount,
State->ActiveTextEntry.Buffer);
PushNodeOnListFromSpecification(State->NodeList, NodeSpecifications[ListIndexFromHotItem],
Mouse.Pos, State->NodeRenderSettings, State->Permanent);
CloseSearchLister(State, Event, Mouse);
}

View File

@ -575,7 +575,7 @@ struct search_lister_result
b32 ShouldRemainOpen;
};
typedef char* search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, s32 Offset);
typedef string search_lister_get_list_item_at_offset(u8* ListMemory, s32 ListLength, string SearchString, s32 Offset);
internal search_lister_result
EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimension, string Title,
@ -600,35 +600,29 @@ EvaluateSearchLister (render_command_buffer* RenderBuffer, v2 TopLeft, v2 Dimens
TopLeft.y -= 30;
s32 VisibleItemIndex = 0;
for (s32 i = 0; i < ListLength; i++)
string ListItemText = GetListItem(ListMemory, ListLength, *SearchString, VisibleItemIndex);
while(ListItemText.Length > 0)
{
char* ListItemText = GetListItem(ListMemory, ListLength, i);
Assert(ListItemText);
string ListItemString = MakeStringLiteral(ListItemText);
v2 Min = v2{TopLeft.x, TopLeft.y - 30};
v2 Max = Min + Dimension - v2{0, Config.Margin.y};
if (SearchString->Length == 0 ||
StringContainsStringCaseInsensitive(ListItemString, *SearchString))
v4 ButtonColor = Config.ButtonColor_Inactive;
if (VisibleItemIndex == HotItem)
{
v2 Min = v2{TopLeft.x, TopLeft.y - 30};
v2 Max = Min + Dimension - v2{0, Config.Margin.y};
v4 ButtonColor = Config.ButtonColor_Inactive;
if (VisibleItemIndex == HotItem)
{
ButtonColor = Config.ButtonColor_Active;
}
button_result Button = EvaluateButton(RenderBuffer, Min, Max, Config.Margin, ListItemString,
ButtonColor, ButtonColor, Config.TextColor, Config.TextColor,
Config.Font, Mouse);
if (Button.Pressed)
{
Result.SelectedItem = i;
}
TopLeft.y -= 30;
VisibleItemIndex++;
ButtonColor = Config.ButtonColor_Active;
}
button_result Button = EvaluateButton(RenderBuffer, Min, Max, Config.Margin, ListItemText,
ButtonColor, ButtonColor, Config.TextColor, Config.TextColor,
Config.Font, Mouse);
if (Button.Pressed)
{
Result.SelectedItem = VisibleItemIndex;
}
TopLeft.y -= 30;
ListItemText = GetListItem(ListMemory, ListLength, *SearchString, ++VisibleItemIndex);
}
return Result;

View File

@ -1,78 +0,0 @@
TODO FOLDHAUS
Hardening
- memory visualization
- separate rendering thread
- cache led positions. Only update if they are moving
- input context changes
- - shift drag to 10x drag speed
- select nodes -> delete nodes
- remove node connections
Name
- Splash screen (like blender) (thisll be fun)
- - Image importer (stb image? or find a png > bmp converter for the image you have)
- - Display on startup
/Debug
x Make debug scope tracking thread safe - was throwing an error in stringsequal but that stopped.
x Keep an eye out.
Application
- More efficient HSV <-> RGB
- Save and load a session
- - Serialize Nodes
- Don't render if the window isn't visible
Development
- Fix your scope time tracker to account for threads.
- Nest scope times so you can see totals/dig in
- Log memory allocations
Interface
- fullscreen
- In world interface elements
- - Handles for Patterns
- - UI Popups
- - Value modifiers
- Scroll view
- Update the text system - use system fonts
Switch To Nodes
x basic node elements
- - evaluation step (one node at a time)
- - selector node (has a list of connections that it can switch between)
- serialize
- delete nodes
Structure
- motion
Renderer
- Mouse Picking - point at a led and see info about it
- Camera: pan
- Camera: zoom
- Camera: leds always face camera
Resource Management
- TODO: Need to figure out which textures are currently in graphics memory and which need to be resubmitted
- Icons
Animation
- timeline
- create clips that play
- clips can have parameters that drive them?
- clips should have prerequesites
- - channels active
- - patterns active in the channel
- - when a clip is playing, it should just take over the whole structure
Command Line
- select a channel/pattern
Optimization
- patterns are asking to be multithreaded
- probably want to convert as much color functions to use u32 Packed Colors
- - Probably want to think about this more. What about supporting different color depths
- for different output devices?

View File

@ -249,11 +249,10 @@ GET_FONT_INFO(Win32GetFontInfo)
HGDIOBJ SelectObjectResult = SelectObject(FontDrawingDC, FontBitmap);
CurrentFont = CreateFont(PixelHeight, 0, 0, 0,
// TODO(Peter): Font weight, need a platform way to request others
FW_NORMAL,
FALSE, // Italic
FALSE, // Underling
FALSE, // Strikeout,
FontWeight,
Italic,
Underline,
Strikeout,
ANSI_CHARSET,
OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS,
@ -297,8 +296,7 @@ DRAW_FONT_CODEPOINT(Win32DrawFontCodepoint)
COLORREF PixelColor;
for (u32 Y = 0; Y < *OutHeight; Y++)
{
// TODO(Peter): * 4 b/c its 4 bytes per pixel. Switch to our bitmap_texture struct for clarity
// and fewer fields to this function
// NOTE(Peter): XOffset * 4 b/c its 4 bytes per pixel.
u8* Channel = (u8*)Row + (XOffset * 4);
for (u32 X = 0; X < *OutWidth; X++)
{
@ -375,39 +373,63 @@ HandleWindowMessage (MSG Message, window* Window, input_queue* InputQueue, mouse
case WM_LBUTTONDOWN:
{
b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000;
b32 AltDown = GetKeyState(VK_MENU) & 0x8000;
b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000;
AddInputEventEntry(InputQueue, KeyCode_MouseLeftButton, false, true,
false, false, false, false);
ShiftDown, AltDown, CtrlDown, false);
Mouse->DownPos = Mouse->Pos;
}break;
case WM_MBUTTONDOWN:
{
b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000;
b32 AltDown = GetKeyState(VK_MENU) & 0x8000;
b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000;
AddInputEventEntry(InputQueue, KeyCode_MouseMiddleButton, false, true,
false, false, false, false);
ShiftDown, AltDown, CtrlDown, false);
}break;
case WM_RBUTTONDOWN:
{
b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000;
b32 AltDown = GetKeyState(VK_MENU) & 0x8000;
b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000;
AddInputEventEntry(InputQueue, KeyCode_MouseRightButton, false, true,
false, false, false, false);
ShiftDown, AltDown, CtrlDown, false);
}break;
case WM_LBUTTONUP:
{
b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000;
b32 AltDown = GetKeyState(VK_MENU) & 0x8000;
b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000;
AddInputEventEntry(InputQueue, KeyCode_MouseLeftButton, true, false,
false, false, false, false);
ShiftDown, AltDown, CtrlDown, false);
}break;
case WM_MBUTTONUP:
{
b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000;
b32 AltDown = GetKeyState(VK_MENU) & 0x8000;
b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000;
AddInputEventEntry(InputQueue, KeyCode_MouseMiddleButton, true, false,
false, false, false, false);
ShiftDown, AltDown, CtrlDown, false);
}break;
case WM_RBUTTONUP:
{
b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000;
b32 AltDown = GetKeyState(VK_MENU) & 0x8000;
b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000;
AddInputEventEntry(InputQueue, KeyCode_MouseRightButton, true, false,
false, false, false, false);
ShiftDown, AltDown, CtrlDown, false);
}break;
case WM_SYSKEYDOWN:
@ -422,9 +444,13 @@ HandleWindowMessage (MSG Message, window* Window, input_queue* InputQueue, mouse
b32 KeyWasDown = (Message.lParam & (1 << 30)) != 0;
b32 KeyIsDown = (Message.lParam & (1 << 31)) == 0;
b32 ShiftDown = GetKeyState(VK_SHIFT) & 0x8000;
b32 AltDown = GetKeyState(VK_MENU) & 0x8000;
b32 CtrlDown = GetKeyState(VK_CONTROL) & 0x8000;
// New Input Queue
// TODO(Peter): Come back and add state tracking for the modifier keys
AddInputEventEntry(InputQueue, Key, KeyWasDown, KeyIsDown, false, false, false, false);
AddInputEventEntry(InputQueue, Key, KeyWasDown, KeyIsDown,
ShiftDown, AltDown, CtrlDown, false);
}break;
default:

View File

@ -0,0 +1,78 @@
TODO FOLDHAUS
Hardening
- memory visualization
- separate rendering thread
- cache led positions. Only update if they are moving
x input context changes
- - shift drag to 10x drag speed
- select nodes -> delete nodes
- remove node connections
Name
- Splash screen (like blender) (thisll be fun)
- - Image importer (stb image? or find a png > bmp converter for the image you have)
- - Display on startup
/Debug
x Make debug scope tracking thread safe - was throwing an error in stringsequal but that stopped.
x Keep an eye out.
Application
- More efficient HSV <-> RGB
- Save and load a session
- - Serialize Nodes
- Don't render if the window isn't visible
Development
- Fix your scope time tracker to account for threads.
- Nest scope times so you can see totals/dig in
- Log memory allocations
Interface
- fullscreen
- In world interface elements
- - Handles for Patterns
- - UI Popups
- - Value modifiers
- Scroll view
- Update the text system - use system fonts
Switch To Nodes
x basic node elements
- - evaluation step (one node at a time)
- - selector node (has a list of connections that it can switch between)
- serialize
- delete nodes
Structure
- motion
Renderer
- Mouse Picking - point at a led and see info about it
- Camera: pan
- Camera: zoom
- Camera: leds always face camera
Resource Management
- TODO: Need to figure out which textures are currently in graphics memory and which need to be resubmitted
- Icons
Animation
- timeline
- create clips that play
- clips can have parameters that drive them?
- clips should have prerequesites
- - channels active
- - patterns active in the channel
- - when a clip is playing, it should just take over the whole structure
Command Line
- select a channel/pattern
Optimization
- patterns are asking to be multithreaded
- probably want to convert as much color functions to use u32 Packed Colors
- - Probably want to think about this more. What about supporting different color depths
- for different output devices?