diff --git a/Content/G2I_Game/UI/Menu/Gallery/WB_Gallery.uasset b/Content/G2I_Game/UI/Menu/Gallery/WB_Gallery.uasset new file mode 100644 index 0000000..78ef916 Binary files /dev/null and b/Content/G2I_Game/UI/Menu/Gallery/WB_Gallery.uasset differ diff --git a/Content/G2I_Game/UI/Menu/WB_MainMenu.uasset b/Content/G2I_Game/UI/Menu/WB_MainMenu.uasset index c0e969c..4e34e5a 100644 Binary files a/Content/G2I_Game/UI/Menu/WB_MainMenu.uasset and b/Content/G2I_Game/UI/Menu/WB_MainMenu.uasset differ diff --git a/Content/G2I_Game/UI/StringsRu/ST_CommonUI.uasset b/Content/G2I_Game/UI/StringsRu/ST_CommonUI.uasset index 89b434e..b384908 100644 Binary files a/Content/G2I_Game/UI/StringsRu/ST_CommonUI.uasset and b/Content/G2I_Game/UI/StringsRu/ST_CommonUI.uasset differ diff --git a/Content/G2I_Game/UI/StringsRu/ST_Gallery.uasset b/Content/G2I_Game/UI/StringsRu/ST_Gallery.uasset new file mode 100644 index 0000000..1c67c8e Binary files /dev/null and b/Content/G2I_Game/UI/StringsRu/ST_Gallery.uasset differ diff --git a/Source/G2I/Private/UI/G2IUIManager.cpp b/Source/G2I/Private/UI/G2IUIManager.cpp index b54716e..b440570 100644 --- a/Source/G2I/Private/UI/G2IUIManager.cpp +++ b/Source/G2I/Private/UI/G2IUIManager.cpp @@ -26,6 +26,7 @@ #include "Menu/Elements/G2IControlListItem.h" #include "Menu/Elements/G2IControlRow.h" #include "Menu/Elements/TextRow/G2ITextMultiValuePropertyRow.h" +#include "Menu/Gallery/G2IGalleryWidget.h" #include "Menu/Options/G2ICharacterControlsWidget.h" #include "Menu/Options/G2IOptionsWidget.h" @@ -756,6 +757,21 @@ void UG2IUIManager::SetupPauseWidget(const TFunction& NewContinueAction) } } +void UG2IUIManager::SetupGalleryWidget(const TFunction& NewBackAction) const +{ + if (!ensure(DisplayManager)) + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find %s"), *GetName(), + *UG2IUIDisplayManager::StaticClass()->GetName()); + return; + } + if (UG2IGalleryWidget *Widget = Cast( + DisplayManager->GetWidget(EG2IWidgetNames::Gallery))) + { + Widget->OnBack = NewBackAction; + } +} + void UG2IUIManager::SetupControlsWidget(UWidgetSwitcher* CharacterControlsSwitcher) const { if (!ensure(CharacterControlsSwitcher)) diff --git a/Source/G2I/Private/UI/Widgets/Menu/G2IMainMenuWidget.cpp b/Source/G2I/Private/UI/Widgets/Menu/G2IMainMenuWidget.cpp index fa2626b..e3e783e 100644 --- a/Source/G2I/Private/UI/Widgets/Menu/G2IMainMenuWidget.cpp +++ b/Source/G2I/Private/UI/Widgets/Menu/G2IMainMenuWidget.cpp @@ -52,6 +52,14 @@ void UG2IMainMenuWidget::BindDelegates() { UE_LOG(LogG2I, Error, TEXT("Creators button isn't existed in %s"), *GetName()); } + if (ensure(GalleryButton)) + { + GalleryButton->OnClicked.AddDynamic(this, &ThisClass::OnGalleryButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("Gallery button isn't existed in %s"), *GetName()); + } if (ensure(QuitGameButton)) { QuitGameButton->OnClicked.AddDynamic(this, &ThisClass::OnQuitGameButtonClicked); @@ -136,6 +144,20 @@ void UG2IMainMenuWidget::OnCreatorsButtonClicked() UIManager->SetupCreatorsWidget(GetShowCurrentWidgetFunction()); } +void UG2IMainMenuWidget::OnGalleryButtonClicked() +{ + if (!ensure(UIManager)) + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find %s"), *GetName(), + *UG2IUIManager::StaticClass()->GetName()); + return; + } + UIManager->HideWidget(EG2IWidgetNames::MainMenu); + UIManager->OpenWidget(EG2IWidgetNames::Gallery); + + UIManager->SetupGalleryWidget(GetShowCurrentWidgetFunction()); +} + void UG2IMainMenuWidget::OnQuitGameButtonClicked() { if (!ensure(UIManager)) diff --git a/Source/G2I/Private/UI/Widgets/Menu/Gallery/G2IGalleryWidget.cpp b/Source/G2I/Private/UI/Widgets/Menu/Gallery/G2IGalleryWidget.cpp new file mode 100644 index 0000000..13e9de8 --- /dev/null +++ b/Source/G2I/Private/UI/Widgets/Menu/Gallery/G2IGalleryWidget.cpp @@ -0,0 +1,269 @@ +#include "Menu/Gallery/G2IGalleryWidget.h" +#include "G2I.h" +#include "G2IUIManager.h" +#include "G2IWidgetNames.h" +#include "Components/Button.h" +#include "Components/Image.h" + +void UG2IGalleryWidget::InitializeAfterManagerLoading() +{ + Super::InitializeAfterManagerLoading(); + + InitializeDefaults(); + BindDelegates(); +} + +void UG2IGalleryWidget::InitializeDefaults() +{ + LockEmptySections(); + OpenStartImage(); +} + +void UG2IGalleryWidget::LockEmptySections() const +{ + PreviousButton->SetIsEnabled(false); + NextButton->SetIsEnabled(false); + if (IsSectionEmpty(EG2IGallerySectionsName::Locations)) + { + LocationsGalleryButton->SetIsEnabled(false); + } + if (IsSectionEmpty(EG2IGallerySectionsName::Environment)) + { + EnvironmentGalleryButton->SetIsEnabled(false); + } + if (IsSectionEmpty(EG2IGallerySectionsName::MainCharacters)) + { + MainCharactersGalleryButton->SetIsEnabled(false); + } + if (IsSectionEmpty(EG2IGallerySectionsName::MinorCharacters)) + { + MinorCharactersGalleryButton->SetIsEnabled(false); + } + if (IsSectionEmpty(EG2IGallerySectionsName::Puzzles)) + { + PuzzlesGalleryButton->SetIsEnabled(false); + } +} + +void UG2IGalleryWidget::OpenStartImage() +{ + if (LocationsGalleryButton->GetIsEnabled()) + { + OpenSection(EG2IGallerySectionsName::Locations); + return; + } + if (EnvironmentGalleryButton->GetIsEnabled()) + { + OpenSection(EG2IGallerySectionsName::Environment); + return; + } + if (MainCharactersGalleryButton->GetIsEnabled()) + { + OpenSection(EG2IGallerySectionsName::MainCharacters); + return; + } + if (MinorCharactersGalleryButton->GetIsEnabled()) + { + OpenSection(EG2IGallerySectionsName::MinorCharacters); + return; + } + if (PuzzlesGalleryButton->GetIsEnabled()) + { + OpenSection(EG2IGallerySectionsName::Puzzles); + return; + } +} + +void UG2IGalleryWidget::BindDelegates() +{ + if (ensure(BackButton)) + { + BackButton->OnClicked.AddDynamic(this, &ThisClass::OnBackButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find BackButton"), *GetName()); + } + if (ensure(PreviousButton)) + { + PreviousButton->OnClicked.AddDynamic(this, &ThisClass::OnPreviousButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find PreviousButton"), *GetName()); + } + if (ensure(NextButton)) + { + NextButton->OnClicked.AddDynamic(this, &ThisClass::OnNextButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find NextButton"), *GetName()); + } + if (ensure(LocationsGalleryButton)) + { + LocationsGalleryButton->OnClicked.AddDynamic(this, &ThisClass::OnLocationsGalleryButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find Button of Locations Gallery"), *GetName()); + } + if (ensure(EnvironmentGalleryButton)) + { + EnvironmentGalleryButton->OnClicked.AddDynamic(this, &ThisClass::OnEnvironmentGalleryButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find Button of Environment Gallery"), *GetName()); + } + if (ensure(MainCharactersGalleryButton)) + { + MainCharactersGalleryButton->OnClicked.AddDynamic(this, &ThisClass::OnMainCharactersGalleryButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find Button of Main Characters Gallery"), *GetName()); + } + if (ensure(MinorCharactersGalleryButton)) + { + MinorCharactersGalleryButton->OnClicked.AddDynamic(this, &ThisClass::OnMinorCharactersGalleryButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find Button of Minor Characters Gallery"), *GetName()); + } + if (ensure(PuzzlesGalleryButton)) + { + PuzzlesGalleryButton->OnClicked.AddDynamic(this, &ThisClass::OnPuzzlesGalleryButtonClicked); + } + else + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find Button of Puzzles Gallery"), *GetName()); + } +} + +void UG2IGalleryWidget::OnBackButtonClicked() +{ + if (OnBack) + { + OnBack(); + } + else + { + UE_LOG(LogG2I, Log, TEXT("Back function is undefined in %s"), *GetName()); + } + + if (!ensure(UIManager)) + { + UE_LOG(LogG2I, Error, TEXT("%s: Couldn't find %s"), *GetName(), + *UG2IUIManager::StaticClass()->GetName()); + return; + } + UIManager->CloseWidget(EG2IWidgetNames::Gallery); +} + +void UG2IGalleryWidget::OnPreviousButtonClicked() +{ + OpenImage(CurrentIndex - 1); +} + +void UG2IGalleryWidget::OnNextButtonClicked() +{ + OpenImage(CurrentIndex + 1); +} + +void UG2IGalleryWidget::OpenImage(const int32 Index) +{ + const auto* SectionPtr = Sections.Find(CurrentSection); + if (!SectionPtr || SectionPtr->SectionImages.IsEmpty()) + { + UE_LOG(LogG2I, Warning, TEXT("%s: Attempt to select empty Gallery Section"), *GetName()); + return; + } + const int32 NewIndex = (Index + SectionPtr->SectionImages.Num()) % SectionPtr->SectionImages.Num(); + if (SetTexture(SectionPtr->SectionImages[NewIndex])) + { + CurrentIndex = NewIndex; + } +} + +bool UG2IGalleryWidget::SetTexture(UTexture2D* NewTexture) const +{ + if (!NewTexture) + { + UE_LOG(LogG2I, Warning, TEXT("%s: Attempt to set null texture"), *GetName()); + return false; + } + CurrentImage->SetBrushFromTexture(NewTexture, true); + return true; +} + +bool UG2IGalleryWidget::IsSectionEmpty(const EG2IGallerySectionsName SectionName) const +{ + if (const auto *Section = Sections.Find(SectionName)) + { + return Section->SectionImages.IsEmpty(); + } + return true; +} + +void UG2IGalleryWidget::OpenNewSection(const EG2IGallerySectionsName NewSectionName) +{ + if (CurrentSection == NewSectionName) + { + return; + } + OpenSection(NewSectionName); +} + +void UG2IGalleryWidget::OpenSection(const EG2IGallerySectionsName SectionName) +{ + const auto* SectionPtr = Sections.Find(SectionName); + if (!ensure(SectionPtr) || !ensure(!SectionPtr->SectionImages.IsEmpty())) + { + UE_LOG(LogG2I, Error, TEXT("%s: Attempt to select empty Gallery Section"), *GetName()); + return; + } + + if (SectionPtr->SectionImages.Num() > 1) + { + PreviousButton->SetIsEnabled(true); + NextButton->SetIsEnabled(true); + } + else + { + PreviousButton->SetIsEnabled(false); + NextButton->SetIsEnabled(false); + } + + if (SetTexture(SectionPtr->SectionImages[0])) + { + CurrentSection = SectionName; + CurrentIndex = 0; + } +} + +void UG2IGalleryWidget::OnLocationsGalleryButtonClicked() +{ + OpenNewSection(EG2IGallerySectionsName::Locations); +} + +void UG2IGalleryWidget::OnEnvironmentGalleryButtonClicked() +{ + OpenNewSection(EG2IGallerySectionsName::Environment); +} + +void UG2IGalleryWidget::OnMainCharactersGalleryButtonClicked() +{ + OpenNewSection(EG2IGallerySectionsName::MainCharacters); +} + +void UG2IGalleryWidget::OnMinorCharactersGalleryButtonClicked() +{ + OpenNewSection(EG2IGallerySectionsName::MinorCharacters); +} + +void UG2IGalleryWidget::OnPuzzlesGalleryButtonClicked() +{ + OpenNewSection(EG2IGallerySectionsName::Puzzles); +} diff --git a/Source/G2I/Public/DataDefinitions/Enums/G2IWidgetNames.h b/Source/G2I/Public/DataDefinitions/Enums/G2IWidgetNames.h index 26f6544..461c522 100644 --- a/Source/G2I/Public/DataDefinitions/Enums/G2IWidgetNames.h +++ b/Source/G2I/Public/DataDefinitions/Enums/G2IWidgetNames.h @@ -24,5 +24,6 @@ enum class EG2IWidgetNames : uint8 CutSceneStartBoilerRoom UMETA(DisplayName = "CutScene - in Boiler Room"), CutSceneStartChildrenRoom UMETA(DisplayName = "CutScene - in Child Room"), CutSceneStartHall UMETA(DisplayName = "CutScene - in Hall"), - CutSceneEndGame UMETA(DisplayName = "CutScene - End Game") + CutSceneEndGame UMETA(DisplayName = "CutScene - End Game"), + Gallery UMETA(DisplayName = "Gallery widget") }; \ No newline at end of file diff --git a/Source/G2I/Public/UI/G2IUIManager.h b/Source/G2I/Public/UI/G2IUIManager.h index 60d8085..2a1779f 100644 --- a/Source/G2I/Public/UI/G2IUIManager.h +++ b/Source/G2I/Public/UI/G2IUIManager.h @@ -141,4 +141,7 @@ class G2I_API UG2IUIManager : public UGameInstanceSubsystem // ==================== CUT SCENES WIDGETS ==================== void CloseCutScene(EG2IWidgetNames WidgetName) const; + + // ==================== GALLERY WIDGETS ==================== + void SetupGalleryWidget(const TFunction& NewBackAction) const; }; \ No newline at end of file diff --git a/Source/G2I/Public/UI/Widgets/Menu/G2IMainMenuWidget.h b/Source/G2I/Public/UI/Widgets/Menu/G2IMainMenuWidget.h index f0c9ab6..6fdc835 100644 --- a/Source/G2I/Public/UI/Widgets/Menu/G2IMainMenuWidget.h +++ b/Source/G2I/Public/UI/Widgets/Menu/G2IMainMenuWidget.h @@ -25,6 +25,9 @@ class G2I_API UG2IMainMenuWidget : public UG2IUserWidget UPROPERTY(meta = (BindWidget)) TObjectPtr CreatorsButton; + UPROPERTY(meta = (BindWidget)) + TObjectPtr GalleryButton; + UPROPERTY(meta = (BindWidget)) TObjectPtr QuitGameButton; @@ -41,6 +44,9 @@ class G2I_API UG2IMainMenuWidget : public UG2IUserWidget UFUNCTION() void OnCreatorsButtonClicked(); + UFUNCTION() + void OnGalleryButtonClicked(); + UFUNCTION() void OnQuitGameButtonClicked(); diff --git a/Source/G2I/Public/UI/Widgets/Menu/Gallery/G2IGalleryWidget.h b/Source/G2I/Public/UI/Widgets/Menu/Gallery/G2IGalleryWidget.h new file mode 100644 index 0000000..a279bcd --- /dev/null +++ b/Source/G2I/Public/UI/Widgets/Menu/Gallery/G2IGalleryWidget.h @@ -0,0 +1,120 @@ +#pragma once + +#include "CoreMinimal.h" +#include "G2IUserWidget.h" +#include "G2IGalleryWidget.generated.h" + +class UImage; +class UButton; + +UENUM(BlueprintType) +enum class EG2IGallerySectionsName : uint8 +{ + Locations, + Environment, + MainCharacters, + MinorCharacters, + Puzzles +}; + +USTRUCT(BlueprintType) +struct FG2IGallerySectionInfo +{ + GENERATED_BODY() + + UPROPERTY(EditAnywhere) + TArray> SectionImages; +}; + +/** + * + */ +UCLASS() +class G2I_API UG2IGalleryWidget : public UG2IUserWidget +{ + GENERATED_BODY() + +public: + + UPROPERTY(meta = (BindWidget)) + TObjectPtr CurrentImage; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr PreviousButton; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr NextButton; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr LocationsGalleryButton; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr EnvironmentGalleryButton; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr MainCharactersGalleryButton; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr MinorCharactersGalleryButton; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr PuzzlesGalleryButton; + + UPROPERTY(meta = (BindWidget)) + TObjectPtr BackButton; + +private: + + EG2IGallerySectionsName CurrentSection = EG2IGallerySectionsName::Locations; + + int32 CurrentIndex = 0; + + UPROPERTY(EditAnywhere, meta = (AllowPrivateAccess = true)) + TMap Sections; + +public: + + TFunction OnBack; + +protected: + + virtual void InitializeAfterManagerLoading() override; + + UFUNCTION() + void OnBackButtonClicked(); + + UFUNCTION() + void OnPreviousButtonClicked(); + + UFUNCTION() + void OnNextButtonClicked(); + + UFUNCTION() + void OnLocationsGalleryButtonClicked(); + + UFUNCTION() + void OnEnvironmentGalleryButtonClicked(); + + UFUNCTION() + void OnMainCharactersGalleryButtonClicked(); + + UFUNCTION() + void OnMinorCharactersGalleryButtonClicked(); + + UFUNCTION() + void OnPuzzlesGalleryButtonClicked(); + +private: + + void InitializeDefaults(); + void LockEmptySections() const; + void OpenStartImage(); + void BindDelegates(); + + bool IsSectionEmpty(EG2IGallerySectionsName SectionName) const; + + void OpenNewSection(EG2IGallerySectionsName NewSectionName); + void OpenSection(EG2IGallerySectionsName SectionName); + void OpenImage(int32 Index); + bool SetTexture(UTexture2D* NewTexture) const; +}; \ No newline at end of file