GeneralNodeTitleComponent.cpp 17 KB

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