UE4C++Slate编程构架浅析

UE4C++Slate编程构架浅析

  • 1.前言
    虚幻引擎所自带有的所有可视化的UI都是有Slate构成,具体可用控件反射器跟,如果不会可参考控件反射器的使用
  • 模块添加
    UE4C++Slate编程构架浅析_第1张图片
    打开你的项目的[项目名称].build.cs 文件,添加要使用到的模块
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" });
PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
  • 控件显示
    为了在你的游戏中显示一个Slate控件,则必须将该控件添加到游戏视口中。到当前游戏视口的引用可以通过 UEngine 的 GameViewport 成员获得。GEngine->GameViewport
GEngine->GameViewport->AddViewportWidgetContent(
    SNew(MyWidgetPtr.ToSharedRef())
);
  • 从视口中删除控件
//删除对应Widget
GEngine->GameViewport->RemoveViewportWidgetContent(
    SNew(MyWidgetPtr.ToSharedRef())
);
//删除所有的Widget
GEngine->GameViewport->RemoveAllViewportWidgets();
  • 2.正文
    UE4C++Slate编程构架浅析_第2张图片

以ColorPick举例,使用控件反射器去跟踪Slate结构UE4C++Slate编程构架浅析_第3张图片
参考下图与代码,我们可以看到Slate是很具有结构性的,其实参考代码不难看出它俩之间的联系
UE4C++Slate编程构架浅析_第4张图片

	SmallTrash = SNew(SHorizontalBox)
	+ SHorizontalBox::Slot()
		.AutoWidth()
		[
			SNew(SColorTrash)
				.UsesSmallIcon(true)
		];
	
	this->ChildSlot
	[
		SNew(SVerticalBox)

		+ SVerticalBox::Slot()
			.AutoHeight()
			[
				SNew(SGridPanel)
					.FillColumn(0, 1.0f)

				+ SGridPanel::Slot(0, 0)
					.Padding(0.0f, 1.0f, 20.0f, 1.0f)
					[
						SNew(SHorizontalBox)

						+ SHorizontalBox::Slot()
							.FillWidth(1.0f)
							.Padding(0.0f, 1.0f)
							[
								SNew(SOverlay)

								+ SOverlay::Slot()
									[
										// color theme bar
										SAssignNew(CurrentThemeBar, SThemeColorBlocksBar)
											.ColorTheme(this, &SColorPicker::HandleThemeBarColorTheme)
											.EmptyText(LOCTEXT("EmptyBarHint", "Drag & drop colors here to save"))
											.HideTrashCallback(this, &SColorPicker::HideSmallTrash)
											.ShowTrashCallback(this, &SColorPicker::ShowSmallTrash)
											.ToolTipText(LOCTEXT("CurrentThemeBarToolTip", "Current Color Theme"))
											.UseAlpha(SharedThis(this), &SColorPicker::HandleThemeBarUseAlpha)
											.UseSRGB(SharedThis(this), &SColorPicker::HandleColorPickerUseSRGB)
											.OnSelectColor(this, &SColorPicker::HandleThemeBarColorSelected)
									]

								// hack: need to fix SThemeColorBlocksBar::EmptyText to render properly
								+ SOverlay::Slot()
									.HAlign(HAlign_Center)
									.VAlign(VAlign_Center)
									[
										SNew(STextBlock)
										.Text(LOCTEXT("EmptyBarHint", "Drag & drop colors here to save"))
										.Visibility(this, &SColorPicker::HandleThemeBarHintVisibility)
									]
							]

						+ SHorizontalBox::Slot()
							.AutoWidth()
							[
								// color theme selector
								SAssignNew(ColorThemeButtonOrSmallTrash, SBorder)
									.BorderImage(FStyleDefaults::GetNoBrush())
									.Padding(0.0f)
							]
					]

				+ SGridPanel::Slot(1, 0)
					.HAlign(HAlign_Right)
					.VAlign(VAlign_Center)
					[
						// sRGB check box
						SNew(SCheckBox)
							.ToolTipText(LOCTEXT("SRGBCheckboxToolTip", "Toggle gamma corrected sRGB previewing"))
							.IsChecked(this, &SColorPicker::HandleSRGBCheckBoxIsChecked)
							.OnCheckStateChanged(this, &SColorPicker::HandleSRGBCheckBoxCheckStateChanged)
							[
								SNew(STextBlock)
									.Text(LOCTEXT("SRGBCheckboxLabel", "sRGB Preview"))
							]
					]

				+ SGridPanel::Slot(0, 1)
					.Padding(0.0f, 8.0f, 20.0f, 0.0f)
					[
						SNew(SBorder)
							.BorderImage(FCoreStyle::Get().GetBrush("NoBorder"))
							.Padding(0.0f)
							.OnMouseButtonDown(this, &SColorPicker::HandleColorAreaMouseDown)
							[
								SNew(SOverlay)

								// color wheel
								+ SOverlay::Slot()
									[
										SNew(SHorizontalBox)

										+ SHorizontalBox::Slot()
											.FillWidth(1.0f)
											.HAlign(HAlign_Center)
											[
												SNew(SColorWheel)
													.SelectedColor(this, &SColorPicker::GetCurrentColor)
													.Visibility(this, &SColorPicker::HandleColorPickerModeVisibility, EColorPickerModes::Wheel)
													.OnValueChanged(this, &SColorPicker::HandleColorSpectrumValueChanged)
													.OnMouseCaptureBegin(this, &SColorPicker::HandleInteractiveChangeBegin)
													.OnMouseCaptureEnd(this, &SColorPicker::HandleInteractiveChangeEnd)
											]

										+ SHorizontalBox::Slot()
											.AutoWidth()
											.Padding(4.0f, 0.0f)
											[
												// saturation slider
												MakeColorSlider(EColorPickerChannels::Saturation)
											]

										+ SHorizontalBox::Slot()
											.AutoWidth()
											[
												// value slider
												MakeColorSlider(EColorPickerChannels::Value)
											]
									]

								// color spectrum
								+ SOverlay::Slot()
									[
										SNew(SBox)
											.HeightOverride(200.0f)
											.WidthOverride(292.0f)
											[
												SNew(SColorSpectrum)
													.SelectedColor(this, &SColorPicker::GetCurrentColor)
													.Visibility(this, &SColorPicker::HandleColorPickerModeVisibility, EColorPickerModes::Spectrum)
													.OnValueChanged(this, &SColorPicker::HandleColorSpectrumValueChanged)
													.OnMouseCaptureBegin(this, &SColorPicker::HandleInteractiveChangeBegin)
													.OnMouseCaptureEnd(this, &SColorPicker::HandleInteractiveChangeEnd)
											]
									]
							]
					]

				+ SGridPanel::Slot(1, 1)
					.Padding(0.0f, 8.0f, 0.0f, 0.0f)
					[
						SNew(SVerticalBox)

						+ SVerticalBox::Slot()
							.AutoHeight()
							[
								SNew(SBox)
									.HeightOverride(100.0f)
									.WidthOverride(70.0f)
									[
										// color preview
										MakeColorPreviewBox()
									]
							]

						+ SVerticalBox::Slot()
							.AutoHeight()
							.Padding(0.0f, 16.0f, 0.0f, 0.0f)
							.VAlign(VAlign_Top)
							[
								SNew(SHorizontalBox)

								+ SHorizontalBox::Slot()
									.HAlign(HAlign_Left)
									[
										// mode selector
										SNew(SButton)
											.OnClicked(this, &SColorPicker::HandleColorPickerModeButtonClicked)
											.Content()
											[
												SNew(SImage)
													.Image(FCoreStyle::Get().GetBrush("ColorPicker.Mode"))
													.ToolTipText(LOCTEXT("ColorPickerModeEToolTip", "Toggle between color wheel and color spectrum."))
											]									
									]

								+ SHorizontalBox::Slot()
									.HAlign(HAlign_Right)
									[
										// eye dropper
										SNew(SEyeDropperButton)
											.OnValueChanged(this, &SColorPicker::HandleRGBColorChanged)
											.OnBegin(this, &SColorPicker::HandleInteractiveChangeBegin)
											.OnComplete(this, &SColorPicker::HandleEyeDropperButtonComplete)
											.DisplayGamma(DisplayGamma)
											.Visibility(bValidCreationOverrideExists ? EVisibility::Collapsed : EVisibility::Visible)
									]
							]
					]
			]

		// advanced settings
		+ SVerticalBox::Slot()
			.AutoHeight()
			.Padding(0.0f, 4.0f, 0.0f, 0.0f)
			[
				SNew(SExpandableArea)
					.AreaTitle(LOCTEXT("AdvancedAreaTitle", "Advanced"))
					.BorderBackgroundColor(FLinearColor::Transparent)
					.InitiallyCollapsed(!bAdvancedSectionExpanded)
					.OnAreaExpansionChanged(this, &SColorPicker::HandleAdvancedAreaExpansionChanged)
					.Padding(FMargin(0.0f, 1.0f, 0.0f, 8.0f))
					.BodyContent()
					[
						SNew(SHorizontalBox)

						// RGBA inputs
						+ SHorizontalBox::Slot()
							.Padding(0.0f, 0.0f, 4.0f, 0.0f)
							[
								SNew(SVerticalBox)

								// Red
								+ SVerticalBox::Slot()
									[
										MakeColorSpinBox(EColorPickerChannels::Red)
									]

								// Green
								+ SVerticalBox::Slot()
									.Padding(0.0f, 8.0f, 0.0f, 0.0f)
									[
										MakeColorSpinBox(EColorPickerChannels::Green)
									]

								// Blue
								+ SVerticalBox::Slot()
									.Padding(0.0f, 8.0f, 0.0f, 0.0f)
									[
										MakeColorSpinBox(EColorPickerChannels::Blue)
									]

								// Alpha
								+ SVerticalBox::Slot()
									.Padding(0.0f, 8.0f, 0.0f, 0.0f)
									[
										MakeColorSpinBox(EColorPickerChannels::Alpha)
									]
							]

						// HSV & Hex inputs
						+ SHorizontalBox::Slot()
							.Padding(4.0f, 0.0f, 0.0f, 0.0f)
							[
								SNew(SVerticalBox)
							
								// Hue
								+ SVerticalBox::Slot()
								[
									MakeColorSpinBox(EColorPickerChannels::Hue)
								]

								// Saturation
								+ SVerticalBox::Slot()
								.Padding(0.0f, 8.0f, 0.0f, 0.0f)
								[
									MakeColorSpinBox(EColorPickerChannels::Saturation)
								]

								// Value
								+ SVerticalBox::Slot()
								.Padding(0.0f, 8.0f, 0.0f, 0.0f)
								[
									MakeColorSpinBox(EColorPickerChannels::Value)
								]

								// Hex linear
								+ SVerticalBox::Slot()
									.HAlign(HAlign_Right)
									.VAlign(VAlign_Top)
									.Padding(0.0f, 12.0f, 0.0f, 0.0f)
									[
										SNew(SHorizontalBox)
											.ToolTipText(LOCTEXT("HexLinearSliderToolTip", "Hexadecimal Linear Value"))

										+ SHorizontalBox::Slot()
											.AutoWidth()
											.Padding(0.0f, 0.0f, 4.0f, 0.0f)
											.VAlign(VAlign_Center)
											[
												SNew(STextBlock)
													.Text(LOCTEXT("HexLinearInputLabel", "Hex Linear"))
											]

										+ SHorizontalBox::Slot()
											.AutoWidth()
											.MaxWidth(72.0f)
											[
												SNew(SEditableTextBox)
													.MinDesiredWidth(72.0f)
													.Text(this, &SColorPicker::HandleHexLinearBoxText)
													.OnTextCommitted(this, &SColorPicker::HandleHexLinearInputTextCommitted)
											]
								]

								// Hex sRGB
								+ SVerticalBox::Slot()
									.HAlign(HAlign_Right)
									.VAlign(VAlign_Top)
									.Padding(0.0f, 8.0f, 0.0f, 0.0f)
									[
										SNew(SHorizontalBox)
										.ToolTipText(LOCTEXT("HexSRGBSliderToolTip", "Hexadecimal sRGB Value"))

										+ SHorizontalBox::Slot()
											.AutoWidth()
											.Padding(0.0f, 0.0f, 4.0f, 0.0f)
											.VAlign(VAlign_Center)
											[
												SNew(STextBlock)
												.Text(LOCTEXT("HexSRGBInputLabel", "Hex sRGB"))
											]

										+ SHorizontalBox::Slot()
											.AutoWidth()
											.MaxWidth(72.0f)
											[
												SNew(SEditableTextBox)
												.MinDesiredWidth(72.0f)
												.Text(this, &SColorPicker::HandleHexSRGBBoxText)
												.OnTextCommitted(this, &SColorPicker::HandleHexSRGBInputTextCommitted)
											]
								]
						]
				]
			]

		// dialog buttons
		+ SVerticalBox::Slot()
			.AutoHeight()
			.HAlign(HAlign_Right)
			.VAlign(VAlign_Center)
			.Padding(0.0f, 12.0f, 0.0f, 0.0f)
			[
				SNew(SUniformGridPanel)
					.MinDesiredSlotHeight(FCoreStyle::Get().GetFloat("StandardDialog.MinDesiredSlotHeight"))
					.MinDesiredSlotWidth(FCoreStyle::Get().GetFloat("StandardDialog.MinDesiredSlotWidth"))
					.SlotPadding(FCoreStyle::Get().GetMargin("StandardDialog.SlotPadding"))
					.Visibility((ParentWindowPtr.IsValid() || bValidCreationOverrideExists) ? EVisibility::Visible : EVisibility::Collapsed)

				+ SUniformGridPanel::Slot(0, 0)
					[
						// ok button
						SNew(SButton)
							.ContentPadding( FCoreStyle::Get().GetMargin("StandardDialog.ContentPadding") )
							.HAlign(HAlign_Center)
							.Text(LOCTEXT("OKButton", "OK"))
							.OnClicked(this, &SColorPicker::HandleOkButtonClicked)
					]

				+ SUniformGridPanel::Slot(1, 0)
					[
						// cancel button
						SNew(SButton)
							.ContentPadding( FCoreStyle::Get().GetMargin("StandardDialog.ContentPadding") )
							.HAlign(HAlign_Center)
							.Text(LOCTEXT("CancelButton", "Cancel"))
							.OnClicked(this, &SColorPicker::HandleCancelButtonClicked)
					]
			]
	];

对比代码与Slate层级之后,我们发现Slate编程有些奇怪,但很具有结构,而Slate为什么会能这样连写呢,第一反应有人觉得这是C++语法吗,请接着往下看。
在这里插入图片描述
注:宏定义#表示链接,\用于作换行
UE4C++Slate编程构架浅析_第5张图片
UE4C++Slate编程构架浅析_第6张图片
UE4C++Slate编程构架浅析_第7张图片
可连续用点是因为返回值类型全是自身,就一直调用自己的方法,再将自己返回出去
UE4C++Slate编程构架浅析_第8张图片
UE4C++Slate编程构架浅析_第9张图片UE4C++Slate编程构架浅析_第10张图片

它也对+号等进行了重载
UE4C++Slate编程构架浅析_第11张图片
在这类建立时候,用SLATE_BEGIN_ARGS宏进行了这些基础方法的生成与实现,因此,这是导致Slate语法奇怪的原因,当你知道了这些重载之后再来看Slate语法将会恍然大悟。
列如下图:创窗口设置大小为(541,632),绑定了窗口名字的Lamda表达式,设置其名字为ColorPicker,接下来的操作大家多去看看大概就明白什么意思了。
UE4C++Slate编程构架浅析_第12张图片

你可能感兴趣的:(UEC++,ue4,c++)