The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.6KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. #pragma once
  19. #include "../../Application/jucer_Application.h"
  20. //==============================================================================
  21. class UserAvatarComponent final : public Component,
  22. public SettableTooltipClient,
  23. public ChangeBroadcaster,
  24. private LicenseController::LicenseStateListener
  25. {
  26. public:
  27. UserAvatarComponent (bool isInteractive)
  28. : interactive (isInteractive)
  29. {
  30. ProjucerApplication::getApp().getLicenseController().addListener (this);
  31. lookAndFeelChanged();
  32. }
  33. ~UserAvatarComponent() override
  34. {
  35. ProjucerApplication::getApp().getLicenseController().removeListener (this);
  36. }
  37. void paint (Graphics& g) override
  38. {
  39. auto bounds = getLocalBounds();
  40. if (! isGPL)
  41. {
  42. bounds = bounds.removeFromRight (bounds.getHeight());
  43. Path ellipse;
  44. ellipse.addEllipse (bounds.toFloat());
  45. g.reduceClipRegion (ellipse);
  46. }
  47. g.drawImage (currentAvatar, bounds.toFloat(), RectanglePlacement::fillDestination);
  48. }
  49. void mouseUp (const MouseEvent&) override
  50. {
  51. triggerClick();
  52. }
  53. void triggerClick()
  54. {
  55. if (interactive)
  56. {
  57. PopupMenu menu;
  58. menu.addCommandItem (ProjucerApplication::getApp().commandManager.get(), CommandIDs::loginLogout);
  59. menu.showMenuAsync (PopupMenu::Options().withTargetComponent (this));
  60. }
  61. }
  62. bool isDisplaingGPLLogo() const noexcept { return isGPL; }
  63. std::unique_ptr<AccessibilityHandler> createAccessibilityHandler() override
  64. {
  65. return interactive ? std::make_unique<AccessibilityHandler> (*this,
  66. AccessibilityRole::button,
  67. AccessibilityActions().addAction (AccessibilityActionType::press,
  68. [this] { triggerClick(); }))
  69. : nullptr;
  70. }
  71. private:
  72. //==============================================================================
  73. static Image createGPLAvatarImage()
  74. {
  75. if (auto logo = Drawable::createFromImageData (BinaryData::gpl_logo_svg, BinaryData::gpl_logo_svgSize))
  76. {
  77. auto bounds = logo->getDrawableBounds();
  78. Image image (Image::ARGB, roundToInt (bounds.getWidth()), roundToInt (bounds.getHeight()), true);
  79. Graphics g (image);
  80. logo->draw (g, 1.0f);
  81. return image;
  82. }
  83. jassertfalse;
  84. return {};
  85. }
  86. Image createStandardAvatarImage()
  87. {
  88. Image image (Image::ARGB, 250, 250, true);
  89. Graphics g (image);
  90. g.setColour (findColour (defaultButtonBackgroundColourId));
  91. g.fillAll();
  92. g.setColour (findColour (defaultIconColourId));
  93. auto path = getIcons().user;
  94. g.fillPath (path, RectanglePlacement (RectanglePlacement::centred)
  95. .getTransformToFit (path.getBounds(), image.getBounds().reduced (image.getHeight() / 5).toFloat()));
  96. return image;
  97. }
  98. //==============================================================================
  99. void licenseStateChanged() override
  100. {
  101. auto state = ProjucerApplication::getApp().getLicenseController().getCurrentState();
  102. isGPL = ProjucerApplication::getApp().getLicenseController().getCurrentState().isGPL();
  103. if (interactive)
  104. {
  105. auto formattedUserString = [state]() -> String
  106. {
  107. if (state.isSignedIn())
  108. return (state.isGPL() ? "" : (state.username + " - ")) + state.getLicenseTypeString();
  109. return "Not logged in";
  110. }();
  111. setTooltip (formattedUserString);
  112. }
  113. currentAvatar = isGPL ? gplAvatarImage
  114. : state.isSignedIn() ? standardAvatarImage : signedOutAvatarImage;
  115. repaint();
  116. sendChangeMessage();
  117. }
  118. void lookAndFeelChanged() override
  119. {
  120. standardAvatarImage = createStandardAvatarImage();
  121. signedOutAvatarImage = createStandardAvatarImage();
  122. if (interactive)
  123. signedOutAvatarImage.multiplyAllAlphas (0.4f);
  124. licenseStateChanged();
  125. repaint();
  126. }
  127. //==============================================================================
  128. Image standardAvatarImage, signedOutAvatarImage, gplAvatarImage { createGPLAvatarImage() }, currentAvatar;
  129. bool isGPL = false, interactive = false;
  130. };