AkAudioStyle.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /*******************************************************************************
  2. The content of this file includes portions of the proprietary AUDIOKINETIC Wwise
  3. Technology released in source code form as part of the game integration package.
  4. The content of this file may not be used without valid licenses to the
  5. AUDIOKINETIC Wwise Technology.
  6. Note that the use of the game engine is subject to the Unreal(R) Engine End User
  7. License Agreement at https://www.unrealengine.com/en-US/eula/unreal
  8. License Usage
  9. Licensees holding valid licenses to the AUDIOKINETIC Wwise Technology may use
  10. this file in accordance with the end user license agreement provided with the
  11. software or, alternatively, in accordance with the terms contained
  12. in a written agreement between you and Audiokinetic Inc.
  13. Copyright (c) 2023 Audiokinetic Inc.
  14. *******************************************************************************/
  15. #include "AkAudioStyle.h"
  16. #include "AkAudioDevice.h"
  17. #include "Framework/Notifications/NotificationManager.h"
  18. #include "WaapiPicker/WwiseTreeItem.h"
  19. #include "Styling/SlateStyle.h"
  20. #include "Styling/SlateStyleRegistry.h"
  21. #include "Engine/Texture2D.h"
  22. #include "Widgets/Notifications/SNotificationList.h"
  23. TSharedPtr< FSlateStyleSet > FAkAudioStyle::StyleInstance = nullptr;
  24. UMaterial* FAkAudioStyle::TextMaterial = nullptr;
  25. /* Taken from the Wwise Authoring dark theme. @TODO: Take this from the theme's main.json file. */
  26. TArray<FLinearColor> WwiseUnrealColorPalette = {
  27. FColor(191, 191, 191, 255),
  28. FColor(82, 90, 255, 1),
  29. FColor(41, 169, 255, 1),
  30. FColor(0, 255, 255, 1),
  31. FColor(0, 255, 0, 1),
  32. FColor(183, 255, 0, 1),
  33. FColor(255, 238, 0, 1),
  34. FColor(255, 170, 0, 1),
  35. FColor(255, 128, 0, 1),
  36. FColor(255, 85, 0, 1),
  37. FColor(255, 0, 0, 1),
  38. FColor(255, 0, 255, 1),
  39. FColor(190, 61, 255, 1),
  40. FColor(184, 107, 255, 1),
  41. FColor(112, 119, 255, 1),
  42. FColor(119, 164, 253, 1),
  43. FColor(132, 240, 240, 1),
  44. FColor(136, 242, 136, 1),
  45. FColor(209, 240, 122, 1),
  46. FColor(240, 192, 96, 1),
  47. FColor(255, 179, 102, 1),
  48. FColor(240, 192, 96, 1),
  49. FColor(255, 179, 102, 1),
  50. FColor(255, 146, 92, 1),
  51. FColor(255, 112, 255, 1),
  52. FColor(214, 133, 255, 1),
  53. FColor(166, 128, 255, 1),
  54. FColor(191, 191, 191, 1)
  55. };
  56. namespace AkAudioStyle_Helpers
  57. {
  58. template<typename T1, typename T2>
  59. auto LoadAkTexture(T1&& RelativePath, T2&& TextureName)
  60. {
  61. return LoadObject<UTexture2D>(nullptr, *(FString("/Wwise/") / FString(Forward<T1>(RelativePath)) / FString(Forward<T2>(TextureName)) + FString(".") + FString(Forward<T2>(TextureName))));
  62. }
  63. UMaterial* LoadAkMaterial(const FString& RelativePath, const FString& MaterialName)
  64. {
  65. return LoadObject<UMaterial>(nullptr, *(FString("/Wwise/") + RelativePath + MaterialName + FString(".") + MaterialName));
  66. }
  67. auto CreateAkImageBrush(UTexture2D* Texture, const FVector2D& TextureSize)
  68. {
  69. return new FSlateImageBrush(Texture, TextureSize);
  70. }
  71. template<typename StringType, typename...Args>
  72. auto CreateEngineBoxBrush(FSlateStyleSet& Style, StringType& RelativePath, Args&&... args)
  73. {
  74. return new FSlateBoxBrush(Style.RootToContentDir(Forward<StringType>(RelativePath), TEXT(".png")), Forward<Args>(args)...);
  75. }
  76. template<typename StringType, typename...Args>
  77. auto EngineBoxBrush(FSlateStyleSet& Style, StringType&& RelativePath, Args&&... args)
  78. {
  79. return FSlateBoxBrush(Style.RootToContentDir(Forward<StringType>(RelativePath), TEXT(".png")), Forward<Args>(args)...);
  80. }
  81. template<typename StringType, typename...Args>
  82. auto CreateEngineImageBrush(FSlateStyleSet& Style, StringType& RelativePath, Args&&... args)
  83. {
  84. return new FSlateImageBrush(Style.RootToContentDir(Forward<StringType>(RelativePath), TEXT(".png")), Forward<Args>(args)...);
  85. }
  86. }
  87. void SetAkBrush(FSlateStyleSet& Style, const char* BrushName, const char* TextureName)
  88. {
  89. using namespace AkAudioStyle_Helpers;
  90. const FVector2D Icon15x15(15.0f, 15.0f);
  91. auto Texture = LoadAkTexture("WwiseTree/Icons", TextureName);
  92. if (Texture != nullptr)
  93. {
  94. Texture->AddToRoot();
  95. Style.Set(BrushName, CreateAkImageBrush(Texture, Icon15x15));
  96. }
  97. }
  98. void SetClassThumbnail(FSlateStyleSet& Style, const char* BrushName, const char* TextureName)
  99. {
  100. using namespace AkAudioStyle_Helpers;
  101. const FVector2D ThumbnailSize(256.0f, 256.0f);
  102. auto Texture = LoadAkTexture("WwiseTypes", TextureName);
  103. if (Texture != nullptr)
  104. {
  105. Texture->AddToRoot();
  106. Style.Set(BrushName, CreateAkImageBrush(Texture, ThumbnailSize));
  107. }
  108. }
  109. void SetClassIcon(FSlateStyleSet& Style, const char* BrushName, const char* TextureName)
  110. {
  111. using namespace AkAudioStyle_Helpers;
  112. const FVector2D ThumbnailSize(15.0f, 15.0f);
  113. auto Texture = LoadAkTexture("WwiseTypes", TextureName);
  114. if (Texture != nullptr)
  115. {
  116. Texture->AddToRoot();
  117. Style.Set(BrushName, CreateAkImageBrush(Texture, ThumbnailSize));
  118. }
  119. }
  120. void SetAkResourceBrushes(FSlateStyleSet& Style)
  121. {
  122. SetAkBrush(Style, "AudiokineticTools.WwiseIcon", "Titlebar_WwiseAppIcon");
  123. SetAkBrush(Style, "AudiokineticTools.ActorMixerIcon", "actor_mixer_nor");
  124. SetAkBrush(Style, "AudiokineticTools.SoundIcon", "sound_fx_nor");
  125. SetAkBrush(Style, "AudiokineticTools.SwitchContainerIcon", "container_switch_nor");
  126. SetAkBrush(Style, "AudiokineticTools.RandomSequenceContainerIcon", "container_random_sequence_nor");
  127. SetAkBrush(Style, "AudiokineticTools.BlendContainerIcon", "layer_container_nor");
  128. SetAkBrush(Style, "AudiokineticTools.MotionBusIcon", "motion_bus_nor");
  129. SetAkBrush(Style, "AudiokineticTools.AkBrowserTabIcon", "wwise_logo_32");
  130. SetAkBrush(Style, "AudiokineticTools.EventIcon", "event_nor");
  131. SetAkBrush(Style, "AudiokineticTools.AcousticTextureIcon", "acoutex_nor");
  132. SetAkBrush(Style, "AudiokineticTools.AuxBusIcon", "auxbus_nor");
  133. SetAkBrush(Style, "AudiokineticTools.BusIcon", "bus_nor");
  134. SetAkBrush(Style, "AudiokineticTools.FolderIcon", "folder_nor");
  135. SetAkBrush(Style, "AudiokineticTools.PhysicalFolderIcon", "physical_folder_nor");
  136. SetAkBrush(Style, "AudiokineticTools.WorkUnitIcon", "workunit_nor");
  137. SetAkBrush(Style, "AudiokineticTools.ProjectIcon", "wproj");
  138. SetAkBrush(Style, "AudiokineticTools.RTPCIcon", "gameparameter_nor");
  139. SetAkBrush(Style, "AudiokineticTools.StateIcon", "state_nor");
  140. SetAkBrush(Style, "AudiokineticTools.StateGroupIcon", "stategroup_nor");
  141. SetAkBrush(Style, "AudiokineticTools.SwitchIcon", "switch_nor");
  142. SetAkBrush(Style, "AudiokineticTools.SwitchGroupIcon", "switchgroup_nor");
  143. SetAkBrush(Style, "AudiokineticTools.TriggerIcon", "trigger_nor");
  144. SetAkBrush(Style, "AudiokineticTools.EffectShareSetIcon", "effect_shareset_nor");
  145. SetClassThumbnail(Style, "ClassThumbnail.AkAcousticTexture", "AkAcousticTexture");
  146. SetClassThumbnail(Style, "ClassThumbnail.AkAudioEvent", "AkAudioEvent");
  147. SetClassThumbnail(Style, "ClassThumbnail.AkAuxBus", "AkAuxBus");
  148. SetClassThumbnail(Style, "ClassThumbnail.AkAudioBank", "AkAudioBank");
  149. SetClassThumbnail(Style, "ClassThumbnail.AkInitBank", "AkAudioBank");
  150. SetClassThumbnail(Style, "ClassThumbnail.AkLocalizedMediaAsset", "AkLocalizedMediaAsset");
  151. SetClassThumbnail(Style, "ClassThumbnail.AkMediaAsset", "AkMediaAsset");
  152. SetClassThumbnail(Style, "ClassThumbnail.AkExternalMediaAsset", "AkExternalMediaAsset");
  153. SetClassThumbnail(Style, "ClassThumbnail.AkRtpc", "AkRtpc");
  154. SetClassThumbnail(Style, "ClassThumbnail.AkStateValue", "AkStateValue");
  155. SetClassThumbnail(Style, "ClassThumbnail.AkSwitchValue", "AkSwitchValue");
  156. SetClassThumbnail(Style, "ClassThumbnail.AkTrigger", "AkTrigger");
  157. SetClassThumbnail(Style, "ClassThumbnail.AkEffectShareSet", "AkEffectShareSet");
  158. SetClassThumbnail(Style, "ClassThumbnail.AkAcousticPortal", "AK_Acoustic_Portal");
  159. SetClassIcon(Style, "ClassIcon.AkAcousticPortal", "AK_Acoustic_Portal_Explorer");
  160. SetClassThumbnail(Style, "ClassThumbnail.AkSpatialAudioVolume", "AK_Spatial_Audio_Volume");
  161. SetClassIcon(Style, "ClassIcon.AkSpatialAudioVolume", "AK_Spatial_Audio_Volume_Explorer");
  162. SetClassThumbnail(Style, "ClassThumbnail.AkReverbVolume", "AK_Reverb_Volume");
  163. SetClassIcon(Style, "ClassIcon.AkReverbVolume", "AK_Reverb_Volume_Explorer");
  164. }
  165. void FAkAudioStyle::Initialize()
  166. {
  167. using namespace AkAudioStyle_Helpers;
  168. if (!StyleInstance.IsValid())
  169. {
  170. StyleInstance = MakeShareable(new FSlateStyleSet(FAkAudioStyle::GetStyleSetName()));
  171. auto ContentRoot = FPaths::EngineContentDir() / TEXT("Slate");
  172. StyleInstance->SetContentRoot(ContentRoot);
  173. StyleInstance->SetCoreContentRoot(ContentRoot);
  174. FSlateStyleSet& Style = *StyleInstance.Get();
  175. {
  176. SetAkResourceBrushes(Style);
  177. Style.Set("AudiokineticTools.GroupBorder", CreateEngineBoxBrush(Style, "Common/GroupBorder", FMargin(4.0f / 16.0f)));
  178. Style.Set("AudiokineticTools.AssetDragDropTooltipBackground", CreateEngineBoxBrush(Style, "Old/Menu_Background", FMargin(8.0f / 64.0f)));
  179. FButtonStyle HoverHintOnly = FButtonStyle()
  180. .SetNormal(FSlateNoResource())
  181. .SetHovered(EngineBoxBrush(Style, "Common/Button_Hovered", FMargin(4 / 16.0f), FLinearColor(1, 1, 1, 0.15f)))
  182. .SetPressed(EngineBoxBrush(Style, "Common/Button_Pressed", FMargin(4 / 16.0f), FLinearColor(1, 1, 1, 0.25f)))
  183. .SetNormalPadding(FMargin(0, 0, 0, 1))
  184. .SetPressedPadding(FMargin(0, 1, 0, 0));
  185. Style.Set("AudiokineticTools.HoverHintOnly", HoverHintOnly);
  186. Style.Set("AudiokineticTools.SourceTitleFont", FCoreStyle::GetDefaultFontStyle("Regular", 12));
  187. Style.Set("AudiokineticTools.SourceTreeItemFont", FCoreStyle::GetDefaultFontStyle("Regular", 10));
  188. Style.Set("AudiokineticTools.SourceTreeRootItemFont", FCoreStyle::GetDefaultFontStyle("Regular", 12));
  189. const FVector2D Icon12x12(12.0f, 12.0f);
  190. Style.Set("AudiokineticTools.Button_EllipsisIcon", CreateEngineImageBrush(Style, "Icons/ellipsis_12x", Icon12x12));
  191. }
  192. FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance);
  193. }
  194. }
  195. #undef IMAGE_BRUSH
  196. void FAkAudioStyle::Shutdown()
  197. {
  198. if (StyleInstance.IsValid())
  199. {
  200. FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance);
  201. ensure(StyleInstance.IsUnique());
  202. StyleInstance.Reset();
  203. }
  204. }
  205. void FAkAudioStyle::DisplayEditorMessage(const FText& messageText, EWwiseItemType::Type wwiseItemType /* = EWwiseItemType::Type::None*/, float duration /* = 1.5f */)
  206. {
  207. if (!FApp::CanEverRender())
  208. {
  209. UE_LOG(LogAkAudio, Display, TEXT("DisplayEditorMessage: %s"), *messageText.ToString());
  210. return;
  211. }
  212. FNotificationInfo Info(messageText);
  213. if (wwiseItemType == EWwiseItemType::None)
  214. Info.Image = FAkAudioStyle::GetWwiseIcon();
  215. else
  216. Info.Image = FAkAudioStyle::GetBrush(wwiseItemType);
  217. Info.FadeInDuration = 0.1f;
  218. Info.FadeOutDuration = 0.5f;
  219. Info.ExpireDuration = duration;
  220. Info.bUseThrobber = false;
  221. Info.bUseSuccessFailIcons = false;
  222. Info.bUseLargeFont = true;
  223. Info.bFireAndForget = false;
  224. Info.bAllowThrottleWhenFrameRateIsLow = false;
  225. auto NotificationItem = FSlateNotificationManager::Get().AddNotification(Info);
  226. NotificationItem->SetCompletionState(SNotificationItem::CS_None);
  227. NotificationItem->ExpireAndFadeout();
  228. }
  229. FName FAkAudioStyle::GetStyleSetName()
  230. {
  231. static FName StyleSetName(TEXT("AudiokineticToolsStyle"));
  232. return StyleSetName;
  233. }
  234. const ISlateStyle& FAkAudioStyle::Get()
  235. {
  236. Initialize();
  237. return *StyleInstance;
  238. }
  239. const FSlateBrush* FAkAudioStyle::GetWwiseIcon()
  240. {
  241. auto& Style = Get();
  242. return Style.GetBrush("AudiokineticTools.WwiseIcon");
  243. }
  244. const FSlateBrush* FAkAudioStyle::GetBrush(EWwiseItemType::Type ItemType)
  245. {
  246. auto& Style = Get();
  247. switch (ItemType)
  248. {
  249. case EWwiseItemType::Event: return Style.GetBrush("AudiokineticTools.EventIcon");
  250. case EWwiseItemType::AcousticTexture: return Style.GetBrush("AudiokineticTools.AcousticTextureIcon");
  251. case EWwiseItemType::AuxBus: return Style.GetBrush("AudiokineticTools.AuxBusIcon");
  252. case EWwiseItemType::Bus: return Style.GetBrush("AudiokineticTools.BusIcon");
  253. case EWwiseItemType::Folder: return Style.GetBrush("AudiokineticTools.FolderIcon");
  254. case EWwiseItemType::Project: return Style.GetBrush("AudiokineticTools.ProjectIcon");
  255. case EWwiseItemType::PhysicalFolder: return Style.GetBrush("AudiokineticTools.PhysicalFolderIcon");
  256. case EWwiseItemType::StandaloneWorkUnit:
  257. case EWwiseItemType::NestedWorkUnit: return Style.GetBrush("AudiokineticTools.WorkUnitIcon");
  258. case EWwiseItemType::ActorMixer: return Style.GetBrush("AudiokineticTools.ActorMixerIcon");
  259. case EWwiseItemType::Sound: return Style.GetBrush("AudiokineticTools.SoundIcon");
  260. case EWwiseItemType::SwitchContainer: return Style.GetBrush("AudiokineticTools.SwitchContainerIcon");
  261. case EWwiseItemType::RandomSequenceContainer: return Style.GetBrush("AudiokineticTools.RandomSequenceContainerIcon");
  262. case EWwiseItemType::BlendContainer: return Style.GetBrush("AudiokineticTools.BlendContainerIcon");
  263. case EWwiseItemType::MotionBus: return Style.GetBrush("AudiokineticTools.MotionBusIcon");
  264. case EWwiseItemType::GameParameter: return Style.GetBrush("AudiokineticTools.RTPCIcon");
  265. case EWwiseItemType::State: return Style.GetBrush("AudiokineticTools.StateIcon");
  266. case EWwiseItemType::StateGroup: return Style.GetBrush("AudiokineticTools.StateGroupIcon");
  267. case EWwiseItemType::Switch: return Style.GetBrush("AudiokineticTools.SwitchIcon");
  268. case EWwiseItemType::SwitchGroup: return Style.GetBrush("AudiokineticTools.SwitchGroupIcon");
  269. case EWwiseItemType::Trigger: return Style.GetBrush("AudiokineticTools.TriggerIcon");
  270. case EWwiseItemType::EffectShareSet: return Style.GetBrush("AudiokineticTools.EffectShareSetIcon");
  271. default:
  272. return nullptr;
  273. }
  274. }
  275. const FSlateBrush* FAkAudioStyle::GetBrush(FName PropertyName, const ANSICHAR* Specifier)
  276. {
  277. return Get().GetBrush(PropertyName, Specifier);
  278. }
  279. const FSlateFontInfo FAkAudioStyle::GetFontStyle(FName PropertyName, const ANSICHAR* Specifier)
  280. {
  281. return Get().GetFontStyle(PropertyName, Specifier);
  282. }
  283. UMaterial* FAkAudioStyle::GetAkForegroundTextMaterial()
  284. {
  285. if (TextMaterial == nullptr)
  286. {
  287. TextMaterial = AkAudioStyle_Helpers::LoadAkMaterial(FString(""), FString("DefaultForegroundTextMaterial"));
  288. if (TextMaterial != nullptr)
  289. TextMaterial->AddToRoot();
  290. }
  291. return TextMaterial;
  292. }
  293. FLinearColor FAkAudioStyle::GetWwiseObjectColor(int colorIndex)
  294. {
  295. if (WwiseUnrealColorPalette.Num() > 0)
  296. {
  297. if (colorIndex == -1)
  298. colorIndex = WwiseUnrealColorPalette.Num() - 1;
  299. if (colorIndex < WwiseUnrealColorPalette.Num())
  300. {
  301. return WwiseUnrealColorPalette[colorIndex];
  302. }
  303. }
  304. return FLinearColor();
  305. }