Halfway through with repair of right-click menus
This commit is contained in:
26
Plugins/UEWingman/Deprecated/OldSearchNodeSpawners.cpp
Normal file
26
Plugins/UEWingman/Deprecated/OldSearchNodeSpawners.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// This code was extracted from git commit 0e79b02^ (the commit before it was
|
||||
// replaced with GetGraphContextActions). Original file was:
|
||||
// Plugins/BlueprintMCP/Source/BlueprintMCP/Private/MCPUtils.cpp
|
||||
//
|
||||
// It uses FBlueprintActionDatabase to search for spawnable node types,
|
||||
// which is the correct approach for Blueprint (K2) graphs.
|
||||
|
||||
#include "BlueprintActionDatabase.h"
|
||||
#include "BlueprintNodeSpawner.h"
|
||||
|
||||
FString MCPUtils::NodeSpawnerFullName(UBlueprintNodeSpawner* Spawner)
|
||||
{
|
||||
const FBlueprintActionUiSpec& UiSpec = Spawner->PrimeDefaultUiSpec();
|
||||
FString Category = UiSpec.Category.ToString();
|
||||
FString MenuName = UiSpec.MenuName.ToString();
|
||||
if (Category.IsEmpty())
|
||||
{
|
||||
return MenuName;
|
||||
}
|
||||
return Category + TEXT("|") + MenuName;
|
||||
}
|
||||
|
||||
TArray<UBlueprintNodeSpawner*> MCPUtils::SearchNodeSpawners(const FString& Query, int32 MaxResults, bool ExactMatch, UEdGraph* GraphFilter)
|
||||
{
|
||||
return Result;
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "WingFetcher.h"
|
||||
#include "WingJson.h"
|
||||
#include "WingUtils.h"
|
||||
#include "WingGraphActions.h"
|
||||
#include "EdGraph/EdGraph.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
#include "EdGraph/EdGraphSchema.h"
|
||||
@@ -66,26 +67,25 @@ public:
|
||||
continue;
|
||||
|
||||
// Find the action by exact full name
|
||||
TArray<TSharedPtr<FEdGraphSchemaAction>> Matches = WingUtils::SearchGraphActions(TargetGraph, Entry.ActionName, 2, /*ExactMatch=*/true);
|
||||
if (Matches.Num() == 0)
|
||||
FWingGraphActions GA(TargetGraph, Entry.ActionName, 2, /*ExactMatch=*/true);
|
||||
if (GA.Count() == 0)
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: No action found matching '%s'. Use GraphNodeSearchTypes to find available actions.\n"),
|
||||
*Entry.ActionName);
|
||||
continue;
|
||||
}
|
||||
if (Matches.Num() > 1)
|
||||
if (GA.Count() > 1)
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: Ambiguous: %d actions match '%s'.\n"),
|
||||
Matches.Num(), *Entry.ActionName);
|
||||
GA.Count(), *Entry.ActionName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Perform the action
|
||||
FVector2D Location(Entry.PosX, Entry.PosY);
|
||||
UEdGraphNode* NewNode = Matches[0]->PerformAction(TargetGraph, nullptr, Location, /*bSelectNewNode=*/false);
|
||||
UEdGraphNode* NewNode = GA.Execute(0, Entry.PosX, Entry.PosY);
|
||||
if (!NewNode)
|
||||
{
|
||||
UWingServer::Printf(TEXT("ERROR: PerformAction returned null for '%s'.\n"), *Entry.ActionName);
|
||||
UWingServer::Printf(TEXT("ERROR: Execute returned null for '%s'.\n"), *Entry.ActionName);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "WingHandler.h"
|
||||
#include "WingFetcher.h"
|
||||
#include "WingUtils.h"
|
||||
#include "WingGraphActions.h"
|
||||
#include "EdGraph/EdGraph.h"
|
||||
#include "EdGraph/EdGraphSchema.h"
|
||||
#include "GraphNode_SearchTypes.generated.h"
|
||||
@@ -44,18 +45,18 @@ public:
|
||||
UEdGraph* TargetGraph = F.Walk(Graph).Cast<UEdGraph>();
|
||||
if (!TargetGraph) return;
|
||||
|
||||
TArray<TSharedPtr<FEdGraphSchemaAction>> Actions = WingUtils::SearchGraphActions(TargetGraph, Query, ClampedMax, /*ExactMatch=*/false);
|
||||
FWingGraphActions GA(TargetGraph, Query, ClampedMax, /*ExactMatch=*/false);
|
||||
|
||||
for (const TSharedPtr<FEdGraphSchemaAction>& Action : Actions)
|
||||
for (int32 i = 0; i < GA.Count(); i++)
|
||||
{
|
||||
UWingServer::Printf(TEXT("%s\n"), *WingUtils::ActionFullName(Action));
|
||||
UWingServer::Printf(TEXT("%s\n"), *GA.GetFullName(i));
|
||||
}
|
||||
|
||||
if (Actions.Num() == 0)
|
||||
if (GA.Count() == 0)
|
||||
{
|
||||
UWingServer::Print(TEXT("No matching node types found.\n"));
|
||||
}
|
||||
else if (Actions.Num() >= ClampedMax)
|
||||
else if (GA.Count() >= ClampedMax)
|
||||
{
|
||||
UWingServer::Printf(TEXT("WARNING: Reached limit of %d results. Refine your query or increase MaxResults.\n"), ClampedMax);
|
||||
}
|
||||
|
||||
138
Plugins/UEWingman/Source/UEWingman/Private/WingGraphActions.cpp
Normal file
138
Plugins/UEWingman/Source/UEWingman/Private/WingGraphActions.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
#include "WingGraphActions.h"
|
||||
#include "EdGraph/EdGraphSchema.h"
|
||||
#include "BlueprintActionDatabase.h"
|
||||
#include "BlueprintNodeSpawner.h"
|
||||
#include "EdGraphSchema_K2.h"
|
||||
#include "Kismet2/BlueprintEditorUtils.h"
|
||||
|
||||
FString FWingGraphActions::GetFullName(const FEdGraphSchemaAction& Action)
|
||||
{
|
||||
FString Category = Action.GetCategory().ToString();
|
||||
FString MenuName = Action.GetMenuDescription().ToString();
|
||||
return Category + TEXT("|") + MenuName;
|
||||
}
|
||||
|
||||
FString FWingGraphActions::GetFullName(const UBlueprintNodeSpawner* Spawner)
|
||||
{
|
||||
const FBlueprintActionUiSpec& UiSpec = Spawner->PrimeDefaultUiSpec();
|
||||
FString Category = UiSpec.Category.ToString();
|
||||
FString MenuName = UiSpec.MenuName.ToString();
|
||||
return Category + TEXT("|") + MenuName;
|
||||
}
|
||||
|
||||
bool FWingGraphActions::IsMatch(const FEdGraphSchemaAction& Action, const FString &QueryLower, bool Exact)
|
||||
{
|
||||
FString FullName = GetFullName(Action).ToLower();
|
||||
if (FullName.Len() < 3) return false;
|
||||
if (FullName == QueryLower) return true;
|
||||
if (Exact) return false;
|
||||
if (FullName.Contains(QueryLower)) return true;
|
||||
FString Keywords = Action.GetKeywords().ToString();
|
||||
if (Keywords.ToLower().Contains(QueryLower)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FWingGraphActions::IsMatch(const UBlueprintNodeSpawner* Spawner, const FString &QueryLower, bool Exact)
|
||||
{
|
||||
FString FullName = GetFullName(Spawner).ToLower();
|
||||
if (FullName.Len() < 3) return false;
|
||||
if (FullName == QueryLower) return true;
|
||||
if (Exact) return false;
|
||||
if (FullName.Contains(QueryLower)) return true;
|
||||
FString Keywords = Spawner->PrimeDefaultUiSpec().Keywords.ToString();
|
||||
if (Keywords.ToLower().Contains(QueryLower)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
UEdGraphNode* FWingGraphActions::Execute(FEdGraphSchemaAction& Action, int32 X, int32 Y)
|
||||
{
|
||||
FVector2D Location(X, Y);
|
||||
UEdGraphNode* NewNode = Action.PerformAction(Graph, nullptr, Location, /*bSelectNewNode=*/false);
|
||||
return NewNode;
|
||||
}
|
||||
|
||||
UEdGraphNode* FWingGraphActions::Execute(UBlueprintNodeSpawner* Spawner, int32 X, int32 Y)
|
||||
{
|
||||
FVector2D Location(X, Y);
|
||||
IBlueprintNodeBinder::FBindingSet Bindings;
|
||||
return Spawner->Invoke(Graph, Bindings, Location);
|
||||
}
|
||||
|
||||
void FWingGraphActions::CollectActions(UEdGraph* GraphP, const FString& Query, int32 MaxResults, bool ExactMatch)
|
||||
{
|
||||
Graph = GraphP;
|
||||
FString QueryLower = Query.ToLower();
|
||||
FGraphContextMenuBuilder ContextMenuBuilder(Graph);
|
||||
Graph->GetSchema()->GetGraphContextActions(ContextMenuBuilder);
|
||||
|
||||
for (int32 i = 0; i < ContextMenuBuilder.GetNumActions(); i++)
|
||||
{
|
||||
if ((MaxResults > 0) && (Actions.Num() >= MaxResults)) break;
|
||||
TSharedPtr<FEdGraphSchemaAction> Action = ContextMenuBuilder.GetSchemaAction(i);
|
||||
if (IsMatch(*Action, QueryLower, ExactMatch)) Actions.Add(Action);
|
||||
}
|
||||
}
|
||||
|
||||
void FWingGraphActions::CollectSpawners(UEdGraph* GraphP, const FString& Query, int32 MaxResults, bool ExactMatch)
|
||||
{
|
||||
Graph = GraphP;
|
||||
FString QueryLower = Query.ToLower();
|
||||
|
||||
for (const auto& Pair : FBlueprintActionDatabase::Get().GetAllActions())
|
||||
{
|
||||
for (UBlueprintNodeSpawner* Spawner : Pair.Value)
|
||||
{
|
||||
if ((MaxResults > 0) && (Spawners.Num() >= MaxResults)) break;
|
||||
|
||||
if (!Spawner) continue;
|
||||
|
||||
// Filter by graph compatibility if a graph was provided
|
||||
if (Spawner->NodeClass)
|
||||
{
|
||||
UEdGraphNode* NodeCDO = CastChecked<UEdGraphNode>(Spawner->NodeClass->ClassDefaultObject);
|
||||
if (!NodeCDO->IsCompatibleWithGraph(Graph))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsMatch(Spawner, QueryLower, ExactMatch)) Spawners.Add(Spawner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FString FWingGraphActions::GetFullName(int N)
|
||||
{
|
||||
if (N < Actions.Num())
|
||||
{
|
||||
return GetFullName(*Actions[N]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return GetFullName(Spawners[N - Actions.Num()]);
|
||||
}
|
||||
}
|
||||
|
||||
UEdGraphNode* FWingGraphActions::Execute(int32 N, int32 PosX, int32 PosY)
|
||||
{
|
||||
if (N < Actions.Num())
|
||||
{
|
||||
return Execute(*Actions[N], PosX, PosY);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Execute(Spawners[N - Actions.Num()], PosX, PosY);
|
||||
}
|
||||
}
|
||||
|
||||
FWingGraphActions::FWingGraphActions(UEdGraph *Graph, const FString& Query, int32 MaxResults, bool ExactMatch)
|
||||
{
|
||||
if (Cast<UEdGraphSchema_K2>(Graph->GetSchema()))
|
||||
{
|
||||
CollectSpawners(Graph, Query, MaxResults, ExactMatch);
|
||||
}
|
||||
else
|
||||
{
|
||||
CollectActions(Graph, Query, MaxResults, ExactMatch);
|
||||
}
|
||||
}
|
||||
@@ -471,55 +471,6 @@ UAnimStateTransitionNode* WingUtils::FindTransition(UAnimationStateMachineGraph*
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Graph actions (node spawning)
|
||||
// ============================================================
|
||||
|
||||
FString WingUtils::ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action)
|
||||
{
|
||||
FString Category = Action->GetCategory().ToString();
|
||||
FString MenuName = Action->GetMenuDescription().ToString();
|
||||
if (Category.IsEmpty())
|
||||
return MenuName;
|
||||
return Category + TEXT("|") + MenuName;
|
||||
}
|
||||
|
||||
TArray<TSharedPtr<FEdGraphSchemaAction>> WingUtils::SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults, bool ExactMatch)
|
||||
{
|
||||
FString QueryLower = Query.ToLower();
|
||||
TArray<TSharedPtr<FEdGraphSchemaAction>> Result;
|
||||
|
||||
FGraphContextMenuBuilder ContextMenuBuilder(Graph);
|
||||
Graph->GetSchema()->GetGraphContextActions(ContextMenuBuilder);
|
||||
|
||||
for (int32 i = 0; i < ContextMenuBuilder.GetNumActions(); i++)
|
||||
{
|
||||
TSharedPtr<FEdGraphSchemaAction> Action = ContextMenuBuilder.GetSchemaAction(i);
|
||||
if (!Action.IsValid()) continue;
|
||||
|
||||
FString FullName = ActionFullName(Action);
|
||||
if (FullName.IsEmpty()) continue;
|
||||
|
||||
if (ExactMatch)
|
||||
{
|
||||
if (FullName.ToLower() != QueryLower)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
FString Keywords = Action->GetKeywords().ToString();
|
||||
if (!FullName.ToLower().Contains(QueryLower) && !Keywords.ToLower().Contains(QueryLower))
|
||||
continue;
|
||||
}
|
||||
|
||||
Result.Add(Action);
|
||||
if ((MaxResults > 0) && (Result.Num() >= MaxResults))
|
||||
break;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Support for locating UE Wingman Handlers
|
||||
// ============================================================
|
||||
|
||||
51
Plugins/UEWingman/Source/UEWingman/Public/WingGraphActions.h
Normal file
51
Plugins/UEWingman/Source/UEWingman/Public/WingGraphActions.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "EdGraph/EdGraph.h"
|
||||
|
||||
class UBlueprintNodeSpawner;
|
||||
struct FEdGraphSchemaAction;
|
||||
|
||||
// Holds a collection of graph actions, populated from either the
|
||||
// BlueprintActionDatabase (for K2 graphs) or GetGraphContextActions
|
||||
// (for everything else).
|
||||
struct FWingGraphActions
|
||||
{
|
||||
public:
|
||||
// Constructor populates the list of actions.
|
||||
FWingGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults = 0, bool ExactMatch=false);
|
||||
|
||||
// Get the number of results.
|
||||
int Count() const { return Spawners.Num() + Actions.Num(); }
|
||||
|
||||
// Get the name of the nth result.
|
||||
FString GetFullName(int32 N);
|
||||
|
||||
// Execute the nth result, which should create a graph node.
|
||||
// If it can't, it will print an error and return nullptr.
|
||||
UEdGraphNode *Execute(int32 N, int32 PosX, int32 PosY);
|
||||
|
||||
private:
|
||||
// The Graph that we're generating Actions for.
|
||||
UEdGraph *Graph;
|
||||
|
||||
// One of these two will be populated, depending on graph type.
|
||||
TArray<TSharedPtr<FEdGraphSchemaAction>> Actions;
|
||||
TArray<UBlueprintNodeSpawner*> Spawners;
|
||||
|
||||
// Get the full name of an action.
|
||||
FString GetFullName(const FEdGraphSchemaAction& Action);
|
||||
FString GetFullName(const UBlueprintNodeSpawner* Spawner);
|
||||
|
||||
// Compare an action against a query.
|
||||
bool IsMatch(const FEdGraphSchemaAction& Action, const FString &QueryLower, bool Exact);
|
||||
bool IsMatch(const UBlueprintNodeSpawner* Spawner, const FString &QueryLower, bool Exact);
|
||||
|
||||
// Execute an action
|
||||
UEdGraphNode* Execute(FEdGraphSchemaAction& Action, int32 X, int32 Y);
|
||||
UEdGraphNode* Execute(UBlueprintNodeSpawner* Spawner, int32 X, int32 Y);
|
||||
|
||||
// Routines that collect actions and spawners.
|
||||
void CollectActions(UEdGraph* GraphP, const FString& Query, int32 MaxResults, bool ExactMatch);
|
||||
void CollectSpawners(UEdGraph* GraphP, const FString& Query, int32 MaxResults, bool ExactMatch);
|
||||
};
|
||||
@@ -230,10 +230,6 @@ public:
|
||||
static UAnimStateNode* FindStateByName(UAnimationStateMachineGraph* SMGraph, const FString& StateName);
|
||||
static UAnimStateTransitionNode* FindTransition(UAnimationStateMachineGraph* SMGraph, const FString& FromStateName, const FString& ToStateName);
|
||||
|
||||
// ----- Graph actions (node spawning) -----
|
||||
static FString ActionFullName(const TSharedPtr<FEdGraphSchemaAction>& Action);
|
||||
static TArray<TSharedPtr<FEdGraphSchemaAction>> SearchGraphActions(UEdGraph* Graph, const FString& Query, int32 MaxResults = 0, bool ExactMatch = false);
|
||||
|
||||
// ----- Text formatting -----
|
||||
static FString WrapText(const FString& Text, int32 ColLimit, const FString& Prefix);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user