A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
SDlgDataPropertyValues.cpp
Go to the documentation of this file.
1// Copyright Csaba Molnar, Daniel Butum. All Rights Reserved.
3
4#include "Widgets/Text/STextBlock.h"
5#include "Widgets/Layout/SMissingWidget.h"
6#include "Widgets/Input/SButton.h"
7#include "Widgets/SBoxPanel.h"
8#include "Widgets/Input/SCheckBox.h"
9#include "Widgets/Input/SEditableTextBox.h"
10
11#include "NYReflectionHelper.h"
12
13#define LOCTEXT_NAMESPACE "SDlgDataPropertyValues"
14
15static FText ValidateNameLength(const FText& Text)
16{
17 if (Text.ToString().Len() > NAME_SIZE)
18 {
19 static FText ErrorString = FText::Format(LOCTEXT("NamePropertySizeTooLongError", "Name properties may only be a maximum of {0} characters"),
20 FText::AsNumber(NAME_SIZE));
21 return ErrorString;
22 }
23
24 return FText::GetEmpty();
25}
26
27static FString BoolToFString(const bool Value)
28{
29 return Value ? TEXT("True") : TEXT("False");
30}
31
32static bool FStringToBool(const FString& Value)
33{
34 return FCString::ToBool(*Value);
35}
36
38// SDlgDataProperty
39void SDlgDataPropertyValue::Construct(const FArguments& InArgs, const TSharedPtr<FDlgDataDisplayTreeVariableNode>& InVariableNode)
40{
41 VariableNode = InVariableNode;
42 if (!VariableNode.IsValid())
43 {
44 return;
45 }
46
48
49 ChildSlot
50 [
51 SNew(STextBlock)
52 .Text(this, &Self::GetTextValue)
53 ];
54}
55
56void SDlgDataPropertyValue::Tick(const FGeometry& AllottedGeometry, double InCurrentTime, float InDeltaTime)
57{
58 Super::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
59
60 // We only run this Tick only after TickUpdateTimeSeconds has passed
61 TickPassedDeltaTimeSeconds += InDeltaTime;
63 {
64 return;
65 }
66
67 // Update the value
70}
71
73{
74 if (!VariableNode.IsValid())
75 {
76 return;
77 }
78
79 TWeakObjectPtr<const AActor> Actor = VariableNode->GetParentActor();
80 if (!Actor.IsValid())
81 {
82 return;
83 }
84
85 const FName VariableName = VariableNode->GetVariableName();
86 switch (VariableNode->GetVariableType())
87 {
89 {
90 const int32 Value = IDlgDialogueParticipant::Execute_GetIntValue(Actor.Get(), VariableName);
91 VariableNode->SetVariableValue(FString::FromInt(Value));
92 break;
93 }
95 {
96 const float Value = IDlgDialogueParticipant::Execute_GetFloatValue(Actor.Get(), VariableName);
97 VariableNode->SetVariableValue(FString::SanitizeFloat(Value));
98 break;
99 }
101 {
102 const bool Value = IDlgDialogueParticipant::Execute_GetBoolValue(Actor.Get(), VariableName);
103 VariableNode->SetVariableValue(BoolToFString(Value));
104 break;
105 }
107 {
108 const FName Value = IDlgDialogueParticipant::Execute_GetNameValue(Actor.Get(), VariableName);
109 VariableNode->SetVariableValue(Value.ToString());
110 break;
111 }
112
114 {
115 const int32 Value = FNYReflectionHelper::GetVariable<FNYIntProperty, int32>(Actor.Get(), VariableName);
116 VariableNode->SetVariableValue(FString::FromInt(Value));
117 break;
118 }
120 {
121 const float Value = FNYReflectionHelper::GetVariable<FNYFloatProperty, float>(Actor.Get(), VariableName);
122 VariableNode->SetVariableValue(FString::SanitizeFloat(Value));
123 break;
124 }
126 {
127 const bool Value = FNYReflectionHelper::GetVariable<FNYBoolProperty, bool>(Actor.Get(), VariableName);
128 VariableNode->SetVariableValue(BoolToFString(Value));
129 break;
130 }
132 {
133 const FName Value = FNYReflectionHelper::GetVariable<FNYNameProperty, FName>(Actor.Get(), VariableName);
134 VariableNode->SetVariableValue(Value.ToString());
135 break;
136 }
138 {
139 const FText Value = FNYReflectionHelper::GetVariable<FNYTextProperty, FText>(Actor.Get(), VariableName);
140 VariableNode->SetVariableValue(Value.ToString());
141 break;
142 }
143
145 {
146 // Event does not have any state value, ignore
147 break;
148 }
150 {
151 const bool Value = IDlgDialogueParticipant::Execute_CheckCondition(Actor.Get(), nullptr, VariableName);
152 VariableNode->SetVariableValue(BoolToFString(Value));
153 break;
154 }
156 default:
157 VariableNode->SetVariableValue(TEXT("UNIMPLEMENTED - SHOULD NEVER HAPPEN"));
158 }
159}
160
161
163// SDlgDataTextPropertyValue
164void SDlgDataTextPropertyValue::Construct(const FArguments& InArgs, const TSharedPtr<FDlgDataDisplayTreeVariableNode>& InVariableNode)
165{
166 VariableNode = InVariableNode;
167 if (!VariableNode.IsValid())
168 {
169 return;
170 }
171
174
175 ChildSlot
176 [
177 SNew(SHorizontalBox)
178 +SHorizontalBox::Slot()
179 .FillWidth(1.0f)
180 [
181 SAssignNew(TextBoxWidget, SEditableTextBox)
182 .Text(this, &Self::GetTextValue)
183 .SelectAllTextWhenFocused(true)
184 .ClearKeyboardFocusOnCommit(false)
185 .SelectAllTextOnCommit(true)
186 .MinDesiredWidth(120.f)
187 .OnTextCommitted(this, &Self::HandleTextCommitted)
188 .OnTextChanged(this, &Self::HandleTextChanged)
189 .IsReadOnly(this, &Self::IsReadOnly)
190 ]
191 ];
193}
194
195void SDlgDataTextPropertyValue::HandleTextCommitted(const FText& NewText, ETextCommit::Type CommitInfo)
196{
197 static const FString MultipleValues(TEXT("Multiple Values"));
198 const FString NewString = NewText.ToString();
199 if (NewString == MultipleValues || !VariableNode.IsValid())
200 {
201 // can't set this :(
202 return;
203 }
204
205 TWeakObjectPtr<AActor> Actor = VariableNode->GetParentActor();
206 if (!Actor.IsValid())
207 {
208 return;
209 }
210
211 const FName VariableName = VariableNode->GetVariableName();
212 switch (VariableNode->GetVariableType())
213 {
215 {
216 const int32 Value = NewString.IsNumeric() ? FCString::Atoi(*NewString) : 0;
217 IDlgDialogueParticipant::Execute_ModifyIntValue(Actor.Get(), VariableName, false, Value);
218 break;
219 }
221 {
222 const float Value = NewString.IsNumeric() ? FCString::Atof(*NewString) : 0.f;
223 IDlgDialogueParticipant::Execute_ModifyFloatValue(Actor.Get(), VariableName, false, Value);
224 break;
225 }
227 {
228 const bool Value = FStringToBool(NewString);
229 IDlgDialogueParticipant::Execute_ModifyBoolValue(Actor.Get(), VariableName, Value);
230 break;
231 }
233 {
234 const FName Value(*NewString);
235 IDlgDialogueParticipant::Execute_ModifyNameValue(Actor.Get(), VariableName, Value);
236 break;
237 }
238
240 {
241 const int32 Value = NewString.IsNumeric() ? FCString::Atoi(*NewString) : 0;
242 FNYReflectionHelper::SetVariable<FNYIntProperty>(Actor.Get(), VariableName, Value);
243 break;
244 }
246 {
247 const float Value = NewString.IsNumeric() ? FCString::Atof(*NewString) : 0.f;
248 FNYReflectionHelper::SetVariable<FNYFloatProperty>(Actor.Get(), VariableName, Value);
249 break;
250 }
252 {
253 const bool Value = FStringToBool(NewString);
254 FNYReflectionHelper::SetVariable<FNYBoolProperty>(Actor.Get(), VariableName, Value);
255 break;
256 }
258 {
259 const FName Value(*NewString);
260 FNYReflectionHelper::SetVariable<FNYNameProperty>(Actor.Get(), VariableName, Value);
261 break;
262 }
263
265 {
266 const FText Value = FText::FromString(NewString);
267 FNYReflectionHelper::SetVariable<FNYTextProperty>(Actor.Get(), VariableName, Value);
268 break;
269 }
270
271 // The remaining variable types do not make sense to be text
275 default:
276 break;
277 }
278
280}
281
283{
285 {
286 const FText ErrorMessage = ValidateNameLength(NewText);
287 if (!ErrorMessage.IsEmpty())
288 {
289 VariableNode->SetVariableValue(ErrorMessage.ToString());
290 }
291 }
292}
293
294
296// SDlgDataEventPropertyValue
297void SDlgDataEventPropertyValue::Construct(const FArguments& InArgs, const TSharedPtr<FDlgDataDisplayTreeVariableNode>& InVariableNode)
298{
299 VariableNode = InVariableNode;
300 if (!VariableNode.IsValid())
301 {
302 return;
303 }
304
306 {
307 ChildSlot
308 [
309 SAssignNew(PrimaryWidget, SButton)
310 .ToolTipText(LOCTEXT("EventValueTooltipKey", "Triggers this event. Calls OnDialogueEvent on the Actor."))
311 .OnClicked(this, &Self::HandleTriggerEventClicked)
312 [
313 SNew(STextBlock)
314 .Text(LOCTEXT("EVentButtonTextKey", "Trigger Event"))
315 ]
316 ];
317 }
318 else
319 {
320 ChildSlot
321 [
322 SNew(STextBlock)
323 .Text(LOCTEXT("SDlgDataEventPropertyValueINVALID", "INVALID VariableType INVALID"))
324 ];
325 }
326}
327
329{
330 if (!VariableNode.IsValid() || VariableNode->GetVariableType() != EDlgDataDisplayVariableTreeNodeType::Event)
331 {
332 return FReply::Unhandled();
333 }
334
335 TWeakObjectPtr<AActor> Actor = VariableNode->GetParentActor();
336 if (!Actor.IsValid())
337 {
338 return FReply::Unhandled();
339 }
340
341 // Trigger the event
342 const FName EventName = VariableNode->GetVariableName();
343 IDlgDialogueParticipant::Execute_OnDialogueEvent(Actor.Get(), nullptr, EventName);
344
345 return FReply::Handled();
346}
347
348
350// SDlgDataBoolPropertyValue
351void SDlgDataBoolPropertyValue::Construct(const FArguments& InArgs, const TSharedPtr<FDlgDataDisplayTreeVariableNode>& InVariableNode)
352{
353 VariableNode = InVariableNode;
354 if (!VariableNode.IsValid())
355 {
356 return;
357 }
358
360 ChildSlot
361 [
362 SAssignNew(CheckBoxWidget, SCheckBox)
363 .OnCheckStateChanged(this, &Self::HandleCheckStateChanged)
364 .IsChecked(this, &Self::IsChecked)
365 .Padding(0.0f)
366 ];
368 SetEnabled(TAttribute<bool>(this, &Self::IsBoolProperty));
369}
370
372{
373 // The rest of the focus methods are handled in the parent class.
374 return CheckBoxWidget->HasKeyboardFocus();
375}
376
377FReply SDlgDataBoolPropertyValue::OnMouseButtonDoubleClick(const FGeometry& InMyGeometry, const FPointerEvent& InMouseEvent)
378{
379 if (InMouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
380 {
381 // toggle the our checkbox
382 CheckBoxWidget->ToggleCheckedState();
383
384 // Set focus to this object, but don't capture the mouse
385 return FReply::Handled().SetUserFocus(AsShared(), EFocusCause::Mouse);
386 }
387
388 return FReply::Unhandled();
389}
390
392{
393 if (!VariableNode.IsValid())
394 {
395 return ECheckBoxState::Undetermined;
396 }
397
398 const bool Value = FStringToBool(VariableNode->GetVariableValue());
399 return Value ? ECheckBoxState::Checked : ECheckBoxState::Unchecked;
400}
401
403{
404 // Can only modify bool values
405 if (!IsBoolProperty())
406 {
407 return;
408 }
409
410 TWeakObjectPtr<AActor> Actor = VariableNode->GetParentActor();
411 if (!Actor.IsValid())
412 {
413 return;
414 }
415
416 // Set the bool value
417 const FName VariableName = VariableNode->GetVariableName();
418 const bool Value = InNewState == ECheckBoxState::Checked || InNewState == ECheckBoxState::Undetermined;
420 {
421 FNYReflectionHelper::SetVariable<FNYBoolProperty>(Actor.Get(), VariableName, Value);
422 }
423 else
424 {
425 IDlgDialogueParticipant::Execute_ModifyBoolValue(Actor.Get(), VariableName, Value);
426 }
428}
429
430#undef LOCTEXT_NAMESPACE
static FText ValidateNameLength(const FText &Text)
static FString BoolToFString(const bool Value)
static bool FStringToBool(const FString &Value)
FReply OnMouseButtonDoubleClick(const FGeometry &InMyGeometry, const FPointerEvent &InMouseEvent) override
TSharedPtr< SCheckBox > CheckBoxWidget
void HandleCheckStateChanged(ECheckBoxState InNewState)
bool HasKeyboardFocus() const override
void Construct(const FArguments &InArgs, const TSharedPtr< FDlgDataDisplayTreeVariableNode > &InVariableNode)
void Construct(const FArguments &InArgs, const TSharedPtr< FDlgDataDisplayTreeVariableNode > &InVariableNode)
TSharedPtr< FDlgDataDisplayTreeVariableNode > VariableNode
void Construct(const FArguments &InArgs, const TSharedPtr< FDlgDataDisplayTreeVariableNode > &InVariableNode)
void Tick(const FGeometry &AllottedGeometry, double InCurrentTime, float InDeltaTime) override
TSharedPtr< SWidget > PrimaryWidget
static constexpr float TickUpdateTimeSeconds
TSharedPtr< SEditableTextBox > TextBoxWidget
void Construct(const FArguments &InArgs, const TSharedPtr< FDlgDataDisplayTreeVariableNode > &InVariableNode)
void HandleTextCommitted(const FText &NewText, ETextCommit::Type CommitInfo)
void HandleTextChanged(const FText &NewText)