|
- /*
- ==============================================================================
-
- This file is part of the JUCE library.
- Copyright (c) 2013 - Raw Material Software Ltd.
-
- Permission is granted to use this software under the terms of either:
- a) the GPL v2 (or any later version)
- b) the Affero GPL v3
-
- Details of these licenses can be found at: www.gnu.org/licenses
-
- JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
- A PARTICULAR PURPOSE. See the GNU General Public License for more details.
-
- ------------------------------------------------------------------------------
-
- To release a closed-source product which uses JUCE, commercial licenses are
- available: visit www.juce.com for more information.
-
- ==============================================================================
- */
-
- #ifndef JUCE_RESIZABLEWINDOW_H_INCLUDED
- #define JUCE_RESIZABLEWINDOW_H_INCLUDED
-
-
- //==============================================================================
- /**
- A base class for top-level windows that can be dragged around and resized.
-
- To add content to the window, use its setContentOwned() or setContentNonOwned() methods
- to give it a component that will remain positioned inside it (leaving a gap around
- the edges for a border).
-
- It's not advisable to add child components directly to a ResizableWindow: put them
- inside your content component instead. And overriding methods like resized(), moved(), etc
- is also not recommended - instead override these methods for your content component.
- (If for some obscure reason you do need to override these methods, always remember to
- call the super-class's resized() method too, otherwise it'll fail to lay out the window
- decorations correctly).
-
- By default resizing isn't enabled - use the setResizable() method to enable it and
- to choose the style of resizing to use.
-
- @see TopLevelWindow
- */
- class JUCE_API ResizableWindow : public TopLevelWindow
- {
- public:
- //==============================================================================
- /** Creates a ResizableWindow.
-
- This constructor doesn't specify a background colour, so the LookAndFeel's default
- background colour will be used.
-
- @param name the name to give the component
- @param addToDesktop if true, the window will be automatically added to the
- desktop; if false, you can use it as a child component
- */
- ResizableWindow (const String& name,
- bool addToDesktop);
-
- /** Creates a ResizableWindow.
-
- @param name the name to give the component
- @param backgroundColour the colour to use for filling the window's background.
- @param addToDesktop if true, the window will be automatically added to the
- desktop; if false, you can use it as a child component
- */
- ResizableWindow (const String& name,
- Colour backgroundColour,
- bool addToDesktop);
-
- /** Destructor.
- If a content component has been set with setContentOwned(), it will be deleted.
- */
- ~ResizableWindow();
-
- //==============================================================================
- /** Returns the colour currently being used for the window's background.
-
- As a convenience the window will fill itself with this colour, but you
- can override the paint() method if you need more customised behaviour.
-
- This method is the same as retrieving the colour for ResizableWindow::backgroundColourId.
-
- @see setBackgroundColour
- */
- Colour getBackgroundColour() const noexcept;
-
- /** Changes the colour currently being used for the window's background.
-
- As a convenience the window will fill itself with this colour, but you
- can override the paint() method if you need more customised behaviour.
-
- Note that the opaque state of this window is altered by this call to reflect
- the opacity of the colour passed-in. On window systems which can't support
- semi-transparent windows this might cause problems, (though it's unlikely you'll
- be using this class as a base for a semi-transparent component anyway).
-
- You can also use the ResizableWindow::backgroundColourId colour id to set
- this colour.
-
- @see getBackgroundColour
- */
- void setBackgroundColour (Colour newColour);
-
- //==============================================================================
- /** Make the window resizable or fixed.
-
- @param shouldBeResizable whether it's resizable at all
- @param useBottomRightCornerResizer if true, it'll add a ResizableCornerComponent at the
- bottom-right; if false, it'll use a ResizableBorderComponent
- around the edge
- @see setResizeLimits, isResizable
- */
- void setResizable (bool shouldBeResizable,
- bool useBottomRightCornerResizer);
-
- /** Returns true if resizing is enabled.
- @see setResizable
- */
- bool isResizable() const noexcept;
-
- /** This sets the maximum and minimum sizes for the window.
-
- If the window's current size is outside these limits, it will be resized to
- make sure it's within them.
-
- A direct call to setBounds() will bypass any constraint checks, but when the
- window is dragged by the user or resized by other indirect means, the constrainer
- will limit the numbers involved.
-
- @see setResizable, setFixedAspectRatio
- */
- void setResizeLimits (int newMinimumWidth,
- int newMinimumHeight,
- int newMaximumWidth,
- int newMaximumHeight) noexcept;
-
- /** Returns the bounds constrainer object that this window is using.
- You can access this to change its properties.
- */
- ComponentBoundsConstrainer* getConstrainer() noexcept { return constrainer; }
-
- /** Sets the bounds-constrainer object to use for resizing and dragging this window.
-
- A pointer to the object you pass in will be kept, but it won't be deleted
- by this object, so it's the caller's responsiblity to manage it.
-
- If you pass a nullptr, then no contraints will be placed on the positioning of the window.
- */
- void setConstrainer (ComponentBoundsConstrainer* newConstrainer);
-
- /** Calls the window's setBounds method, after first checking these bounds
- with the current constrainer.
- @see setConstrainer
- */
- void setBoundsConstrained (const Rectangle<int>& bounds);
-
-
- //==============================================================================
- /** Returns true if the window is currently in full-screen mode.
- @see setFullScreen
- */
- bool isFullScreen() const;
-
- /** Puts the window into full-screen mode, or restores it to its normal size.
-
- If true, the window will become full-screen; if false, it will return to the
- last size it was before being made full-screen.
-
- @see isFullScreen
- */
- void setFullScreen (bool shouldBeFullScreen);
-
- /** Returns true if the window is currently minimised.
- @see setMinimised
- */
- bool isMinimised() const;
-
- /** Minimises the window, or restores it to its previous position and size.
-
- When being un-minimised, it'll return to the last position and size it
- was in before being minimised.
-
- @see isMinimised
- */
- void setMinimised (bool shouldMinimise);
-
- /** Returns true if the window has been placed in kiosk-mode.
- @see Desktop::setKioskComponent
- */
- bool isKioskMode() const;
-
- //==============================================================================
- /** Returns a string which encodes the window's current size and position.
-
- This string will encapsulate the window's size, position, and whether it's
- in full-screen mode. It's intended for letting your application save and
- restore a window's position.
-
- Use the restoreWindowStateFromString() to restore from a saved state.
-
- @see restoreWindowStateFromString
- */
- String getWindowStateAsString();
-
- /** Restores the window to a previously-saved size and position.
-
- This restores the window's size, positon and full-screen status from an
- string that was previously created with the getWindowStateAsString()
- method.
-
- @returns false if the string wasn't a valid window state
- @see getWindowStateAsString
- */
- bool restoreWindowStateFromString (const String& previousState);
-
-
- //==============================================================================
- /** Returns the current content component.
-
- This will be the component set by setContentOwned() or setContentNonOwned, or
- nullptr if none has yet been specified.
-
- @see setContentOwned, setContentNonOwned
- */
- Component* getContentComponent() const noexcept { return contentComponent; }
-
- /** Changes the current content component.
-
- This sets a component that will be placed in the centre of the ResizableWindow,
- (leaving a space around the edge for the border).
-
- You should never add components directly to a ResizableWindow (or any of its subclasses)
- with addChildComponent(). Instead, add them to the content component.
-
- @param newContentComponent the new component to use - this component will be deleted when it's
- no longer needed (i.e. when the window is deleted or a new content
- component is set for it). To set a component that this window will not
- delete, call setContentNonOwned() instead.
- @param resizeToFitWhenContentChangesSize if true, then the ResizableWindow will maintain its size
- such that it always fits around the size of the content component. If false,
- the new content will be resized to fit the current space available.
- */
- void setContentOwned (Component* newContentComponent,
- bool resizeToFitWhenContentChangesSize);
-
- /** Changes the current content component.
-
- This sets a component that will be placed in the centre of the ResizableWindow,
- (leaving a space around the edge for the border).
-
- You should never add components directly to a ResizableWindow (or any of its subclasses)
- with addChildComponent(). Instead, add them to the content component.
-
- @param newContentComponent the new component to use - this component will NOT be deleted by this
- component, so it's the caller's responsibility to manage its lifetime (it's
- ok to delete it while this window is still using it). To set a content
- component that the window will delete, call setContentOwned() instead.
- @param resizeToFitWhenContentChangesSize if true, then the ResizableWindow will maintain its size
- such that it always fits around the size of the content component. If false,
- the new content will be resized to fit the current space available.
- */
- void setContentNonOwned (Component* newContentComponent,
- bool resizeToFitWhenContentChangesSize);
-
- /** Removes the current content component.
- If the previous content component was added with setContentOwned(), it will also be deleted. If
- it was added with setContentNonOwned(), it will simply be removed from this component.
- */
- void clearContentComponent();
-
- /** Changes the window so that the content component ends up with the specified size.
-
- This is basically a setSize call on the window, but which adds on the borders,
- so you can specify the content component's target size.
- */
- void setContentComponentSize (int width, int height);
-
- /** Returns the width of the frame to use around the window.
- @see getContentComponentBorder
- */
- virtual BorderSize<int> getBorderThickness();
-
- /** Returns the insets to use when positioning the content component.
- @see getBorderThickness
- */
- virtual BorderSize<int> getContentComponentBorder();
-
- //==============================================================================
- /** A set of colour IDs to use to change the colour of various aspects of the window.
-
- These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
- methods.
-
- @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
- */
- enum ColourIds
- {
- backgroundColourId = 0x1005700, /**< A colour to use to fill the window's background. */
- };
-
- //==============================================================================
- // Deprecated: use setContentOwned() and setContentNonOwned() instead.
- JUCE_DEPRECATED (void setContentComponent (Component* newContentComponent,
- bool deleteOldOne = true,
- bool resizeToFit = false));
- using TopLevelWindow::addToDesktop;
-
- //==============================================================================
- /** This abstract base class is implemented by LookAndFeel classes to provide
- window drawing functionality.
- */
- struct JUCE_API LookAndFeelMethods
- {
- virtual ~LookAndFeelMethods() {}
-
- //==============================================================================
- virtual void drawCornerResizer (Graphics&, int w, int h, bool isMouseOver, bool isMouseDragging) = 0;
- virtual void drawResizableFrame (Graphics&, int w, int h, const BorderSize<int>&) = 0;
-
- virtual void fillResizableWindowBackground (Graphics&, int w, int h, const BorderSize<int>&, ResizableWindow&) = 0;
- virtual void drawResizableWindowBorder (Graphics&, int w, int h, const BorderSize<int>& border, ResizableWindow&) = 0;
- };
-
- protected:
- /** @internal */
- void paint (Graphics&) override;
- /** (if overriding this, make sure you call ResizableWindow::moved() in your subclass) */
- void moved() override;
- /** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */
- void resized() override;
- /** @internal */
- void mouseDown (const MouseEvent&) override;
- /** @internal */
- void mouseDrag (const MouseEvent&) override;
- /** @internal */
- void lookAndFeelChanged() override;
- /** @internal */
- void childBoundsChanged (Component*) override;
- /** @internal */
- void parentSizeChanged() override;
- /** @internal */
- void visibilityChanged() override;
- /** @internal */
- void activeWindowStatusChanged() override;
- /** @internal */
- int getDesktopWindowStyleFlags() const override;
-
- #if JUCE_DEBUG
- /** Overridden to warn people about adding components directly to this component
- instead of using setContentOwned().
-
- If you know what you're doing and are sure you really want to add a component, specify
- a base-class method call to Component::addAndMakeVisible(), to side-step this warning.
- */
- void addChildComponent (Component*, int zOrder = -1);
- /** Overridden to warn people about adding components directly to this component
- instead of using setContentOwned().
-
- If you know what you're doing and are sure you really want to add a component, specify
- a base-class method call to Component::addAndMakeVisible(), to side-step this warning.
- */
- void addAndMakeVisible (Component*, int zOrder = -1);
- #endif
-
- ScopedPointer <ResizableCornerComponent> resizableCorner;
- ScopedPointer <ResizableBorderComponent> resizableBorder;
-
- private:
- //==============================================================================
- Component::SafePointer<Component> contentComponent;
- bool ownsContentComponent, resizeToFitContent, fullscreen;
- ComponentDragger dragger;
- Rectangle<int> lastNonFullScreenPos;
- ComponentBoundsConstrainer defaultConstrainer;
- ComponentBoundsConstrainer* constrainer;
- #if JUCE_DEBUG
- bool hasBeenResized;
- #endif
-
- void initialise (bool addToDesktop);
- void updateLastPosIfNotFullScreen();
- void updateLastPosIfShowing();
- void setContent (Component*, bool takeOwnership, bool resizeToFit);
-
- #if JUCE_CATCH_DEPRECATED_CODE_MISUSE
- // The parameters for these methods have changed - please update your code!
- JUCE_DEPRECATED (void getBorderThickness (int& left, int& top, int& right, int& bottom));
- JUCE_DEPRECATED (void getContentComponentBorder (int& left, int& top, int& right, int& bottom));
- #endif
-
- JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ResizableWindow)
- };
-
-
- #endif // JUCE_RESIZABLEWINDOW_H_INCLUDED
|