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