git subrepo clone --branch=sono6good https://github.com/essej/JUCE.git deps/juce

subrepo:
  subdir:   "deps/juce"
  merged:   "b13f9084e"
upstream:
  origin:   "https://github.com/essej/JUCE.git"
  branch:   "sono6good"
  commit:   "b13f9084e"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
This commit is contained in:
essej
2022-04-18 17:51:22 -04:00
parent 63e175fee6
commit 25bd5d8adb
3210 changed files with 1045392 additions and 0 deletions

View File

@ -0,0 +1,192 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
static Typeface::Ptr getTypefaceForFontFromLookAndFeel (const Font& font)
{
return LookAndFeel::getDefaultLookAndFeel().getTypefaceForFont (font);
}
using GetTypefaceForFont = Typeface::Ptr (*)(const Font&);
extern GetTypefaceForFont juce_getTypefaceForFont;
//==============================================================================
LookAndFeel::LookAndFeel()
{
/* if this fails it means you're trying to create a LookAndFeel object before
the static Colours have been initialised. That ain't gonna work. It probably
means that you're using a static LookAndFeel object and that your compiler has
decided to initialise it before the Colours class.
*/
jassert (Colours::white == Colour (0xffffffff));
juce_getTypefaceForFont = getTypefaceForFontFromLookAndFeel;
}
LookAndFeel::~LookAndFeel()
{
/* This assertion is triggered if you try to delete a LookAndFeel object while something
is still using it!
Reasons may be:
- it's still being used as the default LookAndFeel; or
- it's set as a Component's current lookandfeel; or
- there's a WeakReference to it somewhere else in your code
Generally the fix for this will be to make sure you call
Component::setLookandFeel (nullptr) on any components that were still using
it before you delete it, or call LookAndFeel::setDefaultLookAndFeel (nullptr)
if you had set it up to be the default one. This assertion can also be avoided by
declaring your LookAndFeel object before any of the Components that use it as
the Components will be destroyed before the LookAndFeel.
Deleting a LookAndFeel is unlikely to cause a crash since most things will use a
safe WeakReference to it, but it could cause some unexpected graphical behaviour,
so it's advisable to clear up any references before destroying them!
*/
jassert (masterReference.getNumActiveWeakReferences() == 0
|| (masterReference.getNumActiveWeakReferences() == 1
&& this == &getDefaultLookAndFeel()));
}
//==============================================================================
Colour LookAndFeel::findColour (int colourID) const noexcept
{
const ColourSetting c = { colourID, Colour() };
auto index = colours.indexOf (c);
if (index >= 0)
return colours[index].colour;
jassertfalse;
return Colours::black;
}
void LookAndFeel::setColour (int colourID, Colour newColour) noexcept
{
const ColourSetting c = { colourID, newColour };
auto index = colours.indexOf (c);
if (index >= 0)
colours.getReference (index).colour = newColour;
else
colours.add (c);
}
bool LookAndFeel::isColourSpecified (const int colourID) const noexcept
{
const ColourSetting c = { colourID, Colour() };
return colours.contains (c);
}
//==============================================================================
LookAndFeel& LookAndFeel::getDefaultLookAndFeel() noexcept
{
return Desktop::getInstance().getDefaultLookAndFeel();
}
void LookAndFeel::setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) noexcept
{
Desktop::getInstance().setDefaultLookAndFeel (newDefaultLookAndFeel);
}
//==============================================================================
Typeface::Ptr LookAndFeel::getTypefaceForFont (const Font& font)
{
if (font.getTypefaceName() == Font::getDefaultSansSerifFontName())
{
if (defaultTypeface != nullptr)
return defaultTypeface;
if (defaultSans.isNotEmpty())
{
Font f (font);
f.setTypefaceName (defaultSans);
return Typeface::createSystemTypefaceFor (f);
}
}
return Font::getDefaultTypefaceForFont (font);
}
void LookAndFeel::setDefaultSansSerifTypeface (Typeface::Ptr newDefaultTypeface)
{
if (defaultTypeface != newDefaultTypeface)
{
defaultTypeface = newDefaultTypeface;
Typeface::clearTypefaceCache();
}
}
void LookAndFeel::setDefaultSansSerifTypefaceName (const String& newName)
{
if (defaultSans != newName)
{
defaultTypeface.reset();
Typeface::clearTypefaceCache();
defaultSans = newName;
}
}
//==============================================================================
MouseCursor LookAndFeel::getMouseCursorFor (Component& component)
{
auto cursor = component.getMouseCursor();
for (auto* parent = component.getParentComponent();
parent != nullptr && cursor == MouseCursor::ParentCursor;
parent = parent->getParentComponent())
{
cursor = parent->getMouseCursor();
}
return cursor;
}
std::unique_ptr<LowLevelGraphicsContext> LookAndFeel::createGraphicsContext (const Image& imageToRenderOn,
Point<int> origin,
const RectangleList<int>& initialClip)
{
return std::make_unique<LowLevelGraphicsSoftwareRenderer> (imageToRenderOn, origin, initialClip);
}
//==============================================================================
void LookAndFeel::setUsingNativeAlertWindows (bool shouldUseNativeAlerts)
{
useNativeAlertWindows = shouldUseNativeAlerts;
}
bool LookAndFeel::isUsingNativeAlertWindows()
{
#if JUCE_LINUX || JUCE_BSD
return false; // not available currently..
#else
return useNativeAlertWindows;
#endif
}
} // namespace juce

View File

@ -0,0 +1,246 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/** This class is used to hold a few look and feel base classes which are associated
with classes that may not be present because they're from modules other than
juce_gui_basics.
@tags{GUI}
*/
struct JUCE_API ExtraLookAndFeelBaseClasses
{
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API LassoComponentMethods
{
virtual ~LassoComponentMethods() = default;
virtual void drawLasso (Graphics&, Component& lassoComp) = 0;
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API KeyMappingEditorComponentMethods
{
virtual ~KeyMappingEditorComponentMethods() = default;
virtual void drawKeymapChangeButton (Graphics&, int width, int height, Button&, const String& keyDescription) = 0;
};
//==============================================================================
/** This abstract base class is implemented by LookAndFeel classes. */
struct JUCE_API AudioDeviceSelectorComponentMethods
{
virtual ~AudioDeviceSelectorComponentMethods() = default;
virtual void drawLevelMeter (Graphics&, int width, int height, float level) = 0;
};
};
//==============================================================================
/**
LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses
can be used to apply different 'skins' to the application.
This class is an abstract base-class - for actual look-and-feels that you can
instantiate, see LookAndFeel_V1, LookAndFeel_V2 and LookAndFeel_V3.
@see LookAndFeel_V1, LookAndFeel_V2, LookAndFeel_V3
@tags{GUI}
*/
class JUCE_API LookAndFeel : public ScrollBar::LookAndFeelMethods,
public Button::LookAndFeelMethods,
public ImageButton::LookAndFeelMethods,
public TextEditor::LookAndFeelMethods,
public FileBrowserComponent::LookAndFeelMethods,
public TreeView::LookAndFeelMethods,
public BubbleComponent::LookAndFeelMethods,
public AlertWindow::LookAndFeelMethods,
public PopupMenu::LookAndFeelMethods,
public ComboBox::LookAndFeelMethods,
public Label::LookAndFeelMethods,
public Slider::LookAndFeelMethods,
public ResizableWindow::LookAndFeelMethods,
public DocumentWindow::LookAndFeelMethods,
public TooltipWindow::LookAndFeelMethods,
public TabbedButtonBar::LookAndFeelMethods,
public PropertyComponent::LookAndFeelMethods,
public FilenameComponent::LookAndFeelMethods,
public GroupComponent::LookAndFeelMethods,
public TableHeaderComponent::LookAndFeelMethods,
public CallOutBox::LookAndFeelMethods,
public Toolbar::LookAndFeelMethods,
public ConcertinaPanel::LookAndFeelMethods,
public ProgressBar::LookAndFeelMethods,
public StretchableLayoutResizerBar::LookAndFeelMethods,
public ExtraLookAndFeelBaseClasses::KeyMappingEditorComponentMethods,
public ExtraLookAndFeelBaseClasses::AudioDeviceSelectorComponentMethods,
public ExtraLookAndFeelBaseClasses::LassoComponentMethods,
public SidePanel::LookAndFeelMethods
{
public:
//==============================================================================
/** Creates the default JUCE look and feel. */
LookAndFeel();
/** Destructor. */
~LookAndFeel() override;
//==============================================================================
/** Returns the current default look-and-feel for a component to use when it
hasn't got one explicitly set.
@see setDefaultLookAndFeel
*/
static LookAndFeel& getDefaultLookAndFeel() noexcept;
/** Changes the default look-and-feel.
@param newDefaultLookAndFeel the new look-and-feel object to use - if this is
set to null, it will revert to using the default one. The
object passed-in must be deleted by the caller when
it's no longer needed.
@see getDefaultLookAndFeel
*/
static void setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) noexcept;
//==============================================================================
/** Looks for a colour that has been registered with the given colour ID number.
If a colour has been set for this ID number using setColour(), then it is
returned. If none has been set, it will just return Colours::black.
The colour IDs for various purposes are stored as enums in the components that
they are relevant to - for an example, see Slider::ColourIds,
Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc.
If you're looking up a colour for use in drawing a component, it's usually
best not to call this directly, but to use the Component::findColour() method
instead. That will first check whether a suitable colour has been registered
directly with the component, and will fall-back on calling the component's
LookAndFeel's findColour() method if none is found.
@see setColour, Component::findColour, Component::setColour
*/
Colour findColour (int colourId) const noexcept;
/** Registers a colour to be used for a particular purpose.
For more details, see the comments for findColour().
@see findColour, Component::findColour, Component::setColour
*/
void setColour (int colourId, Colour colour) noexcept;
/** Returns true if the specified colour ID has been explicitly set using the
setColour() method.
*/
bool isColourSpecified (int colourId) const noexcept;
//==============================================================================
/** Returns the typeface that should be used for a given font.
The default implementation just does what you'd expect it to, but you can override
this if you want to intercept fonts and use your own custom typeface object.
@see setDefaultTypeface
*/
virtual Typeface::Ptr getTypefaceForFont (const Font&);
/** Allows you to supply a default typeface that will be returned as the default
sans-serif font.
Instead of a typeface object, you can specify a typeface by name using the
setDefaultSansSerifTypefaceName() method.
You can perform more complex typeface substitutions by overloading
getTypefaceForFont() but this lets you easily set a global typeface.
*/
void setDefaultSansSerifTypeface (Typeface::Ptr newDefaultTypeface);
/** Allows you to change the default sans-serif font.
If you need to supply your own Typeface object for any of the default fonts, rather
than just supplying the name (e.g. if you want to use an embedded font), then
you can instead call setDefaultSansSerifTypeface() with an object to use.
*/
void setDefaultSansSerifTypefaceName (const String& newName);
//==============================================================================
/** Override this to get the chance to swap a component's mouse cursor for a
customised one.
*/
virtual MouseCursor getMouseCursorFor (Component&);
//==============================================================================
/** Creates a new graphics context object. */
virtual std::unique_ptr<LowLevelGraphicsContext> createGraphicsContext (const Image& imageToRenderOn,
Point<int> origin,
const RectangleList<int>& initialClip);
void setUsingNativeAlertWindows (bool shouldUseNativeAlerts);
bool isUsingNativeAlertWindows();
//==============================================================================
/** Draws a small image that spins to indicate that something's happening.
This method should use the current time to animate itself, so just keep
repainting it every so often.
*/
virtual void drawSpinningWaitAnimation (Graphics&, const Colour& colour,
int x, int y, int w, int h) = 0;
//==============================================================================
/** Returns a tick shape for use in yes/no boxes, etc. */
virtual Path getTickShape (float height) = 0;
/** Returns a cross shape for use in yes/no boxes, etc. */
virtual Path getCrossShape (float height) = 0;
//==============================================================================
virtual DropShadower* createDropShadowerForComponent (Component*) = 0;
//==============================================================================
/** Plays the system's default 'beep' noise, to alert the user about something very important. */
virtual void playAlertSound();
private:
//==============================================================================
struct ColourSetting
{
int colourID;
Colour colour;
bool operator< (const ColourSetting& other) const noexcept { return colourID < other.colourID; }
bool operator== (const ColourSetting& other) const noexcept { return colourID == other.colourID; }
};
SortedSet<ColourSetting> colours;
String defaultSans, defaultSerif, defaultFixed;
Typeface::Ptr defaultTypeface;
bool useNativeAlertWindows = false;
JUCE_DECLARE_WEAK_REFERENCEABLE (LookAndFeel)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel)
};
} // namespace juce

View File

@ -0,0 +1,587 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
LookAndFeel_V1::LookAndFeel_V1()
{
setColour (TextButton::buttonColourId, Colour (0xffbbbbff));
setColour (ListBox::outlineColourId, findColour (ComboBox::outlineColourId));
setColour (ScrollBar::thumbColourId, Colour (0xffbbbbdd));
setColour (ScrollBar::backgroundColourId, Colours::transparentBlack);
setColour (Slider::thumbColourId, Colours::white);
setColour (Slider::trackColourId, Colour (0x7f000000));
setColour (Slider::textBoxOutlineColourId, Colours::grey);
setColour (ProgressBar::backgroundColourId, Colours::white.withAlpha (0.6f));
setColour (ProgressBar::foregroundColourId, Colours::green.withAlpha (0.7f));
setColour (PopupMenu::backgroundColourId, Colour (0xffeef5f8));
setColour (PopupMenu::highlightedBackgroundColourId, Colour (0xbfa4c2ce));
setColour (PopupMenu::highlightedTextColourId, Colours::black);
setColour (TextEditor::focusedOutlineColourId, findColour (TextButton::buttonColourId));
scrollbarShadow.setShadowProperties (DropShadow (Colours::black.withAlpha (0.5f), 2, Point<int>()));
}
LookAndFeel_V1::~LookAndFeel_V1()
{
}
//==============================================================================
void LookAndFeel_V1::drawButtonBackground (Graphics& g, Button& button, const Colour& backgroundColour,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
{
const int width = button.getWidth();
const int height = button.getHeight();
const float indent = 2.0f;
const int cornerSize = jmin (roundToInt ((float) width * 0.4f),
roundToInt ((float) height * 0.4f));
Path p;
p.addRoundedRectangle (indent, indent,
(float) width - indent * 2.0f,
(float) height - indent * 2.0f,
(float) cornerSize);
Colour bc (backgroundColour.withMultipliedSaturation (0.3f));
if (shouldDrawButtonAsHighlighted)
{
if (shouldDrawButtonAsDown)
bc = bc.brighter();
else if (bc.getBrightness() > 0.5f)
bc = bc.darker (0.1f);
else
bc = bc.brighter (0.1f);
}
g.setColour (bc);
g.fillPath (p);
g.setColour (bc.contrasting().withAlpha ((shouldDrawButtonAsHighlighted) ? 0.6f : 0.4f));
g.strokePath (p, PathStrokeType ((shouldDrawButtonAsHighlighted) ? 2.0f : 1.4f));
}
void LookAndFeel_V1::drawTickBox (Graphics& g, Component& /*component*/,
float x, float y, float w, float h,
const bool ticked,
const bool isEnabled,
const bool /*shouldDrawButtonAsHighlighted*/,
const bool shouldDrawButtonAsDown)
{
Path box;
box.addRoundedRectangle (0.0f, 2.0f, 6.0f, 6.0f, 1.0f);
g.setColour (isEnabled ? Colours::blue.withAlpha (shouldDrawButtonAsDown ? 0.3f : 0.1f)
: Colours::lightgrey.withAlpha (0.1f));
AffineTransform trans (AffineTransform::scale (w / 9.0f, h / 9.0f).translated (x, y));
g.fillPath (box, trans);
g.setColour (Colours::black.withAlpha (0.6f));
g.strokePath (box, PathStrokeType (0.9f), trans);
if (ticked)
{
Path tick;
tick.startNewSubPath (1.5f, 3.0f);
tick.lineTo (3.0f, 6.0f);
tick.lineTo (6.0f, 0.0f);
g.setColour (isEnabled ? Colours::black : Colours::grey);
g.strokePath (tick, PathStrokeType (2.5f), trans);
}
}
void LookAndFeel_V1::drawToggleButton (Graphics& g, ToggleButton& button, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
{
if (button.hasKeyboardFocus (true))
{
g.setColour (button.findColour (TextEditor::focusedOutlineColourId));
g.drawRect (0, 0, button.getWidth(), button.getHeight());
}
const int tickWidth = jmin (20, button.getHeight() - 4);
drawTickBox (g, button, 4.0f, (float) (button.getHeight() - tickWidth) * 0.5f,
(float) tickWidth, (float) tickWidth,
button.getToggleState(),
button.isEnabled(),
shouldDrawButtonAsHighlighted,
shouldDrawButtonAsDown);
g.setColour (button.findColour (ToggleButton::textColourId));
g.setFont (jmin (15.0f, (float) button.getHeight() * 0.6f));
if (! button.isEnabled())
g.setOpacity (0.5f);
const int textX = tickWidth + 5;
g.drawFittedText (button.getButtonText(),
textX, 4,
button.getWidth() - textX - 2, button.getHeight() - 8,
Justification::centredLeft, 10);
}
void LookAndFeel_V1::drawProgressBar (Graphics& g, ProgressBar& progressBar,
int width, int height,
double progress, const String& textToShow)
{
if (progress < 0 || progress >= 1.0)
{
LookAndFeel_V2::drawProgressBar (g, progressBar, width, height, progress, textToShow);
}
else
{
const Colour background (progressBar.findColour (ProgressBar::backgroundColourId));
const Colour foreground (progressBar.findColour (ProgressBar::foregroundColourId));
g.fillAll (background);
g.setColour (foreground);
g.fillRect (1, 1,
jlimit (0, width - 2, roundToInt (progress * (width - 2))),
height - 2);
if (textToShow.isNotEmpty())
{
g.setColour (Colour::contrasting (background, foreground));
g.setFont ((float) height * 0.6f);
g.drawText (textToShow, 0, 0, width, height, Justification::centred, false);
}
}
}
void LookAndFeel_V1::drawScrollbarButton (Graphics& g, ScrollBar& bar,
int width, int height, int buttonDirection,
bool isScrollbarVertical,
bool shouldDrawButtonAsHighlighted,
bool shouldDrawButtonAsDown)
{
if (isScrollbarVertical)
width -= 2;
else
height -= 2;
Path p;
const auto w = (float) width;
const auto h = (float) height;
if (buttonDirection == 0)
p.addTriangle (w * 0.5f, h * 0.2f,
w * 0.1f, h * 0.7f,
w * 0.9f, h * 0.7f);
else if (buttonDirection == 1)
p.addTriangle (w * 0.8f, h * 0.5f,
w * 0.3f, h * 0.1f,
w * 0.3f, h * 0.9f);
else if (buttonDirection == 2)
p.addTriangle (w * 0.5f, h * 0.8f,
w * 0.1f, h * 0.3f,
w * 0.9f, h * 0.3f);
else if (buttonDirection == 3)
p.addTriangle (w * 0.2f, h * 0.5f,
w * 0.7f, h * 0.1f,
w * 0.7f, h * 0.9f);
if (shouldDrawButtonAsDown)
g.setColour (Colours::white);
else if (shouldDrawButtonAsHighlighted)
g.setColour (Colours::white.withAlpha (0.7f));
else
g.setColour (bar.findColour (ScrollBar::thumbColourId).withAlpha (0.5f));
g.fillPath (p);
g.setColour (Colours::black.withAlpha (0.5f));
g.strokePath (p, PathStrokeType (0.5f));
}
void LookAndFeel_V1::drawScrollbar (Graphics& g, ScrollBar& bar,
int x, int y, int width, int height,
bool isScrollbarVertical, int thumbStartPosition, int thumbSize,
bool isMouseOver, bool isMouseDown)
{
g.fillAll (bar.findColour (ScrollBar::backgroundColourId));
g.setColour (bar.findColour (ScrollBar::thumbColourId)
.withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.15f));
if ((float) thumbSize > 0.0f)
{
Rectangle<int> thumb;
if (isScrollbarVertical)
{
width -= 2;
g.fillRect (x + roundToInt ((float) width * 0.35f), y,
roundToInt ((float) width * 0.3f), height);
thumb.setBounds (x + 1, thumbStartPosition,
width - 2, thumbSize);
}
else
{
height -= 2;
g.fillRect (x, y + roundToInt ((float) height * 0.35f),
width, roundToInt ((float) height * 0.3f));
thumb.setBounds (thumbStartPosition, y + 1,
thumbSize, height - 2);
}
g.setColour (bar.findColour (ScrollBar::thumbColourId)
.withAlpha ((isMouseOver || isMouseDown) ? 0.95f : 0.7f));
g.fillRect (thumb);
g.setColour (Colours::black.withAlpha ((isMouseOver || isMouseDown) ? 0.4f : 0.25f));
g.drawRect (thumb.getX(), thumb.getY(), thumb.getWidth(), thumb.getHeight());
if (thumbSize > 16)
{
for (int i = 3; --i >= 0;)
{
const float linePos = (float) thumbStartPosition + (float) thumbSize * 0.5f + (float) (i - 1) * 4.0f;
g.setColour (Colours::black.withAlpha (0.15f));
if (isScrollbarVertical)
{
g.drawLine ((float) x + (float) width * 0.2f, linePos, (float) width * 0.8f, linePos);
g.setColour (Colours::white.withAlpha (0.15f));
g.drawLine ((float) width * 0.2f, linePos - 1.0f, (float) width * 0.8f, linePos - 1.0f);
}
else
{
g.drawLine (linePos, (float) height * 0.2f, linePos, (float) height * 0.8f);
g.setColour (Colours::white.withAlpha (0.15f));
g.drawLine (linePos - 1.0f, (float) height * 0.2f, linePos - 1.0f, (float) height * 0.8f);
}
}
}
}
}
ImageEffectFilter* LookAndFeel_V1::getScrollbarEffect()
{
return &scrollbarShadow;
}
//==============================================================================
void LookAndFeel_V1::drawPopupMenuBackground (Graphics& g, int width, int height)
{
g.fillAll (findColour (PopupMenu::backgroundColourId));
g.setColour (Colours::black.withAlpha (0.6f));
g.drawRect (0, 0, width, height);
}
void LookAndFeel_V1::drawMenuBarBackground (Graphics& g, int /*width*/, int /*height*/, bool, MenuBarComponent& menuBar)
{
g.fillAll (menuBar.findColour (PopupMenu::backgroundColourId));
}
//==============================================================================
void LookAndFeel_V1::drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor)
{
if (textEditor.isEnabled())
{
g.setColour (textEditor.findColour (TextEditor::outlineColourId));
g.drawRect (0, 0, width, height);
}
}
//==============================================================================
void LookAndFeel_V1::drawComboBox (Graphics& g, int width, int height,
const bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox& box)
{
g.fillAll (box.findColour (ComboBox::backgroundColourId));
g.setColour (box.findColour ((isButtonDown) ? ComboBox::buttonColourId
: ComboBox::backgroundColourId));
g.fillRect (buttonX, buttonY, buttonW, buttonH);
g.setColour (box.findColour (ComboBox::outlineColourId));
g.drawRect (0, 0, width, height);
const float arrowX = 0.2f;
const float arrowH = 0.3f;
const auto x = (float) buttonX;
const auto y = (float) buttonY;
const auto w = (float) buttonW;
const auto h = (float) buttonH;
if (box.isEnabled())
{
Path p;
p.addTriangle (x + w * 0.5f, y + h * (0.45f - arrowH),
x + w * (1.0f - arrowX), y + h * 0.45f,
x + w * arrowX, y + h * 0.45f);
p.addTriangle (x + w * 0.5f, y + h * (0.55f + arrowH),
x + w * (1.0f - arrowX), y + h * 0.55f,
x + w * arrowX, y + h * 0.55f);
g.setColour (box.findColour ((isButtonDown) ? ComboBox::backgroundColourId
: ComboBox::buttonColourId));
g.fillPath (p);
}
}
Font LookAndFeel_V1::getComboBoxFont (ComboBox& box)
{
Font f (jmin (15.0f, (float) box.getHeight() * 0.85f));
f.setHorizontalScale (0.9f);
return f;
}
//==============================================================================
static void drawTriangle (Graphics& g, float x1, float y1, float x2, float y2, float x3, float y3, Colour fill, Colour outline)
{
Path p;
p.addTriangle (x1, y1, x2, y2, x3, y3);
g.setColour (fill);
g.fillPath (p);
g.setColour (outline);
g.strokePath (p, PathStrokeType (0.3f));
}
void LookAndFeel_V1::drawLinearSlider (Graphics& g,
int x, int y, int w, int h,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle style,
Slider& slider)
{
g.fillAll (slider.findColour (Slider::backgroundColourId));
if (style == Slider::LinearBar)
{
g.setColour (slider.findColour (Slider::thumbColourId));
g.fillRect (x, y, (int) sliderPos - x, h);
g.setColour (slider.findColour (Slider::textBoxTextColourId).withMultipliedAlpha (0.5f));
g.drawRect (x, y, (int) sliderPos - x, h);
}
else
{
g.setColour (slider.findColour (Slider::trackColourId)
.withMultipliedAlpha (slider.isEnabled() ? 1.0f : 0.3f));
if (slider.isHorizontal())
{
g.fillRect (x, y + roundToInt ((float) h * 0.6f),
w, roundToInt ((float) h * 0.2f));
}
else
{
g.fillRect (x + roundToInt ((float) w * 0.5f - jmin (3.0f, (float) w * 0.1f)), y,
jmin (4, roundToInt ((float) w * 0.2f)), h);
}
float alpha = 0.35f;
if (slider.isEnabled())
alpha = slider.isMouseOverOrDragging() ? 1.0f : 0.7f;
const Colour fill (slider.findColour (Slider::thumbColourId).withAlpha (alpha));
const Colour outline (Colours::black.withAlpha (slider.isEnabled() ? 0.7f : 0.35f));
if (style == Slider::TwoValueVertical || style == Slider::ThreeValueVertical)
{
drawTriangle (g,
(float) x + (float) w * 0.5f + jmin (4.0f, (float) w * 0.3f), minSliderPos,
(float) x + (float) w * 0.5f - jmin (8.0f, (float) w * 0.4f), minSliderPos - 7.0f,
(float) x + (float) w * 0.5f - jmin (8.0f, (float) w * 0.4f), minSliderPos,
fill, outline);
drawTriangle (g,
(float) x + (float) w * 0.5f + jmin (4.0f, (float) w * 0.3f), maxSliderPos,
(float) x + (float) w * 0.5f - jmin (8.0f, (float) w * 0.4f), maxSliderPos,
(float) x + (float) w * 0.5f - jmin (8.0f, (float) w * 0.4f), maxSliderPos + 7.0f,
fill, outline);
}
else if (style == Slider::TwoValueHorizontal || style == Slider::ThreeValueHorizontal)
{
drawTriangle (g,
minSliderPos, (float) y + (float) h * 0.6f - jmin (4.0f, (float) h * 0.3f),
minSliderPos - 7.0f, (float) y + (float) h * 0.9f,
minSliderPos, (float) y + (float) h * 0.9f,
fill, outline);
drawTriangle (g,
maxSliderPos, (float) y + (float) h * 0.6f - jmin (4.0f, (float) h * 0.3f),
maxSliderPos, (float) y + (float) h * 0.9f,
maxSliderPos + 7.0f, (float) y + (float) h * 0.9f,
fill, outline);
}
if (style == Slider::LinearHorizontal || style == Slider::ThreeValueHorizontal)
{
drawTriangle (g,
sliderPos, (float) y + (float) h * 0.9f,
sliderPos - 7.0f, (float) y + (float) h * 0.2f,
sliderPos + 7.0f, (float) y + (float) h * 0.2f,
fill, outline);
}
else if (style == Slider::LinearVertical || style == Slider::ThreeValueVertical)
{
drawTriangle (g,
(float) x + (float) w * 0.5f - jmin (4.0f, (float) w * 0.3f), sliderPos,
(float) x + (float) w * 0.5f + jmin (8.0f, (float) w * 0.4f), sliderPos - 7.0f,
(float) x + (float) w * 0.5f + jmin (8.0f, (float) w * 0.4f), sliderPos + 7.0f,
fill, outline);
}
}
}
Button* LookAndFeel_V1::createSliderButton (Slider&, const bool isIncrement)
{
if (isIncrement)
return new ArrowButton ("u", 0.75f, Colours::white.withAlpha (0.8f));
return new ArrowButton ("d", 0.25f, Colours::white.withAlpha (0.8f));
}
ImageEffectFilter* LookAndFeel_V1::getSliderEffect (Slider&)
{
return &scrollbarShadow;
}
int LookAndFeel_V1::getSliderThumbRadius (Slider&)
{
return 8;
}
//==============================================================================
void LookAndFeel_V1::drawCornerResizer (Graphics& g, int w, int h, bool isMouseOver, bool isMouseDragging)
{
g.setColour ((isMouseOver || isMouseDragging) ? Colours::lightgrey
: Colours::darkgrey);
const float lineThickness = (float) jmin (w, h) * 0.1f;
for (float i = 0.0f; i < 1.0f; i += 0.3f)
{
g.drawLine ((float) w * i,
(float) h + 1.0f,
(float) w + 1.0f,
(float) h * i,
lineThickness);
}
}
//==============================================================================
Button* LookAndFeel_V1::createDocumentWindowButton (int buttonType)
{
Path shape;
if (buttonType == DocumentWindow::closeButton)
{
shape.addLineSegment (Line<float> (0.0f, 0.0f, 1.0f, 1.0f), 0.35f);
shape.addLineSegment (Line<float> (1.0f, 0.0f, 0.0f, 1.0f), 0.35f);
ShapeButton* const b = new ShapeButton ("close",
Colour (0x7fff3333),
Colour (0xd7ff3333),
Colour (0xf7ff3333));
b->setShape (shape, true, true, true);
return b;
}
else if (buttonType == DocumentWindow::minimiseButton)
{
shape.addLineSegment (Line<float> (0.0f, 0.5f, 1.0f, 0.5f), 0.25f);
DrawableButton* b = new DrawableButton ("minimise", DrawableButton::ImageFitted);
DrawablePath dp;
dp.setPath (shape);
dp.setFill (Colours::black.withAlpha (0.3f));
b->setImages (&dp);
return b;
}
else if (buttonType == DocumentWindow::maximiseButton)
{
shape.addLineSegment (Line<float> (0.5f, 0.0f, 0.5f, 1.0f), 0.25f);
shape.addLineSegment (Line<float> (0.0f, 0.5f, 1.0f, 0.5f), 0.25f);
DrawableButton* b = new DrawableButton ("maximise", DrawableButton::ImageFitted);
DrawablePath dp;
dp.setPath (shape);
dp.setFill (Colours::black.withAlpha (0.3f));
b->setImages (&dp);
return b;
}
jassertfalse;
return nullptr;
}
void LookAndFeel_V1::positionDocumentWindowButtons (DocumentWindow&,
int titleBarX, int titleBarY, int titleBarW, int titleBarH,
Button* minimiseButton,
Button* maximiseButton,
Button* closeButton,
bool positionTitleBarButtonsOnLeft)
{
titleBarY += titleBarH / 8;
titleBarH -= titleBarH / 4;
const int buttonW = titleBarH;
int x = positionTitleBarButtonsOnLeft ? titleBarX + 4
: titleBarX + titleBarW - buttonW - 4;
if (closeButton != nullptr)
{
closeButton->setBounds (x, titleBarY, buttonW, titleBarH);
x += positionTitleBarButtonsOnLeft ? buttonW + buttonW / 5
: -(buttonW + buttonW / 5);
}
if (positionTitleBarButtonsOnLeft)
std::swap (minimiseButton, maximiseButton);
if (maximiseButton != nullptr)
{
maximiseButton->setBounds (x, titleBarY - 2, buttonW, titleBarH);
x += positionTitleBarButtonsOnLeft ? buttonW : -buttonW;
}
if (minimiseButton != nullptr)
minimiseButton->setBounds (x, titleBarY - 2, buttonW, titleBarH);
}
} // namespace juce

View File

@ -0,0 +1,105 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
The original JUCE look-and-feel, as used back from 2002 to about 2007ish.
@see LookAndFeel, LookAndFeel_V2, LookAndFeel_V3
@tags{GUI}
*/
class JUCE_API LookAndFeel_V1 : public LookAndFeel_V2
{
public:
LookAndFeel_V1();
~LookAndFeel_V1() override;
//==============================================================================
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawToggleButton (Graphics&, ToggleButton&,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawTickBox (Graphics&, Component&, float x, float y, float w, float h,
bool ticked, bool isEnabled,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawProgressBar (Graphics&, ProgressBar&, int width, int height,
double progress, const String& textToShow) override;
//==============================================================================
void drawScrollbarButton (Graphics&, ScrollBar&, int width, int height,
int buttonDirection, bool isScrollbarVertical,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height,
bool isScrollbarVertical, int thumbStartPosition, int thumbSize,
bool isMouseOver, bool isMouseDown) override;
ImageEffectFilter* getScrollbarEffect() override;
//==============================================================================
void drawTextEditorOutline (Graphics&, int width, int height, TextEditor&) override;
//==============================================================================
void drawPopupMenuBackground (Graphics&, int width, int height) override;
void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override;
//==============================================================================
void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH, ComboBox&) override;
Font getComboBoxFont (ComboBox&) override;
//==============================================================================
void drawLinearSlider (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
int getSliderThumbRadius (Slider&) override;
Button* createSliderButton (Slider&, bool isIncrement) override;
ImageEffectFilter* getSliderEffect (Slider&) override;
//==============================================================================
void drawCornerResizer (Graphics&, int w, int h, bool isMouseOver, bool isMouseDragging) override;
Button* createDocumentWindowButton (int buttonType) override;
void positionDocumentWindowButtons (DocumentWindow&,
int titleBarX, int titleBarY, int titleBarW, int titleBarH,
Button* minimiseButton, Button* maximiseButton, Button* closeButton,
bool positionTitleBarButtonsOnLeft) override;
private:
DropShadowEffect scrollbarShadow;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V1)
};
} // namespace juce

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,426 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
This LookAndFeel subclass implements the juce style from around 2008-12.
@see LookAndFeel, LookAndFeel_V1, LookAndFeel_V3
@tags{GUI}
*/
class JUCE_API LookAndFeel_V2 : public LookAndFeel
{
public:
LookAndFeel_V2();
~LookAndFeel_V2() override;
//==============================================================================
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
Font getTextButtonFont (TextButton&, int buttonHeight) override;
void drawButtonText (Graphics&, TextButton&,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
int getTextButtonWidthToFitText (TextButton&, int buttonHeight) override;
void drawToggleButton (Graphics&, ToggleButton&,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void changeToggleButtonWidthToFitText (ToggleButton&) override;
void drawTickBox (Graphics&, Component&,
float x, float y, float w, float h,
bool ticked, bool isEnabled,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawDrawableButton (Graphics&, DrawableButton&,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
//==============================================================================
AlertWindow* createAlertWindow (const String& title, const String& message,
const String& button1,
const String& button2,
const String& button3,
MessageBoxIconType iconType,
int numButtons, Component* associatedComponent) override;
void drawAlertBox (Graphics&, AlertWindow&, const Rectangle<int>& textArea, TextLayout&) override;
int getAlertBoxWindowFlags() override;
Array<int> getWidthsForTextButtons (AlertWindow&, const Array<TextButton*>&) override;
int getAlertWindowButtonHeight() override;
/** Override this function to supply a custom font for the alert window title.
This default implementation will use a boldened and slightly larger version
of the alert window message font.
@see getAlertWindowMessageFont.
*/
Font getAlertWindowTitleFont() override;
/** Override this function to supply a custom font for the alert window message.
This default implementation will use the default font with height set to 15.0f.
@see getAlertWindowTitleFont
*/
Font getAlertWindowMessageFont() override;
Font getAlertWindowFont() override;
//==============================================================================
void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) override;
void drawSpinningWaitAnimation (Graphics&, const Colour& colour, int x, int y, int w, int h) override;
bool isProgressBarOpaque (ProgressBar&) override;
//==============================================================================
bool areScrollbarButtonsVisible() override;
void drawScrollbarButton (Graphics&, ScrollBar&, int width, int height, int buttonDirection,
bool isScrollbarVertical, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height,
bool isScrollbarVertical, int thumbStartPosition, int thumbSize,
bool isMouseOver, bool isMouseDown) override;
ImageEffectFilter* getScrollbarEffect() override;
int getMinimumScrollbarThumbSize (ScrollBar&) override;
int getDefaultScrollbarWidth() override;
int getScrollbarButtonSize (ScrollBar&) override;
//==============================================================================
Path getTickShape (float height) override;
Path getCrossShape (float height) override;
//==============================================================================
void drawTreeviewPlusMinusBox (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isOpen, bool isMouseOver) override;
bool areLinesDrawnForTreeView (TreeView&) override;
int getTreeViewIndentSize (TreeView&) override;
//==============================================================================
void fillTextEditorBackground (Graphics&, int width, int height, TextEditor&) override;
void drawTextEditorOutline (Graphics&, int width, int height, TextEditor&) override;
CaretComponent* createCaretComponent (Component* keyFocusOwner) override;
//==============================================================================
const Drawable* getDefaultFolderImage() override;
const Drawable* getDefaultDocumentFileImage() override;
AttributedString createFileChooserHeaderText (const String& title, const String& instructions) override;
void drawFileBrowserRow (Graphics&, int width, int height,
const File& file, const String& filename, Image* icon,
const String& fileSizeDescription, const String& fileTimeDescription,
bool isDirectory, bool isItemSelected, int itemIndex,
DirectoryContentsDisplayComponent&) override;
Button* createFileBrowserGoUpButton() override;
void layoutFileBrowserComponent (FileBrowserComponent&,
DirectoryContentsDisplayComponent*,
FilePreviewComponent*,
ComboBox* currentPathBox,
TextEditor* filenameBox,
Button* goUpButton) override;
//==============================================================================
void drawBubble (Graphics&, BubbleComponent&, const Point<float>& tip, const Rectangle<float>& body) override;
void drawLasso (Graphics&, Component&) override;
//==============================================================================
void drawPopupMenuBackground (Graphics&, int width, int height) override;
void drawPopupMenuBackgroundWithOptions (Graphics&,
int width,
int height,
const PopupMenu::Options&) override;
void drawPopupMenuItem (Graphics&, const Rectangle<int>& area,
bool isSeparator, bool isActive, bool isHighlighted, bool isTicked, bool hasSubMenu,
const String& text, const String& shortcutKeyText,
const Drawable* icon, const Colour* textColour) override;
void drawPopupMenuItemWithOptions (Graphics&, const Rectangle<int>& area,
bool isHighlighted,
const PopupMenu::Item& item,
const PopupMenu::Options&) override;
void drawPopupMenuSectionHeader (Graphics&, const Rectangle<int>& area,
const String& sectionName) override;
void drawPopupMenuSectionHeaderWithOptions (Graphics&, const Rectangle<int>& area,
const String& sectionName,
const PopupMenu::Options&) override;
Font getPopupMenuFont() override;
void drawPopupMenuUpDownArrow (Graphics&, int width, int height, bool isScrollUpArrow) override;
void drawPopupMenuUpDownArrowWithOptions (Graphics&,
int width, int height,
bool isScrollUpArrow,
const PopupMenu::Options&) override;
void getIdealPopupMenuItemSize (const String& text, bool isSeparator, int standardMenuItemHeight,
int& idealWidth, int& idealHeight) override;
void getIdealPopupMenuItemSizeWithOptions (const String& text,
bool isSeparator,
int standardMenuItemHeight,
int& idealWidth,
int& idealHeight,
const PopupMenu::Options&) override;
int getMenuWindowFlags() override;
void preparePopupMenuWindow (Component&) override;
void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override;
int getMenuBarItemWidth (MenuBarComponent&, int itemIndex, const String& itemText) override;
Font getMenuBarFont (MenuBarComponent&, int itemIndex, const String& itemText) override;
int getDefaultMenuBarHeight() override;
void drawMenuBarItem (Graphics&, int width, int height,
int itemIndex, const String& itemText,
bool isMouseOverItem, bool isMenuOpen, bool isMouseOverBar,
MenuBarComponent&) override;
Component* getParentComponentForMenuOptions (const PopupMenu::Options& options) override;
bool shouldPopupMenuScaleWithTargetComponent (const PopupMenu::Options& options) override;
int getPopupMenuBorderSize() override;
int getPopupMenuBorderSizeWithOptions (const PopupMenu::Options&) override;
void drawPopupMenuColumnSeparatorWithOptions (Graphics& g,
const Rectangle<int>& bounds,
const PopupMenu::Options&) override;
int getPopupMenuColumnSeparatorWidthWithOptions (const PopupMenu::Options&) override;
//==============================================================================
void drawComboBox (Graphics&, int width, int height, bool isMouseButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox&) override;
Font getComboBoxFont (ComboBox&) override;
Label* createComboBoxTextBox (ComboBox&) override;
void positionComboBoxText (ComboBox&, Label&, Drawable*) override;
PopupMenu::Options getOptionsForComboBoxPopupMenu (ComboBox&, Label&) override;
void drawComboBoxTextWhenNothingSelected (Graphics&, ComboBox&, Label&) override;
//==============================================================================
void drawLabel (Graphics&, Label&) override;
Font getLabelFont (Label&) override;
BorderSize<int> getLabelBorderSize (Label&) override;
//==============================================================================
void drawLinearSlider (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawLinearSliderBackground (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawLinearSliderThumb (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawRotarySlider (Graphics&, int x, int y, int width, int height,
float sliderPosProportional, float rotaryStartAngle, float rotaryEndAngle,
Slider&) override;
int getSliderThumbRadius (Slider&) override;
Button* createSliderButton (Slider&, bool isIncrement) override;
Label* createSliderTextBox (Slider&) override;
ImageEffectFilter* getSliderEffect (Slider&) override;
Font getSliderPopupFont (Slider&) override;
int getSliderPopupPlacement (Slider&) override;
Slider::SliderLayout getSliderLayout (Slider&) override;
//==============================================================================
Rectangle<int> getTooltipBounds (const String& tipText, Point<int> screenPos, Rectangle<int> parentArea) override;
void drawTooltip (Graphics&, const String& text, int width, int height) override;
//==============================================================================
Button* createFilenameComponentBrowseButton (const String& text) override;
void layoutFilenameComponent (FilenameComponent&, ComboBox* filenameBox, Button* browseButton) override;
//==============================================================================
void drawConcertinaPanelHeader (Graphics&, const Rectangle<int>& area,
bool isMouseOver, bool isMouseDown,
ConcertinaPanel&, Component& panel) override;
//==============================================================================
void drawCornerResizer (Graphics&, int w, int h, bool isMouseOver, bool isMouseDragging) override;
void drawResizableFrame (Graphics&, int w, int h, const BorderSize<int>&) override;
//==============================================================================
void fillResizableWindowBackground (Graphics&, int w, int h, const BorderSize<int>&, ResizableWindow&) override;
void drawResizableWindowBorder (Graphics&, int w, int h, const BorderSize<int>& border, ResizableWindow&) override;
//==============================================================================
void drawDocumentWindowTitleBar (DocumentWindow&, Graphics&, int w, int h,
int titleSpaceX, int titleSpaceW,
const Image* icon, bool drawTitleTextOnLeft) override;
Button* createDocumentWindowButton (int buttonType) override;
void positionDocumentWindowButtons (DocumentWindow&,
int titleBarX, int titleBarY, int titleBarW, int titleBarH,
Button* minimiseButton,
Button* maximiseButton,
Button* closeButton,
bool positionTitleBarButtonsOnLeft) override;
//==============================================================================
DropShadower* createDropShadowerForComponent (Component*) override;
//==============================================================================
void drawStretchableLayoutResizerBar (Graphics&, int w, int h, bool isVerticalBar,
bool isMouseOver, bool isMouseDragging) override;
//==============================================================================
void drawGroupComponentOutline (Graphics&, int w, int h, const String& text,
const Justification&, GroupComponent&) override;
//==============================================================================
int getTabButtonSpaceAroundImage() override;
int getTabButtonOverlap (int tabDepth) override;
int getTabButtonBestWidth (TabBarButton&, int tabDepth) override;
Rectangle<int> getTabButtonExtraComponentBounds (const TabBarButton&, Rectangle<int>& textArea, Component& extraComp) override;
void drawTabButton (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown) override;
Font getTabButtonFont (TabBarButton&, float height) override;
void drawTabButtonText (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown) override;
void drawTabbedButtonBarBackground (TabbedButtonBar&, Graphics&) override;
void drawTabAreaBehindFrontButton (TabbedButtonBar&, Graphics&, int w, int h) override;
void createTabButtonShape (TabBarButton&, Path&, bool isMouseOver, bool isMouseDown) override;
void fillTabButtonShape (TabBarButton&, Graphics&, const Path&, bool isMouseOver, bool isMouseDown) override;
Button* createTabBarExtrasButton() override;
//==============================================================================
void drawImageButton (Graphics&, Image*,
int imageX, int imageY, int imageW, int imageH,
const Colour& overlayColour, float imageOpacity, ImageButton&) override;
//==============================================================================
void drawTableHeaderBackground (Graphics&, TableHeaderComponent&) override;
void drawTableHeaderColumn (Graphics&, TableHeaderComponent&, const String& columnName,
int columnId, int width, int height, bool isMouseOver,
bool isMouseDown, int columnFlags) override;
//==============================================================================
void paintToolbarBackground (Graphics&, int width, int height, Toolbar&) override;
Button* createToolbarMissingItemsButton (Toolbar&) override;
void paintToolbarButtonBackground (Graphics&, int width, int height,
bool isMouseOver, bool isMouseDown,
ToolbarItemComponent&) override;
void paintToolbarButtonLabel (Graphics&, int x, int y, int width, int height,
const String& text, ToolbarItemComponent&) override;
//==============================================================================
void drawPropertyPanelSectionHeader (Graphics&, const String& name, bool isOpen, int width, int height) override;
void drawPropertyComponentBackground (Graphics&, int width, int height, PropertyComponent&) override;
void drawPropertyComponentLabel (Graphics&, int width, int height, PropertyComponent&) override;
Rectangle<int> getPropertyComponentContentPosition (PropertyComponent&) override;
int getPropertyPanelSectionHeaderHeight (const String& sectionTitle) override;
//==============================================================================
void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path& path, Image& cachedImage) override;
int getCallOutBoxBorderSize (const CallOutBox&) override;
float getCallOutBoxCornerSize (const CallOutBox&) override;
//==============================================================================
void drawLevelMeter (Graphics&, int width, int height, float level) override;
void drawKeymapChangeButton (Graphics&, int width, int height, Button&, const String& keyDescription) override;
//==============================================================================
Font getSidePanelTitleFont (SidePanel&) override;
Justification getSidePanelTitleJustification (SidePanel&) override;
Path getSidePanelDismissButtonShape (SidePanel&) override;
//==============================================================================
/** Draws a 3D raised (or indented) bevel using two colours.
The bevel is drawn inside the given rectangle, and greater bevel thicknesses
extend inwards.
The top-left colour is used for the top- and left-hand edges of the
bevel; the bottom-right colour is used for the bottom- and right-hand
edges.
If useGradient is true, then the bevel fades out to make it look more curved
and less angular. If sharpEdgeOnOutside is true, the outside of the bevel is
sharp, and it fades towards the centre; if sharpEdgeOnOutside is false, then
the centre edges are sharp and it fades towards the outside.
*/
static void drawBevel (Graphics&,
int x, int y, int width, int height,
int bevelThickness,
const Colour& topLeftColour = Colours::white,
const Colour& bottomRightColour = Colours::black,
bool useGradient = true,
bool sharpEdgeOnOutside = true);
/** Utility function to draw a shiny, glassy circle (for round LED-type buttons). */
static void drawGlassSphere (Graphics&, float x, float y, float diameter,
const Colour&, float outlineThickness) noexcept;
static void drawGlassPointer (Graphics&, float x, float y, float diameter,
const Colour&, float outlineThickness, int direction) noexcept;
/** Utility function to draw a shiny, glassy oblong (for text buttons). */
static void drawGlassLozenge (Graphics&,
float x, float y, float width, float height,
const Colour&, float outlineThickness, float cornerSize,
bool flatOnLeft, bool flatOnRight, bool flatOnTop, bool flatOnBottom) noexcept;
private:
//==============================================================================
std::unique_ptr<Drawable> folderImage, documentImage;
void drawShinyButtonShape (Graphics&,
float x, float y, float w, float h, float maxCornerSize,
const Colour&, float strokeWidth,
bool flatOnLeft, bool flatOnRight, bool flatOnTop, bool flatOnBottom) noexcept;
class GlassWindowButton;
class SliderLabelComp;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V2)
};
} // namespace juce

View File

@ -0,0 +1,645 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
LookAndFeel_V3::LookAndFeel_V3()
{
setColour (TreeView::selectedItemBackgroundColourId, Colour (0x301111ee));
const Colour textButtonColour (0xffeeeeff);
setColour (TextButton::buttonColourId, textButtonColour);
setColour (TextButton::buttonOnColourId, Colour (0xff888888));
setColour (ComboBox::buttonColourId, textButtonColour);
setColour (ComboBox::focusedOutlineColourId, textButtonColour);
setColour (TextEditor::outlineColourId, Colours::transparentBlack);
setColour (TabbedButtonBar::tabOutlineColourId, Colour (0x66000000));
setColour (TabbedComponent::outlineColourId, Colour (0x66000000));
setColour (Slider::trackColourId, Colour (0xbbffffff));
setColour (Slider::thumbColourId, Colour (0xffddddff));
setColour (BubbleComponent::backgroundColourId, Colour (0xeeeeeedd));
setColour (ScrollBar::thumbColourId, Colour::greyLevel (0.8f).contrasting().withAlpha (0.13f));
setColour (TableHeaderComponent::backgroundColourId, Colours::white.withAlpha (0.6f));
setColour (TableHeaderComponent::outlineColourId, Colours::black.withAlpha (0.5f));
}
LookAndFeel_V3::~LookAndFeel_V3() {}
bool LookAndFeel_V3::areScrollbarButtonsVisible() { return false; }
void LookAndFeel_V3::drawStretchableLayoutResizerBar (Graphics& g, int /*w*/, int /*h*/, bool /*isVerticalBar*/,
bool isMouseOver, bool isMouseDragging)
{
if (isMouseOver || isMouseDragging)
g.fillAll (Colours::yellow.withAlpha (0.4f));
}
void LookAndFeel_V3::drawScrollbar (Graphics& g, ScrollBar& scrollbar, int x, int y, int width, int height,
bool isScrollbarVertical, int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown)
{
Path thumbPath;
if (thumbSize > 0)
{
const float thumbIndent = (float) (isScrollbarVertical ? width : height) * 0.25f;
const float thumbIndentx2 = thumbIndent * 2.0f;
if (isScrollbarVertical)
thumbPath.addRoundedRectangle ((float) x + thumbIndent, (float) thumbStartPosition + thumbIndent,
(float) width - thumbIndentx2, (float) thumbSize - thumbIndentx2, ((float) width - thumbIndentx2) * 0.5f);
else
thumbPath.addRoundedRectangle ((float) thumbStartPosition + thumbIndent, (float) y + thumbIndent,
(float) thumbSize - thumbIndentx2, (float) height - thumbIndentx2, ((float) height - thumbIndentx2) * 0.5f);
}
Colour thumbCol (scrollbar.findColour (ScrollBar::thumbColourId, true));
if (isMouseOver || isMouseDown)
thumbCol = thumbCol.withMultipliedAlpha (2.0f);
g.setColour (thumbCol);
g.fillPath (thumbPath);
g.setColour (thumbCol.contrasting ((isMouseOver || isMouseDown) ? 0.2f : 0.1f));
g.strokePath (thumbPath, PathStrokeType (1.0f));
}
void LookAndFeel_V3::drawConcertinaPanelHeader (Graphics& g, const Rectangle<int>& area,
bool isMouseOver, bool /*isMouseDown*/,
ConcertinaPanel&, Component& panel)
{
const Colour bkg (Colours::grey);
g.setGradientFill (ColourGradient::vertical (Colours::white.withAlpha (isMouseOver ? 0.4f : 0.2f), (float) area.getY(),
Colours::darkgrey.withAlpha (0.1f), (float) area.getBottom()));
g.fillAll();
g.setColour (bkg.contrasting().withAlpha (0.1f));
g.fillRect (area.withHeight (1));
g.fillRect (area.withTop (area.getBottom() - 1));
g.setColour (bkg.contrasting());
g.setFont (Font ((float) area.getHeight() * 0.6f).boldened());
g.drawFittedText (panel.getName(), 4, 0, area.getWidth() - 6, area.getHeight(), Justification::centredLeft, 1);
}
static void drawButtonShape (Graphics& g, const Path& outline, Colour baseColour, float height)
{
const float mainBrightness = baseColour.getBrightness();
const float mainAlpha = baseColour.getFloatAlpha();
g.setGradientFill (ColourGradient::vertical (baseColour.brighter (0.2f), 0.0f,
baseColour.darker (0.25f), height));
g.fillPath (outline);
g.setColour (Colours::white.withAlpha (0.4f * mainAlpha * mainBrightness * mainBrightness));
g.strokePath (outline, PathStrokeType (1.0f), AffineTransform::translation (0.0f, 1.0f)
.scaled (1.0f, (height - 1.6f) / height));
g.setColour (Colours::black.withAlpha (0.4f * mainAlpha));
g.strokePath (outline, PathStrokeType (1.0f));
}
void LookAndFeel_V3::drawButtonBackground (Graphics& g, Button& button, const Colour& backgroundColour,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown)
{
Colour baseColour (backgroundColour.withMultipliedSaturation (button.hasKeyboardFocus (true) ? 1.3f : 0.9f)
.withMultipliedAlpha (button.isEnabled() ? 0.9f : 0.5f));
if (shouldDrawButtonAsDown || shouldDrawButtonAsHighlighted)
baseColour = baseColour.contrasting (shouldDrawButtonAsDown ? 0.2f : 0.1f);
const bool flatOnLeft = button.isConnectedOnLeft();
const bool flatOnRight = button.isConnectedOnRight();
const bool flatOnTop = button.isConnectedOnTop();
const bool flatOnBottom = button.isConnectedOnBottom();
const float width = (float) button.getWidth() - 1.0f;
const float height = (float) button.getHeight() - 1.0f;
if (width > 0 && height > 0)
{
const float cornerSize = 4.0f;
Path outline;
outline.addRoundedRectangle (0.5f, 0.5f, width, height, cornerSize, cornerSize,
! (flatOnLeft || flatOnTop),
! (flatOnRight || flatOnTop),
! (flatOnLeft || flatOnBottom),
! (flatOnRight || flatOnBottom));
drawButtonShape (g, outline, baseColour, height);
}
}
void LookAndFeel_V3::drawTableHeaderBackground (Graphics& g, TableHeaderComponent& header)
{
auto r = header.getLocalBounds();
auto outlineColour = header.findColour (TableHeaderComponent::outlineColourId);
g.setColour (outlineColour);
g.fillRect (r.removeFromBottom (1));
g.setColour (header.findColour (TableHeaderComponent::backgroundColourId));
g.fillRect (r);
g.setColour (outlineColour);
for (int i = header.getNumColumns (true); --i >= 0;)
g.fillRect (header.getColumnPosition (i).removeFromRight (1));
}
int LookAndFeel_V3::getTabButtonOverlap (int /*tabDepth*/) { return -1; }
int LookAndFeel_V3::getTabButtonSpaceAroundImage() { return 0; }
void LookAndFeel_V3::createTabTextLayout (const TabBarButton& button, float length, float depth,
Colour colour, TextLayout& textLayout)
{
Font font (depth * 0.5f);
font.setUnderline (button.hasKeyboardFocus (false));
AttributedString s;
s.setJustification (Justification::centred);
s.append (button.getButtonText().trim(), font, colour);
textLayout.createLayout (s, length);
}
void LookAndFeel_V3::drawTabButton (TabBarButton& button, Graphics& g, bool isMouseOver, bool isMouseDown)
{
const Rectangle<int> activeArea (button.getActiveArea());
const TabbedButtonBar::Orientation o = button.getTabbedButtonBar().getOrientation();
const Colour bkg (button.getTabBackgroundColour());
if (button.getToggleState())
{
g.setColour (bkg);
}
else
{
Point<int> p1, p2;
switch (o)
{
case TabbedButtonBar::TabsAtBottom: p1 = activeArea.getBottomLeft(); p2 = activeArea.getTopLeft(); break;
case TabbedButtonBar::TabsAtTop: p1 = activeArea.getTopLeft(); p2 = activeArea.getBottomLeft(); break;
case TabbedButtonBar::TabsAtRight: p1 = activeArea.getTopRight(); p2 = activeArea.getTopLeft(); break;
case TabbedButtonBar::TabsAtLeft: p1 = activeArea.getTopLeft(); p2 = activeArea.getTopRight(); break;
default: jassertfalse; break;
}
g.setGradientFill (ColourGradient (bkg.brighter (0.2f), p1.toFloat(),
bkg.darker (0.1f), p2.toFloat(), false));
}
g.fillRect (activeArea);
g.setColour (button.findColour (TabbedButtonBar::tabOutlineColourId));
Rectangle<int> r (activeArea);
if (o != TabbedButtonBar::TabsAtBottom) g.fillRect (r.removeFromTop (1));
if (o != TabbedButtonBar::TabsAtTop) g.fillRect (r.removeFromBottom (1));
if (o != TabbedButtonBar::TabsAtRight) g.fillRect (r.removeFromLeft (1));
if (o != TabbedButtonBar::TabsAtLeft) g.fillRect (r.removeFromRight (1));
const float alpha = button.isEnabled() ? ((isMouseOver || isMouseDown) ? 1.0f : 0.8f) : 0.3f;
Colour col (bkg.contrasting().withMultipliedAlpha (alpha));
if (TabbedButtonBar* bar = button.findParentComponentOfClass<TabbedButtonBar>())
{
TabbedButtonBar::ColourIds colID = button.isFrontTab() ? TabbedButtonBar::frontTextColourId
: TabbedButtonBar::tabTextColourId;
if (bar->isColourSpecified (colID))
col = bar->findColour (colID);
else if (isColourSpecified (colID))
col = findColour (colID);
}
const Rectangle<float> area (button.getTextArea().toFloat());
float length = area.getWidth();
float depth = area.getHeight();
if (button.getTabbedButtonBar().isVertical())
std::swap (length, depth);
TextLayout textLayout;
createTabTextLayout (button, length, depth, col, textLayout);
AffineTransform t;
switch (o)
{
case TabbedButtonBar::TabsAtLeft: t = t.rotated (MathConstants<float>::pi * -0.5f).translated (area.getX(), area.getBottom()); break;
case TabbedButtonBar::TabsAtRight: t = t.rotated (MathConstants<float>::pi * 0.5f).translated (area.getRight(), area.getY()); break;
case TabbedButtonBar::TabsAtTop:
case TabbedButtonBar::TabsAtBottom: t = t.translated (area.getX(), area.getY()); break;
default: jassertfalse; break;
}
g.addTransform (t);
textLayout.draw (g, Rectangle<float> (length, depth));
}
void LookAndFeel_V3::drawTabAreaBehindFrontButton (TabbedButtonBar& bar, Graphics& g, const int w, const int h)
{
const float shadowSize = 0.15f;
Rectangle<int> shadowRect, line;
ColourGradient gradient (Colours::black.withAlpha (bar.isEnabled() ? 0.08f : 0.04f), 0, 0,
Colours::transparentBlack, 0, 0, false);
switch (bar.getOrientation())
{
case TabbedButtonBar::TabsAtLeft:
gradient.point1.x = (float) w;
gradient.point2.x = (float) w * (1.0f - shadowSize);
shadowRect.setBounds ((int) gradient.point2.x, 0, w - (int) gradient.point2.x, h);
line.setBounds (w - 1, 0, 1, h);
break;
case TabbedButtonBar::TabsAtRight:
gradient.point2.x = (float) w * shadowSize;
shadowRect.setBounds (0, 0, (int) gradient.point2.x, h);
line.setBounds (0, 0, 1, h);
break;
case TabbedButtonBar::TabsAtTop:
gradient.point1.y = (float) h;
gradient.point2.y = (float) h * (1.0f - shadowSize);
shadowRect.setBounds (0, (int) gradient.point2.y, w, h - (int) gradient.point2.y);
line.setBounds (0, h - 1, w, 1);
break;
case TabbedButtonBar::TabsAtBottom:
gradient.point2.y = (float) h * shadowSize;
shadowRect.setBounds (0, 0, w, (int) gradient.point2.y);
line.setBounds (0, 0, w, 1);
break;
default: break;
}
g.setGradientFill (gradient);
g.fillRect (shadowRect.expanded (2, 2));
g.setColour (bar.findColour (TabbedButtonBar::tabOutlineColourId));
g.fillRect (line);
}
void LookAndFeel_V3::drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor)
{
if (textEditor.isEnabled())
{
if (textEditor.hasKeyboardFocus (true) && ! textEditor.isReadOnly())
{
g.setColour (textEditor.findColour (TextEditor::focusedOutlineColourId));
g.drawRect (0, 0, width, height, 2);
}
else
{
g.setColour (textEditor.findColour (TextEditor::outlineColourId));
g.drawRect (0, 0, width, height);
}
}
}
void LookAndFeel_V3::drawTreeviewPlusMinusBox (Graphics& g, const Rectangle<float>& area,
Colour backgroundColour, bool isOpen, bool isMouseOver)
{
Path p;
p.addTriangle (0.0f, 0.0f, 1.0f, isOpen ? 0.0f : 0.5f, isOpen ? 0.5f : 0.0f, 1.0f);
g.setColour (backgroundColour.contrasting().withAlpha (isMouseOver ? 0.5f : 0.3f));
g.fillPath (p, p.getTransformToScaleToFit (area.reduced (2, area.getHeight() / 4), true));
}
bool LookAndFeel_V3::areLinesDrawnForTreeView (TreeView&)
{
return false;
}
int LookAndFeel_V3::getTreeViewIndentSize (TreeView&)
{
return 20;
}
void LookAndFeel_V3::drawComboBox (Graphics& g, int width, int height, const bool /*isMouseButtonDown*/,
int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box)
{
g.fillAll (box.findColour (ComboBox::backgroundColourId));
if (box.isEnabled() && box.hasKeyboardFocus (false))
{
g.setColour (box.findColour (ComboBox::focusedOutlineColourId));
g.drawRect (0, 0, width, height, 2);
}
else
{
g.setColour (box.findColour (ComboBox::outlineColourId));
g.drawRect (0, 0, width, height);
}
const float arrowX = 0.3f;
const float arrowH = 0.2f;
const auto x = (float) buttonX;
const auto y = (float) buttonY;
const auto w = (float) buttonW;
const auto h = (float) buttonH;
Path p;
p.addTriangle (x + w * 0.5f, y + h * (0.45f - arrowH),
x + w * (1.0f - arrowX), y + h * 0.45f,
x + w * arrowX, y + h * 0.45f);
p.addTriangle (x + w * 0.5f, y + h * (0.55f + arrowH),
x + w * (1.0f - arrowX), y + h * 0.55f,
x + w * arrowX, y + h * 0.55f);
g.setColour (box.findColour (ComboBox::arrowColourId).withMultipliedAlpha (box.isEnabled() ? 1.0f : 0.3f));
g.fillPath (p);
}
void LookAndFeel_V3::drawLinearSlider (Graphics& g, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle style, Slider& slider)
{
g.fillAll (slider.findColour (Slider::backgroundColourId));
if (style == Slider::LinearBar || style == Slider::LinearBarVertical)
{
const float fx = (float) x, fy = (float) y, fw = (float) width, fh = (float) height;
Path p;
if (style == Slider::LinearBarVertical)
p.addRectangle (fx, sliderPos, fw, 1.0f + fh - sliderPos);
else
p.addRectangle (fx, fy, sliderPos - fx, fh);
auto baseColour = slider.findColour (Slider::thumbColourId)
.withMultipliedSaturation (slider.isEnabled() ? 1.0f : 0.5f)
.withMultipliedAlpha (0.8f);
g.setGradientFill (ColourGradient::vertical (baseColour.brighter (0.08f), 0.0f,
baseColour.darker (0.08f), (float) height));
g.fillPath (p);
g.setColour (baseColour.darker (0.2f));
if (style == Slider::LinearBarVertical)
g.fillRect (fx, sliderPos, fw, 1.0f);
else
g.fillRect (sliderPos, fy, 1.0f, fh);
}
else
{
drawLinearSliderBackground (g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, style, slider);
drawLinearSliderThumb (g, x, y, width, height, sliderPos, minSliderPos, maxSliderPos, style, slider);
}
}
void LookAndFeel_V3::drawLinearSliderBackground (Graphics& g, int x, int y, int width, int height,
float /*sliderPos*/,
float /*minSliderPos*/,
float /*maxSliderPos*/,
const Slider::SliderStyle /*style*/, Slider& slider)
{
const float sliderRadius = (float) (getSliderThumbRadius (slider) - 2);
const Colour trackColour (slider.findColour (Slider::trackColourId));
const Colour gradCol1 (trackColour.overlaidWith (Colour (slider.isEnabled() ? 0x13000000 : 0x09000000)));
const Colour gradCol2 (trackColour.overlaidWith (Colour (0x06000000)));
Path indent;
if (slider.isHorizontal())
{
auto iy = (float) y + (float) height * 0.5f - sliderRadius * 0.5f;
g.setGradientFill (ColourGradient::vertical (gradCol1, iy, gradCol2, iy + sliderRadius));
indent.addRoundedRectangle ((float) x - sliderRadius * 0.5f, iy, (float) width + sliderRadius, sliderRadius, 5.0f);
}
else
{
auto ix = (float) x + (float) width * 0.5f - sliderRadius * 0.5f;
g.setGradientFill (ColourGradient::horizontal (gradCol1, ix, gradCol2, ix + sliderRadius));
indent.addRoundedRectangle (ix, (float) y - sliderRadius * 0.5f, sliderRadius, (float) height + sliderRadius, 5.0f);
}
g.fillPath (indent);
g.setColour (trackColour.contrasting (0.5f));
g.strokePath (indent, PathStrokeType (0.5f));
}
void LookAndFeel_V3::drawPopupMenuBackground (Graphics& g, int width, int height)
{
g.fillAll (findColour (PopupMenu::backgroundColourId));
ignoreUnused (width, height);
#if ! JUCE_MAC
g.setColour (findColour (PopupMenu::textColourId).withAlpha (0.6f));
g.drawRect (0, 0, width, height);
#endif
}
void LookAndFeel_V3::drawMenuBarBackground (Graphics& g, int width, int height,
bool, MenuBarComponent& menuBar)
{
auto colour = menuBar.findColour (PopupMenu::backgroundColourId);
Rectangle<int> r (width, height);
g.setColour (colour.contrasting (0.15f));
g.fillRect (r.removeFromTop (1));
g.fillRect (r.removeFromBottom (1));
g.setGradientFill (ColourGradient::vertical (colour, 0, colour.darker (0.08f), (float) height));
g.fillRect (r);
}
void LookAndFeel_V3::drawKeymapChangeButton (Graphics& g, int width, int height,
Button& button, const String& keyDescription)
{
const Colour textColour (button.findColour (0x100ad01 /*KeyMappingEditorComponent::textColourId*/, true));
if (keyDescription.isNotEmpty())
{
if (button.isEnabled())
{
g.setColour (textColour.withAlpha (button.isDown() ? 0.4f : (button.isOver() ? 0.2f : 0.1f)));
g.fillRoundedRectangle (button.getLocalBounds().toFloat(), 4.0f);
g.drawRoundedRectangle (button.getLocalBounds().toFloat(), 4.0f, 1.0f);
}
g.setColour (textColour);
g.setFont ((float) height * 0.6f);
g.drawFittedText (keyDescription, 4, 0, width - 8, height, Justification::centred, 1);
}
else
{
const float thickness = 7.0f;
const float indent = 22.0f;
Path p;
p.addEllipse (0.0f, 0.0f, 100.0f, 100.0f);
p.addRectangle (indent, 50.0f - thickness, 100.0f - indent * 2.0f, thickness * 2.0f);
p.addRectangle (50.0f - thickness, indent, thickness * 2.0f, 50.0f - indent - thickness);
p.addRectangle (50.0f - thickness, 50.0f + thickness, thickness * 2.0f, 50.0f - indent - thickness);
p.setUsingNonZeroWinding (false);
g.setColour (textColour.darker(0.1f).withAlpha (button.isDown() ? 0.7f : (button.isOver() ? 0.5f : 0.3f)));
g.fillPath (p, p.getTransformToScaleToFit (2.0f, 2.0f, (float) width - 4.0f, (float) height - 4.0f, true));
}
if (button.hasKeyboardFocus (false))
{
g.setColour (textColour.withAlpha (0.4f));
g.drawRect (0, 0, width, height);
}
}
class LookAndFeel_V3_DocumentWindowButton : public Button
{
public:
LookAndFeel_V3_DocumentWindowButton (const String& name, Colour c, const Path& normal, const Path& toggled)
: Button (name), colour (c), normalShape (normal), toggledShape (toggled)
{
}
void paintButton (Graphics& g, bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override
{
Colour background (Colours::grey);
if (ResizableWindow* rw = findParentComponentOfClass<ResizableWindow>())
background = rw->getBackgroundColour();
const float cx = (float) getWidth() * 0.5f, cy = (float) getHeight() * 0.5f;
const float diam = jmin (cx, cy) * (shouldDrawButtonAsDown ? 0.60f : 0.65f);
g.setColour (background);
g.fillEllipse (cx - diam, cy - diam, diam * 2.0f, diam * 2.0f);
Colour c (background.contrasting (colour, 0.6f));
if (! isEnabled())
c = c.withAlpha (0.6f);
else if (shouldDrawButtonAsHighlighted)
c = c.brighter();
g.setColour (c);
g.drawEllipse (cx - diam, cy - diam, diam * 2.0f, diam * 2.0f, diam * 0.2f);
Path& p = getToggleState() ? toggledShape : normalShape;
float scale = 0.55f;
g.fillPath (p, p.getTransformToScaleToFit (cx - diam * scale, cy - diam * scale,
diam * 2.0f * scale, diam * 2.0f * scale, true));
}
private:
Colour colour;
Path normalShape, toggledShape;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V3_DocumentWindowButton)
};
Button* LookAndFeel_V3::createDocumentWindowButton (int buttonType)
{
Path shape;
const float crossThickness = 0.25f;
if (buttonType == DocumentWindow::closeButton)
{
shape.addLineSegment (Line<float> (0.0f, 0.0f, 1.0f, 1.0f), crossThickness * 1.4f);
shape.addLineSegment (Line<float> (1.0f, 0.0f, 0.0f, 1.0f), crossThickness * 1.4f);
return new LookAndFeel_V3_DocumentWindowButton ("close", Colour (0xffdd1100), shape, shape);
}
if (buttonType == DocumentWindow::minimiseButton)
{
shape.addLineSegment (Line<float> (0.0f, 0.5f, 1.0f, 0.5f), crossThickness);
return new LookAndFeel_V3_DocumentWindowButton ("minimise", Colour (0xffaa8811), shape, shape);
}
if (buttonType == DocumentWindow::maximiseButton)
{
shape.addLineSegment (Line<float> (0.5f, 0.0f, 0.5f, 1.0f), crossThickness);
shape.addLineSegment (Line<float> (0.0f, 0.5f, 1.0f, 0.5f), crossThickness);
Path fullscreenShape;
fullscreenShape.startNewSubPath (45.0f, 100.0f);
fullscreenShape.lineTo (0.0f, 100.0f);
fullscreenShape.lineTo (0.0f, 0.0f);
fullscreenShape.lineTo (100.0f, 0.0f);
fullscreenShape.lineTo (100.0f, 45.0f);
fullscreenShape.addRectangle (45.0f, 45.0f, 100.0f, 100.0f);
PathStrokeType (30.0f).createStrokedPath (fullscreenShape, fullscreenShape);
return new LookAndFeel_V3_DocumentWindowButton ("maximise", Colour (0xff119911), shape, fullscreenShape);
}
jassertfalse;
return nullptr;
}
Path LookAndFeel_V3::getTickShape (const float height)
{
static const unsigned char pathData[]
= { 110,109,32,210,202,64,126,183,148,64,108,39,244,247,64,245,76,124,64,108,178,131,27,65,246,76,252,64,108,175,242,4,65,246,76,252,
64,108,236,5,68,65,0,0,160,180,108,240,150,90,65,21,136,52,63,108,48,59,16,65,0,0,32,65,108,32,210,202,64,126,183,148,64, 99,101,0,0 };
Path p;
p.loadPathFromData (pathData, sizeof (pathData));
p.scaleToFit (0, 0, height * 2.0f, height, true);
return p;
}
Path LookAndFeel_V3::getCrossShape (const float height)
{
static const unsigned char pathData[]
= { 110,109,88,57,198,65,29,90,171,65,108,63,53,154,65,8,172,126,65,108,76,55,198,65,215,163,38,65,108,141,151,175,65,82,184,242,64,108,117,147,131,65,90,100,81,65,108,184,30,47,65,82,184,242,64,108,59,223,1,65,215,163,38,65,108,84,227,89,65,8,172,126,65,
108,35,219,1,65,29,90,171,65,108,209,34,47,65,231,251,193,65,108,117,147,131,65,207,247,149,65,108,129,149,175,65,231,251,193,65,99,101,0,0 };
Path p;
p.loadPathFromData (pathData, sizeof (pathData));
p.scaleToFit (0, 0, height * 2.0f, height, true);
return p;
}
} // namespace juce

View File

@ -0,0 +1,98 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
The latest JUCE look-and-feel style, as introduced in 2013.
@see LookAndFeel, LookAndFeel_V1, LookAndFeel_V2
@tags{GUI}
*/
class JUCE_API LookAndFeel_V3 : public LookAndFeel_V2
{
public:
LookAndFeel_V3();
~LookAndFeel_V3() override;
//==============================================================================
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawTableHeaderBackground (Graphics&, TableHeaderComponent&) override;
void drawTreeviewPlusMinusBox (Graphics&, const Rectangle<float>& area,
Colour backgroundColour, bool isOpen, bool isMouseOver) override;
bool areLinesDrawnForTreeView (TreeView&) override;
int getTreeViewIndentSize (TreeView&) override;
Button* createDocumentWindowButton (int buttonType) override;
void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH, ComboBox& box) override;
void drawKeymapChangeButton (Graphics&, int width, int height, Button& button, const String& keyDescription) override;
void drawPopupMenuBackground (Graphics&, int width, int height) override;
void drawMenuBarBackground (Graphics&, int width, int height, bool, MenuBarComponent&) override;
int getTabButtonOverlap (int tabDepth) override;
int getTabButtonSpaceAroundImage() override;
void drawTabButton (TabBarButton&, Graphics&, bool isMouseOver, bool isMouseDown) override;
void drawTabAreaBehindFrontButton (TabbedButtonBar& bar, Graphics& g, int w, int h) override;
void drawTextEditorOutline (Graphics&, int width, int height, TextEditor&) override;
void drawStretchableLayoutResizerBar (Graphics&, int w, int h, bool isVerticalBar, bool isMouseOver, bool isMouseDragging) override;
bool areScrollbarButtonsVisible() override;
void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height, bool isScrollbarVertical,
int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown) override;
void drawLinearSlider (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawLinearSliderBackground (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawConcertinaPanelHeader (Graphics&, const Rectangle<int>& area, bool isMouseOver, bool isMouseDown,
ConcertinaPanel&, Component&) override;
Path getTickShape (float height) override;
Path getCrossShape (float height) override;
static void createTabTextLayout (const TabBarButton& button, float length, float depth, Colour colour, TextLayout&);
private:
Image backgroundTexture;
Colour backgroundTextureBaseColour;
};
} // namespace juce

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,258 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
The latest JUCE look-and-feel style, as introduced in 2017.
@see LookAndFeel, LookAndFeel_V1, LookAndFeel_V2, LookAndFeel_V3
@tags{GUI}
*/
class JUCE_API LookAndFeel_V4 : public LookAndFeel_V3
{
public:
/**
A struct containing the set of colours to apply to the GUI
*/
class ColourScheme
{
public:
/** The standard set of colours to use. */
enum UIColour
{
windowBackground = 0,
widgetBackground,
menuBackground,
outline,
defaultText,
defaultFill,
highlightedText,
highlightedFill,
menuText,
numColours
};
template <typename... ItemColours>
ColourScheme (ItemColours... coloursToUse)
{
static_assert (sizeof... (coloursToUse) == numColours, "Must supply one colour for each UIColour item");
const Colour c[] = { Colour (coloursToUse)... };
for (int i = 0; i < numColours; ++i)
palette[i] = c[i];
}
ColourScheme (const ColourScheme&) = default;
ColourScheme& operator= (const ColourScheme&) = default;
/** Returns a colour from the scheme */
Colour getUIColour (UIColour colourToGet) const noexcept;
/** Sets a scheme colour. */
void setUIColour (UIColour colourToSet, Colour newColour) noexcept;
/** Returns true if two ColourPalette objects contain the same colours. */
bool operator== (const ColourScheme&) const noexcept;
/** Returns false if two ColourPalette objects contain the same colours. */
bool operator!= (const ColourScheme&) const noexcept;
private:
Colour palette[numColours];
};
//==============================================================================
/** Creates a LookAndFeel_V4 object with a default colour scheme. */
LookAndFeel_V4();
/** Creates a LookAndFeel_V4 object with a given colour scheme. */
LookAndFeel_V4 (ColourScheme);
/** Destructor. */
~LookAndFeel_V4() override;
//==============================================================================
void setColourScheme (ColourScheme);
ColourScheme& getCurrentColourScheme() noexcept { return currentColourScheme; }
static ColourScheme getDarkColourScheme();
static ColourScheme getMidnightColourScheme();
static ColourScheme getGreyColourScheme();
static ColourScheme getLightColourScheme();
//==============================================================================
Button* createDocumentWindowButton (int) override;
void positionDocumentWindowButtons (DocumentWindow&, int, int, int, int, Button*, Button*, Button*, bool) override;
void drawDocumentWindowTitleBar (DocumentWindow&, Graphics&, int, int, int, int, const Image*, bool) override;
//==============================================================================
Font getTextButtonFont (TextButton&, int buttonHeight) override;
void drawButtonBackground (Graphics&, Button&, const Colour& backgroundColour,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawToggleButton (Graphics&, ToggleButton&,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void drawTickBox (Graphics&, Component&,
float x, float y, float w, float h,
bool ticked, bool isEnabled,
bool shouldDrawButtonAsHighlighted, bool shouldDrawButtonAsDown) override;
void changeToggleButtonWidthToFitText (ToggleButton&) override;
//==============================================================================
AlertWindow* createAlertWindow (const String& title, const String& message,
const String& button1,
const String& button2,
const String& button3,
MessageBoxIconType iconType,
int numButtons, Component* associatedComponent) override;
void drawAlertBox (Graphics&, AlertWindow&, const Rectangle<int>& textArea, TextLayout&) override;
int getAlertWindowButtonHeight() override;
Font getAlertWindowTitleFont() override;
Font getAlertWindowMessageFont() override;
Font getAlertWindowFont() override;
//==============================================================================
void drawProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String& textToShow) override;
bool isProgressBarOpaque (ProgressBar&) override { return false; }
//==============================================================================
int getDefaultScrollbarWidth() override;
void drawScrollbar (Graphics&, ScrollBar&, int x, int y, int width, int height, bool isScrollbarVertical,
int thumbStartPosition, int thumbSize, bool isMouseOver, bool isMouseDown) override;
//==============================================================================
Path getTickShape (float height) override;
Path getCrossShape (float height) override;
//==============================================================================
void fillTextEditorBackground (Graphics&, int width, int height, TextEditor&) override;
void drawTextEditorOutline (Graphics&, int width, int height, TextEditor&) override;
//==============================================================================
Button* createFileBrowserGoUpButton() override;
void layoutFileBrowserComponent (FileBrowserComponent&,
DirectoryContentsDisplayComponent*,
FilePreviewComponent*,
ComboBox* currentPathBox,
TextEditor* filenameBox,
Button* goUpButton) override;
void drawFileBrowserRow (Graphics&, int width, int height,
const File& file, const String& filename, Image* icon,
const String& fileSizeDescription, const String& fileTimeDescription,
bool isDirectory, bool isItemSelected, int itemIndex,
DirectoryContentsDisplayComponent&) override;
//==============================================================================
void drawPopupMenuItem (Graphics&, const Rectangle<int>& area,
bool isSeparator, bool isActive, bool isHighlighted, bool isTicked, bool hasSubMenu,
const String& text, const String& shortcutKeyText,
const Drawable* icon, const Colour* textColour) override;
void getIdealPopupMenuItemSize (const String& text, bool isSeparator, int standardMenuItemHeight,
int& idealWidth, int& idealHeight) override;
void drawMenuBarBackground (Graphics&, int width, int height, bool isMouseOverBar, MenuBarComponent&) override;
void drawMenuBarItem (Graphics&, int width, int height,
int itemIndex, const String& itemText,
bool isMouseOverItem, bool isMenuOpen, bool isMouseOverBar,
MenuBarComponent&) override;
//==============================================================================
void drawComboBox (Graphics&, int width, int height, bool isButtonDown,
int buttonX, int buttonY, int buttonW, int buttonH,
ComboBox&) override;
Font getComboBoxFont (ComboBox&) override;
void positionComboBoxText (ComboBox&, Label&, Drawable*) override;
//==============================================================================
int getSliderThumbRadius (Slider&) override;
void drawLinearSlider (Graphics&, int x, int y, int width, int height,
float sliderPos, float minSliderPos, float maxSliderPos,
const Slider::SliderStyle, Slider&) override;
void drawRotarySlider (Graphics&, int x, int y, int width, int height,
float sliderPosProportional, float rotaryStartAngle,
float rotaryEndAngle, Slider&) override;
void drawPointer (Graphics&, float x, float y, float diameter,
const Colour&, int direction) noexcept;
Label* createSliderTextBox (Slider&) override;
//==============================================================================
void drawTooltip (Graphics&, const String& text, int width, int height) override;
//==============================================================================
void drawConcertinaPanelHeader (Graphics&, const Rectangle<int>& area,
bool isMouseOver, bool isMouseDown,
ConcertinaPanel&, Component& panel) override;
//==============================================================================
void drawLevelMeter (Graphics&, int, int, float) override;
//==============================================================================
void paintToolbarBackground (Graphics&, int width, int height, Toolbar&) override;
void paintToolbarButtonLabel (Graphics&, int x, int y, int width, int height,
const String& text, ToolbarItemComponent&) override;
//==============================================================================
void drawPropertyPanelSectionHeader (Graphics&, const String& name, bool isOpen, int width, int height) override;
void drawPropertyComponentBackground (Graphics&, int width, int height, PropertyComponent&) override;
void drawPropertyComponentLabel (Graphics&, int width, int height, PropertyComponent&) override;
Rectangle<int> getPropertyComponentContentPosition (PropertyComponent&) override;
//==============================================================================
void drawCallOutBoxBackground (CallOutBox&, Graphics&, const Path&, Image&) override;
//==============================================================================
void drawStretchableLayoutResizerBar (Graphics&, int, int, bool, bool, bool) override;
private:
//==============================================================================
void drawLinearProgressBar (Graphics&, ProgressBar&, int width, int height, double progress, const String&);
void drawCircularProgressBar (Graphics&, ProgressBar&, const String&);
int getPropertyComponentIndent (PropertyComponent&);
//==============================================================================
void initialiseColours();
ColourScheme currentColourScheme;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (LookAndFeel_V4)
};
} // namespace juce