void FSequencerTimeSliderController::SetViewRange( float NewRangeMin, float NewRangeMax, EViewRangeInterpolation Interpolation ) { TOptional<float> LocalClampMin = TimeSliderArgs.ClampMin.Get(); TOptional<float> LocalClampMax = TimeSliderArgs.ClampMax.Get(); // Clamp the range if clamp values are set if ( LocalClampMin.IsSet() && NewRangeMin < LocalClampMin.GetValue() ) { NewRangeMin = LocalClampMin.GetValue(); } if ( LocalClampMax.IsSet() && NewRangeMax > LocalClampMax.GetValue() ) { NewRangeMax = LocalClampMax.GetValue(); } const TRange<float> NewRange(NewRangeMin, NewRangeMax); TimeSliderArgs.OnViewRangeChanged.ExecuteIfBound( NewRange, Interpolation ); if( !TimeSliderArgs.ViewRange.IsBound() ) { // The output is not bound to a delegate so we'll manage the value ourselves (no animation) TimeSliderArgs.ViewRange.Set( NewRange ); } }
void FVisualLoggerTimeSliderController::HorizontalScrollBar_OnUserScrolled(float ScrollOffset) { if (!TimeSliderArgs.ViewRange.IsBound()) { TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); TOptional<float> LocalClampMin = TimeSliderArgs.ClampMin.Get(); TOptional<float> LocalClampMax = TimeSliderArgs.ClampMax.Get(); float InThumbSizeFraction = (LocalViewRangeMax - LocalViewRangeMin) / (LocalClampMax.GetValue() - LocalClampMin.GetValue()); float NewViewOutputMin = LocalClampMin.GetValue() + ScrollOffset * (LocalClampMax.GetValue() - LocalClampMin.GetValue()); // The output is not bound to a delegate so we'll manage the value ourselves float NewViewOutputMax = FMath::Min<float>(NewViewOutputMin + (LocalViewRangeMax - LocalViewRangeMin), LocalClampMax.GetValue()); NewViewOutputMin = NewViewOutputMax - (LocalViewRangeMax - LocalViewRangeMin); float InOffsetFraction = (NewViewOutputMin - LocalClampMin.GetValue()) / (LocalClampMax.GetValue() - LocalClampMin.GetValue()); //if (InOffsetFraction + InThumbSizeFraction <= 1) { TimeSliderArgs.ViewRange.Set(TRange<float>(NewViewOutputMin, NewViewOutputMax)); Scrollbar->SetState(InOffsetFraction, InThumbSizeFraction); } } }
/** Parse anything until we find an unescaped { */ TOptional<FExpressionError> ParseLiteral(FExpressionTokenConsumer& Consumer, bool bEmitErrors) { // Include a leading { character - if it was a valid argument token it would have been picked up by a previous token definition bool bFirstChar = true; TOptional<FStringToken> Token = Consumer.GetStream().ParseToken([&](TCHAR C){ if (C == '{' && !bFirstChar) { return EParseState::StopBefore; } else if (C == EscapeChar) { return EParseState::StopBefore; } else { bFirstChar = false; // Keep consuming return EParseState::Continue; } }); if (Token.IsSet()) { // Add the token to the consumer. This moves the read position in the stream to the end of the token. Consumer.Add(Token.GetValue(), FStringLiteral(Token.GetValue())); } return TOptional<FExpressionError>(); }
bool UBlendSpaceBase::IsValidAdditiveInternal(EAdditiveAnimationType AdditiveType) const { TOptional<bool> bIsAdditive; for (int32 I=0; I<SampleData.Num(); ++I) { const UAnimSequence* Animation = SampleData[I].Animation; // test animation to see if it matched additive type bool bAdditiveAnim = ( Animation && Animation->IsValidAdditive() && Animation->AdditiveAnimType == AdditiveType ); // if already has value, but it does not match if ( bIsAdditive.IsSet() ) { // it's inconsistent, we ignore this if (bIsAdditive.GetValue() != bAdditiveAnim) { return false; } } else { bIsAdditive = TOptional<bool>(bAdditiveAnim); } } return (bIsAdditive.IsSet() && bIsAdditive.GetValue()); }
void FWidgetNavigationCustomization::SetNav(UWidget* Widget, EUINavigation Nav, TOptional<EUINavigationRule> Rule, TOptional<FName> WidgetToFocus) { Widget->Modify(); UWidgetNavigation* WidgetNavigation = Widget->Navigation; if (!Widget->Navigation) { WidgetNavigation = NewObject<UWidgetNavigation>(Widget); } FWidgetNavigationData* DirectionNavigation = nullptr; switch ( Nav ) { case EUINavigation::Left: DirectionNavigation = &WidgetNavigation->Left; break; case EUINavigation::Right: DirectionNavigation = &WidgetNavigation->Right; break; case EUINavigation::Up: DirectionNavigation = &WidgetNavigation->Up; break; case EUINavigation::Down: DirectionNavigation = &WidgetNavigation->Down; break; case EUINavigation::Next: DirectionNavigation = &WidgetNavigation->Next; break; case EUINavigation::Previous: DirectionNavigation = &WidgetNavigation->Previous; break; default: // Should not be possible. check(false); return; } if ( Rule.IsSet() ) { DirectionNavigation->Rule = Rule.GetValue(); } if ( WidgetToFocus.IsSet() ) { DirectionNavigation->WidgetToFocus = WidgetToFocus.GetValue(); } if ( WidgetNavigation->IsDefault() ) { // If the navigation rules are all set to the defaults, remove the navigation // information from the widget. Widget->Navigation = nullptr; } else { Widget->Navigation = WidgetNavigation; } }
void FVisualLoggerTimeSliderController::SetTimeRange(float NewViewOutputMin, float NewViewOutputMax) { TimeSliderArgs.ViewRange.Set(TRange<float>(NewViewOutputMin, NewViewOutputMax)); TOptional<float> LocalClampMin = TimeSliderArgs.ClampMin.Get(); TOptional<float> LocalClampMax = TimeSliderArgs.ClampMax.Get(); const float InOffsetFraction = (NewViewOutputMin - LocalClampMin.GetValue()) / (LocalClampMax.GetValue() - LocalClampMin.GetValue()); const float InThumbSizeFraction = (NewViewOutputMax - NewViewOutputMin) / (LocalClampMax.GetValue() - LocalClampMin.GetValue()); Scrollbar->SetState(InOffsetFraction, InThumbSizeFraction); }
/** Consume a number from the specified consumer's stream, if one exists at the current read position */ TOptional<FExpressionError> ConsumeNumber(FExpressionTokenConsumer& Consumer) { auto& Stream = Consumer.GetStream(); TOptional<FStringToken> NumberToken = ExpressionParser::ParseNumber(Stream); if (NumberToken.IsSet()) { Consumer.Add(NumberToken.GetValue(), FExpressionNode(FTextToken(NumberToken.GetValue().GetString(), ETextFilterTextComparisonMode::Partial, FTextToken::EInvertResult::No))); } return TOptional<FExpressionError>(); }
void FCameraDetails::UpdateAspectTextFromProperty() { // Called whenever the actual aspect ratio property changes - clears the text box if the value no longer matches the current text TOptional<float> Value = GetAspectRatio(); if (!Value.IsSet() || Value.GetValue() < LastParsedAspectRatioValue - DELTA || Value.GetValue() > LastParsedAspectRatioValue + DELTA) { LastParsedAspectRatioValue = -1.0f; if (!AspectTextBox->GetText().IsEmpty()) { AspectTextBox->SetText(FText::GetEmpty()); } } }
bool LocalizationCommandletTasks::ImportTextForTargets(const TSharedRef<SWindow>& ParentWindow, const TArray<ULocalizationTarget*>& Targets, const TOptional<FString> DirectoryPath) { TArray<LocalizationCommandletExecution::FTask> Tasks; for (ULocalizationTarget* Target : Targets) { const bool ShouldUseProjectFile = !Target->IsMemberOfEngineTargetSet(); FFormatNamedArguments Arguments; Arguments.Add(TEXT("TargetName"), FText::FromString(Target->Settings.Name)); const FText ImportTaskName = FText::Format(LOCTEXT("ImportTaskNameFormat", "Import Translations for {TargetName}"), Arguments); const FString ImportScriptPath = LocalizationConfigurationScript::GetImportTextConfigPath(Target, TOptional<FString>()); const TOptional<FString> DirectoryPathForTarget = DirectoryPath.IsSet() ? DirectoryPath.GetValue() / Target->Settings.Name : TOptional<FString>(); LocalizationConfigurationScript::GenerateImportTextConfigFile(Target, TOptional<FString>(), DirectoryPathForTarget).Write(ImportScriptPath); Tasks.Add(LocalizationCommandletExecution::FTask(ImportTaskName, ImportScriptPath, ShouldUseProjectFile)); const FText ReportTaskName = FText::Format(LOCTEXT("ReportTaskNameFormat", "Generate Reports for {TargetName}"), Arguments); const FString ReportScriptPath = LocalizationConfigurationScript::GetWordCountReportConfigPath(Target); LocalizationConfigurationScript::GenerateWordCountReportConfigFile(Target).Write(ReportScriptPath); Tasks.Add(LocalizationCommandletExecution::FTask(ReportTaskName, ReportScriptPath, ShouldUseProjectFile)); } return LocalizationCommandletExecution::Execute(ParentWindow, LOCTEXT("ImportForAllTargetsWindowTitle", "Import Translations for All Targets"), Tasks); }
FCursorReply SWidget::OnCursorQuery( const FGeometry& MyGeometry, const FPointerEvent& CursorEvent ) const { TOptional<EMouseCursor::Type> TheCursor = Cursor.Get(); return ( TheCursor.IsSet() ) ? FCursorReply::Cursor( TheCursor.GetValue() ) : FCursorReply::Unhandled(); }
TOptional<FExpressionError> ParseEscapedChar(FExpressionTokenConsumer& Consumer) { FTokenStream& Stream = Consumer.GetStream(); TOptional<FStringToken> Token = Stream.ParseSymbol(EscapeChar); if (!Token.IsSet()) { return TOptional<FExpressionError>(); } FStringToken& TokenValue = Token.GetValue(); // Accumulate the next character into the token TOptional<FStringToken> EscapedChar = Consumer.GetStream().ParseSymbol(&TokenValue); if (!EscapedChar.IsSet()) { return TOptional<FExpressionError>(); } // Check for a valid escape character const TCHAR Character = *EscapedChar->GetTokenStartPos(); if (IsValidEscapeChar(Character)) { // Add the token to the consumer - this moves the read position in the stream to the end of the token. Consumer.Add(TokenValue, FEscapedCharacter(Character)); } return TOptional<FExpressionError>(); }
TOptional<FExpressionError> ParseLiteral(FExpressionTokenConsumer& Consumer) { FTokenStream& Stream = Consumer.GetStream(); TOptional<FStringToken> Token; { bool bFirstChar = true; Token = Stream.ParseToken([&](TCHAR C) { // Always include the first character, since if it was the start of a valid token then it would have been picked up by a higher priority token parser if (bFirstChar) { bFirstChar = false; return EParseState::Continue; } else if (!IsLiteralBreakChar(C)) { return EParseState::Continue; } else { return EParseState::StopBefore; } }); } if (Token.IsSet()) { // Add the token to the consumer - this moves the read position in the stream to the end of the token FStringToken& TokenValue = Token.GetValue(); Consumer.Add(TokenValue, FStringLiteral(TokenValue)); } return TOptional<FExpressionError>(); }
FReply FSequencerTimeSliderController::OnMouseWheel( TSharedRef<SWidget> WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if ( TimeSliderArgs.AllowZoom ) { const float ZoomDelta = -0.1f * MouseEvent.GetWheelDelta(); { TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); const float OutputViewSize = LocalViewRangeMax - LocalViewRangeMin; const float OutputChange = OutputViewSize * ZoomDelta; float NewViewOutputMin = LocalViewRangeMin - (OutputChange * 0.5f); float NewViewOutputMax = LocalViewRangeMax + (OutputChange * 0.5f); if( FMath::Abs( OutputChange ) > 0.01f && NewViewOutputMin < NewViewOutputMax ) { TOptional<float> LocalClampMin = TimeSliderArgs.ClampMin.Get(); TOptional<float> LocalClampMax = TimeSliderArgs.ClampMax.Get(); // Clamp the range if clamp values are set if ( LocalClampMin.IsSet() && NewViewOutputMin < LocalClampMin.GetValue() ) { NewViewOutputMin = LocalClampMin.GetValue(); } if ( LocalClampMax.IsSet() && NewViewOutputMax > LocalClampMax.GetValue() ) { NewViewOutputMax = LocalClampMax.GetValue(); } TimeSliderArgs.OnViewRangeChanged.ExecuteIfBound(TRange<float>(NewViewOutputMin, NewViewOutputMax)); if( !TimeSliderArgs.ViewRange.IsBound() ) { // The output is not bound to a delegate so we'll manage the value ourselves TimeSliderArgs.ViewRange.Set( TRange<float>( NewViewOutputMin, NewViewOutputMax ) ); } } } return FReply::Handled(); } return FReply::Unhandled(); }
TOptional<FVector4> FVectorPropertySection::GetPropertyValueAsVector4() const { if (ChannelsUsed == 2) { TOptional<FVector2D> Vector = GetPropertyValue<FVector2D>(); return Vector.IsSet() ? TOptional<FVector4>(FVector4(Vector.GetValue().X, Vector.GetValue().Y, 0, 0)) : TOptional<FVector4>(); } else if (ChannelsUsed == 3) { TOptional<FVector> Vector = GetPropertyValue<FVector>(); return Vector.IsSet() ? TOptional<FVector4>(FVector4(Vector.GetValue().X, Vector.GetValue().Y, Vector.GetValue().Z, 0)) : TOptional<FVector4>(); } else // ChannelsUsed == 4 { return GetPropertyValue<FVector4>(); } }
TOptional<FGuid> FActorReferencePropertySection::GetActorGuid() const { TOptional<AActor*> CurrentActor = GetPropertyValue<AActor*>(); if (CurrentActor.IsSet() && CurrentActor.GetValue() != nullptr) { return TOptional<FGuid>(GetSequencer()->GetFocusedMovieSceneSequenceInstance()->FindObjectId(*CurrentActor.GetValue())); } return TOptional<FGuid>(FGuid()); }
LexResultType Lex(const TCHAR* InExpression, const FTokenDefinitions& TokenDefinitions) { FExpressionTokenConsumer TokenConsumer(InExpression); TOptional<FExpressionError> Error = TokenDefinitions.ConsumeTokens(TokenConsumer); if (Error.IsSet()) { return MakeError(Error.GetValue()); } return MakeValue(TokenConsumer.Extract()); }
EPopupMethod QueryPopupMethod(const FWidgetPath& PathToQuery) { for (int32 WidgetIndex = PathToQuery.Widgets.Num() - 1; WidgetIndex >= 0; --WidgetIndex) { TOptional<EPopupMethod> PopupMethod = PathToQuery.Widgets[WidgetIndex].Widget->OnQueryPopupMethod(); if (PopupMethod.IsSet()) { return PopupMethod.GetValue(); } } return EPopupMethod::CreateNewWindow; }
/** Parse an escaped character */ TOptional<FExpressionError> ParseEscapedChar(FExpressionTokenConsumer& Consumer, bool bEmitErrors) { static const TCHAR* ValidEscapeChars = TEXT("{`"); TOptional<FStringToken> Token = Consumer.GetStream().ParseSymbol(EscapeChar); if (!Token.IsSet()) { return TOptional<FExpressionError>(); } // Accumulate the next character into the token TOptional<FStringToken> EscapedChar = Consumer.GetStream().ParseSymbol(&Token.GetValue()); if (!EscapedChar.IsSet()) { return TOptional<FExpressionError>(); } // Check for a valid escape character const TCHAR Character = *EscapedChar->GetTokenStartPos(); if (FCString::Strchr(ValidEscapeChars, Character)) { // Add the token to the consumer. This moves the read position in the stream to the end of the token. Consumer.Add(Token.GetValue(), FEscapedCharacter(Character)); return TOptional<FExpressionError>(); } else if (bEmitErrors) { FString CharStr; CharStr += Character; FFormatOrderedArguments Args; Args.Add(FText::FromString(CharStr)); return FExpressionError(FText::Format(LOCTEXT("InvalidEscapeCharacter", "Invalid escape character '{0}'"), Args)); } else { return TOptional<FExpressionError>(); } }
TOptional<FSequencerSnapField::FSnapResult> FSequencerSnapField::Snap(const TArray<float>& InTimes, float Threshold) const { TOptional<FSnapResult> ProspectiveSnap; float SnapDelta = 0.f; for (float Time : InTimes) { TOptional<float> ThisSnap = Snap(Time, Threshold); if (!ThisSnap.IsSet()) { continue; } float ThisSnapDelta = ThisSnap.GetValue() - Time; if (!ProspectiveSnap.IsSet() || FMath::Abs(ThisSnapDelta) < FMath::Abs(SnapDelta)) { ProspectiveSnap = FSnapResult{ Time, ThisSnap.GetValue() }; SnapDelta = ThisSnapDelta; } } return ProspectiveSnap; }
TOptional<FExpressionError> ConsumeOperator(FExpressionTokenConsumer& Consumer) { auto& Stream = Consumer.GetStream(); for (const TCHAR* Moniker : TSymbol::Monikers) { TOptional<FStringToken> OperatorToken = Stream.ParseToken(Moniker); if (OperatorToken.IsSet()) { Consumer.Add(OperatorToken.GetValue(), TSymbol()); } } return TOptional<FExpressionError>(); }
TOptional<FExpressionError> ParseArgument(FExpressionTokenConsumer& Consumer) { // An argument token looks like {ArgName} FTokenStream& Stream = Consumer.GetStream(); TOptional<FStringToken> OpeningChar = Stream.ParseSymbol(ArgStartChar); if (!OpeningChar.IsSet()) { return TOptional<FExpressionError>(); } FStringToken& EntireToken = OpeningChar.GetValue(); // Parse out the argument name TOptional<FStringToken> Identifier = Stream.ParseToken([](TCHAR InC) { if (InC == ArgEndChar) { return EParseState::StopBefore; } else { return EParseState::Continue; } }, &EntireToken); if (!Identifier.IsSet() || !Stream.ParseSymbol(ArgEndChar, &EntireToken).IsSet()) { return TOptional<FExpressionError>(); } // Add the token to the consumer - this moves the read position in the stream to the end of the token FStringToken& IdentifierValue = Identifier.GetValue(); Consumer.Add(EntireToken, FArgumentTokenSpecifier(IdentifierValue)); return TOptional<FExpressionError>(); }
/** Tick this state machine with the given time limit. Will continuously enumerate the machine until TimeLimit is reached */ void Tick(const FTimeLimit& TimeLimit) { while (!TimeLimit.Exceeded()) { const auto& State = Nodes[CurrentState]; TOptional<TState> NewState = State.Endpoint(TimeLimit); if (NewState.IsSet()) { CurrentState = NewState.GetValue(); } else if (State.Type == EStateMachineNode::CallOnce) { break; } } }
TOptional<FExpressionError> FTokenDefinitions::ConsumeToken(FExpressionTokenConsumer& Consumer) const { auto& Stream = Consumer.GetStream(); // Skip over whitespace if (bIgnoreWhitespace) { TOptional<FStringToken> Whitespace = Stream.ParseWhitespace(); if (Whitespace.IsSet()) { Stream.SetReadPos(Whitespace.GetValue()); } } if (Stream.IsEmpty()) { // Trailing whitespace in the expression. return TOptional<FExpressionError>(); } const auto* Pos = Stream.GetRead(); // Try each token in turn. First come first served. for (const auto& Def : Definitions) { // Call the token definition auto Error = Def(Consumer); if (Error.IsSet()) { return Error; } // If the stream has moved on, the definition added one or more tokens, so else if (Stream.GetRead() != Pos) { return TOptional<FExpressionError>(); } } // No token definition matched the stream at its current position - fatal error FFormatOrderedArguments Args; Args.Add(FText::FromString(Consumer.GetStream().GetErrorContext())); Args.Add(Consumer.GetStream().GetPosition()); return FExpressionError(FText::Format(LOCTEXT("LexicalError", "Unrecognized token '{0}' at character {1}"), Args)); }
FCursorReply FUMGDragDropOp::OnCursorQuery() { FCursorReply CursorReply = FGameDragDropOperation::OnCursorQuery(); if ( !CursorReply.IsEventHandled() ) { CursorReply = CursorReply.Cursor(EMouseCursor::Default); } if ( GameViewport ) { TOptional<TSharedRef<SWidget>> CursorWidget = GameViewport->MapCursor(nullptr, CursorReply); if ( CursorWidget.IsSet() ) { CursorReply.SetCursorWidget(GameViewport->GetWindow(), CursorWidget.GetValue()); } } return CursorReply; }
void UAssetImportData::Serialize(FArchive& Ar) { if (Ar.UE4Ver() >= VER_UE4_ASSET_IMPORT_DATA_AS_JSON) { FString Json; if (Ar.IsLoading()) { Ar << Json; TOptional<FAssetImportInfo> Copy = FromJson(MoveTemp(Json)); if (Copy.IsSet()) { CopyFrom(Copy.GetValue()); } } else if (Ar.IsSaving()) { Json = ToJson(); Ar << Json; } } Super::Serialize(Ar); }
TOptional<FKeyHandle> FGroupedKeyArea::DuplicateKey(FKeyHandle KeyToDuplicate) { FKeyGrouping* Group = FindGroup(KeyToDuplicate); if (!Group) { return TOptional<FKeyHandle>(); } const float Time = Group->RepresentativeTime; const int32 NewGroupIndex = Groups.Num(); Groups.Emplace(Time); for (const FKeyGrouping::FKeyIndex& Key : Group->Keys) { TOptional<FKeyHandle> NewKeyHandle = KeyAreas[Key.AreaIndex]->DuplicateKey(Key.KeyHandle); if (NewKeyHandle.IsSet()) { Groups[NewGroupIndex].Keys.Emplace(Key.AreaIndex, NewKeyHandle.GetValue()); } } // Update the global index with our new key FIndexEntry* IndexEntry = GlobalIndex.Find(IndexKey); if (IndexEntry) { FKeyHandle ThisGroupKeyHandle; IndexEntry->GroupHandles.Add(ThisGroupKeyHandle); IndexEntry->HandleToGroup.Add(ThisGroupKeyHandle, NewGroupIndex); IndexEntry->RepresentativeTimes.Add(Time); return ThisGroupKeyHandle; } return TOptional<FKeyHandle>(); }
TOptional<FExpressionError> ParseArgumentModifier(FExpressionTokenConsumer& Consumer) { // An argument modifier token looks like |keyword(args, ...) FTokenStream& Stream = Consumer.GetStream(); TOptional<FStringToken> PipeToken = Stream.ParseSymbol(ArgModChar); if (!PipeToken.IsSet()) { return TOptional<FExpressionError>(); } FStringToken& EntireToken = PipeToken.GetValue(); // Parse out the argument modifier name TOptional<FStringToken> Identifier = Stream.ParseToken([](TCHAR InC) { if (InC == '(') { return EParseState::StopBefore; } else if (FChar::IsIdentifier(InC)) { return EParseState::Continue; } else { return EParseState::Cancel; } }, &EntireToken); if (!Identifier.IsSet() || !Stream.ParseSymbol(TEXT('('), &EntireToken).IsSet()) { return TOptional<FExpressionError>(); } // Valid modifier name? FStringToken& IdentifierValue = Identifier.GetValue(); FTextFormatter::FCompileTextArgumentModifierFuncPtr CompileTextArgumentModifierFunc = FTextFormatter::Get().FindTextArgumentModifier(FTextFormatString::MakeReference(IdentifierValue.GetTokenStartPos(), IdentifierValue.GetTokenEndPos() - IdentifierValue.GetTokenStartPos())); if (!CompileTextArgumentModifierFunc) { return TOptional<FExpressionError>(); } // Parse out the argument modifier parameter text TOptional<FStringToken> Parameters; { TCHAR QuoteChar = 0; int32 NumConsecutiveSlashes = 0; Parameters = Stream.ParseToken([&](TCHAR InC) { if (InC == ')' && QuoteChar == 0) { return EParseState::StopBefore; } else if (InC == '"') { if (InC == QuoteChar) { if (NumConsecutiveSlashes%2 == 0) { QuoteChar = 0; } } else { QuoteChar = InC; } } if (InC == '\\') { ++NumConsecutiveSlashes; } else { NumConsecutiveSlashes = 0; } return EParseState::Continue; }, &EntireToken); } if (!Parameters.IsSet() || !Stream.ParseSymbol(TEXT(')'), &EntireToken).IsSet()) { return TOptional<FExpressionError>(); } // Compile the parameters for this argument modifier FStringToken& ParametersValue = Parameters.GetValue(); TSharedPtr<ITextFormatArgumentModifier> CompiledTextArgumentModifier = CompileTextArgumentModifierFunc(FTextFormatString::MakeReference(ParametersValue.GetTokenStartPos(), ParametersValue.GetTokenEndPos() - ParametersValue.GetTokenStartPos())); if (!CompiledTextArgumentModifier.IsValid()) { return TOptional<FExpressionError>(); } // Add the token to the consumer - this moves the read position in the stream to the end of the token Consumer.Add(EntireToken, FArgumentModifierTokenSpecifier(CompiledTextArgumentModifier.ToSharedRef())); return TOptional<FExpressionError>(); }
FReply FSequencerTimeSliderController::OnMouseMove( TSharedRef<SWidget> WidgetOwner, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if ( WidgetOwner->HasMouseCapture() ) { if (MouseEvent.IsMouseButtonDown( EKeys::RightMouseButton )) { if (!bPanning) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistnace() ) { bPanning = true; } } else { TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); FScrubRangeToScreen ScaleInfo( LocalViewRange, MyGeometry.Size ); FVector2D ScreenDelta = MouseEvent.GetCursorDelta(); FVector2D InputDelta; InputDelta.X = ScreenDelta.X/ScaleInfo.PixelsPerInput; float NewViewOutputMin = LocalViewRangeMin - InputDelta.X; float NewViewOutputMax = LocalViewRangeMax - InputDelta.X; TOptional<float> LocalClampMin = TimeSliderArgs.ClampMin.Get(); TOptional<float> LocalClampMax = TimeSliderArgs.ClampMax.Get(); // Clamp the range if clamp values are set if ( LocalClampMin.IsSet() && NewViewOutputMin < LocalClampMin.GetValue() ) { NewViewOutputMin = LocalClampMin.GetValue(); } if ( LocalClampMax.IsSet() && NewViewOutputMax > LocalClampMax.GetValue() ) { NewViewOutputMax = LocalClampMax.GetValue(); } TimeSliderArgs.OnViewRangeChanged.ExecuteIfBound(TRange<float>(NewViewOutputMin, NewViewOutputMax)); if( !TimeSliderArgs.ViewRange.IsBound() ) { // The output is not bound to a delegate so we'll manage the value ourselves TimeSliderArgs.ViewRange.Set( TRange<float>( NewViewOutputMin, NewViewOutputMax ) ); } } } else if (MouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton )) { if ( !bDraggingScrubber ) { DistanceDragged += FMath::Abs( MouseEvent.GetCursorDelta().X ); if ( DistanceDragged > FSlateApplication::Get().GetDragTriggerDistnace() ) { bDraggingScrubber = true; TimeSliderArgs.OnBeginScrubberMovement.ExecuteIfBound(); } } else { FScrubRangeToScreen RangeToScreen( TimeSliderArgs.ViewRange.Get(), MyGeometry.Size ); FVector2D CursorPos = MyGeometry.AbsoluteToLocal( MouseEvent.GetLastScreenSpacePosition() ); float NewValue = RangeToScreen.LocalXToInput( CursorPos.X ); const USequencerSnapSettings* SnapSettings = GetDefault<USequencerSnapSettings>(); if ( SnapSettings->GetIsSnapEnabled() && SnapSettings->GetSnapPlayTimeToInterval() ) { NewValue = SnapSettings->SnapToInterval(NewValue); } CommitScrubPosition( NewValue, /*bIsScrubbing=*/true ); } } return FReply::Handled(); } return FReply::Unhandled(); }
/** Consume the text from the specified consumer's stream */ TOptional<FExpressionError> ConsumeTextImpl(FExpressionTokenConsumer& Consumer, const TFunctionRef<bool(TCHAR)> IsBreakingCharacter) { auto& Stream = Consumer.GetStream(); FString FinalString; FString CurrentQuotedString; TCHAR QuoteChar = 0; int32 NumConsecutiveSlashes = 0; TOptional<FStringToken> TextToken = Stream.ParseToken([&](TCHAR InC) { if (QuoteChar == 0) // Parsing a non-quoted string... { // Are we starting a quoted sub-string? if (InC == '"' || InC == '\'') { CurrentQuotedString.AppendChar(InC); QuoteChar = InC; NumConsecutiveSlashes = 0; } else { // Consume until we hit a breaking character if (IsBreakingCharacter(InC)) { return EParseState::StopBefore; } FinalString.AppendChar(InC); } } else // Parsing a quoted sub-string... { CurrentQuotedString.AppendChar(InC); // Are we ending a quoted sub-string? if (InC == QuoteChar && NumConsecutiveSlashes%2 == 0) { UnescapeQuotedString(CurrentQuotedString, QuoteChar); FinalString.Append(CurrentQuotedString); CurrentQuotedString.Reset(); QuoteChar = 0; } if (InC == '\\') { NumConsecutiveSlashes++; } else { NumConsecutiveSlashes = 0; } } return EParseState::Continue; }); if (TextToken.IsSet()) { Consumer.Add(TextToken.GetValue(), CreateTextTokenFromUnquotedString(MoveTemp(FinalString))); } return TOptional<FExpressionError>(); }
int32 SProgressBar::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // Used to track the layer ID we will return. int32 RetLayerId = LayerId; bool bEnabled = ShouldBeEnabled( bParentEnabled ); const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FSlateBrush* CurrentFillImage = GetFillImage(); const FLinearColor FillColorAndOpacitySRGB(InWidgetStyle.GetColorAndOpacityTint() * FillColorAndOpacity.Get().GetColor(InWidgetStyle) * CurrentFillImage->GetTint(InWidgetStyle)); const FLinearColor ColorAndOpacitySRGB = InWidgetStyle.GetColorAndOpacityTint(); TOptional<float> ProgressFraction = Percent.Get(); // Paint inside the border only. // Pre-snap the clipping rect to try and reduce common jitter, since the padding is typically only a single pixel. FSlateRect SnappedClippingRect = FSlateRect(FMath::RoundToInt(MyClippingRect.Left), FMath::RoundToInt(MyClippingRect.Top), FMath::RoundToInt(MyClippingRect.Right), FMath::RoundToInt(MyClippingRect.Bottom)); const FSlateRect ForegroundClippingRect = SnappedClippingRect.InsetBy(FMargin(BorderPadding.Get().X, BorderPadding.Get().Y)); const FSlateBrush* CurrentBackgroundImage = GetBackgroundImage(); FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry(), CurrentBackgroundImage, SnappedClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * CurrentBackgroundImage->GetTint( InWidgetStyle ) ); if( ProgressFraction.IsSet() ) { const float ClampedFraction = FMath::Clamp(ProgressFraction.GetValue(), 0.0f, 1.0f); switch (BarFillType) { case EProgressBarFillType::RightToLeft: { FSlateRect ClippedAllotedGeometry = FSlateRect(AllottedGeometry.AbsolutePosition, AllottedGeometry.AbsolutePosition + AllottedGeometry.Size * AllottedGeometry.Scale); ClippedAllotedGeometry.Left = ClippedAllotedGeometry.Right - ClippedAllotedGeometry.GetSize().X * ClampedFraction; // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D::ZeroVector, FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect.IntersectionWith(ClippedAllotedGeometry), DrawEffects, FillColorAndOpacitySRGB ); break; } case EProgressBarFillType::FillFromCenter: { // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D( (AllottedGeometry.Size.X * 0.5f) - ((AllottedGeometry.Size.X * ( ClampedFraction ))*0.5), 0.0f), FVector2D( AllottedGeometry.Size.X * ( ClampedFraction ) , AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect, DrawEffects, FillColorAndOpacitySRGB ); break; } case EProgressBarFillType::TopToBottom: { FSlateRect ClippedAllotedGeometry = FSlateRect(AllottedGeometry.AbsolutePosition, AllottedGeometry.AbsolutePosition + AllottedGeometry.Size * AllottedGeometry.Scale); ClippedAllotedGeometry.Bottom = ClippedAllotedGeometry.Top + ClippedAllotedGeometry.GetSize().Y * ClampedFraction; // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D::ZeroVector, FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect.IntersectionWith(ClippedAllotedGeometry), DrawEffects, FillColorAndOpacitySRGB ); break; } case EProgressBarFillType::BottomToTop: { FSlateRect ClippedAllotedGeometry = FSlateRect(AllottedGeometry.AbsolutePosition, AllottedGeometry.AbsolutePosition + AllottedGeometry.Size * AllottedGeometry.Scale); ClippedAllotedGeometry.Top = ClippedAllotedGeometry.Bottom - ClippedAllotedGeometry.GetSize().Y * ClampedFraction; // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D::ZeroVector, FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect.IntersectionWith(ClippedAllotedGeometry), DrawEffects, FillColorAndOpacitySRGB ); break; } case EProgressBarFillType::LeftToRight: default: { FSlateRect ClippedAllotedGeometry = FSlateRect(AllottedGeometry.AbsolutePosition, AllottedGeometry.AbsolutePosition + AllottedGeometry.Size * AllottedGeometry.Scale); ClippedAllotedGeometry.Right = ClippedAllotedGeometry.Left + ClippedAllotedGeometry.GetSize().X * ClampedFraction; // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D::ZeroVector, FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect.IntersectionWith(ClippedAllotedGeometry), DrawEffects, FillColorAndOpacitySRGB ); break; } } } else { const FSlateBrush* CurrentMarqueeImage = GetMarqueeImage(); // Draw Marquee const float MarqueeAnimOffset = CurrentMarqueeImage->ImageSize.X * MarqueeOffset; const float MarqueeImageSize = CurrentMarqueeImage->ImageSize.X; FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D( MarqueeAnimOffset - MarqueeImageSize, 0.0f ), FVector2D( AllottedGeometry.Size.X + MarqueeImageSize, AllottedGeometry.Size.Y )), CurrentMarqueeImage, ForegroundClippingRect, DrawEffects, ColorAndOpacitySRGB ); } return RetLayerId - 1; }