2 ==============================================================================
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
7 JUCE is an open source library subject to commercial or open-source
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
23 ==============================================================================
29 //==============================================================================
31 A resizable window with a title bar and maximise, minimise and close buttons.
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().
37 All the methods available to a ResizableWindow are also available to this,
38 so it can easily be made resizable, minimised, maximised, etc.
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).
47 You can also automatically add a menu bar to the window, using the setMenuBar()
50 @see ResizableWindow, DialogWindow
54 class JUCE_API DocumentWindow
: public ResizableWindow
57 //==============================================================================
58 /** The set of available button-types that can be put on the title bar.
60 @see setTitleBarButtonsRequired
68 /** A combination of all the buttons above. */
72 //==============================================================================
73 /** Creates a DocumentWindow.
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 The behaviour of native titlebars on macOS is slightly different:
86 the maximiseButton flag controls whether or not the window can enter
87 native fullscreen mode, and the zoom button can be disabled by
88 making the window non-resizable.
89 @param addToDesktop if true, the window will be automatically added to the
90 desktop; if false, you can use it as a child component
93 DocumentWindow (const String
& name
,
94 Colour backgroundColour
,
96 bool addToDesktop
= true);
99 If a content component has been set with setContentOwned(), it will be deleted.
101 ~DocumentWindow() override
;
103 //==============================================================================
104 /** Changes the component's name.
106 (This is overridden from Component::setName() to cause a repaint, as
107 the name is what gets drawn across the window's title bar).
109 void setName (const String
& newName
) override
;
111 /** Sets an icon to show in the title bar, next to the title.
113 A copy is made internally of the image, so the caller can delete the
114 image after calling this. If an empty Image is passed-in, any existing icon
117 void setIcon (const Image
& imageToUse
);
119 /** Changes the height of the title-bar. */
120 void setTitleBarHeight (int newHeight
);
122 /** Returns the current title bar height. */
123 int getTitleBarHeight() const;
125 /** Changes the set of title-bar buttons being shown.
127 @param requiredButtons specifies which of the buttons (close, minimise, maximise)
128 should be shown on the title bar. This value is a bitwise
129 combination of values from the TitleBarButtons enum. Note
130 that it can be "allButtons" to get them all.
131 The behaviour of native titlebars on macOS is slightly different:
132 the maximiseButton flag controls whether or not the window can enter
133 native fullscreen mode, and the zoom button can be disabled by
134 making the window non-resizable.
135 @param positionTitleBarButtonsOnLeft if true, the buttons should go at the
136 left side of the bar; if false, they'll be placed at the right
138 void setTitleBarButtonsRequired (int requiredButtons
,
139 bool positionTitleBarButtonsOnLeft
);
141 /** Sets whether the title should be centred within the window.
143 If true, the title text is shown in the middle of the title-bar; if false,
144 it'll be shown at the left of the bar.
146 void setTitleBarTextCentred (bool textShouldBeCentred
);
148 //==============================================================================
149 /** Creates a menu inside this window.
151 @param menuBarModel this specifies a MenuBarModel that should be used to
152 generate the contents of a menu bar that will be placed
153 just below the title bar, and just above any content
154 component. If this value is a nullptr, any existing menu bar
155 will be removed from the component; if it is not a nullptr,
156 one will be added if it's required.
157 @param menuBarHeight the height of the menu bar component, if one is needed. Pass a value of zero
158 or less to use the look-and-feel's default size.
160 void setMenuBar (MenuBarModel
* menuBarModel
,
161 int menuBarHeight
= 0);
163 /** Returns the current menu bar component, or null if there isn't one.
164 This is probably a MenuBarComponent, unless a custom one has been set using
165 setMenuBarComponent().
167 Component
* getMenuBarComponent() const noexcept
;
169 /** Replaces the current menu bar with a custom component.
170 The component will be owned and deleted by the document window.
172 void setMenuBarComponent (Component
* newMenuBarComponent
);
174 //==============================================================================
175 /** This method is called when the user tries to close the window.
177 This is triggered by the user clicking the close button, or using some other
178 OS-specific key shortcut or OS menu for getting rid of a window.
180 If the window is just a pop-up, you should override this closeButtonPressed()
181 method and make it delete the window in whatever way is appropriate for your
182 app. E.g. you might just want to call "delete this".
184 If your app is centred around this window such that the whole app should quit when
185 the window is closed, then you will probably want to use this method as an opportunity
186 to call JUCEApplicationBase::quit(), and leave the window to be deleted later by your
187 JUCEApplicationBase::shutdown() method. (Doing it this way means that your window will
188 still get cleaned-up if the app is quit by some other means (e.g. a cmd-Q on the mac
189 or closing it via the taskbar icon on Windows).
191 (Note that the DocumentWindow class overrides Component::userTriedToCloseWindow() and
192 redirects it to call this method, so any methods of closing the window that are
193 caught by userTriedToCloseWindow() will also end up here).
195 virtual void closeButtonPressed();
197 /** Callback that is triggered when the minimise button is pressed.
199 This function is only called when using a non-native titlebar.
201 The default implementation of this calls ResizableWindow::setMinimised(), but
202 you can override it to do more customised behaviour.
204 virtual void minimiseButtonPressed();
206 /** Callback that is triggered when the maximise button is pressed, or when the
207 title-bar is double-clicked.
209 This function is only called when using a non-native titlebar.
211 The default implementation of this calls ResizableWindow::setFullScreen(), but
212 you can override it to do more customised behaviour.
214 virtual void maximiseButtonPressed();
216 //==============================================================================
217 /** Returns the close button, (or nullptr if there isn't one). */
218 Button
* getCloseButton() const noexcept
;
220 /** Returns the minimise button, (or nullptr if there isn't one). */
221 Button
* getMinimiseButton() const noexcept
;
223 /** Returns the maximise button, (or nullptr if there isn't one). */
224 Button
* getMaximiseButton() const noexcept
;
226 //==============================================================================
227 /** A set of colour IDs to use to change the colour of various aspects of the window.
229 These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
232 @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
236 textColourId
= 0x1005701, /**< The colour to draw any text with. It's up to the look
237 and feel class how this is used. */
240 //==============================================================================
241 /** This abstract base class is implemented by LookAndFeel classes to provide
242 window drawing functionality.
244 struct JUCE_API LookAndFeelMethods
246 virtual ~LookAndFeelMethods() = default;
248 virtual void drawDocumentWindowTitleBar (DocumentWindow
&,
249 Graphics
&, int w
, int h
,
250 int titleSpaceX
, int titleSpaceW
,
252 bool drawTitleTextOnLeft
) = 0;
254 virtual Button
* createDocumentWindowButton (int buttonType
) = 0;
256 virtual void positionDocumentWindowButtons (DocumentWindow
&,
257 int titleBarX
, int titleBarY
, int titleBarW
, int titleBarH
,
258 Button
* minimiseButton
,
259 Button
* maximiseButton
,
261 bool positionTitleBarButtonsOnLeft
) = 0;
264 //==============================================================================
267 void paint (Graphics
&) override
;
269 void resized() override
;
271 void lookAndFeelChanged() override
;
273 BorderSize
<int> getBorderThickness() override
;
275 BorderSize
<int> getContentComponentBorder() override
;
277 void mouseDoubleClick (const MouseEvent
&) override
;
279 void userTriedToCloseWindow() override
;
281 void activeWindowStatusChanged() override
;
283 int getDesktopWindowStyleFlags() const override
;
285 void parentHierarchyChanged() override
;
287 Rectangle
<int> getTitleBarArea();
291 //==============================================================================
292 int titleBarHeight
= 26, menuBarHeight
= 24, requiredButtons
;
293 bool positionTitleBarButtonsOnLeft
, drawTitleTextCentred
= true;
294 std::unique_ptr
<Button
> titleBarButtons
[3];
296 std::unique_ptr
<Component
> menuBar
;
297 MenuBarModel
* menuBarModel
= nullptr;
299 class ButtonListenerProxy
;
300 std::unique_ptr
<ButtonListenerProxy
> buttonListener
;
302 void repaintTitleBar();
304 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DocumentWindow
)