Audio plugin host https://kx.studio/carla
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.

juce_DocumentWindow.h 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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. namespace juce
  19. {
  20. //==============================================================================
  21. /**
  22. A resizable window with a title bar and maximise, minimise and close buttons.
  23. This subclass of ResizableWindow creates a fairly standard type of window with
  24. a title bar and various buttons. The name of the component is shown in the
  25. title bar, and an icon can optionally be specified with setIcon().
  26. All the methods available to a ResizableWindow are also available to this,
  27. so it can easily be made resizable, minimised, maximised, etc.
  28. It's not advisable to add child components directly to a DocumentWindow: put them
  29. inside your content component instead. And overriding methods like resized(), moved(), etc
  30. is also not recommended - instead override these methods for your content component.
  31. (If for some obscure reason you do need to override these methods, always remember to
  32. call the super-class's resized() method too, otherwise it'll fail to lay out the window
  33. decorations correctly).
  34. You can also automatically add a menu bar to the window, using the setMenuBar()
  35. method.
  36. @see ResizableWindow, DialogWindow
  37. @tags{GUI}
  38. */
  39. class JUCE_API DocumentWindow : public ResizableWindow
  40. {
  41. public:
  42. //==============================================================================
  43. /** The set of available button-types that can be put on the title bar.
  44. @see setTitleBarButtonsRequired
  45. */
  46. enum TitleBarButtons
  47. {
  48. minimiseButton = 1,
  49. maximiseButton = 2,
  50. closeButton = 4,
  51. /** A combination of all the buttons above. */
  52. allButtons = 7
  53. };
  54. //==============================================================================
  55. /** Creates a DocumentWindow.
  56. @param name the name to give the component - this is also
  57. the title shown at the top of the window. To change
  58. this later, use setName()
  59. @param backgroundColour the colour to use for filling the window's background.
  60. @param requiredButtons specifies which of the buttons (close, minimise, maximise)
  61. should be shown on the title bar. This value is a bitwise
  62. combination of values from the TitleBarButtons enum. Note
  63. that it can be "allButtons" to get them all. You
  64. can change this later with the setTitleBarButtonsRequired()
  65. method, which can also specify where they are positioned.
  66. The behaviour of native titlebars on macOS is slightly different:
  67. the maximiseButton flag controls whether or not the window can enter
  68. native fullscreen mode, and the zoom button can be disabled by
  69. making the window non-resizable.
  70. @param addToDesktop if true, the window will be automatically added to the
  71. desktop; if false, you can use it as a child component
  72. @see TitleBarButtons
  73. */
  74. DocumentWindow (const String& name,
  75. Colour backgroundColour,
  76. int requiredButtons,
  77. bool addToDesktop = true);
  78. /** Destructor.
  79. If a content component has been set with setContentOwned(), it will be deleted.
  80. */
  81. ~DocumentWindow() override;
  82. //==============================================================================
  83. /** Changes the component's name.
  84. (This is overridden from Component::setName() to cause a repaint, as
  85. the name is what gets drawn across the window's title bar).
  86. */
  87. void setName (const String& newName) override;
  88. /** Sets an icon to show in the title bar, next to the title.
  89. A copy is made internally of the image, so the caller can delete the
  90. image after calling this. If an empty Image is passed-in, any existing icon
  91. will be removed.
  92. */
  93. void setIcon (const Image& imageToUse);
  94. /** Changes the height of the title-bar. */
  95. void setTitleBarHeight (int newHeight);
  96. /** Returns the current title bar height. */
  97. int getTitleBarHeight() const;
  98. /** Changes the set of title-bar buttons being shown.
  99. @param requiredButtons specifies which of the buttons (close, minimise, maximise)
  100. should be shown on the title bar. This value is a bitwise
  101. combination of values from the TitleBarButtons enum. Note
  102. that it can be "allButtons" to get them all.
  103. The behaviour of native titlebars on macOS is slightly different:
  104. the maximiseButton flag controls whether or not the window can enter
  105. native fullscreen mode, and the zoom button can be disabled by
  106. making the window non-resizable.
  107. @param positionTitleBarButtonsOnLeft if true, the buttons should go at the
  108. left side of the bar; if false, they'll be placed at the right
  109. */
  110. void setTitleBarButtonsRequired (int requiredButtons,
  111. bool positionTitleBarButtonsOnLeft);
  112. /** Sets whether the title should be centred within the window.
  113. If true, the title text is shown in the middle of the title-bar; if false,
  114. it'll be shown at the left of the bar.
  115. */
  116. void setTitleBarTextCentred (bool textShouldBeCentred);
  117. //==============================================================================
  118. /** Creates a menu inside this window.
  119. @param menuBarModel this specifies a MenuBarModel that should be used to
  120. generate the contents of a menu bar that will be placed
  121. just below the title bar, and just above any content
  122. component. If this value is a nullptr, any existing menu bar
  123. will be removed from the component; if it is not a nullptr,
  124. one will be added if it's required.
  125. @param menuBarHeight the height of the menu bar component, if one is needed. Pass a value of zero
  126. or less to use the look-and-feel's default size.
  127. */
  128. void setMenuBar (MenuBarModel* menuBarModel,
  129. int menuBarHeight = 0);
  130. /** Returns the current menu bar component, or null if there isn't one.
  131. This is probably a MenuBarComponent, unless a custom one has been set using
  132. setMenuBarComponent().
  133. */
  134. Component* getMenuBarComponent() const noexcept;
  135. /** Replaces the current menu bar with a custom component.
  136. The component will be owned and deleted by the document window.
  137. */
  138. void setMenuBarComponent (Component* newMenuBarComponent);
  139. //==============================================================================
  140. /** This method is called when the user tries to close the window.
  141. This is triggered by the user clicking the close button, or using some other
  142. OS-specific key shortcut or OS menu for getting rid of a window.
  143. If the window is just a pop-up, you should override this closeButtonPressed()
  144. method and make it delete the window in whatever way is appropriate for your
  145. app. E.g. you might just want to call "delete this".
  146. If your app is centred around this window such that the whole app should quit when
  147. the window is closed, then you will probably want to use this method as an opportunity
  148. to call JUCEApplicationBase::quit(), and leave the window to be deleted later by your
  149. JUCEApplicationBase::shutdown() method. (Doing it this way means that your window will
  150. still get cleaned-up if the app is quit by some other means (e.g. a cmd-Q on the mac
  151. or closing it via the taskbar icon on Windows).
  152. (Note that the DocumentWindow class overrides Component::userTriedToCloseWindow() and
  153. redirects it to call this method, so any methods of closing the window that are
  154. caught by userTriedToCloseWindow() will also end up here).
  155. */
  156. virtual void closeButtonPressed();
  157. /** Callback that is triggered when the minimise button is pressed.
  158. This function is only called when using a non-native titlebar.
  159. The default implementation of this calls ResizableWindow::setMinimised(), but
  160. you can override it to do more customised behaviour.
  161. */
  162. virtual void minimiseButtonPressed();
  163. /** Callback that is triggered when the maximise button is pressed, or when the
  164. title-bar is double-clicked.
  165. This function is only called when using a non-native titlebar.
  166. The default implementation of this calls ResizableWindow::setFullScreen(), but
  167. you can override it to do more customised behaviour.
  168. */
  169. virtual void maximiseButtonPressed();
  170. //==============================================================================
  171. /** Returns the close button, (or nullptr if there isn't one). */
  172. Button* getCloseButton() const noexcept;
  173. /** Returns the minimise button, (or nullptr if there isn't one). */
  174. Button* getMinimiseButton() const noexcept;
  175. /** Returns the maximise button, (or nullptr if there isn't one). */
  176. Button* getMaximiseButton() const noexcept;
  177. //==============================================================================
  178. /** A set of colour IDs to use to change the colour of various aspects of the window.
  179. These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
  180. methods.
  181. @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
  182. */
  183. enum ColourIds
  184. {
  185. textColourId = 0x1005701, /**< The colour to draw any text with. It's up to the look
  186. and feel class how this is used. */
  187. };
  188. //==============================================================================
  189. /** This abstract base class is implemented by LookAndFeel classes to provide
  190. window drawing functionality.
  191. */
  192. struct JUCE_API LookAndFeelMethods
  193. {
  194. virtual ~LookAndFeelMethods() = default;
  195. virtual void drawDocumentWindowTitleBar (DocumentWindow&,
  196. Graphics&, int w, int h,
  197. int titleSpaceX, int titleSpaceW,
  198. const Image* icon,
  199. bool drawTitleTextOnLeft) = 0;
  200. virtual Button* createDocumentWindowButton (int buttonType) = 0;
  201. virtual void positionDocumentWindowButtons (DocumentWindow&,
  202. int titleBarX, int titleBarY, int titleBarW, int titleBarH,
  203. Button* minimiseButton,
  204. Button* maximiseButton,
  205. Button* closeButton,
  206. bool positionTitleBarButtonsOnLeft) = 0;
  207. };
  208. //==============================================================================
  209. #ifndef DOXYGEN
  210. /** @internal */
  211. void paint (Graphics&) override;
  212. /** @internal */
  213. void resized() override;
  214. /** @internal */
  215. void lookAndFeelChanged() override;
  216. /** @internal */
  217. BorderSize<int> getBorderThickness() override;
  218. /** @internal */
  219. BorderSize<int> getContentComponentBorder() override;
  220. /** @internal */
  221. void mouseDoubleClick (const MouseEvent&) override;
  222. /** @internal */
  223. void userTriedToCloseWindow() override;
  224. /** @internal */
  225. void activeWindowStatusChanged() override;
  226. /** @internal */
  227. int getDesktopWindowStyleFlags() const override;
  228. /** @internal */
  229. void parentHierarchyChanged() override;
  230. /** @internal */
  231. Rectangle<int> getTitleBarArea();
  232. #endif
  233. private:
  234. //==============================================================================
  235. int titleBarHeight = 26, menuBarHeight = 24, requiredButtons;
  236. bool positionTitleBarButtonsOnLeft, drawTitleTextCentred = true;
  237. std::unique_ptr<Button> titleBarButtons [3];
  238. Image titleBarIcon;
  239. std::unique_ptr<Component> menuBar;
  240. MenuBarModel* menuBarModel = nullptr;
  241. class ButtonListenerProxy;
  242. std::unique_ptr<ButtonListenerProxy> buttonListener;
  243. void repaintTitleBar();
  244. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DocumentWindow)
  245. };
  246. } // namespace juce