GeneralNodeTitleComponent.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <QGraphicsItem>
  9. #include <QFont>
  10. #include <QPainter>
  11. #include <AzCore/Serialization/EditContext.h>
  12. #include <Components/Nodes/General/GeneralNodeTitleComponent.h>
  13. #include <Components/Nodes/General/GeneralNodeFrameComponent.h>
  14. #include <GraphCanvas/Components/StyleBus.h>
  15. #include <GraphCanvas/Components/Nodes/NodeBus.h>
  16. #include <GraphCanvas/Editor/GraphCanvasProfiler.h>
  17. #include <GraphCanvas/tools.h>
  18. #include <GraphCanvas/Styling/StyleHelper.h>
  19. #include <GraphCanvas/Utils/QtDrawingUtils.h>
  20. #include <GraphCanvas/Components/VisualBus.h>
  21. namespace GraphCanvas
  22. {
  23. // Implementation of RTTI functions for the GeneralNodeTitleComponent SaveData class in a cpp file
  24. AZ_RTTI_NO_TYPE_INFO_IMPL(GeneralNodeTitleComponentSaveData, SceneMemberComponentSaveData<GeneralNodeTitleComponentSaveData>);
  25. //////////////////////////////
  26. // GeneralNodeTitleComponent
  27. //////////////////////////////
  28. void GeneralNodeTitleComponent::Reflect(AZ::ReflectContext* context)
  29. {
  30. AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
  31. if (serializeContext)
  32. {
  33. serializeContext->Class<GeneralNodeTitleComponentSaveData, ComponentSaveData>()
  34. ->Version(1)
  35. ->Field("PaletteOverride", &GeneralNodeTitleComponentSaveData::m_paletteOverride)
  36. ;
  37. serializeContext->Class<GeneralNodeTitleComponent, AZ::Component >()
  38. ->Version(4)
  39. ->Field("Title", &GeneralNodeTitleComponent::m_title)
  40. ->Field("SubTitle", &GeneralNodeTitleComponent::m_subTitle)
  41. ->Field("SaveData", &GeneralNodeTitleComponent::m_saveData)
  42. ->Field("DefaultPalette", &GeneralNodeTitleComponent::m_basePalette)
  43. ;
  44. }
  45. }
  46. GeneralNodeTitleComponent::GeneralNodeTitleComponent()
  47. {
  48. }
  49. void GeneralNodeTitleComponent::Init()
  50. {
  51. m_generalNodeTitleWidget = aznew GeneralNodeTitleGraphicsWidget(GetEntityId());
  52. }
  53. void GeneralNodeTitleComponent::Activate()
  54. {
  55. AZ::EntityId entityId = GetEntityId();
  56. m_saveData.Activate(entityId);
  57. SceneMemberNotificationBus::Handler::BusConnect(entityId);
  58. NodeTitleRequestBus::Handler::BusConnect(entityId);
  59. VisualNotificationBus::Handler::BusConnect(entityId);
  60. if (m_generalNodeTitleWidget)
  61. {
  62. m_generalNodeTitleWidget->SetTitle(m_title);
  63. m_generalNodeTitleWidget->SetSubTitle(m_subTitle);
  64. m_generalNodeTitleWidget->UpdateLayout();
  65. m_generalNodeTitleWidget->Activate();
  66. }
  67. }
  68. void GeneralNodeTitleComponent::Deactivate()
  69. {
  70. if (m_generalNodeTitleWidget)
  71. {
  72. m_generalNodeTitleWidget->Deactivate();
  73. }
  74. SceneMemberNotificationBus::Handler::BusDisconnect();
  75. NodeTitleRequestBus::Handler::BusDisconnect();
  76. VisualNotificationBus::Handler::BusDisconnect();
  77. }
  78. void GeneralNodeTitleComponent::SetDetails(const AZStd::string& title, const AZStd::string& subtitle)
  79. {
  80. m_title = title;
  81. m_subTitle = subtitle;
  82. if (m_generalNodeTitleWidget)
  83. {
  84. m_generalNodeTitleWidget->SetDetails(title, subtitle);
  85. }
  86. }
  87. void GeneralNodeTitleComponent::SetTitle(const AZStd::string& title)
  88. {
  89. m_title = title;
  90. if (m_generalNodeTitleWidget)
  91. {
  92. m_generalNodeTitleWidget->SetTitle(title);
  93. }
  94. }
  95. AZStd::string GeneralNodeTitleComponent::GetTitle() const
  96. {
  97. return m_title;
  98. }
  99. void GeneralNodeTitleComponent::SetSubTitle(const AZStd::string& subtitle)
  100. {
  101. m_subTitle = subtitle;
  102. if (m_generalNodeTitleWidget)
  103. {
  104. m_generalNodeTitleWidget->SetSubTitle(subtitle);
  105. }
  106. }
  107. AZStd::string GeneralNodeTitleComponent::GetSubTitle() const
  108. {
  109. return m_subTitle;
  110. }
  111. QGraphicsWidget* GeneralNodeTitleComponent::GetGraphicsWidget()
  112. {
  113. return m_generalNodeTitleWidget;
  114. }
  115. void GeneralNodeTitleComponent::SetDefaultPalette(const AZStd::string& basePalette)
  116. {
  117. if (m_generalNodeTitleWidget)
  118. {
  119. m_basePalette = basePalette;
  120. m_generalNodeTitleWidget->SetPaletteOverride(basePalette);
  121. }
  122. }
  123. void GeneralNodeTitleComponent::SetPaletteOverride(const AZStd::string& paletteOverride)
  124. {
  125. m_saveData.m_paletteOverride = paletteOverride;
  126. m_saveData.SignalDirty();
  127. if (m_generalNodeTitleWidget)
  128. {
  129. m_generalNodeTitleWidget->SetPaletteOverride(paletteOverride);
  130. }
  131. }
  132. void GeneralNodeTitleComponent::SetDataPaletteOverride(const AZ::Uuid& uuid)
  133. {
  134. if (m_generalNodeTitleWidget)
  135. {
  136. m_generalNodeTitleWidget->SetPaletteOverride(uuid);
  137. }
  138. }
  139. void GeneralNodeTitleComponent::SetColorPaletteOverride(const QColor& color)
  140. {
  141. if (m_generalNodeTitleWidget)
  142. {
  143. m_generalNodeTitleWidget->SetPaletteOverride(color);
  144. }
  145. }
  146. void GeneralNodeTitleComponent::ConfigureIconConfiguration(PaletteIconConfiguration& paletteConfiguration)
  147. {
  148. if (m_generalNodeTitleWidget)
  149. {
  150. m_generalNodeTitleWidget->ConfigureIconConfiguration(paletteConfiguration);
  151. }
  152. }
  153. void GeneralNodeTitleComponent::ClearPaletteOverride()
  154. {
  155. m_saveData.m_paletteOverride = "";
  156. m_saveData.SignalDirty();
  157. if (m_generalNodeTitleWidget)
  158. {
  159. m_generalNodeTitleWidget->ClearPaletteOverride();
  160. }
  161. }
  162. void GeneralNodeTitleComponent::OnSceneSet(const AZ::EntityId& /*graphId*/)
  163. {
  164. if (!m_saveData.m_paletteOverride.empty())
  165. {
  166. if (m_generalNodeTitleWidget)
  167. {
  168. m_generalNodeTitleWidget->SetPaletteOverride(m_saveData.m_paletteOverride);
  169. }
  170. }
  171. else if (!m_basePalette.empty())
  172. {
  173. if (m_generalNodeTitleWidget)
  174. {
  175. m_generalNodeTitleWidget->SetPaletteOverride(m_basePalette);
  176. }
  177. }
  178. }
  179. ///////////////////////////////////
  180. // GeneralNodeTitleGraphicsWidget
  181. ///////////////////////////////////
  182. GeneralNodeTitleGraphicsWidget::GeneralNodeTitleGraphicsWidget(const AZ::EntityId& entityId)
  183. : m_entityId(entityId)
  184. , m_paletteOverride(nullptr)
  185. , m_colorOverride(nullptr)
  186. {
  187. Initialize();
  188. }
  189. GeneralNodeTitleGraphicsWidget::~GeneralNodeTitleGraphicsWidget()
  190. {
  191. delete m_colorOverride;
  192. }
  193. void GeneralNodeTitleGraphicsWidget::Initialize()
  194. {
  195. setCacheMode(QGraphicsItem::CacheMode::DeviceCoordinateCache);
  196. setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
  197. setGraphicsItem(this);
  198. setAcceptHoverEvents(false);
  199. setFlag(ItemIsMovable, false);
  200. m_titleWidget = aznew GraphCanvasLabel(this);
  201. m_subTitleWidget = aznew GraphCanvasLabel(this);
  202. m_linearLayout = new QGraphicsLinearLayout(Qt::Vertical);
  203. setLayout(m_linearLayout);
  204. setData(GraphicsItemName, QStringLiteral("Title/%1").arg(static_cast<AZ::u64>(m_entityId), 16, 16, QChar('0')));
  205. }
  206. void GeneralNodeTitleGraphicsWidget::Activate()
  207. {
  208. AZ::EntityId entityId = GetEntityId();
  209. SceneMemberNotificationBus::Handler::BusConnect(entityId);
  210. NodeNotificationBus::Handler::BusConnect(entityId);
  211. RootGraphicsItemNotificationBus::Handler::BusConnect(entityId);
  212. AZ::EntityId scene;
  213. SceneMemberRequestBus::EventResult(scene, entityId, &SceneMemberRequests::GetScene);
  214. if (scene.IsValid())
  215. {
  216. SceneNotificationBus::Handler::BusConnect(scene);
  217. UpdateStyles();
  218. }
  219. }
  220. void GeneralNodeTitleGraphicsWidget::Deactivate()
  221. {
  222. SceneMemberNotificationBus::Handler::BusDisconnect();
  223. RootGraphicsItemNotificationBus::Handler::BusDisconnect();
  224. NodeNotificationBus::Handler::BusDisconnect();
  225. SceneNotificationBus::Handler::BusDisconnect();
  226. }
  227. void GeneralNodeTitleGraphicsWidget::SetDetails(const AZStd::string& title, const AZStd::string& subtitle)
  228. {
  229. bool updateLayout = false;
  230. if (m_titleWidget)
  231. {
  232. m_titleWidget->SetLabel(title);
  233. updateLayout = true;
  234. }
  235. if (m_subTitleWidget)
  236. {
  237. m_subTitleWidget->SetLabel(subtitle);
  238. updateLayout = true;
  239. }
  240. if (updateLayout)
  241. {
  242. UpdateLayout();
  243. }
  244. }
  245. void GeneralNodeTitleGraphicsWidget::SetTitle(const AZStd::string& title)
  246. {
  247. if (m_titleWidget)
  248. {
  249. m_titleWidget->SetLabel(title);
  250. UpdateLayout();
  251. }
  252. }
  253. void GeneralNodeTitleGraphicsWidget::SetSubTitle(const AZStd::string& subtitle)
  254. {
  255. if (m_subTitleWidget)
  256. {
  257. m_subTitleWidget->SetLabel(subtitle);
  258. UpdateLayout();
  259. }
  260. }
  261. void GeneralNodeTitleGraphicsWidget::SetPaletteOverride(AZStd::string_view paletteOverride)
  262. {
  263. AZ_Error("GraphCanvas", m_colorOverride == nullptr, "Unsupported use of Color and Palete Overrides");
  264. if (m_colorOverride)
  265. {
  266. delete m_colorOverride;
  267. m_colorOverride = nullptr;
  268. }
  269. AZ::EntityId sceneId;
  270. SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
  271. m_paletteOverride = nullptr;
  272. StyleManagerRequestBus::BroadcastResult(m_paletteOverride, &StyleManagerRequests::FindColorPalette, paletteOverride);
  273. update();
  274. }
  275. void GeneralNodeTitleGraphicsWidget::ConfigureIconConfiguration(PaletteIconConfiguration& paletteConfiguration)
  276. {
  277. bool isEnabled = false;
  278. RootGraphicsItemRequestBus::EventResult(isEnabled, GetEntityId(), &RootGraphicsItemRequests::IsEnabled);
  279. if (!isEnabled)
  280. {
  281. if (!m_disabledPalette)
  282. {
  283. StyleManagerRequestBus::BroadcastResult(m_disabledPalette, &StyleManagerRequests::FindColorPalette, "DisabledColorPalette");
  284. }
  285. if (m_disabledPalette)
  286. {
  287. m_disabledPalette->PopulatePaletteConfiguration(paletteConfiguration);
  288. }
  289. }
  290. else if (m_colorOverride)
  291. {
  292. m_colorOverride->PopulatePaletteConfiguration(paletteConfiguration);
  293. }
  294. else if (m_paletteOverride)
  295. {
  296. m_paletteOverride->PopulatePaletteConfiguration(paletteConfiguration);
  297. }
  298. else
  299. {
  300. m_styleHelper.PopulatePaletteConfiguration(paletteConfiguration);
  301. }
  302. }
  303. void GeneralNodeTitleGraphicsWidget::SetPaletteOverride(const AZ::Uuid& uuid)
  304. {
  305. AZ_Error("GraphCanvas", m_colorOverride == nullptr, "Unsupported use of Color and DataType Overrides");
  306. if (m_colorOverride)
  307. {
  308. delete m_colorOverride;
  309. m_colorOverride = nullptr;
  310. }
  311. AZ::EntityId sceneId;
  312. SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
  313. m_paletteOverride = nullptr;
  314. StyleManagerRequestBus::BroadcastResult(m_paletteOverride, &StyleManagerRequests::FindDataColorPalette, uuid);
  315. update();
  316. }
  317. void GeneralNodeTitleGraphicsWidget::SetPaletteOverride(const QColor& color)
  318. {
  319. if (m_colorOverride == nullptr)
  320. {
  321. if (m_paletteOverride != nullptr)
  322. {
  323. m_paletteOverride = nullptr;
  324. }
  325. AZ::EntityId sceneId;
  326. SceneMemberRequestBus::EventResult(sceneId, GetEntityId(), &SceneMemberRequests::GetScene);
  327. m_colorOverride = new Styling::StyleHelper();
  328. m_colorOverride->SetScene(sceneId);
  329. m_colorOverride->SetStyle("ColorOverrideNodeTitlePalette");
  330. }
  331. if (m_colorOverride)
  332. {
  333. m_colorOverride->AddAttributeOverride(Styling::Attribute::BackgroundColor, color);
  334. m_colorOverride->AddAttributeOverride(Styling::Attribute::LineColor, color);
  335. update();
  336. }
  337. }
  338. void GeneralNodeTitleGraphicsWidget::ClearPaletteOverride()
  339. {
  340. m_paletteOverride = nullptr;
  341. update();
  342. }
  343. void GeneralNodeTitleGraphicsWidget::UpdateLayout()
  344. {
  345. while (m_linearLayout->count() != 0)
  346. {
  347. m_linearLayout->removeAt(0);
  348. }
  349. if (!m_titleWidget->GetLabel().empty())
  350. {
  351. m_linearLayout->addItem(m_titleWidget);
  352. }
  353. if (!m_subTitleWidget->GetLabel().empty())
  354. {
  355. m_linearLayout->addItem(m_subTitleWidget);
  356. }
  357. RefreshDisplay();
  358. NodeTitleNotificationsBus::Event(GetEntityId(), &NodeTitleNotifications::OnTitleChanged);
  359. NodeUIRequestBus::Event(GetEntityId(), &NodeUIRequests::AdjustSize);
  360. }
  361. void GeneralNodeTitleGraphicsWidget::UpdateStyles()
  362. {
  363. m_styleHelper.SetStyle(GetEntityId(), Styling::Elements::Title);
  364. qreal spacing = m_styleHelper.GetAttribute(Styling::Attribute::Spacing, 0);
  365. qreal margin = m_styleHelper.GetAttribute(Styling::Attribute::Margin, 0);
  366. m_linearLayout->setSpacing(spacing);
  367. m_linearLayout->setContentsMargins(margin, margin, margin, margin);
  368. m_titleWidget->SetStyle(GetEntityId(), Styling::Elements::MainTitle);
  369. m_subTitleWidget->SetStyle(GetEntityId(), Styling::Elements::SubTitle);
  370. // Just clear our the disabled palette and we'll get it when we need it.
  371. m_disabledPalette = nullptr;
  372. }
  373. void GeneralNodeTitleGraphicsWidget::RefreshDisplay()
  374. {
  375. updateGeometry();
  376. update();
  377. }
  378. void GeneralNodeTitleGraphicsWidget::OnStylesChanged()
  379. {
  380. UpdateStyles();
  381. RefreshDisplay();
  382. }
  383. void GeneralNodeTitleGraphicsWidget::OnAddedToScene(const AZ::EntityId& scene)
  384. {
  385. SceneNotificationBus::Handler::BusConnect(scene);
  386. UpdateStyles();
  387. RefreshDisplay();
  388. }
  389. void GeneralNodeTitleGraphicsWidget::OnRemovedFromScene(const AZ::EntityId& /*scene*/)
  390. {
  391. SceneNotificationBus::Handler::BusDisconnect();
  392. }
  393. void GeneralNodeTitleGraphicsWidget::OnTooltipChanged(const AZStd::string& tooltip)
  394. {
  395. setToolTip(Tools::qStringFromUtf8(tooltip));
  396. }
  397. void GeneralNodeTitleGraphicsWidget::OnEnabledChanged(RootGraphicsItemEnabledState /*enabledState*/)
  398. {
  399. UpdateStyles();
  400. RefreshDisplay();
  401. }
  402. void GeneralNodeTitleGraphicsWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
  403. {
  404. GRAPH_CANVAS_DETAILED_PROFILE_FUNCTION();
  405. if (m_styleHelper.GetColor(Styling::Attribute::BackgroundColor) == Qt::transparent) // If the background color is set to transparent, we dont need to worry about any of this
  406. {
  407. return;
  408. }
  409. // Background
  410. QRectF bounds = boundingRect();
  411. qreal cornerRadius = 0.0;
  412. NodeUIRequestBus::EventResult(cornerRadius, GetEntityId(), &NodeUIRequests::GetCornerRadius);
  413. // Ensure the bounds are large enough to draw the full radius
  414. // Even in our smaller section
  415. if (bounds.height() < 2.0 * cornerRadius)
  416. {
  417. bounds.setHeight(2.0 * cornerRadius);
  418. }
  419. QPainterPath path;
  420. path.setFillRule(Qt::WindingFill);
  421. // -1.0 because the rounding is a little bit short(for some reason), so I subtract one and let it overshoot a smidge.
  422. path.addRoundedRect(bounds, cornerRadius - 1.0, cornerRadius - 1.0);
  423. // We only want corners on the top half. So we need to draw a rectangle over the bottom bits to square it out.
  424. QPointF bottomTopLeft(bounds.bottomLeft());
  425. bottomTopLeft.setY(bottomTopLeft.y() - cornerRadius - 1.0);
  426. path.addRect(QRectF(bottomTopLeft, bounds.bottomRight()));
  427. painter->save();
  428. painter->setClipPath(path);
  429. bool isEnabled = false;
  430. RootGraphicsItemRequestBus::EventResult(isEnabled, GetEntityId(), &RootGraphicsItemRequests::IsEnabled);
  431. if (!isEnabled)
  432. {
  433. if (!m_disabledPalette)
  434. {
  435. StyleManagerRequestBus::BroadcastResult(m_disabledPalette, &StyleManagerRequests::FindColorPalette, "DisabledColorPalette");
  436. }
  437. if (m_disabledPalette)
  438. {
  439. QtDrawingUtils::FillArea((*painter), path.boundingRect(), (*m_disabledPalette));
  440. }
  441. }
  442. else if (m_colorOverride)
  443. {
  444. QtDrawingUtils::FillArea((*painter), path.boundingRect(), (*m_colorOverride));
  445. }
  446. else if (m_paletteOverride)
  447. {
  448. QtDrawingUtils::FillArea((*painter), path.boundingRect(), (*m_paletteOverride));
  449. }
  450. else
  451. {
  452. QtDrawingUtils::FillArea((*painter), path.boundingRect(), m_styleHelper);
  453. }
  454. QLinearGradient gradient(bounds.bottomLeft(), bounds.topLeft());
  455. gradient.setColorAt(0, QColor(0, 0, 0, 102));
  456. gradient.setColorAt(1, QColor(0, 0, 0, 77));
  457. painter->fillPath(path, gradient);
  458. painter->restore();
  459. QGraphicsWidget::paint(painter, option, widget);
  460. }
  461. }