void SBehaviorTreeBlackboardEditor::Construct(const FArguments& InArgs, TSharedRef<FUICommandList> InCommandList, UBlackboardData* InBlackboardData) { OnEntrySelected = InArgs._OnEntrySelected; OnGetDebugKeyValue = InArgs._OnGetDebugKeyValue; OnIsDebuggerReady = InArgs._OnIsDebuggerReady; OnIsDebuggerPaused = InArgs._OnIsDebuggerPaused; OnGetDebugTimeStamp = InArgs._OnGetDebugTimeStamp; OnGetDisplayCurrentState = InArgs._OnGetDisplayCurrentState; OnIsBlackboardModeActive = InArgs._OnIsBlackboardModeActive; TSharedRef<FUICommandList> CommandList = MakeShareable(new FUICommandList); CommandList->MapAction( FBTBlackboardCommands::Get().DeleteEntry, FExecuteAction::CreateSP(this, &SBehaviorTreeBlackboardEditor::HandleDeleteEntry), FCanExecuteAction::CreateSP(this, &SBehaviorTreeBlackboardEditor::CanDeleteEntry) ); CommandList->MapAction( FGenericCommands::Get().Rename, FExecuteAction::CreateSP(this, &SBehaviorTreeBlackboardEditor::HandleRenameEntry), FCanExecuteAction::CreateSP(this, &SBehaviorTreeBlackboardEditor::CanRenameEntry) ); InCommandList->Append(CommandList); SBehaviorTreeBlackboardView::Construct( SBehaviorTreeBlackboardView::FArguments() .OnEntrySelected(InArgs._OnEntrySelected) .OnGetDebugKeyValue(InArgs._OnGetDebugKeyValue) .OnGetDisplayCurrentState(InArgs._OnGetDisplayCurrentState) .OnIsDebuggerReady(InArgs._OnIsDebuggerReady) .OnIsDebuggerPaused(InArgs._OnIsDebuggerPaused) .OnGetDebugTimeStamp(InArgs._OnGetDebugTimeStamp) .OnBlackboardKeyChanged(InArgs._OnBlackboardKeyChanged) .IsReadOnly(false), CommandList, InBlackboardData ); }
void FCPPRichTextSyntaxHighlighterTextLayoutMarshaller::ParseTokens(const FString& SourceString, FTextLayout& TargetTextLayout, TArray<FSyntaxTokenizer::FTokenizedLine> TokenizedLines) { enum class EParseState : uint8 { None, LookingForString, LookingForCharacter, LookingForSingleLineComment, LookingForMultiLineComment, }; // Parse the tokens, generating the styled runs for each line EParseState ParseState = EParseState::None; for(const FSyntaxTokenizer::FTokenizedLine& TokenizedLine : TokenizedLines) { TSharedRef<FString> ModelString = MakeShareable(new FString()); TArray< TSharedRef< IRun > > Runs; if(ParseState == EParseState::LookingForSingleLineComment) { ParseState = EParseState::None; } for(const FSyntaxTokenizer::FToken& Token : TokenizedLine.Tokens) { const FString TokenText = SourceString.Mid(Token.Range.BeginIndex, Token.Range.Len()); const FTextRange ModelRange(ModelString->Len(), ModelString->Len() + TokenText.Len()); ModelString->Append(TokenText); FRunInfo RunInfo(TEXT("SyntaxHighlight.CPP.Normal")); FTextBlockStyle TextBlockStyle = SyntaxTextStyle.NormalTextStyle; const bool bIsWhitespace = FString(TokenText).TrimTrailing().IsEmpty(); if(!bIsWhitespace) { bool bHasMatchedSyntax = false; if(Token.Type == FSyntaxTokenizer::ETokenType::Syntax) { if(ParseState == EParseState::None && TokenText == TEXT("\"")) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.String"); TextBlockStyle = SyntaxTextStyle.StringTextStyle; ParseState = EParseState::LookingForString; bHasMatchedSyntax = true; } else if(ParseState == EParseState::LookingForString && TokenText == TEXT("\"")) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Normal"); TextBlockStyle = SyntaxTextStyle.StringTextStyle; ParseState = EParseState::None; } else if(ParseState == EParseState::None && TokenText == TEXT("\'")) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.String"); TextBlockStyle = SyntaxTextStyle.StringTextStyle; ParseState = EParseState::LookingForCharacter; bHasMatchedSyntax = true; } else if(ParseState == EParseState::LookingForCharacter && TokenText == TEXT("\'")) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Normal"); TextBlockStyle = SyntaxTextStyle.StringTextStyle; ParseState = EParseState::None; } else if(ParseState == EParseState::None && TokenText.StartsWith(TEXT("#"))) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.PreProcessorKeyword"); TextBlockStyle = SyntaxTextStyle.PreProcessorKeywordTextStyle; ParseState = EParseState::None; } else if(ParseState == EParseState::None && TokenText == TEXT("//")) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Comment"); TextBlockStyle = SyntaxTextStyle.CommentTextStyle; ParseState = EParseState::LookingForSingleLineComment; } else if(ParseState == EParseState::None && TokenText == TEXT("/*")) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Comment"); TextBlockStyle = SyntaxTextStyle.CommentTextStyle; ParseState = EParseState::LookingForMultiLineComment; } else if(ParseState == EParseState::LookingForMultiLineComment && TokenText == TEXT("*/")) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Comment"); TextBlockStyle = SyntaxTextStyle.CommentTextStyle; ParseState = EParseState::None; } else if(ParseState == EParseState::None && TChar<WIDECHAR>::IsAlpha(TokenText[0])) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Keyword"); TextBlockStyle = SyntaxTextStyle.KeywordTextStyle; ParseState = EParseState::None; } else if(ParseState == EParseState::None && !TChar<WIDECHAR>::IsAlpha(TokenText[0])) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Operator"); TextBlockStyle = SyntaxTextStyle.OperatorTextStyle; ParseState = EParseState::None; } } // It's possible that we fail to match a syntax token if we're in a state where it isn't parsed // In this case, we treat it as a literal token if(Token.Type == FSyntaxTokenizer::ETokenType::Literal || !bHasMatchedSyntax) { if(ParseState == EParseState::LookingForString) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.String"); TextBlockStyle = SyntaxTextStyle.StringTextStyle; } else if(ParseState == EParseState::LookingForCharacter) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.String"); TextBlockStyle = SyntaxTextStyle.StringTextStyle; } else if(ParseState == EParseState::LookingForSingleLineComment) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Comment"); TextBlockStyle = SyntaxTextStyle.CommentTextStyle; } else if(ParseState == EParseState::LookingForMultiLineComment) { RunInfo.Name = TEXT("SyntaxHighlight.CPP.Comment"); TextBlockStyle = SyntaxTextStyle.CommentTextStyle; } } TSharedRef< ISlateRun > Run = FSlateTextRun::Create(RunInfo, ModelString, TextBlockStyle, ModelRange); Runs.Add(Run); } else { RunInfo.Name = TEXT("SyntaxHighlight.CPP.WhiteSpace"); TSharedRef< ISlateRun > Run = FWhiteSpaceTextRun::Create(RunInfo, ModelString, TextBlockStyle, ModelRange, 4); Runs.Add(Run); } } TargetTextLayout.AddLine(ModelString, Runs); } }
void FRichTextSyntaxHighlighterTextLayoutMarshaller::ParseTokens(const FString& SourceString, FTextLayout& TargetTextLayout, TArray<FSyntaxTokenizer::FTokenizedLine> TokenizedLines) { enum class EParseState : uint8 { LookingForNode, LookingForNodeName, LookingForNodeAttributeKey, LookingForNodeAttribueValueBegin, LookingForNodeAttribueValueBody, }; // Parse the tokens, generating the styled runs for each line EParseState ParseState = EParseState::LookingForNode; for(const FSyntaxTokenizer::FTokenizedLine& TokenizedLine : TokenizedLines) { TSharedRef<FString> ModelString = MakeShareable(new FString()); TArray< TSharedRef< IRun > > Runs; for(const FSyntaxTokenizer::FToken& Token : TokenizedLine.Tokens) { const FString TokenText = SourceString.Mid(Token.Range.BeginIndex, Token.Range.Len()); const FTextRange ModelRange(ModelString->Len(), ModelString->Len() + TokenText.Len()); ModelString->Append(TokenText); FRunInfo RunInfo(TEXT("SyntaxHighlight.Normal")); FTextBlockStyle TextBlockStyle = SyntaxTextStyle.NormalTextStyle; const bool bIsWhitespace = FString(TokenText).TrimTrailing().IsEmpty(); if(!bIsWhitespace) { bool bHasMatchedSyntax = false; if(Token.Type == FSyntaxTokenizer::ETokenType::Syntax) { if(ParseState == EParseState::LookingForNode && TokenText == TEXT("<")) { RunInfo.Name = TEXT("SyntaxHighlight.Node"); TextBlockStyle = SyntaxTextStyle.NodeTextStyle; ParseState = EParseState::LookingForNodeName; bHasMatchedSyntax = true; } else if(ParseState == EParseState::LookingForNodeAttributeKey && TokenText == TEXT(">")) { RunInfo.Name = TEXT("SyntaxHighlight.Node"); TextBlockStyle = SyntaxTextStyle.NodeTextStyle; ParseState = EParseState::LookingForNode; } else if(ParseState == EParseState::LookingForNode && TokenText == TEXT("</>")) { RunInfo.Name = TEXT("SyntaxHighlight.Node"); TextBlockStyle = SyntaxTextStyle.NodeTextStyle; // No state change bHasMatchedSyntax = true; } else if(ParseState == EParseState::LookingForNodeAttributeKey && TokenText == TEXT("=")) { RunInfo.Name = TEXT("SyntaxHighlight.NodeAttribueAssignment"); TextBlockStyle = SyntaxTextStyle.NodeAttribueAssignmentTextStyle; ParseState = EParseState::LookingForNodeAttribueValueBegin; bHasMatchedSyntax = true; } else if(ParseState == EParseState::LookingForNodeAttribueValueBegin && TokenText == TEXT("\"")) { RunInfo.Name = TEXT("SyntaxHighlight.NodeAttributeValue"); TextBlockStyle = SyntaxTextStyle.NodeAttributeValueTextStyle; ParseState = EParseState::LookingForNodeAttribueValueBody; bHasMatchedSyntax = true; } else if(ParseState == EParseState::LookingForNodeAttribueValueBody && TokenText == TEXT("\"")) { RunInfo.Name = TEXT("SyntaxHighlight.NodeAttributeValue"); TextBlockStyle = SyntaxTextStyle.NodeAttributeValueTextStyle; ParseState = EParseState::LookingForNodeAttributeKey; bHasMatchedSyntax = true; } } // It's possible that we fail to match a syntax token if we're in a state where it isn't parsed // In this case, we treat it as a literal token if(Token.Type == FSyntaxTokenizer::ETokenType::Literal || !bHasMatchedSyntax) { if(ParseState == EParseState::LookingForNodeName) { RunInfo.Name = TEXT("SyntaxHighlight.Node"); TextBlockStyle = SyntaxTextStyle.NodeTextStyle; ParseState = EParseState::LookingForNodeAttributeKey; } else if(ParseState == EParseState::LookingForNodeAttributeKey) { RunInfo.Name = TEXT("SyntaxHighlight.NodeAttributeKey"); TextBlockStyle = SyntaxTextStyle.NodeAttributeKeyTextStyle; // No state change, a key can be multiple tokens - consume until we find an equals } else if(ParseState == EParseState::LookingForNodeAttribueValueBody) { RunInfo.Name = TEXT("SyntaxHighlight.NodeAttributeValue"); TextBlockStyle = SyntaxTextStyle.NodeAttributeValueTextStyle; // No state change, a value can be multiple tokens - consume until we find a closing quote } } } TSharedRef< ISlateRun > Run = FSlateTextRun::Create(RunInfo, ModelString, TextBlockStyle, ModelRange); Runs.Add(Run); } TargetTextLayout.AddLine(ModelString, Runs); } }