Skip to content

Commit

Permalink
initial implementation of the plugin ui
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeseese committed Dec 7, 2023
1 parent f57cf7d commit ffda61f
Show file tree
Hide file tree
Showing 7 changed files with 380 additions and 0 deletions.
5 changes: 5 additions & 0 deletions SDKDemo/Plugins/HathoraSDK/HathoraSDK.uplugin
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
"Name": "HathoraSDK",
"Type": "Runtime",
"LoadingPhase": "Default"
},
{
"Name": "HathoraSDKEditor",
"Type": "Editor",
"LoadingPhase": "PostDefault"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2023 Hathora, Inc.

using UnrealBuildTool;

public class HathoraSDKEditor : ModuleRules
{
public HathoraSDKEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;

PublicIncludePaths.AddRange(
new string[] {
// ... add public include paths required here ...
}
);


PrivateIncludePaths.AddRange(
new string[] {
// ... add other private include paths required here ...
}
);


PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
}
);


PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Slate",
"SlateCore",
"WorkspaceMenuStructure",
"InputCore",
"HathoraSDK",
}
);


DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright Epic Games, Inc. All Rights Reserved.

#include "HathoraSDKEditorModule.h"
#include "HathoraSDKEditorCommands.h"
#include "Framework/Docking/TabManager.h"
#include "Widgets/Docking/SDockTab.h"
#include "ToolMenus.h"
#include "WorkspaceMenuStructure.h"
#include "WorkspaceMenuStructureModule.h"
#include "SHathoraSDKWidget.h"

#define LOCTEXT_NAMESPACE "FHathoraSDKEditorModule"

DEFINE_LOG_CATEGORY(LogHathoraSDKEditorModule)
IMPLEMENT_MODULE(FHathoraSDKEditorModule, HathoraSDKEditorModule)

FName FHathoraSDKEditorModule::TabNameOpenTab(TEXT("HathoraSDKOpenTab"));

void FHathoraSDKEditorModule::StartupModule()
{
FHathoraSDKEditorCommands::Register();

PluginCommands = MakeShareable(new FUICommandList);

PluginCommands->MapAction(
FHathoraSDKEditorCommands::Get().OpenWindow,
FExecuteAction::CreateRaw(this, &FHathoraSDKEditorModule::ButtonClicked),
FCanExecuteAction()
);

FGlobalTabmanager::Get()->RegisterNomadTabSpawner(TabNameOpenTab,FOnSpawnTab::CreateRaw(this, &FHathoraSDKEditorModule::CreatePluginTab))
.SetDisplayName(LOCTEXT("FHathoraSDKTabTitle", "Hathora SDK"))
.SetTooltipText(LOCTEXT("FHathoraSDKTooltipText", "Open the Hathora SDK development tools."))
.SetGroup(WorkspaceMenu::GetMenuStructure().GetToolsCategory());

}

void FHathoraSDKEditorModule::ShutdownModule()
{
if (FSlateApplication::IsInitialized())
{
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(TabNameOpenTab);
}
}

void FHathoraSDKEditorModule::ButtonClicked()
{
FGlobalTabmanager::Get()->TryInvokeTab(TabNameOpenTab);
}

TSharedRef<SDockTab> FHathoraSDKEditorModule::CreatePluginTab(const FSpawnTabArgs& SpawnTabArgs)
{
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SHathoraSDKWidget)
];
}

#undef LOCTEXT_NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// Copyright 2023 Hathora, Inc.

#include "SHathoraSDKWidget.h"
#include "HathoraSDK.h"
#include "HathoraSDKAppV1.h"
#include "SlateBasics.h"
#include "Styling/AppStyle.h"
#include "Widgets/Layout/SWidgetSwitcher.h"
#include "Widgets/Layout/SScaleBox.h"

#define LOCTEXT_NAMESPACE "SHathoraSDKWidget"

void SHathoraSDKWidget::Construct(const FArguments& InArgs)
{
TSharedRef<SVerticalBox> LoggedInWidget = SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Text(LOCTEXT("DeveloperTokenLabel", "Developer Token"))
]
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SAssignNew(DeveloperTokenTextBox, SEditableTextBox)
.IsPassword(true)
]
]
// + SVerticalBox::Slot()
// .AutoHeight()
// [
// SNew(SButton)
// .Text(LOCTEXT("LoggedInButtonText", "[Logged In] Log in with another account"))
// ]
];

TSharedRef<SVerticalBox> Applications = SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Text(LOCTEXT("ApplicationsLabel", "Target Application"))
]
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SAssignNew(ApplicationComboBox, SApplicationComboBox)
.OptionsSource(&ApplicationsList)
.OnSelectionChanged(this, &SHathoraSDKWidget::ApplicationSelected)
.OnGenerateWidget(this, &SHathoraSDKWidget::GenerateApplicationComboBoxItem)
[
SNew(SBox)
]
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SButton)
.OnClicked(this, &SHathoraSDKWidget::RefreshApplications)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("GenericCommands.Redo"))
]
]
]
+ SVerticalBox::Slot()
.AutoHeight()
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(STextBlock)
.Text(LOCTEXT("ApplicationIdLabel", "AppId"))
]
+ SHorizontalBox::Slot()
.FillWidth(1.0f)
[
SAssignNew(AppIdTextBlock, STextBlock)
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SButton)
[
SNew(SImage)
.Image(FAppStyle::GetBrush("DataTableEditor.Copy.Small"))
]
]
];

ChildSlot
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.AutoHeight()
[
LoggedInWidget
]
+ SVerticalBox::Slot()
.AutoHeight()
[
Applications
]
];
}

TSharedRef<SWidget> SHathoraSDKWidget::GenerateApplicationComboBoxItem(FHathoraApplicationPtr Item) const
{
return SNew(STextBlock)
.Text(FText::FromString(Item->AppName))
.Font(FCoreStyle::GetDefaultFontStyle("Regular", 16));
}

FReply SHathoraSDKWidget::RefreshApplications()
{
UHathoraSDK* SDK = UHathoraSDK::CreateHathoraSDK();
SDK->SetAuthToken(DeveloperTokenTextBox->GetText().ToString());
if (SDK->IsLoggedIn())
{
SDK->AppV1->GetApps(
UHathoraSDKAppV1::FHathoraOnGetApps::CreateLambda(
[this](const FHathoraGetAppsResult Result)
{
ApplicationsList.Empty();

if (!Result.ErrorMessage.IsEmpty())
{
return;
}

for (FHathoraApplication Application : Result.Data)
{
ApplicationsList.Add(MakeShareable(new FHathoraApplication(Application)));
}

ApplicationComboBox->RefreshOptions();
}
)
);
}

return FReply::Handled();
}

void SHathoraSDKWidget::ApplicationSelected(FHathoraApplicationPtr ProposedSelection, ESelectInfo::Type SelectInfo)
{
if (ProposedSelection.IsValid())
{
AppIdTextBlock->SetText(FText::FromString(*ProposedSelection->AppId));
}
}

#undef LOCTEXT_NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2023 Hathora, Inc.

#pragma once

#include "CoreMinimal.h"
#include "Framework/Commands/Commands.h"

#define LOCTEXT_NAMESPACE "FHathoraSDKEditorCommands"

class FHathoraSDKEditorCommands : public TCommands< FHathoraSDKEditorCommands > {
public:
FHathoraSDKEditorCommands() :
TCommands< FHathoraSDKEditorCommands >(
TEXT("HathoraSDK"),
FText::FromString("Hathora SDK"),
NAME_None,
"HathoraSDKEditorCommandsStyle"
) {}

TSharedPtr< FUICommandInfo > OpenWindow;

virtual void RegisterCommands() override {
UI_COMMAND(
OpenWindow,
"HathoraSDK",
"Open the Hathora SDK window",
EUserInterfaceActionType::Button,
FInputChord());
}
};

#undef LOCTEXT_NAMESPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2023 Hathora, Inc.

#pragma once

#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"

class SDockTab;
class FSpawnTabArgs;

DECLARE_LOG_CATEGORY_EXTERN(LogHathoraSDKEditorModule, Log, All)

class FHathoraSDKEditorModule : public IModuleInterface
{
public:

/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;

private:
TSharedPtr<class FUICommandList> PluginCommands;

static FName TabNameOpenTab;

void ButtonClicked();
TSharedRef<SDockTab> CreatePluginTab(const FSpawnTabArgs& SpawnTabArgs);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2023 Hathora, Inc.

#pragma once

#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "HathoraSDKAppV1.h"
#include "Widgets/Input/SComboBox.h"
#include "Widgets/Input/SEditableTextBox.h"
// #include "Widgets/Layout/SGridPanel.h"

class SHathoraSDKWidget : public SCompoundWidget
{
public:
typedef TSharedPtr<FHathoraApplication> FHathoraApplicationPtr;
typedef SComboBox<FHathoraApplicationPtr> SApplicationComboBox;

SLATE_BEGIN_ARGS(SHathoraSDKWidget)
{
}
SLATE_END_ARGS()

void Construct(const FArguments& InArgs);

private:
TSharedRef<SWidget> GenerateApplicationComboBoxItem(FHathoraApplicationPtr Item) const;
void ApplicationSelected(FHathoraApplicationPtr ProposedSelection, ESelectInfo::Type SelectInfo);

FReply RefreshApplications();

TSharedPtr<SEditableTextBox> DeveloperTokenTextBox;
TSharedPtr<SApplicationComboBox> ApplicationComboBox;
TArray<FHathoraApplicationPtr> ApplicationsList;
TSharedPtr<STextBlock> AppIdTextBlock;
};

0 comments on commit ffda61f

Please sign in to comment.