UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SSegmentedControl.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "Styling/AppStyle.h"
8#include "Widgets/SBoxPanel.h"
16
26template< typename OptionType >
28{
29
30public:
31
33 struct FSlot : public TSlotBase<FSlot>, public TAlignmentWidgetSlotMixin<FSlot>
34 {
36 : TSlotBase<FSlot>()
38 , _Text()
39 , _Tooltip()
40 , _Icon(nullptr)
41 , _Value(InValue)
42 { }
43
51
53 {
56 if (InArgs._Text.IsSet())
57 {
58 _Text = MoveTemp(InArgs._Text);
59 }
60 if (InArgs._ToolTip.IsSet())
61 {
62 _Tooltip = MoveTemp(InArgs._ToolTip);
63 }
64 if (InArgs._ToolTipWidget.IsSet())
65 {
66 _ToolTipWidget = MoveTemp(InArgs._ToolTipWidget);
67 }
68 if (InArgs._Icon.IsSet())
69 {
70 _Icon = MoveTemp(InArgs._Icon);
71 }
72 if (InArgs._Value.IsSet())
73 {
74 _Value = MoveTemp(InArgs._Value.GetValue());
75 }
76 }
77
79 {
80 _Text = MoveTemp(InText);
81 }
82
83 FText GetText() const
84 {
85 return _Text.Get();
86 }
87
92
93 const FSlateBrush* GetIcon() const
94 {
95 return _Icon.Get();
96 }
97
99 {
100 _Tooltip = MoveTemp(InTooltip);
101 }
102
104 {
105 return _Tooltip.Get();
106 }
107
109
110 private:
111 TAttribute<FText> _Text;
112 TAttribute<FText> _Tooltip;
113 TAttribute<TSharedPtr<IToolTip>> _ToolTipWidget;
115
116 OptionType _Value;
117 TWeakPtr<SCheckBox> _CheckBox;
118 };
119
121 {
123 }
124
128
130 : _Style(&FAppStyle::Get().GetWidgetStyle<FSegmentedControlStyle>("SegmentedControl"))
131 , _TextStyle(&FAppStyle::Get().GetWidgetStyle<FTextBlockStyle>("SmallButtonText"))
135 {}
137 SLATE_SLOT_ARGUMENT(FSlot, Slots)
138
139
141
142
144
145
150 SLATE_ARGUMENT(bool, SupportsMultiSelection)
151
152
156 SLATE_ARGUMENT(bool, SupportsEmptySelection)
157
158
160
161
163
164
165 SLATE_ATTRIBUTE(FMargin, UniformPadding)
166
167
168 SLATE_EVENT(FOnValueChanged, OnValueChanged)
169
170
171 SLATE_EVENT(FOnValuesChanged, OnValuesChanged)
172
173
174 SLATE_EVENT(FOnValueChecked, OnValueChecked)
175
176
177 SLATE_ARGUMENT(int32, MaxSegmentsPerLine)
179
181 : Children(this)
182 , CurrentValues(*this)
183 {}
184
185 void Construct( const FArguments& InArgs )
186 {
187 check(InArgs._Style);
188
189 Style = InArgs._Style;
190 TextStyle = InArgs._TextStyle;
191
192 SupportsMultiSelection = InArgs._SupportsMultiSelection;
193 SupportsEmptySelection = InArgs._SupportsEmptySelection;
194 CurrentValuesIsBound = false; // will be set by SetValue or SetValues
195
196 if(InArgs._Value.IsBound() || InArgs._Value.IsSet())
197 {
198 SetValue(InArgs._Value, false);
199 }
200 else if(InArgs._Values.IsBound() || InArgs._Values.IsSet())
201 {
202 SetValues(InArgs._Values, false);
203 }
204
205 OnValueChanged = InArgs._OnValueChanged;
206 OnValuesChanged = InArgs._OnValuesChanged;
207 OnValueChecked = InArgs._OnValueChecked;
208
209 UniformPadding = InArgs._UniformPadding;
210
211 MaxSegmentsPerLine = InArgs._MaxSegmentsPerLine;
212 Children.AddSlots(MoveTemp(const_cast<TArray<typename FSlot::FSlotArguments>&>(InArgs._Slots)));
214 }
215
217 {
218 // The right padding will be applied later at the end so we dont accumulate left+right padding between all buttons
219 FMargin SlotPadding = Style->UniformPadding;
220 SlotPadding.Right = 0.0f;
221
223
224 const int32 NumSlots = Children.Num();
225 for ( int32 SlotIndex = 0; SlotIndex < NumSlots; ++SlotIndex )
226 {
227 TSharedRef<SWidget> Child = Children[SlotIndex].GetWidget();
228 FSlot* ChildSlotPtr = &Children[SlotIndex];
229 const OptionType ChildValue = ChildSlotPtr->_Value;
230
232 if (ChildSlotPtr->_Icon.IsBound() || ChildSlotPtr->_Text.IsBound())
233 {
234 SpacerLambda = MakeAttributeLambda([ChildSlotPtr]() { return (ChildSlotPtr->_Icon.Get() != nullptr && !ChildSlotPtr->_Text.Get().IsEmpty()) ? FVector2D(8.0f, 1.0f) : FVector2D::ZeroVector; });
235 }
236 else
237 {
238 SpacerLambda = (ChildSlotPtr->_Icon.Get() != nullptr && !ChildSlotPtr->_Text.Get().IsEmpty()) ? FVector2D(8.0f, 1.0f) : FVector2D::ZeroVector;
239 }
240
242 {
244
246 .AutoWidth()
247 .VAlign(VAlign_Center)
248 [
249 SNew(SImage)
250 .ColorAndOpacity(FSlateColor::UseForeground())
251 .Image(ChildSlotPtr->_Icon)
252 ]
253
255 .AutoWidth()
256 [
258 .Size(SpacerLambda)
259 ]
260
262 .VAlign(VAlign_Center)
263 .AutoWidth()
264 [
266 .TextStyle(TextStyle)
267 .Text(ChildSlotPtr->_Text)
268 ];
269 }
270
271 const FCheckBoxStyle* CheckBoxStyle = &Style->ControlStyle;
272 if (SlotIndex == 0)
273 {
274 CheckBoxStyle = &Style->FirstControlStyle;
275 }
276 else if (SlotIndex == NumSlots - 1)
277 {
278 CheckBoxStyle = &Style->LastControlStyle;
279 }
280
281 const int32 ColumnIndex = MaxSegmentsPerLine > 0 ? SlotIndex % MaxSegmentsPerLine : SlotIndex;
282 const int32 RowIndex = MaxSegmentsPerLine > 0 ? SlotIndex / MaxSegmentsPerLine : 0;
283
284 // Note HAlignment is applied at the check box level because if it were applied here it would make the slots look physically disconnected from each other
285 UniformBox->AddSlot(ColumnIndex, RowIndex)
286 .VAlign(ChildSlotPtr->GetVerticalAlignment())
287 [
290 .HAlign(ChildSlotPtr->GetHorizontalAlignment())
291 .ToolTipText(ChildSlotPtr->_Tooltip)
292 .ToolTip(ChildSlotPtr->_ToolTipWidget)
293 .Style(CheckBoxStyle)
294 .IsChecked(GetCheckBoxStateAttribute(ChildValue))
295 .OnCheckStateChanged(this, &SSegmentedControl::CommitValue, ChildValue)
296 .Padding(UniformPadding)
297 [
298 Child
299 ]
300 ];
301 }
302
304 [
306 .BorderImage(&Style->BackgroundBrush)
307 .Padding(FMargin(0,0,Style->UniformPadding.Right,0))
308 [
309 UniformBox.ToSharedRef()
310 ]
311 ];
312
313 UpdateCheckboxValuesIfNeeded();
314 }
315
316 // Slot Management
319 {
321 {
324 {
326 {
327 SharedThis->RebuildChildren();
328 }
329 }};
330 }
331 else
332 {
334 }
335 }
336
338 {
339 return Children.Num();
340 }
341
343 {
344 const TArray<OptionType> Values = GetValues();
345 if(Values.IsEmpty())
346 {
347 return OptionType();
348 }
349 return Values[0];
350 }
351
353 {
354 return CurrentValues.Get();
355 }
356
358 {
359 const TArray<OptionType> Values = GetValues();
360 return Values.Contains(InValue);
361 }
362
365 {
366 if(InValue.IsBound())
367 {
369 {
370 TArray<OptionType> Values;
371 Values.Add(InValue.Get());
372 return Values;
373 }), bUpdateChildren);
374 }
375 else if(InValue.IsSet())
376 {
377 TArray<OptionType> Values = {InValue.Get()};
379 }
380 else
381 {
383 }
384 }
385
388 {
389 CurrentValuesIsBound = InValues.IsBound();
390
391 if(CurrentValuesIsBound)
392 {
393 CurrentValues.Assign(*this, InValues);
394 }
395 else if(InValues.IsSet())
396 {
397 CurrentValues.Set(*this, InValues.Get());
398 }
399 else
400 {
401 CurrentValues.Unbind(*this);
402 };
403
405 {
406 UpdateCheckboxValuesIfNeeded();
407 }
408 }
409
412 const TArray<FText>& InLabels,
415 bool bSupportsMultiSelection = true,
416 FOnValuesChanged OnValuesChanged = FOnValuesChanged())
417 {
419
421 .SupportsMultiSelection(bSupportsMultiSelection)
422 .Values(InValues)
423 .OnValuesChanged(OnValuesChanged);
424
425 ensure(InKeys.Num() == InLabels.Num());
426 ensure(InKeys.Num() == InTooltips.Num());
427
428 for(int32 Index = 0; Index < InKeys.Num(); Index++)
429 {
430 Widget->AddSlot(InKeys[Index], false)
431 .Text(InLabels[Index])
432 .ToolTip(InTooltips[Index]);
433 }
434
435 Widget->RebuildChildren();
436
437 return Widget;
438 }
439
440private:
441
442 TAttribute<ECheckBoxState> GetCheckBoxStateAttribute(OptionType InValue) const
443 {
444 auto Lambda = [this, InValue]()
445 {
446 const TArray<OptionType> Values = GetValues();
448 };
449
450 if (CurrentValuesIsBound)
451 {
452 return MakeAttributeLambda(Lambda);
453 }
454
455 return Lambda();
456 }
457
458 void UpdateCheckboxValuesIfNeeded()
459 {
460 if (!CurrentValuesIsBound)
461 {
462 const TArray<OptionType> Values = GetValues();
463
464 for (int32 Index = 0; Index < Children.Num(); ++Index)
465 {
466 const FSlot& Slot = Children[Index];
467 if (const TSharedPtr<SCheckBox> CheckBox = Slot._CheckBox.Pin())
468 {
469 CheckBox->SetIsChecked(Values.Contains(Slot._Value) ? ECheckBoxState::Checked : ECheckBoxState::Unchecked);
470 }
471 }
472 }
473 }
474
475 void CommitValue(const ECheckBoxState InCheckState, OptionType InValue)
476 {
477 const TArray<OptionType> PreviousValues = CurrentValues.Get();
479
480 // don't allow to deselect the last checkbox
481 if(InCheckState != ECheckBoxState::Checked && Values.Num() == 1)
482 {
483 if(!SupportsEmptySelection)
484 {
485 UpdateCheckboxValuesIfNeeded();
486 return;
487 }
488 }
489
490 bool bModifierIsDown = false;
491 if(SupportsMultiSelection)
492 {
496 }
497
498 // if the attribute is not bound update our internal state
500 {
502 {
503 Values.AddUnique(InValue);
504 }
505 else
506 {
507 Values.Remove(InValue);
508 }
509 }
510 else
511 {
513 {
514 Values.Reset();
515 Values.Add(InValue);
516 }
517 }
518
519 if (!CurrentValuesIsBound)
520 {
521 CurrentValues.Set(*this, Values);
522
523 UpdateCheckboxValuesIfNeeded();
524 }
525
526 if(OnValueChecked.IsBound())
527 {
529 {
530 for(const OptionType PreviousValue : PreviousValues)
531 {
532 if(!Values.Contains(PreviousValue))
533 {
534 OnValueChecked.Execute(PreviousValue, ECheckBoxState::Unchecked);
535 }
536 }
537 }
538
539 OnValueChecked.Execute(InValue, InCheckState);
540 }
541
543 {
544 OnValueChanged.ExecuteIfBound(InValue);
545 }
546
547 OnValuesChanged.ExecuteIfBound(Values);
548 }
549
550private:
551 TPanelChildren<FSlot> Children;
552
553 FOnValueChanged OnValueChanged;
554 FOnValuesChanged OnValuesChanged;
555 FOnValueChecked OnValueChecked;
556
558
559 TAttribute<FMargin> UniformPadding;
560
561 const FSegmentedControlStyle* Style;
562
563 const FTextBlockStyle* TextStyle;
564
565 int32 MaxSegmentsPerLine = 0;
566
567 bool CurrentValuesIsBound = false;
568 bool SupportsMultiSelection = false;
569 bool SupportsEmptySelection = false;
570};
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define check(expr)
Definition AssertionMacros.h:314
#define ensure( InExpression)
Definition AssertionMacros.h:464
decltype(auto) MakeAttributeLambda(LambdaType &&InCallable, PayloadTypes &&... InputPayload)
Definition Attribute.h:545
@ INDEX_NONE
Definition CoreMiscDefines.h:150
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define SLATE_STYLE_ARGUMENT(ArgType, ArgName)
Definition DeclarativeSyntaxSupport.h:280
#define SAssignNew(ExposeAs, WidgetType,...)
Definition DeclarativeSyntaxSupport.h:41
#define SLATE_SLOT_ARGUMENT(SlotType, SlotName)
Definition DeclarativeSyntaxSupport.h:348
#define SNew(WidgetType,...)
Definition DeclarativeSyntaxSupport.h:37
#define SLATE_ATTRIBUTE(AttrType, AttrName)
Definition DeclarativeSyntaxSupport.h:192
#define SLATE_EVENT(DelegateName, EventName)
Definition DeclarativeSyntaxSupport.h:458
#define SLATE_END_ARGS()
Definition DeclarativeSyntaxSupport.h:116
#define SLATE_SLOT_END_ARGS()
Definition DeclarativeSyntaxSupport.h:386
#define SLATE_ARGUMENT(ArgType, ArgName)
Definition DeclarativeSyntaxSupport.h:208
UE::Math::TVector2< double > FVector2D
Definition MathFwd.h:48
ECheckBoxState
Definition SlateTypes.h:65
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
Definition AppStyle.h:24
Definition ChildrenBase.h:27
bool IsControlDown() const
Definition GenericApplication.h:158
bool IsShiftDown() const
Definition GenericApplication.h:128
static FSlateApplication & Get()
Definition SlateApplication.h:319
SLATE_API FModifierKeysState GetModifierKeys() const
Definition SlateApplication.cpp:3166
Definition Text.h:385
Definition SBorder.h:31
Definition SCheckBox.h:30
Definition SCompoundWidget.h:22
FCompoundWidgetOneChildSlot ChildSlot
Definition SCompoundWidget.h:113
Definition SBoxPanel.h:171
static FSlot::FSlotArguments Slot()
Definition SBoxPanel.h:272
Definition SImage.h:29
static SLATECORE_API TSharedRef< class SWidget > NullWidget
Definition SNullWidget.h:22
Definition SSegmentedControl.h:28
DECLARE_DELEGATE_OneParam(FOnValueChanged, OptionType)
void RebuildChildren()
Definition SSegmentedControl.h:216
SLATE_BEGIN_ARGS(SSegmentedControl< OptionType >)
Definition SSegmentedControl.h:129
DECLARE_DELEGATE_OneParam(FOnValuesChanged, TArray< OptionType >)
typename TPanelChildren< FSlot >::FScopedWidgetSlotArguments FScopedWidgetSlotArguments
Definition SSegmentedControl.h:317
OptionType GetValue() const
Definition SSegmentedControl.h:342
void Construct(const FArguments &InArgs)
Definition SSegmentedControl.h:185
void SetValues(TAttribute< TArray< OptionType > > InValues, bool bUpdateChildren=true)
Definition SSegmentedControl.h:387
FScopedWidgetSlotArguments AddSlot(const OptionType &InValue, bool bRebuildChildren=true)
Definition SSegmentedControl.h:318
static TSharedPtr< SSegmentedControl< OptionType > > Create(const TArray< OptionType > &InKeys, const TArray< FText > &InLabels, const TArray< FText > &InTooltips, const TAttribute< TArray< OptionType > > &InValues, bool bSupportsMultiSelection=true, FOnValuesChanged OnValuesChanged=FOnValuesChanged())
Definition SSegmentedControl.h:410
TArray< OptionType > GetValues() const
Definition SSegmentedControl.h:352
static FSlot::FSlotArguments Slot(const OptionType &InValue)
Definition SSegmentedControl.h:120
DECLARE_DELEGATE_TwoParams(FOnValueChecked, OptionType, ECheckBoxState)
int32 NumSlots() const
Definition SSegmentedControl.h:337
void SetValue(TAttribute< OptionType > InValue, bool bUpdateChildren=true)
Definition SSegmentedControl.h:364
bool HasValue(OptionType InValue)
Definition SSegmentedControl.h:357
Definition SSpacer.h:21
Definition STextBlock.h:45
Definition SUniformGridPanel.h:19
Definition BasicLayoutWidgetSlot.h:19
void ConstructMixin(const FChildren &SlotOwner, FSlotArgumentsMixin &&InArgs)
Definition BasicLayoutWidgetSlot.h:56
Definition Array.h:670
SizeType Remove(const ElementType &Item)
Definition Array.h:3091
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void Reset(SizeType NewSize=0)
Definition Array.h:2246
bool Contains(const ComparisonType &Item) const
Definition Array.h:1518
UE_REWRITE bool IsEmpty() const
Definition Array.h:1133
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
UE_FORCEINLINE_HINT SizeType AddUnique(ElementType &&Item)
Definition Array.h:2993
Definition Attribute.h:17
const ObjectType & Get() const
Definition Attribute.h:241
Definition Children.h:461
void AddSlots(TArray< typename SlotType::FSlotArguments > SlotArguments)
Definition Children.h:515
virtual int32 Num() const override
Definition Children.h:485
TWeakPtr< SWidget, Mode > AsWeak()
Definition SharedPointer.h:1718
static UE_FORCEINLINE_HINT TSharedRef< OtherType, Mode > SharedThis(OtherType *ThisPtr)
Definition SharedPointer.h:1780
Definition SharedPointer.h:692
Definition SharedPointer.h:153
Definition SlotBase.h:122
void Construct(const FChildren &SlotOwner, FSlotArguments &&InArgs)
Definition SlotBase.h:212
Definition SharedPointer.h:1295
UE_FORCEINLINE_HINT TSharedPtr< ObjectType, Mode > Pin() const &
Definition SharedPointer.h:1512
int32 CheckBox
Definition BoundingVolumeHierarchy.cpp:270
@ false
Definition radaudio_common.h:23
U16 Index
Definition radfft.cpp:71
Definition SlateTypes.h:105
Definition Margin.h:17
float Right
Definition Margin.h:30
Definition SegmentedControlStyle.h:16
FCheckBoxStyle FirstControlStyle
Definition SegmentedControlStyle.h:41
FCheckBoxStyle ControlStyle
Definition SegmentedControlStyle.h:34
FCheckBoxStyle LastControlStyle
Definition SegmentedControlStyle.h:48
FSlateBrush BackgroundBrush
Definition SegmentedControlStyle.h:53
FMargin UniformPadding
Definition SegmentedControlStyle.h:60
Definition SlateBrush.h:239
static FSlateColor UseForeground()
Definition SlateColor.h:198
Definition SlotBase.h:25
Definition SlateTypes.h:326
Definition SSegmentedControl.h:34
const FSlateBrush * GetIcon() const
Definition SSegmentedControl.h:93
void SetIcon(TAttribute< const FSlateBrush * > InBrush)
Definition SSegmentedControl.h:88
FText GetToolTip() const
Definition SSegmentedControl.h:103
FText GetText() const
Definition SSegmentedControl.h:83
SLATE_SLOT_BEGIN_ARGS_OneMixin(FSlot, TSlotBase< FSlot >, TAlignmentWidgetSlotMixin< FSlot >) void Construct(const FChildren &SlotOwner
void SetText(TAttribute< FText > InText)
Definition SSegmentedControl.h:78
FSlotArguments && InArgs
Definition SSegmentedControl.h:53
FSlot(const OptionType &InValue)
Definition SSegmentedControl.h:35
void SetToolTip(TAttribute< FText > InTooltip)
Definition SSegmentedControl.h:98
Definition Optional.h:131
static CORE_API const TVector2< double > ZeroVector
Definition Vector2D.h:63
static CORE_API const TVector< double > ZeroVector
Definition Vector.h:79