AkSlider.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  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. /*------------------------------------------------------------------------------------
  16. includes.
  17. ------------------------------------------------------------------------------------*/
  18. #include "AkWaapiUMG/Components/AkSlider.h"
  19. #include "AkAudioDevice.h"
  20. #include "Widgets/DeclarativeSyntaxSupport.h"
  21. #include "AkWaapiSlate/Widgets/Input/AkSSlider.h"
  22. #include "UMGStyle.h"
  23. #include "AkWaapiUMG/Components/AkWwiseObjectDetailsStructCustomization.h"
  24. #include "AkWaapiUMG/Components/AkPropertyToControlCustomization.h"
  25. #include "AkWaapiUMG/Components/WwiseUmgDragDropOp.h"
  26. #include "AkWaapiUMG/Components/WwisePropertyDragDropOp.h"
  27. #include "AkWaapiUtils.h"
  28. #include "AkWaapiBlueprints/AkWaapiCalls.h"
  29. #include "Widgets/Input/SSlider.h"
  30. #include "Async/Async.h"
  31. #if WITH_EDITOR
  32. #include "Editor.h"
  33. #include "Modules/ModuleManager.h"
  34. #include "PropertyEditorModule.h"
  35. #endif
  36. /*------------------------------------------------------------------------------------
  37. Defines
  38. ------------------------------------------------------------------------------------*/
  39. #define LOCTEXT_NAMESPACE "AkWaapiUMG"
  40. /*------------------------------------------------------------------------------------
  41. Helpers
  42. ------------------------------------------------------------------------------------*/
  43. static inline const float ComputeValue(const float inValue, const float inMaxValue, const float inMinValue)
  44. {
  45. return (inValue - inMinValue) / (inMaxValue - inMinValue);
  46. }
  47. /*------------------------------------------------------------------------------------
  48. Implementation
  49. ------------------------------------------------------------------------------------*/
  50. /////////////////////////////////////////////////////
  51. // UAkSlider
  52. UAkSlider::UAkSlider(const FObjectInitializer& ObjectInitializer)
  53. : Super(ObjectInitializer)
  54. {
  55. Orientation = EOrientation::Orient_Horizontal;
  56. SliderBarColor = FLinearColor::White;
  57. SliderHandleColor = FLinearColor::White;
  58. StepSize = 0.01f;
  59. AkSSlider::FArguments Defaults;
  60. WidgetStyle = *Defaults._Style;
  61. IsFocusable = true;
  62. SubscriptionId = 0;
  63. }
  64. void UAkSlider::BeginDestroy()
  65. {
  66. UnsubscribePropertyChangedCallback();
  67. Super::BeginDestroy();
  68. }
  69. TSharedRef<SWidget> UAkSlider::RebuildWidget()
  70. {
  71. #if WITH_EDITOR
  72. FPropertyEditorModule& PropertyModule = FModuleManager::GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
  73. PropertyModule.RegisterCustomPropertyTypeLayout("AkWwiseObjectDetails", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FAkWwiseObjectDetailsStructCustomization::MakeInstance));
  74. PropertyModule.RegisterCustomPropertyTypeLayout("AkPropertyToControl", FOnGetPropertyTypeCustomizationInstance::CreateStatic(&FAkPropertyToControlCustomization::MakeInstance));
  75. PropertyModule.NotifyCustomizationModuleChanged();
  76. #endif//WITH_EDITOR
  77. MyAkSlider = SNew(AkSSlider)
  78. .Style(&WidgetStyle)
  79. .IsFocusable(IsFocusable)
  80. .OnValueChanged(BIND_UOBJECT_DELEGATE(FOnFloatValueChanged, HandleOnValueChanged))
  81. .OnDrop(FOnDrop::CreateUObject(this, &UAkSlider::HandleDropped));
  82. SynchronizePropertyWithWwise();
  83. #if WITH_EDITOR
  84. if (!IsRunningGame())
  85. {
  86. return CreateDesignerOutline(MyAkSlider.ToSharedRef());
  87. }
  88. #endif
  89. return MyAkSlider.ToSharedRef();
  90. }
  91. void UAkSlider::SynchronizeProperties()
  92. {
  93. Super::SynchronizeProperties();
  94. TAttribute<float> ValueBinding = PROPERTY_BINDING(float, Value);
  95. if (MyAkSlider.IsValid())
  96. {
  97. TSharedPtr<SSlider> MySlider = MyAkSlider->GetAkSilder();
  98. MySlider->SetOrientation(Orientation);
  99. MySlider->SetSliderBarColor(SliderBarColor);
  100. MySlider->SetSliderHandleColor(SliderHandleColor);
  101. MySlider->SetValue(ValueBinding);
  102. MySlider->SetLocked(Locked);
  103. MySlider->SetIndentHandle(IndentHandle);
  104. MySlider->SetStepSize(StepSize);
  105. MyAkSlider->SetAkSliderRangeMin(minValue);
  106. MyAkSlider->SetAkSliderRangeMax(maxValue);
  107. ItemToControl.ItemPath = ItemToControl.ItemPicked.ItemPath;
  108. bool shouldSynchronize = false;
  109. if (!ThePropertyToControl.ItemProperty.IsEmpty() && (ThePropertyToControl.ItemProperty != MyAkSlider->GetAkSliderItemProperty()))
  110. {
  111. MyAkSlider->SetAkSliderItemProperty(ThePropertyToControl.ItemProperty);
  112. shouldSynchronize = true;
  113. }
  114. if (!ItemToControl.ItemPicked.ItemId.IsEmpty() && (ItemToControl.ItemPicked.ItemId != MyAkSlider->GetAkSliderItemId()))
  115. {
  116. MyAkSlider->SetAkSliderItemId(ItemToControl.ItemPicked.ItemId);
  117. shouldSynchronize = true;
  118. }
  119. if (shouldSynchronize)
  120. SynchronizePropertyWithWwise();
  121. }
  122. }
  123. void UAkSlider::ReleaseSlateResources(bool bReleaseChildren)
  124. {
  125. Super::ReleaseSlateResources(bReleaseChildren);
  126. UnsubscribePropertyChangedCallback();
  127. MyAkSlider.Reset();
  128. }
  129. void UAkSlider::HandleOnValueChanged(float InValue)
  130. {
  131. OnValueChanged.Broadcast(InValue);
  132. }
  133. float UAkSlider::GetValue() const
  134. {
  135. if (MyAkSlider.IsValid() )
  136. {
  137. TSharedPtr<SSlider> MySlider = MyAkSlider->GetAkSilder();
  138. if (MySlider.IsValid())
  139. {
  140. return MySlider->GetValue();
  141. }
  142. }
  143. return Value;
  144. }
  145. void UAkSlider::SetValue(float InValue)
  146. {
  147. Value = InValue;
  148. if ( MyAkSlider.IsValid() )
  149. {
  150. TSharedPtr<SSlider> MySlider = MyAkSlider->GetAkSilder();
  151. if (MySlider.IsValid())
  152. {
  153. MySlider->SetValue(InValue);
  154. }
  155. }
  156. }
  157. void UAkSlider::SetIndentHandle(bool InIndentHandle)
  158. {
  159. IndentHandle = InIndentHandle;
  160. if ( MyAkSlider.IsValid() )
  161. {
  162. TSharedPtr<SSlider> MySlider = MyAkSlider->GetAkSilder();
  163. if (MySlider.IsValid())
  164. {
  165. MySlider->SetIndentHandle(InIndentHandle);
  166. }
  167. }
  168. }
  169. void UAkSlider::SetLocked(bool InLocked)
  170. {
  171. Locked = InLocked;
  172. if ( MyAkSlider.IsValid() )
  173. {
  174. TSharedPtr<SSlider> MySlider = MyAkSlider->GetAkSilder();
  175. if (MySlider.IsValid())
  176. {
  177. MySlider->SetLocked(InLocked);
  178. }
  179. }
  180. }
  181. void UAkSlider::SetStepSize(float InValue)
  182. {
  183. StepSize = InValue;
  184. if (MyAkSlider.IsValid())
  185. {
  186. TSharedPtr<SSlider> MySlider = MyAkSlider->GetAkSilder();
  187. if (MySlider.IsValid())
  188. {
  189. MySlider->SetStepSize(InValue);
  190. }
  191. }
  192. }
  193. void UAkSlider::SetSliderHandleColor(FLinearColor InValue)
  194. {
  195. SliderHandleColor = InValue;
  196. if (MyAkSlider.IsValid())
  197. {
  198. TSharedPtr<SSlider> MySlider = MyAkSlider->GetAkSilder();
  199. if (MySlider.IsValid())
  200. {
  201. MySlider->SetSliderHandleColor(InValue);
  202. }
  203. }
  204. }
  205. void UAkSlider::SetSliderBarColor(FLinearColor InValue)
  206. {
  207. SliderBarColor = InValue;
  208. if (MyAkSlider.IsValid())
  209. {
  210. TSharedPtr<SSlider> MySlider = MyAkSlider->GetAkSilder();
  211. if (MySlider.IsValid())
  212. {
  213. MySlider->SetSliderBarColor(InValue);
  214. }
  215. }
  216. }
  217. void UAkSlider::SetAkSliderItemId(const FGuid& ItemId)
  218. {
  219. if (ItemId.IsValid())
  220. {
  221. MyAkSlider->SetAkSliderItemId(ItemId.ToString(EGuidFormats::DigitsWithHyphensInBraces));
  222. SynchronizePropertyWithWwise();
  223. }
  224. }
  225. const FGuid UAkSlider::GetAkSliderItemId() const
  226. {
  227. FGuid ItemId = FGuid::NewGuid();
  228. FGuid::ParseExact(MyAkSlider->GetAkSliderItemId(), EGuidFormats::DigitsWithHyphensInBraces, ItemId);
  229. return ItemId;
  230. }
  231. void UAkSlider::SetAkSliderItemProperty(const FString& ItemProperty)
  232. {
  233. if (!ItemProperty.IsEmpty())
  234. {
  235. MyAkSlider->SetAkSliderItemProperty(ItemProperty);
  236. SynchronizePropertyWithWwise();
  237. }
  238. }
  239. const FString UAkSlider::GetAkSliderItemProperty() const
  240. {
  241. return MyAkSlider->GetAkSliderItemProperty();
  242. }
  243. void UAkSlider::SynchronizePropertyWithWwise()
  244. {
  245. if (MyAkSlider.IsValid())
  246. {
  247. const FString& ItemId = MyAkSlider->GetAkSliderItemId();
  248. const FString& ItemProperty = MyAkSlider->GetAkSliderItemProperty();
  249. if (!ItemId.IsEmpty() && !ItemProperty.IsEmpty())
  250. {
  251. TSharedPtr<FJsonObject> ItemInfoResult;
  252. if (CallWappiGetPropertySate(ItemId, ItemProperty, ItemInfoResult) && MyAkSlider.IsValid())
  253. {
  254. double PropertyValue = 0.0;
  255. if (ItemInfoResult->TryGetNumberField(WwiseWaapiHelper::AT + ItemProperty, PropertyValue))
  256. {
  257. double maxRange = MyAkSlider->GetAkSliderRangeMax().GetValue();
  258. double minRange = MyAkSlider->GetAkSliderRangeMin().GetValue();
  259. if (PropertyValue > maxRange)
  260. {
  261. MyAkSlider->SetAkSliderRangeMax(PropertyValue);
  262. maxRange = PropertyValue;
  263. }
  264. if (PropertyValue < minRange)
  265. {
  266. MyAkSlider->SetAkSliderRangeMin(PropertyValue);
  267. minRange = PropertyValue;
  268. }
  269. const float newValue = ComputeValue(PropertyValue, maxRange, minRange);
  270. SetValue(newValue);
  271. }
  272. }
  273. if (SubscriptionId != 0)
  274. {
  275. bool isUnsubscribed;
  276. UAkWaapiCalls::Unsubscribe(FAkWaapiSubscriptionId(SubscriptionId), isUnsubscribed);
  277. }
  278. TSharedPtr<FJsonObject> outJsonResult;
  279. auto wampEventCallback = WampEventCallback::CreateLambda([this](uint64_t id, TSharedPtr<FJsonObject> in_UEJsonObject)
  280. {
  281. AsyncTask(ENamedThreads::GameThread, [this, id, in_UEJsonObject]
  282. {
  283. if (MyAkSlider.IsValid())
  284. {
  285. double PropertyValue = 0.0;
  286. if (in_UEJsonObject->TryGetNumberField(WwiseWaapiHelper::NEW, PropertyValue))
  287. {
  288. double maxRange = MyAkSlider->GetAkSliderRangeMax().GetValue();
  289. double minRange = MyAkSlider->GetAkSliderRangeMin().GetValue();
  290. if (PropertyValue > maxRange)
  291. {
  292. MyAkSlider->SetAkSliderRangeMax(PropertyValue);
  293. maxRange = PropertyValue;
  294. }
  295. else if (PropertyValue < minRange)
  296. {
  297. MyAkSlider->SetAkSliderRangeMin(PropertyValue);
  298. minRange = PropertyValue;
  299. }
  300. const float newValue = ComputeValue(PropertyValue, maxRange, minRange);
  301. SetValue(newValue);
  302. }
  303. }
  304. });
  305. });
  306. SubscribeToPropertyStateChange(ItemId, ItemProperty, wampEventCallback, SubscriptionId, outJsonResult);
  307. }
  308. }
  309. }
  310. void UAkSlider::UnsubscribePropertyChangedCallback()
  311. {
  312. if (SubscriptionId != 0)
  313. {
  314. bool isUnsubscribed;
  315. UAkWaapiCalls::Unsubscribe(FAkWaapiSubscriptionId(SubscriptionId), isUnsubscribed);
  316. if (isUnsubscribed)
  317. SubscriptionId = 0;
  318. }
  319. }
  320. FReply UAkSlider::HandleDropped(const FGeometry& DropZoneGeometry, const FDragDropEvent& DragDropEvent)
  321. {
  322. TSharedPtr<FDragDropOperation> Operation = DragDropEvent.GetOperation();
  323. if (Operation.IsValid())
  324. {
  325. if (OnItemDropped.IsBound() && Operation->IsOfType<FWwiseUmgDragDropOp>())
  326. {
  327. const auto& AssetDragDropOp = StaticCastSharedPtr<FWwiseUmgDragDropOp>(Operation);
  328. if (AssetDragDropOp.IsValid())
  329. {
  330. const TArray<TSharedPtr<FWwiseTreeItem>>& WwiseAssets = AssetDragDropOp->GetWiseItems();
  331. if (WwiseAssets.Num() && WwiseAssets[0].IsValid())
  332. {
  333. OnItemDropped.Broadcast(WwiseAssets[0]->ItemId);
  334. SynchronizePropertyWithWwise();
  335. return FReply::Handled();
  336. }
  337. }
  338. }
  339. else if (OnPropertyDropped.IsBound() && Operation->IsOfType<FWwisePropertyDragDropOp>())
  340. {
  341. const auto& AssetDragDropOp = StaticCastSharedPtr<FWwisePropertyDragDropOp>(Operation);
  342. if (AssetDragDropOp.IsValid())
  343. {
  344. const TArray<TSharedPtr<FString>>& WwiseAssets = AssetDragDropOp->GetWiseProperties();
  345. if (WwiseAssets.Num() && WwiseAssets[0].IsValid())
  346. {
  347. OnPropertyDropped.Broadcast(*WwiseAssets[0].Get());
  348. SynchronizePropertyWithWwise();
  349. return FReply::Handled();
  350. }
  351. }
  352. }
  353. SynchronizePropertyWithWwise();
  354. }
  355. return FReply::Unhandled();
  356. }
  357. #if WITH_EDITOR
  358. const FText UAkSlider::GetPaletteCategory()
  359. {
  360. return LOCTEXT("Wwise", "Wwise");
  361. }
  362. #endif
  363. /////////////////////////////////////////////////////
  364. #undef LOCTEXT_NAMESPACE