AkAudioStyle.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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 "AkAcousticTexture.h"
  17. #include "AkAudioDevice.h"
  18. #include "AkAudioEvent.h"
  19. #include "AkAuxBus.h"
  20. #include "AkEffectShareSet.h"
  21. #include "AkRtpc.h"
  22. #include "AkStateValue.h"
  23. #include "AkSwitchValue.h"
  24. #include "AkTrigger.h"
  25. #include "WaapiPicker/WwiseTreeItem.h"
  26. #include "Engine/Texture2D.h"
  27. #include "Framework/Notifications/NotificationManager.h"
  28. #include "Styling/SlateStyle.h"
  29. #include "Styling/SlateStyleRegistry.h"
  30. #include "Widgets/Notifications/SNotificationList.h"
  31. #if WITH_EDITOR
  32. #include "Wwise/Ref/WwiseRefType.h"
  33. #endif
  34. TSharedPtr< FSlateStyleSet > FAkAudioStyle::StyleInstance = nullptr;
  35. UMaterial* FAkAudioStyle::TextMaterial = nullptr;
  36. /* Taken from the Wwise Authoring dark theme. @TODO: Take this from the theme's main.json file. */
  37. TArray<FLinearColor> WwiseUnrealColorPalette = {
  38. FColor(191, 191, 191, 255),
  39. FColor(82, 90, 255, 1),
  40. FColor(41, 169, 255, 1),
  41. FColor(0, 255, 255, 1),
  42. FColor(0, 255, 0, 1),
  43. FColor(183, 255, 0, 1),
  44. FColor(255, 238, 0, 1),
  45. FColor(255, 170, 0, 1),
  46. FColor(255, 128, 0, 1),
  47. FColor(255, 85, 0, 1),
  48. FColor(255, 0, 0, 1),
  49. FColor(255, 0, 255, 1),
  50. FColor(190, 61, 255, 1),
  51. FColor(184, 107, 255, 1),
  52. FColor(112, 119, 255, 1),
  53. FColor(119, 164, 253, 1),
  54. FColor(132, 240, 240, 1),
  55. FColor(136, 242, 136, 1),
  56. FColor(209, 240, 122, 1),
  57. FColor(240, 192, 96, 1),
  58. FColor(255, 179, 102, 1),
  59. FColor(240, 192, 96, 1),
  60. FColor(255, 179, 102, 1),
  61. FColor(255, 146, 92, 1),
  62. FColor(255, 112, 255, 1),
  63. FColor(214, 133, 255, 1),
  64. FColor(166, 128, 255, 1),
  65. FColor(191, 191, 191, 1)
  66. };
  67. namespace AkAudioStyle_Helpers
  68. {
  69. template<typename T1, typename T2>
  70. auto LoadAkTexture(T1&& RelativePath, T2&& TextureName)
  71. {
  72. return LoadObject<UTexture2D>(nullptr, *(FString("/Wwise/") / FString(Forward<T1>(RelativePath)) / FString(Forward<T2>(TextureName)) + FString(".") + FString(Forward<T2>(TextureName))));
  73. }
  74. UMaterial* LoadAkMaterial(const FString& RelativePath, const FString& MaterialName)
  75. {
  76. return LoadObject<UMaterial>(nullptr, *(FString("/Wwise/") + RelativePath + MaterialName + FString(".") + MaterialName));
  77. }
  78. auto CreateAkImageBrush(UTexture2D* Texture, const FVector2D& TextureSize)
  79. {
  80. return new FSlateImageBrush(Texture, TextureSize);
  81. }
  82. template<typename StringType, typename...Args>
  83. auto CreateEngineBoxBrush(FSlateStyleSet& Style, StringType& RelativePath, Args&&... args)
  84. {
  85. return new FSlateBoxBrush(Style.RootToContentDir(Forward<StringType>(RelativePath), TEXT(".png")), Forward<Args>(args)...);
  86. }
  87. template<typename StringType, typename...Args>
  88. auto EngineBoxBrush(FSlateStyleSet& Style, StringType&& RelativePath, Args&&... args)
  89. {
  90. return FSlateBoxBrush(Style.RootToContentDir(Forward<StringType>(RelativePath), TEXT(".png")), Forward<Args>(args)...);
  91. }
  92. template<typename StringType, typename...Args>
  93. auto CreateEngineImageBrush(FSlateStyleSet& Style, StringType& RelativePath, Args&&... args)
  94. {
  95. return new FSlateImageBrush(Style.RootToContentDir(Forward<StringType>(RelativePath), TEXT(".png")), Forward<Args>(args)...);
  96. }
  97. }
  98. void SetAkBrush(FSlateStyleSet& Style, const char* BrushName, const char* TextureName)
  99. {
  100. using namespace AkAudioStyle_Helpers;
  101. const FVector2D Icon15x15(15.0f, 15.0f);
  102. auto Texture = LoadAkTexture("WwiseTree/Icons", TextureName);
  103. if (Texture != nullptr)
  104. {
  105. Texture->AddToRoot();
  106. Style.Set(BrushName, CreateAkImageBrush(Texture, Icon15x15));
  107. }
  108. }
  109. void SetClassThumbnail(FSlateStyleSet& Style, const char* BrushName, const char* TextureName)
  110. {
  111. using namespace AkAudioStyle_Helpers;
  112. const FVector2D ThumbnailSize(256.0f, 256.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 SetClassIcon(FSlateStyleSet& Style, const char* BrushName, const char* TextureName)
  121. {
  122. using namespace AkAudioStyle_Helpers;
  123. const FVector2D ThumbnailSize(15.0f, 15.0f);
  124. auto Texture = LoadAkTexture("WwiseTypes", TextureName);
  125. if (Texture != nullptr)
  126. {
  127. Texture->AddToRoot();
  128. Style.Set(BrushName, CreateAkImageBrush(Texture, ThumbnailSize));
  129. }
  130. }
  131. void SetAkResourceBrushes(FSlateStyleSet& Style)
  132. {
  133. SetAkBrush(Style, "AudiokineticTools.WwiseIcon", "Titlebar_WwiseAppIcon");
  134. SetAkBrush(Style, "AudiokineticTools.ActorMixerIcon", "actor_mixer_nor");
  135. SetAkBrush(Style, "AudiokineticTools.SoundIcon", "sound_fx_nor");
  136. SetAkBrush(Style, "AudiokineticTools.SwitchContainerIcon", "container_switch_nor");
  137. SetAkBrush(Style, "AudiokineticTools.RandomSequenceContainerIcon", "container_random_sequence_nor");
  138. SetAkBrush(Style, "AudiokineticTools.BlendContainerIcon", "layer_container_nor");
  139. SetAkBrush(Style, "AudiokineticTools.MotionBusIcon", "motion_bus_nor");
  140. SetAkBrush(Style, "AudiokineticTools.AkBrowserTabIcon", "wwise_logo_32");
  141. SetAkBrush(Style, "AudiokineticTools.EventIcon", "event_nor");
  142. SetAkBrush(Style, "AudiokineticTools.AcousticTextureIcon", "acoutex_nor");
  143. SetAkBrush(Style, "AudiokineticTools.AuxBusIcon", "auxbus_nor");
  144. SetAkBrush(Style, "AudiokineticTools.BusIcon", "bus_nor");
  145. SetAkBrush(Style, "AudiokineticTools.FolderIcon", "folder_nor");
  146. SetAkBrush(Style, "AudiokineticTools.PhysicalFolderIcon", "physical_folder_nor");
  147. SetAkBrush(Style, "AudiokineticTools.WorkUnitIcon", "workunit_nor");
  148. SetAkBrush(Style, "AudiokineticTools.ProjectIcon", "wproj");
  149. SetAkBrush(Style, "AudiokineticTools.RTPCIcon", "gameparameter_nor");
  150. SetAkBrush(Style, "AudiokineticTools.StateIcon", "state_nor");
  151. SetAkBrush(Style, "AudiokineticTools.StateGroupIcon", "stategroup_nor");
  152. SetAkBrush(Style, "AudiokineticTools.SwitchIcon", "switch_nor");
  153. SetAkBrush(Style, "AudiokineticTools.SwitchGroupIcon", "switchgroup_nor");
  154. SetAkBrush(Style, "AudiokineticTools.TriggerIcon", "trigger_nor");
  155. SetAkBrush(Style, "AudiokineticTools.EffectShareSetIcon", "effect_shareset_nor");
  156. SetClassThumbnail(Style, "ClassThumbnail.AkAcousticTexture", "AkAcousticTexture");
  157. SetClassThumbnail(Style, "ClassThumbnail.AkAudioEvent", "AkAudioEvent");
  158. SetClassThumbnail(Style, "ClassThumbnail.AkAuxBus", "AkAuxBus");
  159. SetClassThumbnail(Style, "ClassThumbnail.AkAudioBank", "AkAudioBank");
  160. SetClassThumbnail(Style, "ClassThumbnail.AkInitBank", "AkAudioBank");
  161. SetClassThumbnail(Style, "ClassThumbnail.AkLocalizedMediaAsset", "AkLocalizedMediaAsset");
  162. SetClassThumbnail(Style, "ClassThumbnail.AkMediaAsset", "AkMediaAsset");
  163. SetClassThumbnail(Style, "ClassThumbnail.AkExternalMediaAsset", "AkExternalMediaAsset");
  164. SetClassThumbnail(Style, "ClassThumbnail.AkRtpc", "AkRtpc");
  165. SetClassThumbnail(Style, "ClassThumbnail.AkStateValue", "AkStateValue");
  166. SetClassThumbnail(Style, "ClassThumbnail.AkSwitchValue", "AkSwitchValue");
  167. SetClassThumbnail(Style, "ClassThumbnail.AkTrigger", "AkTrigger");
  168. SetClassThumbnail(Style, "ClassThumbnail.AkEffectShareSet", "AkEffectShareSet");
  169. SetClassThumbnail(Style, "ClassThumbnail.AkAcousticPortal", "AK_Acoustic_Portal");
  170. SetClassIcon(Style, "ClassIcon.AkAcousticPortal", "AK_Acoustic_Portal_Explorer");
  171. SetClassThumbnail(Style, "ClassThumbnail.AkSpatialAudioVolume", "AK_Spatial_Audio_Volume");
  172. SetClassIcon(Style, "ClassIcon.AkSpatialAudioVolume", "AK_Spatial_Audio_Volume_Explorer");
  173. SetClassThumbnail(Style, "ClassThumbnail.AkReverbVolume", "AK_Reverb_Volume");
  174. SetClassIcon(Style, "ClassIcon.AkReverbVolume", "AK_Reverb_Volume_Explorer");
  175. }
  176. void FAkAudioStyle::Initialize()
  177. {
  178. using namespace AkAudioStyle_Helpers;
  179. if (!StyleInstance.IsValid())
  180. {
  181. StyleInstance = MakeShareable(new FSlateStyleSet(FAkAudioStyle::GetStyleSetName()));
  182. auto ContentRoot = FPaths::EngineContentDir() / TEXT("Slate");
  183. StyleInstance->SetContentRoot(ContentRoot);
  184. StyleInstance->SetCoreContentRoot(ContentRoot);
  185. FSlateStyleSet& Style = *StyleInstance.Get();
  186. {
  187. SetAkResourceBrushes(Style);
  188. Style.Set("AudiokineticTools.GroupBorder", CreateEngineBoxBrush(Style, "Common/GroupBorder", FMargin(4.0f / 16.0f)));
  189. Style.Set("AudiokineticTools.AssetDragDropTooltipBackground", CreateEngineBoxBrush(Style, "Old/Menu_Background", FMargin(8.0f / 64.0f)));
  190. FButtonStyle HoverHintOnly = FButtonStyle()
  191. .SetNormal(FSlateNoResource())
  192. .SetHovered(EngineBoxBrush(Style, "Common/Button_Hovered", FMargin(4 / 16.0f), FLinearColor(1, 1, 1, 0.15f)))
  193. .SetPressed(EngineBoxBrush(Style, "Common/Button_Pressed", FMargin(4 / 16.0f), FLinearColor(1, 1, 1, 0.25f)))
  194. .SetNormalPadding(FMargin(0, 0, 0, 1))
  195. .SetPressedPadding(FMargin(0, 1, 0, 0));
  196. Style.Set("AudiokineticTools.HoverHintOnly", HoverHintOnly);
  197. Style.Set("AudiokineticTools.SourceTitleFont", FCoreStyle::GetDefaultFontStyle("Regular", 12));
  198. Style.Set("AudiokineticTools.SourceTreeItemFont", FCoreStyle::GetDefaultFontStyle("Regular", 10));
  199. Style.Set("AudiokineticTools.SourceTreeRootItemFont", FCoreStyle::GetDefaultFontStyle("Regular", 12));
  200. const FVector2D Icon12x12(12.0f, 12.0f);
  201. Style.Set("AudiokineticTools.Button_EllipsisIcon", CreateEngineImageBrush(Style, "Icons/ellipsis_12x", Icon12x12));
  202. }
  203. FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance);
  204. }
  205. }
  206. #undef IMAGE_BRUSH
  207. void FAkAudioStyle::Shutdown()
  208. {
  209. if (StyleInstance.IsValid())
  210. {
  211. FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance);
  212. ensure(StyleInstance.IsUnique());
  213. StyleInstance.Reset();
  214. }
  215. }
  216. void FAkAudioStyle::DisplayEditorMessage(const FText& messageText, EWwiseItemType::Type wwiseItemType /* = EWwiseItemType::Type::None*/, float duration /* = 1.5f */)
  217. {
  218. if (!FApp::CanEverRender())
  219. {
  220. UE_LOG(LogAkAudio, Display, TEXT("DisplayEditorMessage: %s"), *messageText.ToString());
  221. return;
  222. }
  223. FNotificationInfo Info(messageText);
  224. if (wwiseItemType == EWwiseItemType::None)
  225. Info.Image = FAkAudioStyle::GetWwiseIcon();
  226. else
  227. Info.Image = FAkAudioStyle::GetBrush(wwiseItemType);
  228. Info.FadeInDuration = 0.1f;
  229. Info.FadeOutDuration = 0.5f;
  230. Info.ExpireDuration = duration;
  231. Info.bUseThrobber = false;
  232. Info.bUseSuccessFailIcons = false;
  233. Info.bUseLargeFont = true;
  234. Info.bFireAndForget = false;
  235. Info.bAllowThrottleWhenFrameRateIsLow = false;
  236. auto NotificationItem = FSlateNotificationManager::Get().AddNotification(Info);
  237. NotificationItem->SetCompletionState(SNotificationItem::CS_None);
  238. NotificationItem->ExpireAndFadeout();
  239. }
  240. FName FAkAudioStyle::GetStyleSetName()
  241. {
  242. static FName StyleSetName(TEXT("AudiokineticToolsStyle"));
  243. return StyleSetName;
  244. }
  245. const ISlateStyle& FAkAudioStyle::Get()
  246. {
  247. Initialize();
  248. return *StyleInstance;
  249. }
  250. const FSlateBrush* FAkAudioStyle::GetWwiseIcon()
  251. {
  252. auto& Style = Get();
  253. return Style.GetBrush("AudiokineticTools.WwiseIcon");
  254. }
  255. const FSlateBrush* FAkAudioStyle::GetBrush(EWwiseItemType::Type ItemType)
  256. {
  257. auto& Style = Get();
  258. switch (ItemType)
  259. {
  260. case EWwiseItemType::Event: return Style.GetBrush("AudiokineticTools.EventIcon");
  261. case EWwiseItemType::AcousticTexture: return Style.GetBrush("AudiokineticTools.AcousticTextureIcon");
  262. case EWwiseItemType::AuxBus: return Style.GetBrush("AudiokineticTools.AuxBusIcon");
  263. case EWwiseItemType::Bus: return Style.GetBrush("AudiokineticTools.BusIcon");
  264. case EWwiseItemType::Folder: return Style.GetBrush("AudiokineticTools.FolderIcon");
  265. case EWwiseItemType::Project: return Style.GetBrush("AudiokineticTools.ProjectIcon");
  266. case EWwiseItemType::PhysicalFolder: return Style.GetBrush("AudiokineticTools.PhysicalFolderIcon");
  267. case EWwiseItemType::StandaloneWorkUnit:
  268. case EWwiseItemType::NestedWorkUnit: return Style.GetBrush("AudiokineticTools.WorkUnitIcon");
  269. case EWwiseItemType::ActorMixer: return Style.GetBrush("AudiokineticTools.ActorMixerIcon");
  270. case EWwiseItemType::Sound: return Style.GetBrush("AudiokineticTools.SoundIcon");
  271. case EWwiseItemType::SwitchContainer: return Style.GetBrush("AudiokineticTools.SwitchContainerIcon");
  272. case EWwiseItemType::RandomSequenceContainer: return Style.GetBrush("AudiokineticTools.RandomSequenceContainerIcon");
  273. case EWwiseItemType::BlendContainer: return Style.GetBrush("AudiokineticTools.BlendContainerIcon");
  274. case EWwiseItemType::MotionBus: return Style.GetBrush("AudiokineticTools.MotionBusIcon");
  275. case EWwiseItemType::GameParameter: return Style.GetBrush("AudiokineticTools.RTPCIcon");
  276. case EWwiseItemType::State: return Style.GetBrush("AudiokineticTools.StateIcon");
  277. case EWwiseItemType::StateGroup: return Style.GetBrush("AudiokineticTools.StateGroupIcon");
  278. case EWwiseItemType::Switch: return Style.GetBrush("AudiokineticTools.SwitchIcon");
  279. case EWwiseItemType::SwitchGroup: return Style.GetBrush("AudiokineticTools.SwitchGroupIcon");
  280. case EWwiseItemType::Trigger: return Style.GetBrush("AudiokineticTools.TriggerIcon");
  281. case EWwiseItemType::EffectShareSet: return Style.GetBrush("AudiokineticTools.EffectShareSetIcon");
  282. default:
  283. return nullptr;
  284. }
  285. }
  286. #if WITH_EDITOR
  287. const FSlateBrush* FAkAudioStyle::GetBrush(EWwiseRefType WwiseRefType)
  288. {
  289. EWwiseItemType::Type ItemType = EWwiseItemType::Type::None;
  290. switch (WwiseRefType)
  291. {
  292. case EWwiseRefType::Event:
  293. ItemType = EWwiseItemType::Event;
  294. break;
  295. case EWwiseRefType::SwitchContainer:
  296. ItemType = EWwiseItemType::SwitchContainer;
  297. break;
  298. case EWwiseRefType::Bus:
  299. ItemType = EWwiseItemType::Bus;
  300. break;
  301. case EWwiseRefType::AuxBus:
  302. ItemType = EWwiseItemType::AuxBus;
  303. break;
  304. case EWwiseRefType::GameParameter:
  305. ItemType = EWwiseItemType::GameParameter;
  306. break;
  307. case EWwiseRefType::StateGroup:
  308. ItemType = EWwiseItemType::StateGroup;
  309. break;
  310. case EWwiseRefType::State:
  311. ItemType = EWwiseItemType::State;
  312. break;
  313. case EWwiseRefType::SwitchGroup:
  314. ItemType = EWwiseItemType::SwitchGroup;
  315. break;
  316. case EWwiseRefType::Switch:
  317. ItemType = EWwiseItemType::Switch;
  318. break;
  319. case EWwiseRefType::Trigger:
  320. ItemType = EWwiseItemType::Trigger;
  321. break;
  322. case EWwiseRefType::AcousticTexture:
  323. ItemType = EWwiseItemType::AcousticTexture;
  324. break;
  325. case EWwiseRefType::PluginShareSet:
  326. ItemType = EWwiseItemType::EffectShareSet;
  327. break;
  328. }
  329. return GetBrush(ItemType);
  330. }
  331. const FSlateBrush* FAkAudioStyle::GetBrush(UClass* Class)
  332. {
  333. EWwiseItemType::Type ItemType = EWwiseItemType::Type::None;
  334. if (Class == UAkAudioEvent::StaticClass())
  335. {
  336. ItemType = EWwiseItemType::Event;
  337. }
  338. if (Class == UAkAcousticTexture::StaticClass())
  339. {
  340. ItemType = EWwiseItemType::AcousticTexture;
  341. }
  342. if (Class == UAkRtpc::StaticClass())
  343. {
  344. ItemType = EWwiseItemType::GameParameter;
  345. }
  346. if (Class == UAkStateValue::StaticClass())
  347. {
  348. ItemType = EWwiseItemType::State;
  349. }
  350. if (Class == UAkSwitchValue::StaticClass())
  351. {
  352. ItemType = EWwiseItemType::Switch;
  353. }
  354. if (Class == UAkTrigger::StaticClass())
  355. {
  356. ItemType = EWwiseItemType::Trigger;
  357. }
  358. if (Class == UAkEffectShareSet::StaticClass())
  359. {
  360. ItemType = EWwiseItemType::EffectShareSet;
  361. }
  362. if (Class == UAkAuxBus::StaticClass())
  363. {
  364. ItemType = EWwiseItemType::AuxBus;
  365. }
  366. return GetBrush(ItemType);
  367. }
  368. #endif
  369. const FSlateBrush* FAkAudioStyle::GetBrush(FName PropertyName, const ANSICHAR* Specifier)
  370. {
  371. return Get().GetBrush(PropertyName, Specifier);
  372. }
  373. const FSlateFontInfo FAkAudioStyle::GetFontStyle(FName PropertyName, const ANSICHAR* Specifier)
  374. {
  375. return Get().GetFontStyle(PropertyName, Specifier);
  376. }
  377. UMaterial* FAkAudioStyle::GetAkForegroundTextMaterial()
  378. {
  379. if (TextMaterial == nullptr)
  380. {
  381. TextMaterial = AkAudioStyle_Helpers::LoadAkMaterial(FString(""), FString("DefaultForegroundTextMaterial"));
  382. if (TextMaterial != nullptr)
  383. TextMaterial->AddToRoot();
  384. }
  385. return TextMaterial;
  386. }
  387. FLinearColor FAkAudioStyle::GetWwiseObjectColor(int colorIndex)
  388. {
  389. if (WwiseUnrealColorPalette.Num() > 0)
  390. {
  391. if (colorIndex == -1)
  392. colorIndex = WwiseUnrealColorPalette.Num() - 1;
  393. if (colorIndex < WwiseUnrealColorPalette.Num())
  394. {
  395. return WwiseUnrealColorPalette[colorIndex];
  396. }
  397. }
  398. return FLinearColor();
  399. }