Removed nodes from the project
This commit is contained in:
parent
1fea9cdb91
commit
da76bb46f5
|
@ -186,7 +186,6 @@ RELOAD_STATIC_DATA(ReloadStaticData)
|
||||||
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_MouseLeftButton, Command_Began, KeyCode_Invalid,
|
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_MouseLeftButton, Command_Began, KeyCode_Invalid,
|
||||||
Begin3DViewMouseRotate);
|
Begin3DViewMouseRotate);
|
||||||
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_U, Command_Began, KeyCode_Invalid, OpenUniverseView);
|
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_U, Command_Began, KeyCode_Invalid, OpenUniverseView);
|
||||||
RegisterKeyPressCommand(&State->DefaultInputCommandRegistry, KeyCode_Tab, Command_Began, KeyCode_Invalid, OpenNodeView);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,14 +296,6 @@ INITIALIZE_APPLICATION(InitializeApplication)
|
||||||
|
|
||||||
GlobalDebugServices->Interface.RenderSculpture = true;
|
GlobalDebugServices->Interface.RenderSculpture = true;
|
||||||
|
|
||||||
State->NodeList = AllocateNodeList(State->Permanent, 128);
|
|
||||||
State->OutputNode = PushOutputNodeOnList(State->NodeList, v2{500, 250}, State->Permanent);
|
|
||||||
{
|
|
||||||
State->NodeRenderSettings.PortColors[MemberType_r32] = RedV4;
|
|
||||||
State->NodeRenderSettings.PortColors[MemberType_s32] = GreenV4;
|
|
||||||
State->NodeRenderSettings.PortColors[MemberType_v4] = BlueV4;
|
|
||||||
State->NodeRenderSettings.Font = State->Font;
|
|
||||||
}
|
|
||||||
ReloadStaticData(Context, GlobalDebugServices, Alloc, Free);
|
ReloadStaticData(Context, GlobalDebugServices, Alloc, Free);
|
||||||
|
|
||||||
{ // MODES PLAYGROUND
|
{ // MODES PLAYGROUND
|
||||||
|
@ -414,18 +405,7 @@ UPDATE_AND_RENDER(UpdateAndRender)
|
||||||
|
|
||||||
HandleInput(State, InputQueue, Mouse);
|
HandleInput(State, InputQueue, Mouse);
|
||||||
|
|
||||||
for (s32 AssemblyIndex = 0; AssemblyIndex < State->AssembliesCount; AssemblyIndex++)
|
// Update Visuals Here
|
||||||
{
|
|
||||||
assembly Assembly = State->AssemblyList[AssemblyIndex];
|
|
||||||
UpdateOutputNodeCalculations(State->OutputNode, State->NodeList,
|
|
||||||
State->Permanent, State->Transient,
|
|
||||||
Assembly.LEDs,
|
|
||||||
Assembly.Colors,
|
|
||||||
Assembly.LEDCount,
|
|
||||||
Context.DeltaTime);
|
|
||||||
ResetNodesUpdateState(State->NodeList);
|
|
||||||
}
|
|
||||||
ClearTransientNodeColorBuffers(State->NodeList);
|
|
||||||
|
|
||||||
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
s32 HeaderSize = State->NetworkProtocolHeaderSize;
|
||||||
dmx_buffer_list* DMXBuffers = 0;
|
dmx_buffer_list* DMXBuffers = 0;
|
||||||
|
|
|
@ -23,8 +23,6 @@ typedef struct app_state app_state;
|
||||||
|
|
||||||
#include "foldhaus_text_entry.h"
|
#include "foldhaus_text_entry.h"
|
||||||
|
|
||||||
#include "foldhaus_default_nodes.h"
|
|
||||||
#include "generated/foldhaus_nodes_generated.cpp"
|
|
||||||
#include "foldhaus_search_lister.h"
|
#include "foldhaus_search_lister.h"
|
||||||
|
|
||||||
enum network_protocol
|
enum network_protocol
|
||||||
|
@ -63,10 +61,6 @@ struct app_state
|
||||||
input_command_queue CommandQueue;
|
input_command_queue CommandQueue;
|
||||||
text_entry ActiveTextEntry;
|
text_entry ActiveTextEntry;
|
||||||
|
|
||||||
node_list* NodeList;
|
|
||||||
node_header* OutputNode;
|
|
||||||
|
|
||||||
node_render_settings NodeRenderSettings;
|
|
||||||
bitmap_font* Font;
|
bitmap_font* Font;
|
||||||
interface_config Interface;
|
interface_config Interface;
|
||||||
};
|
};
|
||||||
|
@ -74,7 +68,7 @@ struct app_state
|
||||||
internal void OpenColorPicker(app_state* State, v4* Address);
|
internal void OpenColorPicker(app_state* State, v4* Address);
|
||||||
|
|
||||||
#include "foldhaus_assembly.cpp"
|
#include "foldhaus_assembly.cpp"
|
||||||
#include "foldhaus_node.cpp"
|
|
||||||
#include "foldhaus_debug_visuals.h"
|
#include "foldhaus_debug_visuals.h"
|
||||||
//#include "foldhaus_sacn_view.cpp"
|
//#include "foldhaus_sacn_view.cpp"
|
||||||
#include "foldhaus_text_entry.cpp"
|
#include "foldhaus_text_entry.cpp"
|
||||||
|
|
|
@ -298,13 +298,6 @@ DrawDebugInterface (render_command_buffer* RenderBuffer, r32 StartX, interface_c
|
||||||
TopOfScreenLinePos, WhiteV4);
|
TopOfScreenLinePos, WhiteV4);
|
||||||
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
||||||
|
|
||||||
PrintF(&DebugString, "Nodes Memory: %d / %d",
|
|
||||||
State->NodeList->TotalUsed,
|
|
||||||
State->NodeList->TotalMax);
|
|
||||||
DrawString(RenderBuffer, DebugString, Interface.Font,
|
|
||||||
TopOfScreenLinePos, WhiteV4);
|
|
||||||
TopOfScreenLinePos.y -= NewLineYOffset(*Interface.Font);
|
|
||||||
|
|
||||||
PrintF(&DebugString, "Render Buffer: %d / %d (at this point)",
|
PrintF(&DebugString, "Render Buffer: %d / %d (at this point)",
|
||||||
RenderBuffer->CommandMemoryUsed,
|
RenderBuffer->CommandMemoryUsed,
|
||||||
RenderBuffer->CommandMemorySize);
|
RenderBuffer->CommandMemorySize);
|
||||||
|
|
|
@ -128,504 +128,6 @@ FOLDHAUS_INPUT_COMMAND_PROC(OpenUniverseView)
|
||||||
OpState->Zoom = 1.0f;
|
OpState->Zoom = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Node Lister
|
|
||||||
//
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
struct node_lister_operation_state
|
|
||||||
{
|
|
||||||
search_lister SearchLister;
|
|
||||||
v2 ListPosition;
|
|
||||||
};
|
|
||||||
|
|
||||||
OPERATION_RENDER_PROC(RenderNodeLister)
|
|
||||||
{
|
|
||||||
node_lister_operation_state* OpState = (node_lister_operation_state*)Operation.OpStateMemory;
|
|
||||||
|
|
||||||
v2 TopLeft = OpState->ListPosition;
|
|
||||||
v2 Dimension = v2{300, 30};
|
|
||||||
|
|
||||||
// Filter the lister
|
|
||||||
OpState->SearchLister.Filter = State->ActiveTextEntry.Buffer;
|
|
||||||
FilterSearchLister(&OpState->SearchLister);
|
|
||||||
|
|
||||||
// Display Search Lister
|
|
||||||
search_lister_result NodeListerResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
|
|
||||||
MakeStringLiteral("Nodes List"),
|
|
||||||
OpState->SearchLister.SourceList,
|
|
||||||
OpState->SearchLister.FilteredIndexLUT,
|
|
||||||
OpState->SearchLister.FilteredListCount,
|
|
||||||
OpState->SearchLister.HotItem,
|
|
||||||
&State->ActiveTextEntry.Buffer,
|
|
||||||
State->ActiveTextEntry.CursorPosition,
|
|
||||||
State->Font, State->Interface, Mouse);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerNextItem)
|
|
||||||
{
|
|
||||||
node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state);
|
|
||||||
OpState->SearchLister.HotItem = GetNextFilteredItem(OpState->SearchLister);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerPrevItem)
|
|
||||||
{
|
|
||||||
node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state);
|
|
||||||
OpState->SearchLister.HotItem = GetPrevFilteredItem(OpState->SearchLister);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeLister)
|
|
||||||
{
|
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseNodeLister)
|
|
||||||
{
|
|
||||||
node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state);
|
|
||||||
s32 FilteredNodeIndex = OpState->SearchLister.HotItem;
|
|
||||||
if (FilteredNodeIndex >= 0)
|
|
||||||
{
|
|
||||||
s32 NodeIndex = OpState->SearchLister.FilteredIndexLUT[FilteredNodeIndex];
|
|
||||||
PushNodeOnListFromSpecification(State->NodeList, (node_type)NodeIndex,
|
|
||||||
Mouse.Pos, State->Permanent);
|
|
||||||
}
|
|
||||||
CloseNodeLister(State, Event, Mouse);
|
|
||||||
}
|
|
||||||
|
|
||||||
input_command UniverseViewCommads [] = {
|
|
||||||
{ KeyCode_DownArrow, KeyCode_Invalid, Command_Began, NodeListerNextItem },
|
|
||||||
{ KeyCode_UpArrow, KeyCode_Invalid, Command_Began, NodeListerPrevItem },
|
|
||||||
{ KeyCode_Enter, KeyCode_Invalid, Command_Began, SelectAndCloseNodeLister },
|
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, CloseNodeLister },
|
|
||||||
{ KeyCode_Esc, KeyCode_Invalid, Command_Began, CloseNodeLister },
|
|
||||||
DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY,
|
|
||||||
};
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
|
|
||||||
{
|
|
||||||
operation_mode* AddNodeOperation = ActivateOperationModeWithCommands(&State->Modes, UniverseViewCommads);
|
|
||||||
|
|
||||||
AddNodeOperation->Render = RenderNodeLister;
|
|
||||||
|
|
||||||
node_lister_operation_state* OpState = CreateOperationState(AddNodeOperation,
|
|
||||||
&State->Modes,
|
|
||||||
node_lister_operation_state);
|
|
||||||
{
|
|
||||||
OpState->SearchLister.SourceListCount = NodeSpecificationsCount;
|
|
||||||
OpState->SearchLister.SourceList = PushArray(&State->Modes.Arena, string, OpState->SearchLister.SourceListCount);
|
|
||||||
{
|
|
||||||
for (s32 i = 0; i < OpState->SearchLister.SourceListCount; i++)
|
|
||||||
{
|
|
||||||
OpState->SearchLister.SourceList[i] = MakeString(
|
|
||||||
NodeSpecifications[i].Name,
|
|
||||||
NodeSpecifications[i].NameLength);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
OpState->SearchLister.Filter = MakeString(PushArray(&State->Modes.Arena, char, 64), 0, 64);
|
|
||||||
|
|
||||||
OpState->SearchLister.FilteredListMax = OpState->SearchLister.SourceListCount;
|
|
||||||
OpState->SearchLister.FilteredListCount = 0;
|
|
||||||
OpState->SearchLister.FilteredIndexLUT = PushArray(&State->Modes.Arena, s32, OpState->SearchLister.SourceListCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
OpState->ListPosition = Mouse.Pos;
|
|
||||||
SetTextInputDestinationToString(&State->ActiveTextEntry, &OpState->SearchLister.Filter);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Node Color Picker
|
|
||||||
//
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
struct color_picker_operation_state
|
|
||||||
{
|
|
||||||
v4* ValueAddr;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
CloseColorPicker(app_state* State)
|
|
||||||
{
|
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(CloseColorPickerCommand)
|
|
||||||
{
|
|
||||||
CloseColorPicker(State);
|
|
||||||
}
|
|
||||||
|
|
||||||
OPERATION_RENDER_PROC(RenderColorPicker)
|
|
||||||
{
|
|
||||||
color_picker_operation_state* OpState = (color_picker_operation_state*)Operation.OpStateMemory;
|
|
||||||
|
|
||||||
|
|
||||||
b32 ShouldClose = EvaluateColorPicker(RenderBuffer, OpState->ValueAddr,
|
|
||||||
v2{200, 200}, State->Interface, Mouse);
|
|
||||||
|
|
||||||
if (ShouldClose)
|
|
||||||
{
|
|
||||||
CloseColorPicker(State);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input_command ColorPickerCommands [] = {
|
|
||||||
{ KeyCode_Esc, KeyCode_Invalid, Command_Began, CloseColorPickerCommand },
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
OpenColorPicker(app_state* State, node_connection* Connection)
|
|
||||||
{
|
|
||||||
operation_mode* ColorPickerMode = ActivateOperationModeWithCommands(&State->Modes, ColorPickerCommands);
|
|
||||||
ColorPickerMode->Render = RenderColorPicker;
|
|
||||||
|
|
||||||
color_picker_operation_state* OpState = CreateOperationState(ColorPickerMode,
|
|
||||||
&State->Modes,
|
|
||||||
color_picker_operation_state);
|
|
||||||
OpState->ValueAddr = Connection->V4ValuePtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Node Field Text Edit
|
|
||||||
//
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(EndNodeFieldTextEdit)
|
|
||||||
{
|
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
|
||||||
}
|
|
||||||
|
|
||||||
input_command NodeFieldTextEditCommands [] = {
|
|
||||||
{ KeyCode_Enter, KeyCode_Invalid, Command_Began, EndNodeFieldTextEdit },
|
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, EndNodeFieldTextEdit },
|
|
||||||
DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY,
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
BeginNodeFieldTextEdit(app_state* State, node_connection* Connection)
|
|
||||||
{
|
|
||||||
operation_mode* NodeFieldTextEditMode = ActivateOperationModeWithCommands(&State->Modes,
|
|
||||||
NodeFieldTextEditCommands);
|
|
||||||
|
|
||||||
SetTextInputDestinationToFloat(&State->ActiveTextEntry, Connection->R32ValuePtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Node Port Mouse Drag
|
|
||||||
//
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
struct drag_node_port_operation_state
|
|
||||||
{
|
|
||||||
node_interaction Interaction;
|
|
||||||
};
|
|
||||||
|
|
||||||
OPERATION_RENDER_PROC(RenderDraggingNodePort)
|
|
||||||
{
|
|
||||||
drag_node_port_operation_state* OpState = (drag_node_port_operation_state*)Operation.OpStateMemory;
|
|
||||||
UpdateDraggingNodePort(Mouse.Pos, OpState->Interaction, State->NodeList,
|
|
||||||
State->NodeRenderSettings, RenderBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(EndDraggingNodePort)
|
|
||||||
{
|
|
||||||
drag_node_port_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_port_operation_state);
|
|
||||||
|
|
||||||
TryConnectNodes(OpState->Interaction, Mouse.Pos, State->NodeList, State->NodeRenderSettings);
|
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
|
||||||
}
|
|
||||||
|
|
||||||
input_command DragNodePortInputCommands[] = {
|
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDraggingNodePort },
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
BeginDraggingNodePort(app_state* State, node_interaction Interaction)
|
|
||||||
{
|
|
||||||
operation_mode* DragNodePortMode = ActivateOperationModeWithCommands(
|
|
||||||
&State->Modes,
|
|
||||||
DragNodePortInputCommands);
|
|
||||||
DragNodePortMode->Render = RenderDraggingNodePort;
|
|
||||||
|
|
||||||
drag_node_port_operation_state* OpState = CreateOperationState(DragNodePortMode,
|
|
||||||
&State->Modes,
|
|
||||||
drag_node_port_operation_state);
|
|
||||||
OpState->Interaction = Interaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Node Field Mouse Drag
|
|
||||||
//
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
OPERATION_RENDER_PROC(RenderDragNodeField)
|
|
||||||
{
|
|
||||||
// TODO(Peter):
|
|
||||||
//UpdateDraggingNodeValue(Mouse.Pos, Mouse.OldPos, OpState->Interaction, State->NodeList, State->NodeRenderSettings, State);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
BeginInteractWithNodeField(app_state* State, node_interaction Interaction)
|
|
||||||
{
|
|
||||||
// TODO(Peter):
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Node Mouse Drag
|
|
||||||
//
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
struct drag_node_operation_state
|
|
||||||
{
|
|
||||||
node_interaction Interaction;
|
|
||||||
};
|
|
||||||
|
|
||||||
OPERATION_RENDER_PROC(RenderDraggingNode)
|
|
||||||
{
|
|
||||||
drag_node_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_operation_state);
|
|
||||||
UpdateDraggingNode(Mouse.Pos, OpState->Interaction, State->NodeList,
|
|
||||||
State->NodeRenderSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(EndDraggingNode)
|
|
||||||
{
|
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
|
||||||
}
|
|
||||||
|
|
||||||
input_command DragNodeInputCommands[] = {
|
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDraggingNode },
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
BeginDraggingNode(app_state* State, node_interaction Interaction)
|
|
||||||
{
|
|
||||||
operation_mode* DragNodeMode = ActivateOperationModeWithCommands(
|
|
||||||
&State->Modes,
|
|
||||||
DragNodeInputCommands);
|
|
||||||
DragNodeMode->Render = RenderDraggingNode;
|
|
||||||
|
|
||||||
drag_node_operation_state* OpState = CreateOperationState(DragNodeMode,
|
|
||||||
&State->Modes,
|
|
||||||
drag_node_operation_state);
|
|
||||||
OpState->Interaction = Interaction;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Node View
|
|
||||||
//
|
|
||||||
///////////////////////////////////////
|
|
||||||
|
|
||||||
struct node_view_operation_state
|
|
||||||
{
|
|
||||||
s32 SelectedNodeHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseDragInteraction)
|
|
||||||
{
|
|
||||||
node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state);
|
|
||||||
|
|
||||||
node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.DownPos, State->NodeRenderSettings);
|
|
||||||
if (Node)
|
|
||||||
{
|
|
||||||
node_interaction NewInteraction = GetNodeInteractionType(Node,
|
|
||||||
Mouse.Pos,
|
|
||||||
State->NodeRenderSettings);
|
|
||||||
if (IsDraggingNodePort(NewInteraction))
|
|
||||||
{
|
|
||||||
BeginDraggingNodePort(State, NewInteraction);
|
|
||||||
}
|
|
||||||
else if(IsDraggingNodeValue(NewInteraction))
|
|
||||||
{
|
|
||||||
// TODO(Peter): This probably wants to live in a mouse held action
|
|
||||||
// the first frame we realize we're held over a field, just transition to
|
|
||||||
// drag node field
|
|
||||||
//BeginInteractWithNodeField(State, NewInteraction, State->NodeRenderSettings);
|
|
||||||
}
|
|
||||||
else // IsDraggingNode
|
|
||||||
{
|
|
||||||
OpState->SelectedNodeHandle = Node->Handle;
|
|
||||||
BeginDraggingNode(State, NewInteraction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
OpState->SelectedNodeHandle = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseSelectInteraction)
|
|
||||||
{
|
|
||||||
node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state);
|
|
||||||
|
|
||||||
node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.Pos, State->NodeRenderSettings);
|
|
||||||
if (Node)
|
|
||||||
{
|
|
||||||
node_interaction NewInteraction = GetNodeInteractionType(Node,
|
|
||||||
Mouse.Pos,
|
|
||||||
State->NodeRenderSettings);
|
|
||||||
if(IsDraggingNodeValue(NewInteraction))
|
|
||||||
{
|
|
||||||
node_connection* Connection = Node->Connections + NewInteraction.InputValue;
|
|
||||||
struct_member_type InputType = Connection->Type;
|
|
||||||
|
|
||||||
if (InputType == MemberType_r32)
|
|
||||||
{
|
|
||||||
BeginNodeFieldTextEdit(State, Connection);
|
|
||||||
}
|
|
||||||
else if (InputType == MemberType_v4)
|
|
||||||
{
|
|
||||||
OpenColorPicker(State, Connection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OPERATION_RENDER_PROC(RenderNodeView)
|
|
||||||
{
|
|
||||||
node_view_operation_state* OpState = (node_view_operation_state*)Operation.OpStateMemory;
|
|
||||||
|
|
||||||
DEBUG_TRACK_FUNCTION;
|
|
||||||
|
|
||||||
MakeStringBuffer(NodeHeaderBuffer, 128);
|
|
||||||
|
|
||||||
node_header* SelectedNode = GetNodeWithHandle(State->NodeList, OpState->SelectedNodeHandle);
|
|
||||||
|
|
||||||
node_list_iterator NodeIter = GetNodeListIterator(*State->NodeList);
|
|
||||||
while (NodeIteratorIsValid(NodeIter))
|
|
||||||
{
|
|
||||||
node_header* Node = NodeIter.At;
|
|
||||||
|
|
||||||
rect NodeBounds = CalculateNodeBounds(Node, State->NodeRenderSettings);
|
|
||||||
b32 DrawFields = PointIsInRect(Mouse.Pos, NodeBounds);
|
|
||||||
|
|
||||||
if (Node == SelectedNode)
|
|
||||||
{
|
|
||||||
PushRenderQuad2D(RenderBuffer, NodeBounds.Min - v2{2, 2}, NodeBounds.Max + v2{2, 2}, WhiteV4);
|
|
||||||
}
|
|
||||||
|
|
||||||
PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.5f, .5f, .5f, 1.f});
|
|
||||||
|
|
||||||
// TODO(Peter): This is just for debug purposes. We can remove and go back to just having
|
|
||||||
// Node->Name in DrawString
|
|
||||||
string NodeName = GetNodeName(*Node);
|
|
||||||
PrintF(&NodeHeaderBuffer, "%.*s: %d", NodeName.Length, NodeName.Memory, Node->Handle);
|
|
||||||
DrawString(RenderBuffer, NodeHeaderBuffer, State->NodeRenderSettings.Font,
|
|
||||||
v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (State->NodeRenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)},
|
|
||||||
WhiteV4);
|
|
||||||
|
|
||||||
for (s32 Connection = 0; Connection < Node->ConnectionsCount; Connection++)
|
|
||||||
{
|
|
||||||
v4 PortColor = State->NodeRenderSettings.PortColors[Node->Connections[Connection].Type];
|
|
||||||
|
|
||||||
// Inputs
|
|
||||||
if (ConnectionIsInput(Node, Connection))
|
|
||||||
{
|
|
||||||
rect PortBounds = CalculateNodeInputPortBounds(Node, Connection, State->NodeRenderSettings);
|
|
||||||
DrawPort(RenderBuffer, PortBounds, PortColor);
|
|
||||||
|
|
||||||
//
|
|
||||||
// TODO(Peter): I don't like excluding OutputNode, feels too much like a special case
|
|
||||||
// but I don't want to get in to the meta programming right now.
|
|
||||||
// We should just generate a spec and struct member types for NodeType_OutputNode
|
|
||||||
//
|
|
||||||
// :ExcludingOutputNodeSpecialCase
|
|
||||||
//
|
|
||||||
if (Node->Type != NodeType_OutputNode && DrawFields)
|
|
||||||
{
|
|
||||||
node_specification Spec = NodeSpecifications[Node->Type];
|
|
||||||
node_struct_member Member = Spec.MemberList[Connection];
|
|
||||||
DrawString(RenderBuffer, MakeString(Member.Name),
|
|
||||||
State->NodeRenderSettings.Font,
|
|
||||||
v2{PortBounds.Min.x - 8, PortBounds.Min.y}, WhiteV4, Align_Right);
|
|
||||||
}
|
|
||||||
|
|
||||||
rect ValueBounds = CalculateNodeInputValueBounds(Node, Connection, State->NodeRenderSettings);
|
|
||||||
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
|
|
||||||
|
|
||||||
// NOTE(Peter): its way easier to draw the connection on the input port b/c its a 1:1 relationship,
|
|
||||||
// whereas output ports might have many connections, they really only know about the most recent one
|
|
||||||
// Not sure if this is a problem. We mostly do everything backwards here, starting at the
|
|
||||||
// most downstream node and working back up to find dependencies.
|
|
||||||
if (ConnectionHasUpstreamConnection(Node, Connection))
|
|
||||||
{
|
|
||||||
rect ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, State->NodeList, State->NodeRenderSettings);
|
|
||||||
v2 InputCenter = CalculateRectCenter(PortBounds);
|
|
||||||
v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds);
|
|
||||||
PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Outputs
|
|
||||||
if (ConnectionIsOutput(Node, Connection))
|
|
||||||
{
|
|
||||||
rect PortBounds = CalculateNodeOutputPortBounds(Node, Connection, State->NodeRenderSettings);
|
|
||||||
DrawPort(RenderBuffer, PortBounds, PortColor);
|
|
||||||
|
|
||||||
if (DrawFields)
|
|
||||||
{
|
|
||||||
node_specification Spec = NodeSpecifications[Node->Type];
|
|
||||||
node_struct_member Member = Spec.MemberList[Connection];
|
|
||||||
DrawString(RenderBuffer, MakeString(Member.Name),
|
|
||||||
State->NodeRenderSettings.Font,
|
|
||||||
v2{PortBounds.Max.x + 8, PortBounds.Min.y}, WhiteV4);
|
|
||||||
}
|
|
||||||
|
|
||||||
rect ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, State->NodeRenderSettings);
|
|
||||||
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (s32 Button = 0; Button < 3; Button++)
|
|
||||||
{
|
|
||||||
rect ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, State->NodeRenderSettings);
|
|
||||||
PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Next(&NodeIter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(NodeViewDeleteNode)
|
|
||||||
{
|
|
||||||
node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state);
|
|
||||||
if (OpState->SelectedNodeHandle > 0)
|
|
||||||
{
|
|
||||||
node_header* SelectedNode = GetNodeWithHandle(State->NodeList, OpState->SelectedNodeHandle);
|
|
||||||
FreeNodeOnList(State->NodeList, SelectedNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeView)
|
|
||||||
{
|
|
||||||
DeactivateCurrentOperationMode(&State->Modes);
|
|
||||||
}
|
|
||||||
|
|
||||||
input_command NodeViewCommands [] = {
|
|
||||||
{ KeyCode_Tab, KeyCode_Invalid, Command_Began, CloseNodeView},
|
|
||||||
{ KeyCode_A, KeyCode_Invalid, Command_Began, OpenNodeLister},
|
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, NodeViewBeginMouseDragInteraction},
|
|
||||||
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, NodeViewBeginMouseSelectInteraction},
|
|
||||||
{ KeyCode_X, KeyCode_Invalid, Command_Began, NodeViewDeleteNode},
|
|
||||||
};
|
|
||||||
|
|
||||||
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeView)
|
|
||||||
{
|
|
||||||
operation_mode* NodeViewMode = ActivateOperationModeWithCommands(&State->Modes, NodeViewCommands);
|
|
||||||
NodeViewMode->Render = RenderNodeView;
|
|
||||||
|
|
||||||
node_view_operation_state* OpState = CreateOperationState(NodeViewMode,
|
|
||||||
&State->Modes,
|
|
||||||
node_view_operation_state);
|
|
||||||
|
|
||||||
OpState->SelectedNodeHandle = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// 3D View Mouse Rotate
|
// 3D View Mouse Rotate
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
internal b32
|
||||||
|
NamePassesFilter (string Target, string Filter)
|
||||||
|
{
|
||||||
|
return (Filter.Length == 0 || StringContainsStringCaseInsensitive(Target, Filter));
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
FilterSearchLister (search_lister* SearchLister)
|
FilterSearchLister (search_lister* SearchLister)
|
||||||
{
|
{
|
||||||
|
@ -9,7 +15,7 @@ FilterSearchLister (search_lister* SearchLister)
|
||||||
for (s32 i = 0; i < SearchLister->SourceListCount; i++)
|
for (s32 i = 0; i < SearchLister->SourceListCount; i++)
|
||||||
{
|
{
|
||||||
string* NameString = SearchLister->SourceList + i;
|
string* NameString = SearchLister->SourceList + i;
|
||||||
if (SpecificationPassesFilter(*NameString, SearchLister->Filter))
|
if (NamePassesFilter(*NameString, SearchLister->Filter))
|
||||||
{
|
{
|
||||||
SearchLister->FilteredIndexLUT[SearchLister->FilteredListCount++] = i;
|
SearchLister->FilteredIndexLUT[SearchLister->FilteredListCount++] = i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,498 @@
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Node Lister
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
struct node_lister_operation_state
|
||||||
|
{
|
||||||
|
search_lister SearchLister;
|
||||||
|
v2 ListPosition;
|
||||||
|
};
|
||||||
|
|
||||||
|
OPERATION_RENDER_PROC(RenderNodeLister)
|
||||||
|
{
|
||||||
|
node_lister_operation_state* OpState = (node_lister_operation_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
|
v2 TopLeft = OpState->ListPosition;
|
||||||
|
v2 Dimension = v2{300, 30};
|
||||||
|
|
||||||
|
// Filter the lister
|
||||||
|
OpState->SearchLister.Filter = State->ActiveTextEntry.Buffer;
|
||||||
|
FilterSearchLister(&OpState->SearchLister);
|
||||||
|
|
||||||
|
// Display Search Lister
|
||||||
|
search_lister_result NodeListerResult = EvaluateSearchLister (RenderBuffer, TopLeft, Dimension,
|
||||||
|
MakeStringLiteral("Nodes List"),
|
||||||
|
OpState->SearchLister.SourceList,
|
||||||
|
OpState->SearchLister.FilteredIndexLUT,
|
||||||
|
OpState->SearchLister.FilteredListCount,
|
||||||
|
OpState->SearchLister.HotItem,
|
||||||
|
&State->ActiveTextEntry.Buffer,
|
||||||
|
State->ActiveTextEntry.CursorPosition,
|
||||||
|
State->Font, State->Interface, Mouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerNextItem)
|
||||||
|
{
|
||||||
|
node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state);
|
||||||
|
OpState->SearchLister.HotItem = GetNextFilteredItem(OpState->SearchLister);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(NodeListerPrevItem)
|
||||||
|
{
|
||||||
|
node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state);
|
||||||
|
OpState->SearchLister.HotItem = GetPrevFilteredItem(OpState->SearchLister);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeLister)
|
||||||
|
{
|
||||||
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(SelectAndCloseNodeLister)
|
||||||
|
{
|
||||||
|
node_lister_operation_state* OpState = GetCurrentOperationState(State->Modes, node_lister_operation_state);
|
||||||
|
s32 FilteredNodeIndex = OpState->SearchLister.HotItem;
|
||||||
|
if (FilteredNodeIndex >= 0)
|
||||||
|
{
|
||||||
|
s32 NodeIndex = OpState->SearchLister.FilteredIndexLUT[FilteredNodeIndex];
|
||||||
|
PushNodeOnListFromSpecification(State->NodeList, (node_type)NodeIndex,
|
||||||
|
Mouse.Pos, State->Permanent);
|
||||||
|
}
|
||||||
|
CloseNodeLister(State, Event, Mouse);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_command UniverseViewCommads [] = {
|
||||||
|
{ KeyCode_DownArrow, KeyCode_Invalid, Command_Began, NodeListerNextItem },
|
||||||
|
{ KeyCode_UpArrow, KeyCode_Invalid, Command_Began, NodeListerPrevItem },
|
||||||
|
{ KeyCode_Enter, KeyCode_Invalid, Command_Began, SelectAndCloseNodeLister },
|
||||||
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, CloseNodeLister },
|
||||||
|
{ KeyCode_Esc, KeyCode_Invalid, Command_Began, CloseNodeLister },
|
||||||
|
DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY,
|
||||||
|
};
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeLister)
|
||||||
|
{
|
||||||
|
operation_mode* AddNodeOperation = ActivateOperationModeWithCommands(&State->Modes, UniverseViewCommads);
|
||||||
|
|
||||||
|
AddNodeOperation->Render = RenderNodeLister;
|
||||||
|
|
||||||
|
node_lister_operation_state* OpState = CreateOperationState(AddNodeOperation,
|
||||||
|
&State->Modes,
|
||||||
|
node_lister_operation_state);
|
||||||
|
{
|
||||||
|
OpState->SearchLister.SourceListCount = NodeSpecificationsCount;
|
||||||
|
OpState->SearchLister.SourceList = PushArray(&State->Modes.Arena, string, OpState->SearchLister.SourceListCount);
|
||||||
|
{
|
||||||
|
for (s32 i = 0; i < OpState->SearchLister.SourceListCount; i++)
|
||||||
|
{
|
||||||
|
OpState->SearchLister.SourceList[i] = MakeString(
|
||||||
|
NodeSpecifications[i].Name,
|
||||||
|
NodeSpecifications[i].NameLength);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OpState->SearchLister.Filter = MakeString(PushArray(&State->Modes.Arena, char, 64), 0, 64);
|
||||||
|
|
||||||
|
OpState->SearchLister.FilteredListMax = OpState->SearchLister.SourceListCount;
|
||||||
|
OpState->SearchLister.FilteredListCount = 0;
|
||||||
|
OpState->SearchLister.FilteredIndexLUT = PushArray(&State->Modes.Arena, s32, OpState->SearchLister.SourceListCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
OpState->ListPosition = Mouse.Pos;
|
||||||
|
SetTextInputDestinationToString(&State->ActiveTextEntry, &OpState->SearchLister.Filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Node Color Picker
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
struct color_picker_operation_state
|
||||||
|
{
|
||||||
|
v4* ValueAddr;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
CloseColorPicker(app_state* State)
|
||||||
|
{
|
||||||
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(CloseColorPickerCommand)
|
||||||
|
{
|
||||||
|
CloseColorPicker(State);
|
||||||
|
}
|
||||||
|
|
||||||
|
OPERATION_RENDER_PROC(RenderColorPicker)
|
||||||
|
{
|
||||||
|
color_picker_operation_state* OpState = (color_picker_operation_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
|
|
||||||
|
b32 ShouldClose = EvaluateColorPicker(RenderBuffer, OpState->ValueAddr,
|
||||||
|
v2{200, 200}, State->Interface, Mouse);
|
||||||
|
|
||||||
|
if (ShouldClose)
|
||||||
|
{
|
||||||
|
CloseColorPicker(State);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input_command ColorPickerCommands [] = {
|
||||||
|
{ KeyCode_Esc, KeyCode_Invalid, Command_Began, CloseColorPickerCommand },
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
OpenColorPicker(app_state* State, node_connection* Connection)
|
||||||
|
{
|
||||||
|
operation_mode* ColorPickerMode = ActivateOperationModeWithCommands(&State->Modes, ColorPickerCommands);
|
||||||
|
ColorPickerMode->Render = RenderColorPicker;
|
||||||
|
|
||||||
|
color_picker_operation_state* OpState = CreateOperationState(ColorPickerMode,
|
||||||
|
&State->Modes,
|
||||||
|
color_picker_operation_state);
|
||||||
|
OpState->ValueAddr = Connection->V4ValuePtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Node Field Text Edit
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(EndNodeFieldTextEdit)
|
||||||
|
{
|
||||||
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_command NodeFieldTextEditCommands [] = {
|
||||||
|
{ KeyCode_Enter, KeyCode_Invalid, Command_Began, EndNodeFieldTextEdit },
|
||||||
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, EndNodeFieldTextEdit },
|
||||||
|
DEFAULT_TEXT_ENTRY_INPUT_COMMANDS_ARRAY_ENTRY,
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BeginNodeFieldTextEdit(app_state* State, node_connection* Connection)
|
||||||
|
{
|
||||||
|
operation_mode* NodeFieldTextEditMode = ActivateOperationModeWithCommands(&State->Modes,
|
||||||
|
NodeFieldTextEditCommands);
|
||||||
|
|
||||||
|
SetTextInputDestinationToFloat(&State->ActiveTextEntry, Connection->R32ValuePtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Node Port Mouse Drag
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
struct drag_node_port_operation_state
|
||||||
|
{
|
||||||
|
node_interaction Interaction;
|
||||||
|
};
|
||||||
|
|
||||||
|
OPERATION_RENDER_PROC(RenderDraggingNodePort)
|
||||||
|
{
|
||||||
|
drag_node_port_operation_state* OpState = (drag_node_port_operation_state*)Operation.OpStateMemory;
|
||||||
|
UpdateDraggingNodePort(Mouse.Pos, OpState->Interaction, State->NodeList,
|
||||||
|
State->NodeRenderSettings, RenderBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(EndDraggingNodePort)
|
||||||
|
{
|
||||||
|
drag_node_port_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_port_operation_state);
|
||||||
|
|
||||||
|
TryConnectNodes(OpState->Interaction, Mouse.Pos, State->NodeList, State->NodeRenderSettings);
|
||||||
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_command DragNodePortInputCommands[] = {
|
||||||
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDraggingNodePort },
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BeginDraggingNodePort(app_state* State, node_interaction Interaction)
|
||||||
|
{
|
||||||
|
operation_mode* DragNodePortMode = ActivateOperationModeWithCommands(
|
||||||
|
&State->Modes,
|
||||||
|
DragNodePortInputCommands);
|
||||||
|
DragNodePortMode->Render = RenderDraggingNodePort;
|
||||||
|
|
||||||
|
drag_node_port_operation_state* OpState = CreateOperationState(DragNodePortMode,
|
||||||
|
&State->Modes,
|
||||||
|
drag_node_port_operation_state);
|
||||||
|
OpState->Interaction = Interaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Node Field Mouse Drag
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
OPERATION_RENDER_PROC(RenderDragNodeField)
|
||||||
|
{
|
||||||
|
// TODO(Peter):
|
||||||
|
//UpdateDraggingNodeValue(Mouse.Pos, Mouse.OldPos, OpState->Interaction, State->NodeList, State->NodeRenderSettings, State);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BeginInteractWithNodeField(app_state* State, node_interaction Interaction)
|
||||||
|
{
|
||||||
|
// TODO(Peter):
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Node Mouse Drag
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
struct drag_node_operation_state
|
||||||
|
{
|
||||||
|
node_interaction Interaction;
|
||||||
|
};
|
||||||
|
|
||||||
|
OPERATION_RENDER_PROC(RenderDraggingNode)
|
||||||
|
{
|
||||||
|
drag_node_operation_state* OpState = GetCurrentOperationState(State->Modes, drag_node_operation_state);
|
||||||
|
UpdateDraggingNode(Mouse.Pos, OpState->Interaction, State->NodeList,
|
||||||
|
State->NodeRenderSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(EndDraggingNode)
|
||||||
|
{
|
||||||
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_command DragNodeInputCommands[] = {
|
||||||
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, EndDraggingNode },
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
BeginDraggingNode(app_state* State, node_interaction Interaction)
|
||||||
|
{
|
||||||
|
operation_mode* DragNodeMode = ActivateOperationModeWithCommands(
|
||||||
|
&State->Modes,
|
||||||
|
DragNodeInputCommands);
|
||||||
|
DragNodeMode->Render = RenderDraggingNode;
|
||||||
|
|
||||||
|
drag_node_operation_state* OpState = CreateOperationState(DragNodeMode,
|
||||||
|
&State->Modes,
|
||||||
|
drag_node_operation_state);
|
||||||
|
OpState->Interaction = Interaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Node View
|
||||||
|
//
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
struct node_view_operation_state
|
||||||
|
{
|
||||||
|
s32 SelectedNodeHandle;
|
||||||
|
};
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseDragInteraction)
|
||||||
|
{
|
||||||
|
node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state);
|
||||||
|
|
||||||
|
node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.DownPos, State->NodeRenderSettings);
|
||||||
|
if (Node)
|
||||||
|
{
|
||||||
|
node_interaction NewInteraction = GetNodeInteractionType(Node,
|
||||||
|
Mouse.Pos,
|
||||||
|
State->NodeRenderSettings);
|
||||||
|
if (IsDraggingNodePort(NewInteraction))
|
||||||
|
{
|
||||||
|
BeginDraggingNodePort(State, NewInteraction);
|
||||||
|
}
|
||||||
|
else if(IsDraggingNodeValue(NewInteraction))
|
||||||
|
{
|
||||||
|
// TODO(Peter): This probably wants to live in a mouse held action
|
||||||
|
// the first frame we realize we're held over a field, just transition to
|
||||||
|
// drag node field
|
||||||
|
//BeginInteractWithNodeField(State, NewInteraction, State->NodeRenderSettings);
|
||||||
|
}
|
||||||
|
else // IsDraggingNode
|
||||||
|
{
|
||||||
|
OpState->SelectedNodeHandle = Node->Handle;
|
||||||
|
BeginDraggingNode(State, NewInteraction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OpState->SelectedNodeHandle = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(NodeViewBeginMouseSelectInteraction)
|
||||||
|
{
|
||||||
|
node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state);
|
||||||
|
|
||||||
|
node_header* Node = GetNodeUnderPoint(State->NodeList, Mouse.Pos, State->NodeRenderSettings);
|
||||||
|
if (Node)
|
||||||
|
{
|
||||||
|
node_interaction NewInteraction = GetNodeInteractionType(Node,
|
||||||
|
Mouse.Pos,
|
||||||
|
State->NodeRenderSettings);
|
||||||
|
if(IsDraggingNodeValue(NewInteraction))
|
||||||
|
{
|
||||||
|
node_connection* Connection = Node->Connections + NewInteraction.InputValue;
|
||||||
|
struct_member_type InputType = Connection->Type;
|
||||||
|
|
||||||
|
if (InputType == MemberType_r32)
|
||||||
|
{
|
||||||
|
BeginNodeFieldTextEdit(State, Connection);
|
||||||
|
}
|
||||||
|
else if (InputType == MemberType_v4)
|
||||||
|
{
|
||||||
|
OpenColorPicker(State, Connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OPERATION_RENDER_PROC(RenderNodeView)
|
||||||
|
{
|
||||||
|
node_view_operation_state* OpState = (node_view_operation_state*)Operation.OpStateMemory;
|
||||||
|
|
||||||
|
DEBUG_TRACK_FUNCTION;
|
||||||
|
|
||||||
|
MakeStringBuffer(NodeHeaderBuffer, 128);
|
||||||
|
|
||||||
|
node_header* SelectedNode = GetNodeWithHandle(State->NodeList, OpState->SelectedNodeHandle);
|
||||||
|
|
||||||
|
node_list_iterator NodeIter = GetNodeListIterator(*State->NodeList);
|
||||||
|
while (NodeIteratorIsValid(NodeIter))
|
||||||
|
{
|
||||||
|
node_header* Node = NodeIter.At;
|
||||||
|
|
||||||
|
rect NodeBounds = CalculateNodeBounds(Node, State->NodeRenderSettings);
|
||||||
|
b32 DrawFields = PointIsInRect(Mouse.Pos, NodeBounds);
|
||||||
|
|
||||||
|
if (Node == SelectedNode)
|
||||||
|
{
|
||||||
|
PushRenderQuad2D(RenderBuffer, NodeBounds.Min - v2{2, 2}, NodeBounds.Max + v2{2, 2}, WhiteV4);
|
||||||
|
}
|
||||||
|
|
||||||
|
PushRenderQuad2D(RenderBuffer, NodeBounds.Min, NodeBounds.Max, v4{.5f, .5f, .5f, 1.f});
|
||||||
|
|
||||||
|
// TODO(Peter): This is just for debug purposes. We can remove and go back to just having
|
||||||
|
// Node->Name in DrawString
|
||||||
|
string NodeName = GetNodeName(*Node);
|
||||||
|
PrintF(&NodeHeaderBuffer, "%.*s: %d", NodeName.Length, NodeName.Memory, Node->Handle);
|
||||||
|
DrawString(RenderBuffer, NodeHeaderBuffer, State->NodeRenderSettings.Font,
|
||||||
|
v2{NodeBounds.Min.x + 5, NodeBounds.Max.y - (State->NodeRenderSettings.Font->PixelHeight + NODE_HEADER_HEIGHT + 5)},
|
||||||
|
WhiteV4);
|
||||||
|
|
||||||
|
for (s32 Connection = 0; Connection < Node->ConnectionsCount; Connection++)
|
||||||
|
{
|
||||||
|
v4 PortColor = State->NodeRenderSettings.PortColors[Node->Connections[Connection].Type];
|
||||||
|
|
||||||
|
// Inputs
|
||||||
|
if (ConnectionIsInput(Node, Connection))
|
||||||
|
{
|
||||||
|
rect PortBounds = CalculateNodeInputPortBounds(Node, Connection, State->NodeRenderSettings);
|
||||||
|
DrawPort(RenderBuffer, PortBounds, PortColor);
|
||||||
|
|
||||||
|
//
|
||||||
|
// TODO(Peter): I don't like excluding OutputNode, feels too much like a special case
|
||||||
|
// but I don't want to get in to the meta programming right now.
|
||||||
|
// We should just generate a spec and struct member types for NodeType_OutputNode
|
||||||
|
//
|
||||||
|
// :ExcludingOutputNodeSpecialCase
|
||||||
|
//
|
||||||
|
if (Node->Type != NodeType_OutputNode && DrawFields)
|
||||||
|
{
|
||||||
|
node_specification Spec = NodeSpecifications[Node->Type];
|
||||||
|
node_struct_member Member = Spec.MemberList[Connection];
|
||||||
|
DrawString(RenderBuffer, MakeString(Member.Name),
|
||||||
|
State->NodeRenderSettings.Font,
|
||||||
|
v2{PortBounds.Min.x - 8, PortBounds.Min.y}, WhiteV4, Align_Right);
|
||||||
|
}
|
||||||
|
|
||||||
|
rect ValueBounds = CalculateNodeInputValueBounds(Node, Connection, State->NodeRenderSettings);
|
||||||
|
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
|
||||||
|
|
||||||
|
// NOTE(Peter): its way easier to draw the connection on the input port b/c its a 1:1 relationship,
|
||||||
|
// whereas output ports might have many connections, they really only know about the most recent one
|
||||||
|
// Not sure if this is a problem. We mostly do everything backwards here, starting at the
|
||||||
|
// most downstream node and working back up to find dependencies.
|
||||||
|
if (ConnectionHasUpstreamConnection(Node, Connection))
|
||||||
|
{
|
||||||
|
rect ConnectedPortBounds = GetBoundsOfPortConnectedToInput(Node, Connection, State->NodeList, State->NodeRenderSettings);
|
||||||
|
v2 InputCenter = CalculateRectCenter(PortBounds);
|
||||||
|
v2 OutputCenter = CalculateRectCenter(ConnectedPortBounds);
|
||||||
|
PushRenderLine2D(RenderBuffer, OutputCenter, InputCenter, 1, WhiteV4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputs
|
||||||
|
if (ConnectionIsOutput(Node, Connection))
|
||||||
|
{
|
||||||
|
rect PortBounds = CalculateNodeOutputPortBounds(Node, Connection, State->NodeRenderSettings);
|
||||||
|
DrawPort(RenderBuffer, PortBounds, PortColor);
|
||||||
|
|
||||||
|
if (DrawFields)
|
||||||
|
{
|
||||||
|
node_specification Spec = NodeSpecifications[Node->Type];
|
||||||
|
node_struct_member Member = Spec.MemberList[Connection];
|
||||||
|
DrawString(RenderBuffer, MakeString(Member.Name),
|
||||||
|
State->NodeRenderSettings.Font,
|
||||||
|
v2{PortBounds.Max.x + 8, PortBounds.Min.y}, WhiteV4);
|
||||||
|
}
|
||||||
|
|
||||||
|
rect ValueBounds = CalculateNodeOutputValueBounds(Node, Connection, State->NodeRenderSettings);
|
||||||
|
DrawValueDisplay(RenderBuffer, ValueBounds, Node->Connections[Connection], State->NodeRenderSettings.Font);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (s32 Button = 0; Button < 3; Button++)
|
||||||
|
{
|
||||||
|
rect ButtonRect = CalculateNodeDragHandleBounds(NodeBounds, Button, State->NodeRenderSettings);
|
||||||
|
PushRenderQuad2D(RenderBuffer, ButtonRect.Min, ButtonRect.Max, DragButtonColors[Button]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Next(&NodeIter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(NodeViewDeleteNode)
|
||||||
|
{
|
||||||
|
node_view_operation_state* OpState = GetCurrentOperationState(State->Modes, node_view_operation_state);
|
||||||
|
if (OpState->SelectedNodeHandle > 0)
|
||||||
|
{
|
||||||
|
node_header* SelectedNode = GetNodeWithHandle(State->NodeList, OpState->SelectedNodeHandle);
|
||||||
|
FreeNodeOnList(State->NodeList, SelectedNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(CloseNodeView)
|
||||||
|
{
|
||||||
|
DeactivateCurrentOperationMode(&State->Modes);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_command NodeViewCommands [] = {
|
||||||
|
{ KeyCode_Tab, KeyCode_Invalid, Command_Began, CloseNodeView},
|
||||||
|
{ KeyCode_A, KeyCode_Invalid, Command_Began, OpenNodeLister},
|
||||||
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Began, NodeViewBeginMouseDragInteraction},
|
||||||
|
{ KeyCode_MouseLeftButton, KeyCode_Invalid, Command_Ended, NodeViewBeginMouseSelectInteraction},
|
||||||
|
{ KeyCode_X, KeyCode_Invalid, Command_Began, NodeViewDeleteNode},
|
||||||
|
};
|
||||||
|
|
||||||
|
FOLDHAUS_INPUT_COMMAND_PROC(OpenNodeView)
|
||||||
|
{
|
||||||
|
operation_mode* NodeViewMode = ActivateOperationModeWithCommands(&State->Modes, NodeViewCommands);
|
||||||
|
NodeViewMode->Render = RenderNodeView;
|
||||||
|
|
||||||
|
node_view_operation_state* OpState = CreateOperationState(NodeViewMode,
|
||||||
|
&State->Modes,
|
||||||
|
node_view_operation_state);
|
||||||
|
|
||||||
|
OpState->SelectedNodeHandle = 0;
|
||||||
|
}
|
Loading…
Reference in New Issue