mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
331 lines
11 KiB
C++
331 lines
11 KiB
C++
/*
|
|
==============================================================================
|
|
|
|
This file is part of the JUCE library - "Jules' Utility Class Extensions"
|
|
Copyright 2004-12 by Raw Material Software Ltd.
|
|
|
|
------------------------------------------------------------------------------
|
|
|
|
JUCE can be redistributed and/or modified under the terms of the GNU General
|
|
Public License (Version 2), as published by the Free Software Foundation.
|
|
A copy of the license is included in the JUCE distribution, or can be found
|
|
online 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.rawmaterialsoftware.com/juce for more information.
|
|
|
|
==============================================================================
|
|
*/
|
|
|
|
#include "../JuceDemoHeader.h"
|
|
|
|
//==============================================================================
|
|
/** Just a simple window that deletes itself when closed. */
|
|
class BasicWindow : public DocumentWindow
|
|
{
|
|
public:
|
|
BasicWindow (const String& name, Colour backgroundColour, int buttonsNeeded)
|
|
: DocumentWindow (name, backgroundColour, buttonsNeeded)
|
|
{
|
|
}
|
|
|
|
void closeButtonPressed()
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
private:
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BasicWindow)
|
|
};
|
|
|
|
//==============================================================================
|
|
/** This window contains a ColourSelector which can be used to change the window's colour. */
|
|
class ColourSelectorWindow : public DocumentWindow,
|
|
private ChangeListener
|
|
{
|
|
public:
|
|
ColourSelectorWindow (const String& name, Colour backgroundColour, int buttonsNeeded)
|
|
: DocumentWindow (name, backgroundColour, buttonsNeeded),
|
|
selector (ColourSelector::showColourAtTop | ColourSelector::showSliders | ColourSelector::showColourspace)
|
|
{
|
|
selector.setCurrentColour (backgroundColour);
|
|
selector.setColour (ColourSelector::backgroundColourId, Colours::transparentWhite);
|
|
selector.addChangeListener (this);
|
|
setContentOwned (&selector, false);
|
|
}
|
|
|
|
~ColourSelectorWindow()
|
|
{
|
|
selector.removeChangeListener (this);
|
|
}
|
|
|
|
void closeButtonPressed()
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
private:
|
|
ColourSelector selector;
|
|
|
|
void changeListenerCallback (ChangeBroadcaster* source)
|
|
{
|
|
if (source == &selector)
|
|
setBackgroundColour (selector.getCurrentColour());
|
|
}
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ColourSelectorWindow)
|
|
};
|
|
|
|
//==============================================================================
|
|
class BouncingBallComponent : public Component,
|
|
public Timer
|
|
{
|
|
public:
|
|
BouncingBallComponent()
|
|
{
|
|
setInterceptsMouseClicks (false, false);
|
|
|
|
Random random;
|
|
|
|
const float size = 10.0f + random.nextInt (30);
|
|
|
|
ballBounds.setBounds (random.nextFloat() * 100.0f,
|
|
random.nextFloat() * 100.0f,
|
|
size, size);
|
|
|
|
direction.x = random.nextFloat() * 8.0f - 4.0f;
|
|
direction.y = random.nextFloat() * 8.0f - 4.0f;
|
|
|
|
colour = Colour ((juce::uint32) random.nextInt())
|
|
.withAlpha (0.5f)
|
|
.withBrightness (0.7f);
|
|
|
|
startTimer (60);
|
|
}
|
|
|
|
void paint (Graphics& g)
|
|
{
|
|
g.setColour (colour);
|
|
g.fillEllipse (ballBounds - getPosition().toFloat());
|
|
}
|
|
|
|
void timerCallback()
|
|
{
|
|
ballBounds += direction;
|
|
|
|
if (ballBounds.getX() < 0) direction.x = std::abs (direction.x);
|
|
if (ballBounds.getY() < 0) direction.y = std::abs (direction.y);
|
|
if (ballBounds.getRight() > getParentWidth()) direction.x = -std::abs (direction.x);
|
|
if (ballBounds.getBottom() > getParentHeight()) direction.y = -std::abs (direction.y);
|
|
|
|
setBounds (ballBounds.getSmallestIntegerContainer());
|
|
}
|
|
|
|
private:
|
|
Colour colour;
|
|
Rectangle<float> ballBounds;
|
|
Point<float> direction;
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BouncingBallComponent)
|
|
};
|
|
|
|
//==============================================================================
|
|
class BouncingBallsContainer : public Component
|
|
{
|
|
public:
|
|
BouncingBallsContainer (int numBalls)
|
|
{
|
|
for (int i = 0; i < numBalls; ++i)
|
|
{
|
|
BouncingBallComponent* newBall = new BouncingBallComponent();
|
|
balls.add (newBall);
|
|
addAndMakeVisible (newBall);
|
|
}
|
|
}
|
|
|
|
void mouseDown (const MouseEvent& e)
|
|
{
|
|
dragger.startDraggingComponent (this, e);
|
|
}
|
|
|
|
void mouseDrag (const MouseEvent& e)
|
|
{
|
|
// as there's no titlebar we have to manage the dragging ourselves
|
|
dragger.dragComponent (this, e, 0);
|
|
}
|
|
|
|
void paint (Graphics& g)
|
|
{
|
|
if (isOpaque())
|
|
g.fillAll (Colours::white);
|
|
else
|
|
g.fillAll (Colours::blue.withAlpha (0.2f));
|
|
|
|
g.setFont (16.0f);
|
|
g.setColour (Colours::black);
|
|
g.drawFittedText ("This window has no titlebar and a transparent background.",
|
|
getLocalBounds().reduced (8, 0),
|
|
Justification::centred, 5);
|
|
|
|
g.drawRect (getLocalBounds());
|
|
}
|
|
|
|
private:
|
|
ComponentDragger dragger;
|
|
OwnedArray<BouncingBallComponent> balls;
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (BouncingBallsContainer)
|
|
};
|
|
|
|
//==============================================================================
|
|
class WindowsDemo : public Component,
|
|
private Button::Listener
|
|
{
|
|
public:
|
|
enum Windows
|
|
{
|
|
dialog,
|
|
document,
|
|
alert,
|
|
numWindows
|
|
};
|
|
|
|
WindowsDemo()
|
|
{
|
|
setOpaque (true);
|
|
|
|
showWindowsButton.setButtonText ("Show Windows");
|
|
addAndMakeVisible (&showWindowsButton);
|
|
showWindowsButton.addListener (this);
|
|
|
|
closeWindowsButton.setButtonText ("Close Windows");
|
|
addAndMakeVisible (&closeWindowsButton);
|
|
closeWindowsButton.addListener (this);
|
|
}
|
|
|
|
~WindowsDemo()
|
|
{
|
|
closeAllWindows();
|
|
|
|
closeWindowsButton.removeListener (this);
|
|
showWindowsButton.removeListener (this);
|
|
}
|
|
|
|
void paint (Graphics& g) override
|
|
{
|
|
g.fillAll (Colours::grey);
|
|
}
|
|
|
|
void resized() override
|
|
{
|
|
const Rectangle<int> buttonSize (0, 0, 108, 28);
|
|
Rectangle<int> area ((getWidth() / 2) - (buttonSize.getWidth() / 2),
|
|
(getHeight() / 2) - buttonSize.getHeight(),
|
|
buttonSize.getWidth(), buttonSize.getHeight());
|
|
showWindowsButton.setBounds (area.reduced (2));
|
|
closeWindowsButton.setBounds (area.translated (0, buttonSize.getHeight()).reduced (2));
|
|
}
|
|
|
|
private:
|
|
// Because in this demo the windows delete themselves, we'll use the
|
|
// Component::SafePointer class to point to them, which automatically becomes
|
|
// null when the component that it points to is deleted.
|
|
Array< Component::SafePointer<Component> > windows;
|
|
TextButton showWindowsButton, closeWindowsButton;
|
|
|
|
void showAllWindows()
|
|
{
|
|
closeAllWindows();
|
|
|
|
showDocumentWindow (false);
|
|
showDocumentWindow (true);
|
|
showTransparentWindow();
|
|
showDialogWindow();
|
|
}
|
|
|
|
void closeAllWindows()
|
|
{
|
|
for (int i = 0; i < windows.size(); ++i)
|
|
windows.getReference(i).deleteAndZero();
|
|
|
|
windows.clear();
|
|
}
|
|
|
|
void showDialogWindow()
|
|
{
|
|
String m;
|
|
|
|
m << "Dialog Windows can be used to quickly show a component, usually blocking mouse input to other windows." << newLine
|
|
<< newLine
|
|
<< "They can also be quickly closed with the escape key, try it now.";
|
|
|
|
DialogWindow::LaunchOptions options;
|
|
Label* label = new Label();
|
|
label->setText (m, dontSendNotification);
|
|
label->setColour (Label::textColourId, Colours::whitesmoke);
|
|
options.content.setOwned (label);
|
|
|
|
Rectangle<int> area (0, 0, 300, 200);
|
|
options.content->setSize (area.getWidth(), area.getHeight());
|
|
|
|
options.dialogTitle = "Dialog Window";
|
|
options.dialogBackgroundColour = Colour (0xff0e345a);
|
|
options.escapeKeyTriggersCloseButton = true;
|
|
options.useNativeTitleBar = false;
|
|
options.resizable = true;
|
|
|
|
const RectanglePlacement placement (RectanglePlacement::xRight + RectanglePlacement::yBottom + RectanglePlacement::doNotResize);
|
|
|
|
DialogWindow* dw = options.launchAsync();
|
|
dw->centreWithSize (300, 200);
|
|
}
|
|
|
|
void showDocumentWindow (bool native)
|
|
{
|
|
DocumentWindow* dw = new ColourSelectorWindow ("Document Window", getRandomBrightColour(), DocumentWindow::allButtons);
|
|
windows.add (dw);
|
|
|
|
Rectangle<int> area (0, 0, 300, 400);
|
|
const RectanglePlacement placement ((native ? RectanglePlacement::xLeft : RectanglePlacement::xRight)
|
|
+ RectanglePlacement::yTop + RectanglePlacement::doNotResize);
|
|
Rectangle<int> result (placement.appliedTo (area, Desktop::getInstance().getDisplays().getMainDisplay().userArea.reduced (20)));
|
|
dw->setBounds (result);
|
|
|
|
dw->setResizable (true, ! native);
|
|
dw->setUsingNativeTitleBar (native);
|
|
dw->setVisible (true);
|
|
}
|
|
|
|
void showTransparentWindow()
|
|
{
|
|
BouncingBallsContainer* balls = new BouncingBallsContainer (3);
|
|
balls->addToDesktop (ComponentPeer::windowIsTemporary);
|
|
windows.add (balls);
|
|
|
|
Rectangle<int> area (0, 0, 200, 200);
|
|
const RectanglePlacement placement (RectanglePlacement::xLeft + RectanglePlacement::yBottom + RectanglePlacement::doNotResize);
|
|
Rectangle<int> result (placement.appliedTo (area, Desktop::getInstance().getDisplays().getMainDisplay().userArea.reduced (20)));
|
|
balls->setBounds (result);
|
|
|
|
balls->setVisible (true);
|
|
}
|
|
|
|
void buttonClicked (Button* button) override
|
|
{
|
|
if (button == &showWindowsButton)
|
|
showAllWindows();
|
|
else if (button == &closeWindowsButton)
|
|
closeAllWindows();
|
|
}
|
|
|
|
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WindowsDemo);
|
|
};
|
|
|
|
// This static object will register this demo type in a global list of demos..
|
|
static JuceDemoType<WindowsDemo> demo ("10 Components: Windows");
|