1651 lines
60 KiB
C++
1651 lines
60 KiB
C++
// @lint-ignore-every LICENSELINT
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
#include "OculusXRPlatformToolWidget.h"
|
|
#include "Widgets/Text/SRichTextBlock.h"
|
|
#include "DesktopPlatformModule.h"
|
|
#include "Editor.h"
|
|
#include "Styling/AppStyle.h"
|
|
#include "Misc/FileHelper.h"
|
|
#include "Internationalization/Regex.h"
|
|
#include "Misc/MessageDialog.h"
|
|
#include "Widgets/Layout/SExpandableArea.h"
|
|
#include "Widgets/Images/SImage.h"
|
|
#include "HAL/FileManagerGeneric.h"
|
|
#include "DOM/JsonObject.h"
|
|
#include "Serialization/JsonSerializer.h"
|
|
#include "OculusXRHMDModule.h"
|
|
#include "GenericPlatform/GenericPlatformMisc.h"
|
|
#include "Interfaces/IPluginManager.h"
|
|
#include "SHyperlinkLaunchURL.h"
|
|
#include "Misc/EngineVersionComparison.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "OculusPlatformToolWidget"
|
|
#define TEXT_INDENT_OFFSET 20.0f
|
|
|
|
const FString UrlPlatformUtil = "https://www.oculus.com/download_app/?id=1076686279105243";
|
|
const FString ProjectPlatformUtilPath = "Oculus/Tools/ovr-platform-util.exe";
|
|
|
|
FText OculusPlatformDialogTitle = LOCTEXT("DownloadOculusPlatformUtility", "Download Oculus Platform Utility");
|
|
FText OculusPlatformDialogMessage = LOCTEXT("DownloadOculusPlatformUtilityMessage",
|
|
"Oculus Platform Window would like to download the latest version of the Oculus Platform Utility."
|
|
" Oculus Platform Utility is a command-line tool that enables the uploading of builds to your release channels on the Oculus Developer Dashboard."
|
|
"\n\nYou can learn more about the Oculus Platform Utility at https://developer.oculus.com/distribute/publish-reference-platform-command-line-utility/"
|
|
"\n\nCanceling will prevent the download and the UPLOAD button will be unfunctional. Would you like the tool to download the Oculus Platform Utility to your project?");
|
|
|
|
static bool bShowUploadDebugSymbols = false;
|
|
|
|
FString SOculusPlatformToolWidget::LogText;
|
|
|
|
SOculusPlatformToolWidget::SOculusPlatformToolWidget()
|
|
{
|
|
LogTextUpdated = false;
|
|
ActiveUploadButton = true;
|
|
Options2DCollapsed = true;
|
|
RequestUploadButtonActive = true;
|
|
OptionsRedistPackagesCollapsed = true;
|
|
|
|
EnableUploadButtonDel.BindRaw(this, &SOculusPlatformToolWidget::EnableUploadButton);
|
|
UpdateLogTextDel.BindRaw(this, &SOculusPlatformToolWidget::UpdateLogText);
|
|
SetProcessDel.BindRaw(this, &SOculusPlatformToolWidget::SetPlatformProcess);
|
|
|
|
LoadConfigSettings();
|
|
|
|
FOculusXRHMDModule::GetPluginWrapper().SendEvent2("oculus_platform_tool", "show_window", "integration");
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
|
|
{
|
|
// Update log text if it changes, otherwise constant updating will yeild the field unselectable.
|
|
if (LogTextUpdated)
|
|
{
|
|
ToolConsoleLog->SetText(FText::FromString(LogText));
|
|
LogTextUpdated = false;
|
|
}
|
|
|
|
if (RequestUploadButtonActive != ActiveUploadButton)
|
|
{
|
|
ActiveUploadButton = RequestUploadButtonActive;
|
|
BuildButtonToolbar(ButtonToolbar);
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::Construct(const FArguments& InArgs)
|
|
{
|
|
auto logTextBox = SNew(SMultiLineEditableTextBox).IsReadOnly(true);
|
|
ToolConsoleLog = logTextBox;
|
|
|
|
auto mainVerticalBox = SNew(SVerticalBox);
|
|
GeneralSettingsBox = mainVerticalBox;
|
|
|
|
auto buttonToolbarBox = SNew(SHorizontalBox);
|
|
ButtonToolbar = buttonToolbarBox;
|
|
|
|
auto optionalSettings = SNew(SVerticalBox);
|
|
OptionalSettings = optionalSettings;
|
|
|
|
auto expansionFilesSettings = SNew(SVerticalBox);
|
|
ExpansionFilesSettings = expansionFilesSettings;
|
|
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
BuildButtonToolbar(ButtonToolbar);
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
if (PlatformSettings->GetTargetPlatform() == (uint8)EOculusXRPlatformTarget::Rift)
|
|
{
|
|
BuildRiftOptionalFields(OptionalSettings);
|
|
}
|
|
else
|
|
{
|
|
OptionalSettings.Get()->ClearChildren();
|
|
}
|
|
}
|
|
|
|
FString ODHIconPath = IPluginManager::Get().FindPlugin(TEXT("OculusXR"))->GetBaseDir() / TEXT("Resources/Icon128.png");
|
|
const FName BrushName(*ODHIconPath);
|
|
FSlateApplication::Get().GetRenderer()->GenerateDynamicImageResource(BrushName);
|
|
ODHIconDynamicImageBrush = MakeShareable(new FSlateDynamicImageBrush(BrushName, FVector2D(60.0f, 60.0f)));
|
|
|
|
#if PLATFORM_MAC
|
|
FString odhLink = "https://developer.oculus.com/downloads/package/oculus-developer-hub-mac/?source=unreal";
|
|
#else
|
|
FString odhLink = "https://developer.oculus.com/downloads/package/oculus-developer-hub-win/?source=unreal";
|
|
#endif
|
|
|
|
ChildSlot
|
|
[SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("ToolPanel.LightGroupBorder"))
|
|
.Padding(2)
|
|
[SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot().Padding(0, 0).FillHeight(1.f)
|
|
[SNew(SScrollBox)
|
|
+ SScrollBox::Slot()
|
|
[SNew(SExpandableArea)
|
|
.HeaderPadding(5)
|
|
.Padding(5)
|
|
.BorderBackgroundColor(FLinearColor(0.4f, 0.4f, 0.4f, 1.0f))
|
|
.BodyBorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
.BodyBorderBackgroundColor(FLinearColor::White)
|
|
.InitiallyCollapsed(false)
|
|
.HeaderContent()
|
|
[SNew(SRichTextBlock)
|
|
.TextStyle(FAppStyle::Get(), "ToolBar.Heading")
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.AutoWrapText(true)
|
|
.Text(LOCTEXT("GeneralSettings", "<RichTextBlock.Bold>General Settings</>"))]
|
|
.BodyContent()
|
|
[mainVerticalBox]]
|
|
+ SScrollBox::Slot()
|
|
[SNew(SExpandableArea)
|
|
.HeaderPadding(5)
|
|
.Padding(5)
|
|
.BorderBackgroundColor(FLinearColor(0.4f, 0.4f, 0.4f, 1.0f))
|
|
.BodyBorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
.BodyBorderBackgroundColor(FLinearColor::White)
|
|
.InitiallyCollapsed(true)
|
|
.HeaderContent()
|
|
[SNew(SRichTextBlock)
|
|
.TextStyle(FAppStyle::Get(), "ToolBar.Heading")
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.AutoWrapText(true)
|
|
.Text(LOCTEXT("OptionalSettings", "<RichTextBlock.Bold>Optional Settings</>"))]
|
|
.BodyContent()
|
|
[SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot().AutoHeight()
|
|
[optionalSettings]]]
|
|
+ SScrollBox::Slot()
|
|
[SNew(SExpandableArea)
|
|
.HeaderPadding(5)
|
|
.Padding(5)
|
|
.BorderBackgroundColor(FLinearColor(0.4f, 0.4f, 0.4f, 1.0f))
|
|
.BodyBorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
.BodyBorderBackgroundColor(FLinearColor::White)
|
|
.InitiallyCollapsed(true)
|
|
.HeaderContent()
|
|
[SNew(SRichTextBlock)
|
|
.TextStyle(FAppStyle::Get(), "ToolBar.Heading")
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.AutoWrapText(true)
|
|
.Text(LOCTEXT("ExpansionFileSettings", "<RichTextBlock.Bold>Expansion Files</>"))]
|
|
.BodyContent()
|
|
[SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot().AutoHeight()
|
|
[expansionFilesSettings]]]]
|
|
+ SVerticalBox::Slot().AutoHeight()
|
|
[buttonToolbarBox]
|
|
+ SVerticalBox::Slot().FillHeight(1.f)
|
|
[SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
[logTextBox]]
|
|
+ SVerticalBox::Slot().AutoHeight().Padding(2.0f)
|
|
[SNew(SBorder)
|
|
.BorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(60.0f)
|
|
.HeightOverride(60.0f)
|
|
[SNew(SImage)
|
|
.Image(ODHIconDynamicImageBrush.IsValid() ? ODHIconDynamicImageBrush.Get() : nullptr)]]
|
|
+ SHorizontalBox::Slot().FillWidth(1.0f)
|
|
[SNew(SVerticalBox)
|
|
+ SVerticalBox::Slot().AutoHeight().Padding(2.0f)
|
|
[SNew(SRichTextBlock)
|
|
.Text(LOCTEXT("ODHCallout",
|
|
"<RichTextBlock.Bold>Oculus Developer Hub</> is a desktop companion tool that can upload builds, manage apps and reduce friction in daily Quest development."))
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.AutoWrapText(true)]
|
|
+ SVerticalBox::Slot().AutoHeight()
|
|
[SNew(SBox)
|
|
.HAlign(HAlign_Left)
|
|
[SNew(SHyperlinkLaunchURL, odhLink)
|
|
.Text(LOCTEXT("ODHDownloadPage", "Download Oculus Developer Hub"))
|
|
.ToolTipText(LOCTEXT("ODHDownloadPageTooltip", "Opens a page that provides the download link for Oculus Developer Hub"))]]]]]]];
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildGeneralSettingsBox(TSharedPtr<SVerticalBox> box)
|
|
{
|
|
if (PlatformSettings == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
box.Get()->ClearChildren();
|
|
|
|
BuildTextComboBoxField(GeneralSettingsBox, LOCTEXT("TargetPlatform", "Target Platform"),
|
|
&OculusPlatforms, OculusPlatforms[PlatformSettings->GetTargetPlatform()],
|
|
&SOculusPlatformToolWidget::OnPlatformSettingChanged);
|
|
|
|
// Build field for Oculus Application ID.
|
|
BuildTextField(box, LOCTEXT("AppID", "Oculus Application ID"), FText::FromString(PlatformSettings->GetApplicationID()),
|
|
LOCTEXT("AppIDTT", "Specifies the ID of your app. Obtained from the API tab of your app in the Oculus Dashboard."),
|
|
&SOculusPlatformToolWidget::OnApplicationIDChanged);
|
|
|
|
// Build field for Oculus Application Token.
|
|
BuildTextField(box, LOCTEXT("AppToken", "Oculus Application Token"), FText::FromString(PlatformSettings->GetApplicationToken()),
|
|
LOCTEXT("AppTokenTT", "Specifies the app secret token. Obtained from the API tab of your app in the Oculus Dashboard."),
|
|
&SOculusPlatformToolWidget::OnApplicationTokenChanged, true);
|
|
|
|
// Build field for Release Channel.
|
|
BuildTextField(box, LOCTEXT("ReleaseChannel", "Release Channel"), FText::FromString(PlatformSettings->GetReleaseChannel()),
|
|
LOCTEXT("ReleaseChannelTT", "Specifies the release channel for uploading the build. Release channel names are not case-sensitive."),
|
|
&SOculusPlatformToolWidget::OnReleaseChannelChanged);
|
|
|
|
// Build field for Release Notes.
|
|
BuildTextField(box, LOCTEXT("ReleaseNote", "Release Note"), FText::FromString(PlatformSettings->GetReleaseNote()),
|
|
LOCTEXT("ReleaseNoteTT", "Specifies the release note text shown to users."),
|
|
&SOculusPlatformToolWidget::OnReleaseNoteChanged);
|
|
|
|
// Platform specific fields.
|
|
if (PlatformSettings->GetTargetPlatform() == (uint8)EOculusXRPlatformTarget::Rift)
|
|
{
|
|
// Build field for Rift Build Directory.
|
|
BuildFileDirectoryField(box, LOCTEXT("BuildPath", "Rift Build Directory"), FText::FromString(PlatformSettings->OculusRiftBuildDirectory),
|
|
LOCTEXT("BuildPathTT", "Specifies the full path to the directory containing your build files."),
|
|
&SOculusPlatformToolWidget::OnSelectRiftBuildDirectory, &SOculusPlatformToolWidget::OnClearRiftBuildDirectory);
|
|
|
|
// Build field for Build Version.
|
|
BuildTextField(box, LOCTEXT("BuildVersion", "Build Version"), FText::FromString(PlatformSettings->OculusRiftBuildVersion),
|
|
LOCTEXT("BuildVersionTT", "Specifies the version number shown to users."),
|
|
&SOculusPlatformToolWidget::OnRiftBuildVersionChanged);
|
|
|
|
// Build field for Launch File Path.
|
|
BuildFileDirectoryField(box, LOCTEXT("LaunchPath", "Launch File Path"), FText::FromString(PlatformSettings->GetLaunchFilePath()),
|
|
LOCTEXT("LaunchPathTT", " Specifies the path to the executable that launches your app."),
|
|
&SOculusPlatformToolWidget::OnSelectLaunchFilePath, &SOculusPlatformToolWidget::OnClearLaunchFilePath);
|
|
}
|
|
else
|
|
{
|
|
// Build field for APK File Path.
|
|
BuildFileDirectoryField(box, LOCTEXT("APKLaunchPath", "APK File Path"), FText::FromString(PlatformSettings->GetLaunchFilePath()),
|
|
LOCTEXT("APKLaunchPathTT", " Specifies the path to the APK that launches your app."),
|
|
&SOculusPlatformToolWidget::OnSelectLaunchFilePath, &SOculusPlatformToolWidget::OnClearLaunchFilePath);
|
|
|
|
BuildCheckBoxField(box, LOCTEXT("UploadDebugSymbols", "Upload Debug Symbols"), PlatformSettings->UploadDebugSymbols,
|
|
LOCTEXT("UploadDebugSymbolsTT", "If checked, debug symbols will be uploaded along with the application."),
|
|
&SOculusPlatformToolWidget::OnUploadDebugSymbolsChanged);
|
|
|
|
if (PlatformSettings->UploadDebugSymbols)
|
|
{
|
|
if (bShowUploadDebugSymbols != PlatformSettings->UploadDebugSymbols)
|
|
{
|
|
if (PlatformSettings->GetSymbolDirPath().IsEmpty())
|
|
{
|
|
FString defaultPath = GenerateSymbolPath();
|
|
PlatformSettings->SetSymbolDirPath(FPaths::ConvertRelativePathToFull(defaultPath));
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
// Build field for Debug symbol directory path.
|
|
BuildFileDirectoryField(box, LOCTEXT("SymbolPath", "Symbol Directory Path"), FText::FromString(PlatformSettings->GetSymbolDirPath()),
|
|
LOCTEXT("SymbolPathTT", "Specifies the path to the directory containing the app symbols (libUE4.so)."),
|
|
&SOculusPlatformToolWidget::OnSelectSymbolDirPath, &SOculusPlatformToolWidget::OnClearSymbolDirPath, 1);
|
|
|
|
BuildCheckBoxField(box, LOCTEXT("DebugSymbolsOnly", "Upload Debug Symbols Only"), PlatformSettings->DebugSymbolsOnly,
|
|
LOCTEXT("DebugSymbolsOnlyTT", "If checked, the tool will upload onyl debug symbols to an existing build. Requires Build ID, App ID, App Token, and Debug Symbols Directory."),
|
|
&SOculusPlatformToolWidget::OnDebugSymbolsOnlyChanged, 1);
|
|
|
|
if (PlatformSettings->DebugSymbolsOnly)
|
|
{
|
|
BuildTextField(box, LOCTEXT("BuildID", "Build ID"), FText::FromString(PlatformSettings->BuildID),
|
|
LOCTEXT("BuildIDTT", "Specifies the Build ID to upload debug symbols to."),
|
|
&SOculusPlatformToolWidget::OnBuildIDChanged, false, 1);
|
|
}
|
|
}
|
|
bShowUploadDebugSymbols = PlatformSettings->UploadDebugSymbols;
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildTextField(TSharedPtr<SVerticalBox> box, FText name, FText text, FText tooltip,
|
|
PTextComittedDel deleg, bool isPassword, int32 indentAmount)
|
|
{
|
|
FMargin textMargin = FMargin(TEXT_INDENT_OFFSET * indentAmount, 1.0f, 1.0f, 1.0f);
|
|
|
|
box.Get()->AddSlot().Padding(1).AutoHeight()
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(250.f)
|
|
.Padding(textMargin)
|
|
[SNew(STextBlock)
|
|
.Text(name)
|
|
.ToolTipText(tooltip)]]
|
|
+ SHorizontalBox::Slot().Padding(1).FillWidth(1.f)
|
|
[SNew(SEditableTextBox)
|
|
.Text(text)
|
|
.IsPassword(isPassword)
|
|
.OnTextCommitted(this, deleg)]];
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildTextComboBoxField(TSharedPtr<SVerticalBox> box, FText name,
|
|
TArray<TSharedPtr<FString>>* options, TSharedPtr<FString> current, PTextComboBoxDel deleg, int32 indentAmount)
|
|
{
|
|
FMargin textMargin = FMargin(TEXT_INDENT_OFFSET * indentAmount, 1.0f, 1.0f, 1.0f);
|
|
|
|
box.Get()->AddSlot().Padding(1).AutoHeight()
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(250.f)
|
|
.Padding(textMargin)
|
|
[SNew(SRichTextBlock)
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.Text(name)]]
|
|
+ SHorizontalBox::Slot().Padding(1).FillWidth(1.f)
|
|
[SNew(STextComboBox)
|
|
.OptionsSource(options)
|
|
.InitiallySelectedItem(current)
|
|
.OnSelectionChanged(this, deleg)]];
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildCheckBoxField(TSharedPtr<SVerticalBox> box, FText name, bool check,
|
|
FText tooltip, PCheckBoxChangedDel deleg, int32 indentAmount)
|
|
{
|
|
FMargin textMargin = FMargin(TEXT_INDENT_OFFSET * indentAmount, 1.0f, 1.0f, 1.0f);
|
|
|
|
box.Get()->AddSlot().Padding(1).AutoHeight()
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(250.f)
|
|
.Padding(textMargin)
|
|
[SNew(SRichTextBlock)
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.Text(name)]]
|
|
+ SHorizontalBox::Slot().Padding(1).FillWidth(1.f)
|
|
[SNew(SCheckBox)
|
|
.OnCheckStateChanged(this, deleg)
|
|
.IsChecked(check ? ECheckBoxState::Checked : ECheckBoxState::Unchecked)]];
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildFileDirectoryField(TSharedPtr<SVerticalBox> box, FText name, FText path, FText tooltip,
|
|
PButtonClickedDel deleg, PButtonClickedDel clearDeleg, int32 indentAmount)
|
|
{
|
|
EVisibility cancelButtonVisibility = path.IsEmpty() ? EVisibility::Hidden : EVisibility::Visible;
|
|
FMargin textMargin = FMargin(TEXT_INDENT_OFFSET * indentAmount, 1.0f, 1.0f, 1.0f);
|
|
|
|
box.Get()->AddSlot().Padding(1).AutoHeight()
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(250.f)
|
|
.Padding(textMargin)
|
|
[SNew(STextBlock)
|
|
.Text(name)
|
|
.ToolTipText(tooltip)]]
|
|
+ SHorizontalBox::Slot().Padding(1).FillWidth(1.f)
|
|
[SNew(SEditableText)
|
|
.Text(path)
|
|
.IsReadOnly(true)
|
|
.Justification(ETextJustify::Left)]
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth().HAlign(EHorizontalAlignment::HAlign_Right)
|
|
[SNew(SButton)
|
|
.Text(FText::FromString("X"))
|
|
.Visibility(cancelButtonVisibility)
|
|
.OnClicked(this, clearDeleg)
|
|
.ButtonColorAndOpacity(FLinearColor(0.36f, 0.1f, 0.05f))]
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth().HAlign(EHorizontalAlignment::HAlign_Right)
|
|
[SNew(SButton)
|
|
.Text((LOCTEXT("Choose", "Choose...")))
|
|
.OnClicked(this, deleg)]];
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildButtonToolbar(TSharedPtr<SHorizontalBox> box)
|
|
{
|
|
box.Get()->ClearChildren();
|
|
|
|
box.Get()->AddSlot().FillWidth(1.f);
|
|
box.Get()->AddSlot().AutoWidth().Padding(2.f)
|
|
[SNew(SButton)
|
|
.Text((LOCTEXT("Upload", "Upload")))
|
|
.OnClicked(this, &SOculusPlatformToolWidget::OnStartPlatformUpload)
|
|
.IsEnabled(ActiveUploadButton)];
|
|
box.Get()->AddSlot().AutoWidth().Padding(2.f)
|
|
[SNew(SButton)
|
|
.Text((LOCTEXT("Cancel", "Cancel")))
|
|
.OnClicked(this, &SOculusPlatformToolWidget::OnCancelUpload)
|
|
.IsEnabled(!ActiveUploadButton)];
|
|
box.Get()->AddSlot().FillWidth(1.f);
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildRiftOptionalFields(TSharedPtr<SVerticalBox> box)
|
|
{
|
|
if (PlatformSettings == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
box.Get()->ClearChildren();
|
|
|
|
// Add Launch Parameter Field
|
|
BuildTextField(box, LOCTEXT("LaunchParams", "Launch Parameters"), FText::FromString(PlatformSettings->OculusRiftLaunchParams),
|
|
LOCTEXT("LaunchParamsTT", ""),
|
|
&SOculusPlatformToolWidget::OnRiftLaunchParamsChanged);
|
|
|
|
// Add Firewall Exception Toggle
|
|
BuildCheckBoxField(box, LOCTEXT("Firewall", "Firewall Exception"), PlatformSettings->OculusRiftFireWallException,
|
|
LOCTEXT("FirewallTT", ""),
|
|
&SOculusPlatformToolWidget::OnRiftFirewallChanged);
|
|
|
|
// Add Gamepad Emulation Dropdown
|
|
BuildTextComboBoxField(box, LOCTEXT("GamepadEmu", "Gamepad Emulation"),
|
|
&RiftGamepadEmulation, RiftGamepadEmulation[(uint8)PlatformSettings->GetRiftGamepadEmulation()],
|
|
&SOculusPlatformToolWidget::OnRiftGamepadEmulationChanged);
|
|
|
|
// Generate 2D Settings Expandable Area
|
|
TSharedRef<SVerticalBox> settings2DBox = SNew(SVerticalBox);
|
|
|
|
// Add 2D Launch File Field
|
|
BuildFileDirectoryField(settings2DBox, LOCTEXT("2DLaunch", "2D Launch File"), FText::FromString(PlatformSettings->OculusRift2DLaunchPath),
|
|
LOCTEXT("2DLaunchPathTT", ""),
|
|
&SOculusPlatformToolWidget::OnSelect2DLaunchPath, &SOculusPlatformToolWidget::OnClear2DLaunchPath);
|
|
|
|
// Add 2D Launch Parameter Field
|
|
BuildTextField(settings2DBox, LOCTEXT("2DLaunchParams", "2D Launch Parameters"), FText::FromString(PlatformSettings->OculusRift2DLaunchParams),
|
|
LOCTEXT("2DLaunchParamsTT", ""),
|
|
&SOculusPlatformToolWidget::On2DLaunchParamsChanged);
|
|
|
|
box.Get()->AddSlot().AutoHeight().Padding(1)
|
|
[SNew(SExpandableArea)
|
|
.HeaderPadding(5)
|
|
.Padding(5)
|
|
.BorderBackgroundColor(FLinearColor(0.4f, 0.4f, 0.4f, 1.0f))
|
|
.BodyBorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
.BodyBorderBackgroundColor(FLinearColor::White)
|
|
.InitiallyCollapsed(Options2DCollapsed)
|
|
.OnAreaExpansionChanged(this, &SOculusPlatformToolWidget::On2DOptionsExpanded)
|
|
.HeaderContent()
|
|
[SNew(SRichTextBlock)
|
|
.TextStyle(FAppStyle::Get(), "ToolBar.Heading")
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.AutoWrapText(true)
|
|
.Text(LOCTEXT("2DSettings", "<RichTextBlock.Bold>2D Settings</>"))]
|
|
.BodyContent()
|
|
[settings2DBox]];
|
|
|
|
BuildRedistPackagesBox(box);
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildRedistPackagesBox(TSharedPtr<SVerticalBox> box)
|
|
{
|
|
// Create check box toggle for each redistributable package we loaded
|
|
TSharedRef<SVerticalBox> redistBox = SNew(SVerticalBox);
|
|
for (int i = 0; i < PlatformSettings->OculusRedistPackages.Num(); i++)
|
|
{
|
|
FOculusXRRedistPackage* Package = &PlatformSettings->OculusRedistPackages[i];
|
|
redistBox->AddSlot()
|
|
.Padding(1)
|
|
.AutoHeight()
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(250.f)
|
|
[SNew(SRichTextBlock)
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.Text(FText::FromString(Package->Name))]]
|
|
+ SHorizontalBox::Slot().Padding(1).FillWidth(1.f)
|
|
[SNew(SCheckBox)
|
|
.OnCheckStateChanged(this, &SOculusPlatformToolWidget::OnRedistPackageStateChanged, Package)
|
|
.IsChecked(Package->Included ? ECheckBoxState::Checked : ECheckBoxState::Unchecked)]];
|
|
}
|
|
|
|
box.Get()->AddSlot().AutoHeight().Padding(1)
|
|
[SNew(SExpandableArea)
|
|
.HeaderPadding(5)
|
|
.Padding(5)
|
|
.BorderBackgroundColor(FLinearColor(0.4f, 0.4f, 0.4f, 1.0f))
|
|
.BodyBorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
.BodyBorderBackgroundColor(FLinearColor::White)
|
|
.InitiallyCollapsed(OptionsRedistPackagesCollapsed)
|
|
.OnAreaExpansionChanged(this, &SOculusPlatformToolWidget::OnRedistPackagesExpanded)
|
|
.HeaderContent()
|
|
[SNew(SRichTextBlock)
|
|
.TextStyle(FAppStyle::Get(), "ToolBar.Heading")
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.AutoWrapText(true)
|
|
.Text(LOCTEXT("RedistPack", "<RichTextBlock.Bold>Redistributable Packages</>"))]
|
|
.BodyContent()
|
|
[redistBox]];
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildExpansionFileBox(TSharedPtr<SVerticalBox> box)
|
|
{
|
|
if (PlatformSettings == nullptr)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ExpansionFilesSettings.Get()->ClearChildren();
|
|
|
|
if (PlatformSettings->GetTargetPlatform() == (uint8)EOculusXRPlatformTarget::Rift)
|
|
{
|
|
BuildFileDirectoryField(box, LOCTEXT("LanguagePacks", "Language Packs Directory"), FText::FromString(PlatformSettings->GetLanguagePacksPath()),
|
|
LOCTEXT("LanguagePacksTT", ""), &SOculusPlatformToolWidget::OnSelectLanguagePacksPath, &SOculusPlatformToolWidget::OnClearLanguagePacksPath);
|
|
}
|
|
|
|
BuildFileDirectoryField(box, LOCTEXT("ExpansionFilesDirectory", "Expansion Files Directory"), FText::FromString(PlatformSettings->GetExpansionFilesPath()),
|
|
LOCTEXT("ExpansionFilesTT", ""), &SOculusPlatformToolWidget::OnSelectExpansionFilesPath, &SOculusPlatformToolWidget::OnClearExpansionFilesPath);
|
|
|
|
TArray<FOculusXRAssetConfig>* AssetConfigs = PlatformSettings->GetAssetConfigs();
|
|
if (AssetConfigs)
|
|
{
|
|
for (int i = 0; i < AssetConfigs->Num(); i++)
|
|
{
|
|
auto AssetConfigBox = SNew(SVerticalBox);
|
|
BuildAssetConfigBox(AssetConfigBox, (*AssetConfigs)[i], i);
|
|
|
|
box.Get()->AddSlot().AutoHeight().Padding(1)
|
|
[SNew(SExpandableArea)
|
|
.HeaderPadding(5)
|
|
.Padding(5)
|
|
.BorderBackgroundColor(FLinearColor(0.4f, 0.4f, 0.4f, 1.0f))
|
|
.BodyBorderImage(FAppStyle::GetBrush("ToolPanel.GroupBorder"))
|
|
.BodyBorderBackgroundColor(FLinearColor::White)
|
|
.HeaderContent()
|
|
[SNew(SRichTextBlock)
|
|
.TextStyle(FAppStyle::Get(), "ToolBar.Heading")
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.AutoWrapText(true)
|
|
.Text(FText::FromString((*AssetConfigs)[i].Name))]
|
|
.BodyContent()
|
|
[AssetConfigBox]];
|
|
}
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::BuildAssetConfigBox(TSharedPtr<SVerticalBox> box, FOculusXRAssetConfig config, int index)
|
|
{
|
|
box.Get()->AddSlot().Padding(1).AutoHeight()
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(250.f)
|
|
[SNew(SRichTextBlock)
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.Text(LOCTEXT("AssetType", "Asset Type"))]]
|
|
+ SHorizontalBox::Slot().Padding(1).FillWidth(1.f)
|
|
[SNew(STextComboBox)
|
|
.OptionsSource(&AssetType)
|
|
.InitiallySelectedItem(AssetType[(uint8)config.AssetType])
|
|
.OnSelectionChanged(this, &SOculusPlatformToolWidget::OnAssetConfigTypeChanged, index)]];
|
|
|
|
box.Get()->AddSlot().Padding(1).AutoHeight()
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(250.f)
|
|
[SNew(SRichTextBlock)
|
|
.DecoratorStyleSet(&FAppStyle::Get())
|
|
.Text(LOCTEXT("AssetRequired", "Required"))]]
|
|
+ SHorizontalBox::Slot().Padding(1).FillWidth(1.f)
|
|
[SNew(SCheckBox)
|
|
.OnCheckStateChanged(this, &SOculusPlatformToolWidget::OnAssetConfigRequiredChanged, index)
|
|
.IsChecked(config.Required ? ECheckBoxState::Checked : ECheckBoxState::Unchecked)]];
|
|
|
|
box.Get()->AddSlot().Padding(1).AutoHeight()
|
|
[SNew(SHorizontalBox)
|
|
+ SHorizontalBox::Slot().Padding(1).AutoWidth()
|
|
[SNew(SBox)
|
|
.WidthOverride(250.f)
|
|
[SNew(STextBlock)
|
|
.Text(LOCTEXT("SKU", "SKU"))]]
|
|
+ SHorizontalBox::Slot().Padding(1).FillWidth(1.f)
|
|
[SNew(SEditableTextBox)
|
|
.Text(FText::FromString(config.Sku))
|
|
.OnTextCommitted(this, &SOculusPlatformToolWidget::OnAssetConfigSKUChanged, index)]];
|
|
}
|
|
|
|
bool SOculusPlatformToolWidget::ConstructArguments(FString& args)
|
|
{
|
|
if (PlatformSettings == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (PlatformSettings->UploadDebugSymbols && PlatformSettings->DebugSymbolsOnly)
|
|
{
|
|
return ConstructDebugSymbolArguments(args);
|
|
}
|
|
|
|
// Build the args string that will be passed to the CLI. Print all errors that occur to the log.
|
|
bool success = true;
|
|
|
|
switch (PlatformSettings->GetTargetPlatform())
|
|
{
|
|
case (uint8)EOculusXRPlatformTarget::Rift:
|
|
args = "upload-rift-build";
|
|
break;
|
|
case (uint8)EOculusXRPlatformTarget::Quest:
|
|
args = "upload-quest-build";
|
|
break;
|
|
default:
|
|
UpdateLogText(LogText + "ERROR: Invalid target platform selected");
|
|
success = false;
|
|
break;
|
|
}
|
|
|
|
// Oculus Application ID check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::IDFieldValidator, PlatformSettings->GetApplicationID(),
|
|
LOCTEXT("ApplicationID", "Application ID").ToString(), success);
|
|
args += " --app_id \"" + PlatformSettings->GetApplicationID() + "\"";
|
|
|
|
// Oculus Application Token check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::GenericFieldValidator, PlatformSettings->GetApplicationToken(),
|
|
LOCTEXT("ApplicationToken", "Application Token").ToString(), success);
|
|
args += " --app_secret \"" + PlatformSettings->GetApplicationToken() + "\"";
|
|
|
|
// Release Channel check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::GenericFieldValidator, PlatformSettings->GetReleaseChannel(),
|
|
LOCTEXT("ReleaseChannel", "Release Channel").ToString(), success);
|
|
args += " --channel \"" + PlatformSettings->GetReleaseChannel() + "\"";
|
|
|
|
// Release Note check and command. Not a required command.
|
|
if (!PlatformSettings->GetReleaseNote().IsEmpty())
|
|
{
|
|
FString SanatizedReleaseNote = PlatformSettings->GetReleaseNote();
|
|
SanatizedReleaseNote = SanatizedReleaseNote.Replace(TEXT("\""), TEXT("\"\""));
|
|
args += " --notes \"" + SanatizedReleaseNote + "\"";
|
|
}
|
|
|
|
// Platform specific commands
|
|
if (PlatformSettings->GetTargetPlatform() == (uint8)EOculusXRPlatformTarget::Rift)
|
|
{
|
|
// Launch File Path check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::FileFieldValidator, PlatformSettings->GetLaunchFilePath(),
|
|
LOCTEXT("LaunchFile", "Launch File Path").ToString(), success);
|
|
args += " --launch-file \"" + PlatformSettings->GetLaunchFilePath() + "\"";
|
|
|
|
// Rift Build Directory check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::DirectoryFieldValidator, PlatformSettings->OculusRiftBuildDirectory,
|
|
LOCTEXT("RiftBuildDir", "Rift Build Directory").ToString(), success);
|
|
args += " --build_dir \"" + PlatformSettings->OculusRiftBuildDirectory + "\"";
|
|
|
|
// Rift Build Version check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::GenericFieldValidator, PlatformSettings->OculusRiftBuildVersion,
|
|
LOCTEXT("BuildVersion", "Build Version").ToString(), success);
|
|
args += " --version \"" + PlatformSettings->OculusRiftBuildVersion + "\"";
|
|
|
|
// Rift Launch Parameters check and command
|
|
if (!PlatformSettings->OculusRiftLaunchParams.IsEmpty())
|
|
{
|
|
ValidateTextField(&SOculusPlatformToolWidget::LaunchParamValidator, PlatformSettings->OculusRiftLaunchParams,
|
|
LOCTEXT("LaunchParam", "Launch Parameters").ToString(), success);
|
|
args += " --launch_params \"" + PlatformSettings->OculusRiftLaunchParams + "\"";
|
|
}
|
|
|
|
// Rift 2D Options checks and commands
|
|
if (!PlatformSettings->OculusRift2DLaunchPath.IsEmpty())
|
|
{
|
|
ValidateTextField(&SOculusPlatformToolWidget::FileFieldValidator, PlatformSettings->OculusRift2DLaunchPath,
|
|
LOCTEXT("2DLaunchFile", "2D Launch File Path").ToString(), success);
|
|
args += " --launch_file_2d \"" + PlatformSettings->OculusRift2DLaunchPath + "\"";
|
|
|
|
if (!PlatformSettings->OculusRift2DLaunchParams.IsEmpty())
|
|
{
|
|
ValidateTextField(&SOculusPlatformToolWidget::LaunchParamValidator, PlatformSettings->OculusRift2DLaunchParams,
|
|
LOCTEXT("2DLaunchParams", "2D Launch Parameters").ToString(), success);
|
|
args += " --launch_params_2d \"" + PlatformSettings->OculusRift2DLaunchParams + "\"";
|
|
}
|
|
}
|
|
|
|
// Rift Firewall Exception command
|
|
if (PlatformSettings->OculusRiftFireWallException)
|
|
{
|
|
args += " --firewall_exceptions true";
|
|
}
|
|
|
|
// Rift Gamepad Emulation command
|
|
if (PlatformSettings->GetRiftGamepadEmulation() > EOculusXRGamepadEmulation::Off && PlatformSettings->GetRiftGamepadEmulation() < EOculusXRGamepadEmulation::Length)
|
|
{
|
|
args += " --gamepad-emulation ";
|
|
switch (PlatformSettings->GetRiftGamepadEmulation())
|
|
{
|
|
case EOculusXRGamepadEmulation::Twinstick:
|
|
args += "TWINSTICK";
|
|
break;
|
|
case EOculusXRGamepadEmulation::RightDPad:
|
|
args += "RIGHT_D_PAD";
|
|
break;
|
|
case EOculusXRGamepadEmulation::LeftDPad:
|
|
args += "LEFT_D_PAD";
|
|
break;
|
|
default:
|
|
args += "OFF";
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Rift Redistributable Packages commands
|
|
TArray<FString> IncludedPackages;
|
|
for (int i = 0; i < PlatformSettings->OculusRedistPackages.Num(); i++)
|
|
{
|
|
FOculusXRRedistPackage Package = PlatformSettings->OculusRedistPackages[i];
|
|
if (Package.Included)
|
|
{
|
|
IncludedPackages.Add(Package.Id);
|
|
}
|
|
}
|
|
if (IncludedPackages.Num() > 0)
|
|
{
|
|
args += " --redistributables \"" + FString::Join(IncludedPackages, TEXT(",")) + "\"";
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// APK File Path check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::FileFieldValidator, PlatformSettings->GetLaunchFilePath(),
|
|
LOCTEXT("APKLaunchFile", "APK File Path").ToString(), success);
|
|
args += " --apk \"" + PlatformSettings->GetLaunchFilePath() + "\"";
|
|
|
|
if (PlatformSettings->UploadDebugSymbols)
|
|
{
|
|
ValidateTextField(&SOculusPlatformToolWidget::DirectoryFieldValidator, PlatformSettings->GetSymbolDirPath(),
|
|
LOCTEXT("SymbolDirPath", "Symbol Directory Path").ToString(), success);
|
|
if (success)
|
|
{
|
|
args += " --debug-symbols-dir \"" + PlatformSettings->GetSymbolDirPath() + "\"";
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!PlatformSettings->GetExpansionFilesPath().IsEmpty())
|
|
{
|
|
ValidateTextField(&SOculusPlatformToolWidget::DirectoryFieldValidator, PlatformSettings->GetExpansionFilesPath(),
|
|
LOCTEXT("ExpansionFilesPath", "Expansion Files Path").ToString(), success);
|
|
args += " --assets-dir \"" + PlatformSettings->GetExpansionFilesPath() + "\"";
|
|
|
|
TArray<FOculusXRAssetConfig>* AssetConfigs = PlatformSettings->GetAssetConfigs();
|
|
if (AssetConfigs->Num() > 0)
|
|
{
|
|
TArray<FString> AssetConfig;
|
|
for (int i = 0; i < AssetConfigs->Num(); i++)
|
|
{
|
|
TArray<FString> ConfigParams;
|
|
FOculusXRAssetConfig Config = (*AssetConfigs)[i];
|
|
|
|
if (Config.Required)
|
|
{
|
|
ConfigParams.Add("\\\"required\\\":true");
|
|
}
|
|
if (Config.AssetType > EOculusXRAssetType::Default && Config.AssetType < EOculusXRAssetType::Length)
|
|
{
|
|
FString command = "\\\"type\\\":";
|
|
switch (Config.AssetType)
|
|
{
|
|
case EOculusXRAssetType::Store:
|
|
ConfigParams.Add(command + "\\\"STORE\\\"");
|
|
break;
|
|
case EOculusXRAssetType::Language_Pack:
|
|
ConfigParams.Add(command + "\\\"LANGUAGE_PACK\\\"");
|
|
break;
|
|
default:
|
|
ConfigParams.Add(command + "\\\"DEFAULT\\\"");
|
|
break;
|
|
}
|
|
}
|
|
if (!Config.Sku.IsEmpty())
|
|
{
|
|
ConfigParams.Add("\\\"sku\\\":\\\"" + Config.Sku + "\\\"");
|
|
}
|
|
|
|
if (ConfigParams.Num() > 0)
|
|
{
|
|
FString ConfigCommand = "\\\"" + Config.Name + "\\\":{" + FString::Join(ConfigParams, TEXT(",")) + "}";
|
|
AssetConfig.Add(ConfigCommand);
|
|
}
|
|
}
|
|
|
|
if (AssetConfig.Num())
|
|
{
|
|
args += " --asset_files_config {" + FString::Join(AssetConfig, TEXT(",")) + "}";
|
|
}
|
|
}
|
|
}
|
|
|
|
args += " --upload-from-engine UNREAL";
|
|
|
|
UE_LOG(LogTemp, Warning, TEXT("%s"), *args);
|
|
return success;
|
|
}
|
|
|
|
bool SOculusPlatformToolWidget::ConstructDebugSymbolArguments(FString& args)
|
|
{
|
|
bool success = true;
|
|
args = "upload-debug-symbols";
|
|
|
|
ValidateTextField(&SOculusPlatformToolWidget::IDFieldValidator, PlatformSettings->BuildID,
|
|
LOCTEXT("BuildID", "Build ID").ToString(), success);
|
|
args += " --parent \"" + PlatformSettings->BuildID + "\"";
|
|
|
|
// Oculus Application ID check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::IDFieldValidator, PlatformSettings->GetApplicationID(),
|
|
LOCTEXT("ApplicationID", "Application ID").ToString(), success);
|
|
args += " --app_id \"" + PlatformSettings->GetApplicationID() + "\"";
|
|
|
|
// Oculus Application Token check and command.
|
|
ValidateTextField(&SOculusPlatformToolWidget::GenericFieldValidator, PlatformSettings->GetApplicationToken(),
|
|
LOCTEXT("ApplicationToken", "Application Token").ToString(), success);
|
|
args += " --app_secret \"" + PlatformSettings->GetApplicationToken() + "\"";
|
|
|
|
ValidateTextField(&SOculusPlatformToolWidget::DirectoryFieldValidator, PlatformSettings->GetSymbolDirPath(),
|
|
LOCTEXT("SymbolDirPath", "Symbol Directory Path").ToString(), success);
|
|
args += " --debug-symbols-dir \"" + PlatformSettings->GetSymbolDirPath() + "\"";
|
|
args += " --debug-symbols-pattern \"*.so\"";
|
|
|
|
return success;
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::EnableUploadButton(bool enabled)
|
|
{
|
|
RequestUploadButtonActive = enabled;
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::LoadConfigSettings()
|
|
{
|
|
PlatformSettings = GetMutableDefault<UOculusXRPlatformToolSettings>();
|
|
PlatformEnum = StaticEnum<EOculusXRPlatformTarget>();
|
|
GamepadEmulationEnum = StaticEnum<EOculusXRGamepadEmulation>();
|
|
AssetTypeEnum = StaticEnum<EOculusXRAssetType>();
|
|
|
|
RiftGamepadEmulation.Empty();
|
|
OculusPlatforms.Empty();
|
|
for (uint8 i = 0; i < (uint8)EOculusXRPlatformTarget::Length; i++)
|
|
{
|
|
OculusPlatforms.Add(MakeShareable(new FString(PlatformEnum->GetDisplayNameTextByIndex((int64)i).ToString())));
|
|
}
|
|
for (uint8 i = 0; i < (uint8)EOculusXRGamepadEmulation::Length; i++)
|
|
{
|
|
RiftGamepadEmulation.Add(MakeShareable(new FString(GamepadEmulationEnum->GetDisplayNameTextByIndex((int64)i).ToString())));
|
|
}
|
|
for (uint8 i = 0; i < (uint8)EOculusXRAssetType::Length; i++)
|
|
{
|
|
AssetType.Add(MakeShareable(new FString(AssetTypeEnum->GetDisplayNameTextByIndex((int64)i).ToString())));
|
|
}
|
|
|
|
LoadRedistPackages();
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::LoadRedistPackages()
|
|
{
|
|
(new FAsyncTask<FPlatformLoadRedistPackagesTask>(UpdateLogTextDel))->StartBackgroundTask();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnStartPlatformUpload()
|
|
{
|
|
FString launchArgs;
|
|
|
|
UpdateLogText("");
|
|
FOculusXRHMDModule::GetPluginWrapper().SendEvent2("oculus_platform_tool", "upload", "integration");
|
|
if (ConstructArguments(launchArgs))
|
|
{
|
|
UpdateLogText(LogText + LOCTEXT("StartUpload", "Starting Platform Tool Upload Process . . .\n").ToString());
|
|
(new FAsyncTask<FPlatformUploadTask>(launchArgs, EnableUploadButtonDel, UpdateLogTextDel, SetProcessDel))->StartBackgroundTask();
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnPlatformSettingChanged(TSharedPtr<FString> ItemSelected, ESelectInfo::Type SelectInfo)
|
|
{
|
|
if (!ItemSelected.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (uint8 i = 0; i < (uint8)EOculusXRPlatformTarget::Length; i++)
|
|
{
|
|
if (PlatformEnum->GetDisplayNameTextByIndex(i).EqualTo(FText::FromString(*ItemSelected)))
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetTargetPlatform(i);
|
|
PlatformSettings->SaveConfig();
|
|
|
|
LoadConfigSettings();
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
|
|
OptionalSettings.Get()->ClearChildren();
|
|
if (i == (uint8)EOculusXRPlatformTarget::Rift)
|
|
{
|
|
BuildRiftOptionalFields(OptionalSettings);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnApplicationIDChanged(const FText& InText, ETextCommit::Type InCommitType)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetApplicationID(InText.ToString());
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnApplicationTokenChanged(const FText& InText, ETextCommit::Type InCommitType)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetApplicationToken(InText.ToString());
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnReleaseChannelChanged(const FText& InText, ETextCommit::Type InCommitType)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetReleaseChannel(InText.ToString());
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnReleaseNoteChanged(const FText& InText, ETextCommit::Type InCommitType)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetReleaseNote(InText.ToString());
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnRiftBuildVersionChanged(const FText& InText, ETextCommit::Type InCommitType)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->OculusRiftBuildVersion = InText.ToString();
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnRiftLaunchParamsChanged(const FText& InText, ETextCommit::Type InCommitType)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->OculusRiftLaunchParams = InText.ToString();
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::On2DLaunchParamsChanged(const FText& InText, ETextCommit::Type InCommitType)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->OculusRift2DLaunchParams = InText.ToString();
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnRiftFirewallChanged(ECheckBoxState CheckState)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->OculusRiftFireWallException = CheckState == ECheckBoxState::Checked ? true : false;
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnRedistPackageStateChanged(ECheckBoxState CheckState, FOculusXRRedistPackage* Package)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
Package->Included = CheckState == ECheckBoxState::Checked;
|
|
PlatformSettings->SaveConfig();
|
|
BuildRiftOptionalFields(OptionalSettings);
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnAssetConfigTypeChanged(TSharedPtr<FString> ItemSelected, ESelectInfo::Type SelectInfo, int i)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
TArray<FOculusXRAssetConfig>* AssetConfigs = PlatformSettings->GetAssetConfigs();
|
|
for (int e = 0; e < (uint8)EOculusXRAssetType::Length; e++)
|
|
{
|
|
if (AssetTypeEnum->GetDisplayNameTextByIndex(e).ToString().Equals(*ItemSelected.Get()))
|
|
{
|
|
(*AssetConfigs)[i].AssetType = (EOculusXRAssetType)e;
|
|
break;
|
|
}
|
|
}
|
|
|
|
PlatformSettings->SaveConfig();
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnAssetConfigRequiredChanged(ECheckBoxState CheckState, int i)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
TArray<FOculusXRAssetConfig>* AssetConfigs = PlatformSettings->GetAssetConfigs();
|
|
(*AssetConfigs)[i].Required = CheckState == ECheckBoxState::Checked;
|
|
|
|
PlatformSettings->SaveConfig();
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnAssetConfigSKUChanged(const FText& InText, ETextCommit::Type InCommitType, int i)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
TArray<FOculusXRAssetConfig>* AssetConfigs = PlatformSettings->GetAssetConfigs();
|
|
(*AssetConfigs)[i].Sku = InText.ToString();
|
|
|
|
PlatformSettings->SaveConfig();
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnUploadDebugSymbolsChanged(ECheckBoxState CheckState)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->UploadDebugSymbols = CheckState == ECheckBoxState::Checked ? true : false;
|
|
PlatformSettings->SaveConfig();
|
|
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnDebugSymbolsOnlyChanged(ECheckBoxState CheckState)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->DebugSymbolsOnly = CheckState == ECheckBoxState::Checked ? true : false;
|
|
PlatformSettings->SaveConfig();
|
|
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnBuildIDChanged(const FText& InText, ETextCommit::Type InCommitType)
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->BuildID = InText.ToString();
|
|
PlatformSettings->SaveConfig();
|
|
}
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnRiftGamepadEmulationChanged(TSharedPtr<FString> ItemSelected, ESelectInfo::Type SelectInfo)
|
|
{
|
|
if (!ItemSelected.IsValid())
|
|
{
|
|
return;
|
|
}
|
|
|
|
for (uint8 i = 0; i < (uint8)EOculusXRGamepadEmulation::Length; i++)
|
|
{
|
|
if (GamepadEmulationEnum->GetDisplayNameTextByIndex(i).EqualTo(FText::FromString(*ItemSelected)))
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetRiftGamepadEmulation(i);
|
|
PlatformSettings->SaveConfig();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnSelectRiftBuildDirectory()
|
|
{
|
|
TSharedPtr<SWindow> parentWindow = FSlateApplication::Get().FindWidgetWindow(AsShared());
|
|
const void* parentWindowHandle = (parentWindow.IsValid() && parentWindow->GetNativeWindow().IsValid()) ? parentWindow->GetNativeWindow()->GetOSWindowHandle() : nullptr;
|
|
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
FString path;
|
|
FString defaultPath = PlatformSettings->OculusRiftBuildDirectory.IsEmpty() ? FPaths::ProjectContentDir() : PlatformSettings->OculusRiftBuildDirectory;
|
|
if (FDesktopPlatformModule::Get()->OpenDirectoryDialog(parentWindowHandle, "Choose Rift Build Directory", defaultPath, path))
|
|
{
|
|
PlatformSettings->OculusRiftBuildDirectory = path;
|
|
PlatformSettings->SaveConfig();
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
}
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnClearRiftBuildDirectory()
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->OculusRiftBuildDirectory.Empty();
|
|
PlatformSettings->SaveConfig();
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnSelectLaunchFilePath()
|
|
{
|
|
TSharedPtr<SWindow> parentWindow = FSlateApplication::Get().FindWidgetWindow(AsShared());
|
|
const void* parentWindowHandle = (parentWindow.IsValid() && parentWindow->GetNativeWindow().IsValid()) ? parentWindow->GetNativeWindow()->GetOSWindowHandle() : nullptr;
|
|
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
TArray<FString> path;
|
|
FString defaultPath = PlatformSettings->GetLaunchFilePath().IsEmpty() ? FPaths::ProjectContentDir() : PlatformSettings->GetLaunchFilePath();
|
|
FString fileType = PlatformSettings->GetTargetPlatform() == (uint8)EOculusXRPlatformTarget::Rift ? "Executables (*.exe)|*.exe" : "APKs (*.apk)|*.apk";
|
|
if (FDesktopPlatformModule::Get()->OpenFileDialog(parentWindowHandle, "Choose Launch File", defaultPath, defaultPath, fileType, EFileDialogFlags::None, path))
|
|
{
|
|
if (path.Num() > 0)
|
|
{
|
|
PlatformSettings->SetLaunchFilePath(FPaths::ConvertRelativePathToFull(path[0]));
|
|
}
|
|
PlatformSettings->SaveConfig();
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
}
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnClearLaunchFilePath()
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetLaunchFilePath("");
|
|
PlatformSettings->SaveConfig();
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FString SOculusPlatformToolWidget::GenerateSymbolPath()
|
|
{
|
|
return FPaths::ProjectDir() + TEXT("Binaries/Android/") + FApp::GetProjectName() + TEXT("_Symbols_v1/") + FApp::GetProjectName() + TEXT("-arm64");
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnSelectSymbolDirPath()
|
|
{
|
|
TSharedPtr<SWindow> parentWindow = FSlateApplication::Get().FindWidgetWindow(AsShared());
|
|
const void* parentWindowHandle = (parentWindow.IsValid() && parentWindow->GetNativeWindow().IsValid()) ? parentWindow->GetNativeWindow()->GetOSWindowHandle() : nullptr;
|
|
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
FString dirPath;
|
|
FString defaultPath = PlatformSettings->GetSymbolDirPath().IsEmpty() ? GenerateSymbolPath() : PlatformSettings->GetSymbolDirPath();
|
|
if (FDesktopPlatformModule::Get()->OpenDirectoryDialog(parentWindowHandle, "Choose Launch File", defaultPath, dirPath))
|
|
{
|
|
PlatformSettings->SetSymbolDirPath(FPaths::ConvertRelativePathToFull(dirPath));
|
|
PlatformSettings->SaveConfig();
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
}
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnClearSymbolDirPath()
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetSymbolDirPath("");
|
|
PlatformSettings->SaveConfig();
|
|
BuildGeneralSettingsBox(GeneralSettingsBox);
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnSelect2DLaunchPath()
|
|
{
|
|
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
TSharedPtr<SWindow> parentWindow = FSlateApplication::Get().FindWidgetWindow(AsShared());
|
|
const void* parentWindowHandle = (parentWindow.IsValid() && parentWindow->GetNativeWindow().IsValid()) ? parentWindow->GetNativeWindow()->GetOSWindowHandle() : nullptr;
|
|
TArray<FString> path;
|
|
FString defaultPath = PlatformSettings->OculusRift2DLaunchPath.IsEmpty() ? FPaths::ProjectContentDir() : PlatformSettings->OculusRift2DLaunchPath;
|
|
if (FDesktopPlatformModule::Get()->OpenFileDialog(parentWindowHandle, "Choose 2D Launch File", defaultPath, defaultPath, "Executables (*.exe)|*.exe", EFileDialogFlags::None, path))
|
|
{
|
|
if (path.Num() > 0)
|
|
{
|
|
PlatformSettings->OculusRift2DLaunchPath = FPaths::ConvertRelativePathToFull(path[0]);
|
|
}
|
|
PlatformSettings->SaveConfig();
|
|
BuildRiftOptionalFields(OptionalSettings);
|
|
}
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnClear2DLaunchPath()
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->OculusRift2DLaunchPath.Empty();
|
|
PlatformSettings->SaveConfig();
|
|
BuildRiftOptionalFields(OptionalSettings);
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnCancelUpload()
|
|
{
|
|
if (FMessageDialog::Open(EAppMsgType::OkCancel, LOCTEXT("CancelUploadWarning", "Are you sure you want to cancel the upload process?")) == EAppReturnType::Ok)
|
|
{
|
|
if (PlatformProcess.IsValid())
|
|
{
|
|
FPlatformProcess::TerminateProc(PlatformProcess);
|
|
UpdateLogText(LogText + LOCTEXT("UploadCancel", "Upload process was canceled.").ToString());
|
|
}
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnSelectLanguagePacksPath()
|
|
{
|
|
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
TSharedPtr<SWindow> parentWindow = FSlateApplication::Get().FindWidgetWindow(AsShared());
|
|
const void* parentWindowHandle = (parentWindow.IsValid() && parentWindow->GetNativeWindow().IsValid()) ? parentWindow->GetNativeWindow()->GetOSWindowHandle() : nullptr;
|
|
FString path;
|
|
FString defaultPath = PlatformSettings->GetLanguagePacksPath().IsEmpty() ? FPaths::ProjectContentDir() : PlatformSettings->GetLanguagePacksPath();
|
|
if (FDesktopPlatformModule::Get()->OpenDirectoryDialog(parentWindowHandle, "Choose Language Packs Directory", defaultPath, path))
|
|
{
|
|
PlatformSettings->SetLanguagePacksPath(path);
|
|
PlatformSettings->SaveConfig();
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
}
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnClearLanguagePacksPath()
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetLanguagePacksPath("");
|
|
PlatformSettings->SaveConfig();
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnSelectExpansionFilesPath()
|
|
{
|
|
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
TSharedPtr<SWindow> parentWindow = FSlateApplication::Get().FindWidgetWindow(AsShared());
|
|
const void* parentWindowHandle = (parentWindow.IsValid() && parentWindow->GetNativeWindow().IsValid()) ? parentWindow->GetNativeWindow()->GetOSWindowHandle() : nullptr;
|
|
FString path;
|
|
FString defaultPath = PlatformSettings->GetExpansionFilesPath().IsEmpty() ? FPaths::ProjectContentDir() : PlatformSettings->GetExpansionFilesPath();
|
|
if (FDesktopPlatformModule::Get()->OpenDirectoryDialog(parentWindowHandle, "Choose Expansion Files Directory", defaultPath, path))
|
|
{
|
|
if (!path.Equals(PlatformSettings->GetExpansionFilesPath()))
|
|
{
|
|
if (!path.IsEmpty() && FPaths::DirectoryExists(path))
|
|
{
|
|
TArray<FString> Files;
|
|
//FFileManagerGeneric::Get().FindFilesRecursive(Files, *path, TEXT("*.*"), true, false, false);
|
|
IFileManager::Get().FindFiles(Files, *path);
|
|
|
|
TArray<FOculusXRAssetConfig>* AssetConfigs = PlatformSettings->GetAssetConfigs();
|
|
for (int i = 0; i < Files.Num(); i++)
|
|
{
|
|
FOculusXRAssetConfig AssetConfig;
|
|
AssetConfig.Name = Files[i];
|
|
AssetConfigs->Push(AssetConfig);
|
|
}
|
|
|
|
PlatformSettings->SetExpansionFilesPath(path);
|
|
PlatformSettings->SaveConfig();
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
FReply SOculusPlatformToolWidget::OnClearExpansionFilesPath()
|
|
{
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
PlatformSettings->SetExpansionFilesPath("");
|
|
PlatformSettings->GetAssetConfigs()->Empty();
|
|
PlatformSettings->SaveConfig();
|
|
BuildExpansionFileBox(ExpansionFilesSettings);
|
|
}
|
|
return FReply::Handled();
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::ValidateTextField(PFieldValidatorDel del, FString text, FString name, bool& success)
|
|
{
|
|
FString error = "";
|
|
FFieldValidatorDel fieldValidator;
|
|
|
|
// Check the given field with the given field validator and print the error if it fails.
|
|
fieldValidator.BindSP(this, del);
|
|
if (!fieldValidator.Execute(text, error))
|
|
{
|
|
FString errorMessage = LOCTEXT("Error", "ERROR: Please verify that the {0} is correct. ").ToString();
|
|
errorMessage = FString::Format(*errorMessage, { name });
|
|
UpdateLogText(LogText + errorMessage + (error.IsEmpty() ? "\n" : error + "\n"));
|
|
success = false;
|
|
}
|
|
}
|
|
|
|
bool SOculusPlatformToolWidget::GenericFieldValidator(FString text, FString& error)
|
|
{
|
|
if (text.IsEmpty())
|
|
{
|
|
error = LOCTEXT("FieldEmpty", "The field is empty.").ToString();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool SOculusPlatformToolWidget::IDFieldValidator(FString text, FString& error)
|
|
{
|
|
const FRegexPattern RegExPat(TEXT("^[0-9]+$"));
|
|
FRegexMatcher RegMatcher(RegExPat, text);
|
|
|
|
if (!GenericFieldValidator(text, error))
|
|
{
|
|
return false;
|
|
}
|
|
else if (!RegMatcher.FindNext())
|
|
{
|
|
error = LOCTEXT("InvalidChar", "The field contains invalid characters.").ToString();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool SOculusPlatformToolWidget::DirectoryFieldValidator(FString text, FString& error)
|
|
{
|
|
if (!GenericFieldValidator(text, error))
|
|
{
|
|
return false;
|
|
}
|
|
if (!FPaths::DirectoryExists(text))
|
|
{
|
|
error = LOCTEXT("DirectoryNull", "The directory does not exist.").ToString();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool SOculusPlatformToolWidget::FileFieldValidator(FString text, FString& error)
|
|
{
|
|
if (!GenericFieldValidator(text, error))
|
|
{
|
|
return false;
|
|
}
|
|
if (!FPaths::FileExists(text))
|
|
{
|
|
error = LOCTEXT("FileNull", "The file does not exist.").ToString();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool SOculusPlatformToolWidget::LaunchParamValidator(FString text, FString& error)
|
|
{
|
|
if (text.Contains("\""))
|
|
{
|
|
error = LOCTEXT("LaunchParamError", "The field contains illegal characters.").ToString();
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::On2DOptionsExpanded(bool bExpanded)
|
|
{
|
|
Options2DCollapsed = !bExpanded;
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::OnRedistPackagesExpanded(bool bExpanded)
|
|
{
|
|
OptionsRedistPackagesCollapsed = !bExpanded;
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::UpdateLogText(FString text)
|
|
{
|
|
// Make sure that log text updating happens on the right thread.
|
|
LogText = text;
|
|
LogTextUpdated = true;
|
|
}
|
|
|
|
void SOculusPlatformToolWidget::SetPlatformProcess(FProcHandle proc)
|
|
{
|
|
PlatformProcess = proc;
|
|
}
|
|
|
|
//=======================================================================================
|
|
//FPlatformDownloadTask
|
|
|
|
FPlatformDownloadTask::FPlatformDownloadTask(FUpdateLogTextDel textDel, FEvent* saveEvent)
|
|
{
|
|
UpdateLogText = textDel;
|
|
SaveCompleteEvent = saveEvent;
|
|
|
|
FOculusXRHMDModule::GetPluginWrapper().SendEvent2("oculus_platform_tool", "provision_util", "integration");
|
|
}
|
|
|
|
void FPlatformDownloadTask::DoWork()
|
|
{
|
|
// Create HTTP request for downloading oculus platform tool
|
|
downloadCompleteEvent = FGenericPlatformProcess::GetSynchEventFromPool(false);
|
|
TSharedRef<IHttpRequest, ESPMode::ThreadSafe> httpRequest = FHttpModule::Get().CreateRequest();
|
|
|
|
httpRequest->OnProcessRequestComplete().BindRaw(this, &FPlatformDownloadTask::OnDownloadRequestComplete);
|
|
httpRequest->OnRequestProgress().BindRaw(this, &FPlatformDownloadTask::OnRequestDownloadProgress);
|
|
httpRequest->SetURL(UrlPlatformUtil);
|
|
httpRequest->SetVerb("GET");
|
|
|
|
httpRequest->ProcessRequest();
|
|
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("DownloadProgress", "Downloading Platform Tool: {0}%\n").ToString());
|
|
ToolConsoleLog = SOculusPlatformToolWidget::LogText;
|
|
UpdateProgressLog(0);
|
|
|
|
// Wait for download to complete
|
|
downloadCompleteEvent->Wait();
|
|
|
|
// Save HTTP data
|
|
FString fullPath = FPaths::ConvertRelativePathToFull(FPaths::ProjectContentDir()) + ProjectPlatformUtilPath;
|
|
if (FFileHelper::SaveArrayToFile(httpData, *fullPath))
|
|
{
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("DownloadSuccess", "Platform tool successfully downloaded.\n").ToString());
|
|
}
|
|
else
|
|
{
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("DownloadError", "An error has occured with downloading the platform tool.\n").ToString());
|
|
}
|
|
|
|
if (SaveCompleteEvent != nullptr)
|
|
{
|
|
SaveCompleteEvent->Trigger();
|
|
}
|
|
}
|
|
|
|
void FPlatformDownloadTask::UpdateProgressLog(int progress)
|
|
{
|
|
UpdateLogText.Execute(FString::Format(*ToolConsoleLog, { progress }));
|
|
}
|
|
|
|
void FPlatformDownloadTask::OnRequestDownloadProgress(FHttpRequestPtr HttpRequest, int32 BytesSend, int32 InBytesReceived)
|
|
{
|
|
// Update progress on download in tool console log
|
|
FHttpResponsePtr httpResponse = HttpRequest->GetResponse();
|
|
if (httpResponse.IsValid())
|
|
{
|
|
int progress = ((float)InBytesReceived / (float)httpResponse->GetContentLength()) * 100;
|
|
UpdateProgressLog(progress);
|
|
}
|
|
}
|
|
|
|
void FPlatformDownloadTask::OnDownloadRequestComplete(FHttpRequestPtr HttpRequest, FHttpResponsePtr HttpResponse, bool bSucceeded)
|
|
{
|
|
// Extract data from HTTP response and trigger download complete event
|
|
if (bSucceeded && HttpResponse.IsValid())
|
|
{
|
|
httpData = HttpResponse->GetContent();
|
|
downloadCompleteEvent->Trigger();
|
|
}
|
|
}
|
|
|
|
//=======================================================================================
|
|
//FPlatformUploadTask
|
|
|
|
FPlatformUploadTask::FPlatformUploadTask(FString args, FEnableUploadButtonDel del, FUpdateLogTextDel textDel, FSetProcessDel procDel)
|
|
{
|
|
LaunchArgs = args;
|
|
EnableUploadButton = del;
|
|
UpdateLogText = textDel;
|
|
SetProcess = procDel;
|
|
|
|
EnableUploadButton.Execute(false);
|
|
}
|
|
|
|
void FPlatformUploadTask::DoWork()
|
|
{
|
|
// Check if the platform tool exists in the project directory. If not, start process to download it.
|
|
if (!FPaths::FileExists(FPaths::ProjectContentDir() + ProjectPlatformUtilPath))
|
|
{
|
|
FEvent* PlatformToolCreatedEvent = FGenericPlatformProcess::GetSynchEventFromPool(false);
|
|
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("NoCLI", "Unable to find Oculus Platform Utility.\n").ToString());
|
|
#if UE_VERSION_OLDER_THAN(5, 3, 0)
|
|
EAppReturnType::Type dialogChoice = FMessageDialog::Open(EAppMsgType::OkCancel, OculusPlatformDialogMessage, &OculusPlatformDialogTitle);
|
|
#else
|
|
EAppReturnType::Type dialogChoice = FMessageDialog::Open(EAppMsgType::OkCancel, OculusPlatformDialogMessage, OculusPlatformDialogTitle);
|
|
#endif
|
|
if (dialogChoice == EAppReturnType::Ok)
|
|
{
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("DownloadCLI", "Downloading Oculus Platform Utility . . .\n").ToString());
|
|
(new FAsyncTask<FPlatformDownloadTask>(UpdateLogText, PlatformToolCreatedEvent))->StartBackgroundTask();
|
|
PlatformToolCreatedEvent->Wait();
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("StartUploadAfterDownload", "Starting upload . . .\n").ToString());
|
|
}
|
|
|
|
// Start up the CLI and pass in arguments.
|
|
FPlatformProcess::CreatePipe(ReadPipe, WritePipe);
|
|
FProcHandle PlatformProcess = FPlatformProcess::CreateProc(*(FPaths::ProjectContentDir() + ProjectPlatformUtilPath), *LaunchArgs, false, true, true, nullptr, 0, nullptr, WritePipe, ReadPipe);
|
|
SetProcess.Execute(PlatformProcess);
|
|
|
|
// Redirect CLI output to the tool's log.
|
|
while (FPlatformProcess::IsProcRunning(PlatformProcess))
|
|
{
|
|
FString log = FPlatformProcess::ReadPipe(ReadPipe);
|
|
if (!log.IsEmpty())
|
|
{
|
|
// Remove parts of the log that contain escape character codes
|
|
int32 escapeIndex = log.Find("\u001b");
|
|
while (escapeIndex >= 0)
|
|
{
|
|
int32 lineEndIndex = log.Find("\n", ESearchCase::IgnoreCase, ESearchDir::FromStart, escapeIndex);
|
|
if (lineEndIndex < 0) // If an escape character code exists without a new line end, just remove the escape character
|
|
{
|
|
lineEndIndex = escapeIndex + 1;
|
|
}
|
|
log.RemoveAt(escapeIndex, lineEndIndex - escapeIndex);
|
|
escapeIndex = log.Find("\u001b");
|
|
}
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + log);
|
|
}
|
|
}
|
|
EnableUploadButton.Execute(true);
|
|
}
|
|
|
|
//=======================================================================================
|
|
//FPlatformLoadRedistPackagesTask
|
|
|
|
FPlatformLoadRedistPackagesTask::FPlatformLoadRedistPackagesTask(FUpdateLogTextDel textDel)
|
|
{
|
|
UpdateLogText = textDel;
|
|
}
|
|
|
|
void FPlatformLoadRedistPackagesTask::DoWork()
|
|
{
|
|
UOculusXRPlatformToolSettings* PlatformSettings = GetMutableDefault<UOculusXRPlatformToolSettings>();
|
|
|
|
// Check to see if the CLI exists, we need this to load avalible redist packages
|
|
if (!FPaths::FileExists(FPaths::ProjectContentDir() + ProjectPlatformUtilPath))
|
|
{
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("LoadRedist", "Loading redistributable packages . . .\n").ToString());
|
|
|
|
FEvent* PlatformToolCreatedEvent = FGenericPlatformProcess::GetSynchEventFromPool(false);
|
|
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("NoCLI", "Unable to find Oculus Platform Utility.\n").ToString());
|
|
#if UE_VERSION_OLDER_THAN(5, 3, 0)
|
|
EAppReturnType::Type dialogChoice = FMessageDialog::Open(EAppMsgType::OkCancel, OculusPlatformDialogMessage, &OculusPlatformDialogTitle);
|
|
#else
|
|
EAppReturnType::Type dialogChoice = FMessageDialog::Open(EAppMsgType::OkCancel, OculusPlatformDialogMessage, OculusPlatformDialogTitle);
|
|
#endif
|
|
if (dialogChoice == EAppReturnType::Ok)
|
|
{
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("DownloadCLI", "Downloading Oculus Platform Utility . . .\n").ToString());
|
|
(new FAsyncTask<FPlatformDownloadTask>(UpdateLogText, PlatformToolCreatedEvent))->StartBackgroundTask();
|
|
PlatformToolCreatedEvent->Wait();
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Launch CLI and pass command to list out redist packages currently avalible
|
|
TArray<FOculusXRRedistPackage> LoadedPackages;
|
|
FString Args = "list-redists";
|
|
FPlatformProcess::CreatePipe(ReadPipe, WritePipe);
|
|
FProcHandle PlatformProcess = FPlatformProcess::CreateProc(*(FPaths::ProjectContentDir() + ProjectPlatformUtilPath), *Args, false, true, true, nullptr, 0, nullptr, WritePipe, ReadPipe);
|
|
|
|
// Load redist packages
|
|
while (FPlatformProcess::IsProcRunning(PlatformProcess))
|
|
{
|
|
FString log = FPlatformProcess::ReadPipe(ReadPipe);
|
|
if (!log.IsEmpty() && !log.Contains("\u001b") && !log.Contains("ID"))
|
|
{
|
|
TArray<FString> Packages;
|
|
log.ParseIntoArrayLines(Packages);
|
|
if (Packages.Num() > 0)
|
|
{
|
|
for (int i = 0; i < Packages.Num(); i++)
|
|
{
|
|
FString id, name;
|
|
Packages[i].Split("|", &id, &name);
|
|
|
|
if (!id.IsEmpty() && !name.IsEmpty())
|
|
{
|
|
FOculusXRRedistPackage newPackage;
|
|
newPackage.Name = name;
|
|
newPackage.Id = id;
|
|
|
|
LoadedPackages.Add(newPackage);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check to see if our stored copy of redist packages is outdated
|
|
if (PlatformSettings != nullptr)
|
|
{
|
|
if (LoadedPackages.Num() > PlatformSettings->OculusRedistPackages.Num())
|
|
{
|
|
PlatformSettings->OculusRedistPackages = LoadedPackages;
|
|
PlatformSettings->SaveConfig();
|
|
UpdateLogText.Execute(SOculusPlatformToolWidget::LogText + LOCTEXT("FinishRedistLoad", "Finished updating redistributable packages.\n").ToString());
|
|
}
|
|
}
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|