2022-04-11 17:23:10 +00:00
// SPDX-License-Identifier: GPLv3-or-later WITH Appstore-exception
// Copyright (C) 2020 Jesse Chappell
# include "CustomLookAndFeel.h"
//==============================================================================
CustomLookAndFeel : : CustomLookAndFeel ( )
{
// setColour (mainBackgroundColourId, Colour::greyLevel (0.8f));
//DBG("Sonolook and feel");
setUsingNativeAlertWindows ( true ) ;
fontScale = 1.0 ;
setColourScheme ( getDarkColourScheme ( ) ) ;
getCurrentColourScheme ( ) . setUIColour ( ColourScheme : : UIColour : : windowBackground , Colour : : fromFloatRGBA ( 0.0 , 0.0 , 0.0 , 1.0 ) ) ;
getCurrentColourScheme ( ) . setUIColour ( ColourScheme : : UIColour : : widgetBackground , Colour : : fromFloatRGBA ( 0.1 , 0.1 , 0.1 , 1.0 ) ) ;
getCurrentColourScheme ( ) . setUIColour ( ColourScheme : : UIColour : : outline , Colour : : fromFloatRGBA ( 0.3 , 0.3 , 0.3 , 0.5 ) ) ;
setColour ( Label : : textColourId , Colour ( 0xffcccccc ) ) ;
setColour ( Label : : textWhenEditingColourId , Colour ( 0xffe9e9e9 ) ) ;
setColour ( ResizableWindow : : backgroundColourId , Colour ( 0xff111111 ) ) ;
//setColour (TextButton::buttonColourId, Colour (0xff363636));
setColour ( TextButton : : buttonColourId , Colour : : fromFloatRGBA ( 0.15 , 0.15 , 0.15 , 0.7 ) ) ; // old one
//setColour (TextButton::buttonColourId, Colour::fromFloatRGBA(0.15, 0.15, 0.15, 0.0));
//setColour (TextButton::buttonOnColourId, Colour (0xff3d70c8));
setColour ( TextButton : : buttonOnColourId , Colour : : fromFloatRGBA ( 0.5 , 0.4 , 0.6 , 0.8 ) ) ;
setColour ( TextButton : : textColourOnId , Colour ( 0xddcccccc ) ) ;
setColour ( TextButton : : textColourOffId , Colour ( 0xdde9e9e9 ) ) ;
setColour ( ToggleButton : : textColourId , Colour ( 0xddcccccc ) ) ;
2022-04-13 23:24:44 +00:00
setColour ( ScrollBar : : ColourIds : : thumbColourId , Colour : : fromFloatRGBA ( 0.7 , 0.7 , 0.7 , 0.7 ) ) ;
2022-04-11 17:23:10 +00:00
//setColour (ComboBox::backgroundColourId, Colour (0xff161616));
setColour ( ComboBox : : backgroundColourId , Colour : : fromFloatRGBA ( 0.15 , 0.15 , 0.15 , 0.7 ) ) ;
setColour ( ComboBox : : textColourId , Colour ( 0xffe9e9e9 ) ) ;
setColour ( ComboBox : : outlineColourId , Colour : : fromFloatRGBA ( 0.3 , 0.3 , 0.3 , 0.5 ) ) ;
setColour ( TextEditor : : backgroundColourId , Colour ( 0xff050505 ) ) ;
setColour ( TextEditor : : textColourId , Colour ( 0xffe9e9e9 ) ) ;
setColour ( TextEditor : : highlightColourId , Colour ( 0xff5959f9 ) ) ;
setColour ( TextEditor : : outlineColourId , Colour : : fromFloatRGBA ( 0.3 , 0.3 , 0.3 , 0.5 ) ) ;
setColour ( TextEditor : : focusedOutlineColourId , Colour : : fromFloatRGBA ( 0.5 , 0.5 , 0.5 , 0.7 ) ) ;
setColour ( Slider : : backgroundColourId , Colour : : fromFloatRGBA ( 0.2 , 0.2 , 0.2 , 1.0 ) ) ;
setColour ( Slider : : rotarySliderOutlineColourId , Colour : : fromFloatRGBA ( 0.2 , 0.2 , 0.2 , 1.0 ) ) ;
setColour ( Slider : : textBoxTextColourId , Colour ( 0xddcccccc ) ) ;
setColour ( Slider : : textBoxBackgroundColourId , Colour : : fromFloatRGBA ( 0.05 , 0.05 , 0.05 , 1.0 ) ) ;
setColour ( Slider : : textBoxHighlightColourId , Colour ( 0xaa555555 ) ) ;
setColour ( Slider : : textBoxOutlineColourId , Colour : : fromFloatRGBA ( 0.3 , 0.3 , 0.3 , 0.5 ) ) ;
setColour ( Slider : : trackColourId , Colour : : fromFloatRGBA ( 0.1 , 0.4 , 0.6 , 0.8 ) ) ;
setColour ( Slider : : thumbColourId , Colour : : fromFloatRGBA ( 0.5 , 0.4 , 0.6 , 0.9 ) ) ;
//setColour (Slider::thumbColourId, Colour::fromFloatRGBA(0.2, 0.5, 0.7, 1.0));
setColour ( Slider : : rotarySliderFillColourId , Colour : : fromFloatRGBA ( 0.5 , 0.4 , 0.6 , 0.9 ) ) ;
2022-04-13 23:24:44 +00:00
setColour ( TabbedButtonBar : : tabOutlineColourId , Colour : : fromFloatRGBA ( 0.3 , 0.3 , 0.3 , 0.6 ) ) ;
2022-04-11 17:23:10 +00:00
setColour ( ListBox : : backgroundColourId , Colour : : fromFloatRGBA ( 0.15 , 0.15 , 0.15 , 0.7 ) ) ;
setColour ( ListBox : : outlineColourId , Colour : : fromFloatRGBA ( 0.3 , 0.3 , 0.3 , 0.5 ) ) ;
setColour ( BubbleComponent : : backgroundColourId , Colour : : fromFloatRGBA ( 0.25 , 0.25 , 0.25 , 1.0 ) ) ;
setColour ( BubbleComponent : : outlineColourId , Colour : : fromFloatRGBA ( 0.4 , 0.4 , 0.4 , 0.5 ) ) ;
//setColour (TooltipWindow::textColourId, Colour(0xeecccccc));
setColour ( TooltipWindow : : textColourId , Colour ( 0xee222222 ) ) ;
setColour ( TooltipWindow : : backgroundColourId , Colour ( 0xeeffff99 ) ) ;
setColour ( PopupMenu : : backgroundColourId , Colour : : fromFloatRGBA ( 0.2 , 0.2 , 0.2 , 1.0 ) ) ;
setColour ( PopupMenu : : highlightedBackgroundColourId , Colour : : fromFloatRGBA ( 0.35 , 0.35 , 0.4 , 1.0 ) ) ;
setColour ( SidePanel : : backgroundColour , Colour : : fromFloatRGBA ( 0.17 , 0.17 , 0.17 , 1.0 ) ) ;
//setColour (SonoDrawableButton::overOverlayColourId, Colour::fromFloatRGBA(0.8, 0.8, 0.8, 0.08));
//setColour (SonoDrawableButton::downOverlayColourId, Colour::fromFloatRGBA(0.8, 0.8, 0.8, 0.3));
setColour ( DrawableButton : : textColourId , Colour ( 0xffb9b9b9 ) ) ;
setColour ( DrawableButton : : textColourOnId , Colour ( 0xffe9e9e9 ) ) ;
//setColour (DrawableButton::backgroundColourId, Colour (0xffb9b9b9));
setColour ( DrawableButton : : backgroundOnColourId , Colour : : fromFloatRGBA ( 0.5 , 0.4 , 0.6 , 0.8 ) ) ;
//setColour (ConfigurationRowView::backgroundColourId, Colour::fromFloatRGBA(0.05, 0.05, 0.05, 1.0));
//setColour (ConfigurationRowView::selectedBackgroundColourId, Colour::fromFloatRGBA(0.15, 0.15, 0.15, 1.0));
setColour ( ToggleButton : : tickColourId , Colour : : fromFloatRGBA ( 0.4 , 0.8 , 1.0 , 1.0 ) ) ;
setColour ( DirectoryContentsDisplayComponent : : highlightColourId , Colour : : fromFloatRGBA ( 0.1 , 0.4 , 0.6 , 0.9 ) ) ;
setColour ( DirectoryContentsDisplayComponent : : textColourId , Colour ( 0xffe9e9e9 ) ) ;
// setColour (Label::textColourId, Colour (0xffe9e9e9));
//myFont = Typeface::createSystemTypefaceFor (BinaryData::DejaVuSans_ttf, BinaryData::DejaVuSans_ttfSize);
//setDefaultSansSerifTypefaceName("Gill Sans");
//setDefaultSansSerifTypefaceName("Arial Unicode MS");
//setDefaultSansSerifTypefaceName(myFont.getTypefaceName());
//myFont = Typeface::createSystemTypefaceFor (BinaryData::GillSans_ttc, BinaryData::GillSans_ttcSize);
myFont = Font ( 16 * fontScale ) ;
if ( auto * deflnf = dynamic_cast < CustomLookAndFeel * > ( & LookAndFeel : : getDefaultLookAndFeel ( ) ) ) {
setLanguageCode ( deflnf - > languageCode ) ;
}
//DBG("Myfont name " << myFont.getTypefaceName());
}
void CustomLookAndFeel : : setLanguageCode ( const String & lang )
{
languageCode = lang ;
if ( lang . startsWith ( " zh " ) ) {
fontScale = 1.0f ;
}
else if ( lang . startsWith ( " ko " ) ) {
fontScale = 1.15f ;
}
}
Font CustomLookAndFeel : : getMenuBarFont ( MenuBarComponent & menuBar , int /*itemIndex*/ , const String & /*itemText*/ )
{
return Font ( menuBar . getHeight ( ) * 0.7f ) ;
}
//==============================================================================
void CustomLookAndFeel : : drawCallOutBoxBackground ( CallOutBox & box , Graphics & g ,
const Path & path , Image & cachedImage )
{
if ( cachedImage . isNull ( ) )
{
cachedImage = Image ( Image : : ARGB , box . getWidth ( ) , box . getHeight ( ) , true ) ;
Graphics g2 ( cachedImage ) ;
DropShadow ( Colours : : black . withAlpha ( 0.7f ) , 8 , Point < int > ( 0 , 2 ) ) . drawForPath ( g2 , path ) ;
}
g . setColour ( Colours : : black ) ;
g . drawImageAt ( cachedImage , 0 , 0 ) ;
//g.setColour (getCurrentColourScheme().getUIColour (ColourScheme::UIColour::widgetBackground).withAlpha (0.8f));
g . setColour ( getCurrentColourScheme ( ) . getUIColour ( ColourScheme : : UIColour : : widgetBackground ) ) ;
g . fillPath ( path ) ;
g . setColour ( getCurrentColourScheme ( ) . getUIColour ( ColourScheme : : UIColour : : outline ) . withAlpha ( 0.8f ) ) ;
g . strokePath ( path , PathStrokeType ( 1.0f ) ) ;
}
int CustomLookAndFeel : : getTabButtonBestWidth ( TabBarButton & button , int depth )
{
return 250 ; // 120;
}
int CustomLookAndFeel : : getTabButtonSpaceAroundImage ( ) {
return 0 ;
}
static Colour getTabBackgroundColour ( TabBarButton & button )
{
const Colour bkg ( button . findColour ( TabbedComponent : : backgroundColourId ) . contrasting ( 0.15f ) ) ;
if ( button . isFrontTab ( ) )
return bkg . overlaidWith ( Colours : : yellow . withAlpha ( 0.8f ) ) ;
return bkg ;
}
Rectangle < int > CustomLookAndFeel : : getTabButtonExtraComponentBounds ( const TabBarButton & button , Rectangle < int > & textArea , Component & comp )
{
Rectangle < int > extraComp ;
auto orientation = button . getTabbedButtonBar ( ) . getOrientation ( ) ;
if ( button . getExtraComponentPlacement ( ) = = TabBarButton : : beforeText )
{
switch ( orientation )
{
case TabbedButtonBar : : TabsAtBottom :
case TabbedButtonBar : : TabsAtTop : extraComp = textArea . removeFromLeft ( comp . getWidth ( ) ) ; break ;
case TabbedButtonBar : : TabsAtLeft : extraComp = textArea . removeFromBottom ( comp . getHeight ( ) ) ; break ;
case TabbedButtonBar : : TabsAtRight : extraComp = textArea . removeFromTop ( comp . getHeight ( ) ) ; break ;
default : jassertfalse ; break ;
}
}
else if ( button . getExtraComponentPlacement ( ) = = TabBarButton : : afterText )
{
switch ( orientation )
{
case TabbedButtonBar : : TabsAtBottom :
case TabbedButtonBar : : TabsAtTop : extraComp = textArea . removeFromRight ( comp . getWidth ( ) ) ; break ;
case TabbedButtonBar : : TabsAtLeft : extraComp = textArea . removeFromTop ( comp . getHeight ( ) ) ; break ;
case TabbedButtonBar : : TabsAtRight : extraComp = textArea . removeFromBottom ( comp . getHeight ( ) ) ; break ;
default : jassertfalse ; break ;
}
}
else if ( button . getExtraComponentPlacement ( ) = = TabBarButton : : aboveText )
{
switch ( orientation )
{
case TabbedButtonBar : : TabsAtBottom :
case TabbedButtonBar : : TabsAtTop : extraComp = textArea . removeFromTop ( comp . getHeight ( ) ) ; break ;
case TabbedButtonBar : : TabsAtLeft : extraComp = textArea . removeFromTop ( comp . getHeight ( ) ) ; break ;
case TabbedButtonBar : : TabsAtRight : extraComp = textArea . removeFromTop ( comp . getHeight ( ) ) ; break ;
default : jassertfalse ; break ;
}
// DBG("Extra comp bounds: " << extraComp.toString())
extraComp . translate ( 0 , 3 ) ;
//DBG("After Extra comp bounds: " << extraComp.toString())
}
else if ( button . getExtraComponentPlacement ( ) = = TabBarButton : : belowText )
{
switch ( orientation )
{
case TabbedButtonBar : : TabsAtBottom :
case TabbedButtonBar : : TabsAtTop : extraComp = textArea . removeFromBottom ( comp . getHeight ( ) ) ; break ;
case TabbedButtonBar : : TabsAtLeft : extraComp = textArea . removeFromBottom ( comp . getHeight ( ) ) ; break ;
case TabbedButtonBar : : TabsAtRight : extraComp = textArea . removeFromBottom ( comp . getHeight ( ) ) ; break ;
default : jassertfalse ; break ;
}
}
return extraComp ;
}
void CustomLookAndFeel : : createTabTextLayout ( const TabBarButton & button , float length , float depth ,
Colour colour , TextLayout & textLayout )
{
2022-04-18 19:11:22 +00:00
float hscale = 0.6f ;
# if JUCE_IOS
hscale = 0.5f ;
# endif
float fontsize = button . getExtraComponent ( ) ! = nullptr ? jmin ( depth , 32.0f ) * hscale : jmin ( depth , 32.0f ) * hscale ;
2022-04-11 17:23:10 +00:00
Font font = myFont . withHeight ( fontsize * fontScale ) ;
font . setUnderline ( button . hasKeyboardFocus ( false ) ) ;
AttributedString s ;
s . setWordWrap ( AttributedString : : byWord ) ;
s . setJustification ( Justification : : centred ) ;
s . append ( button . getButtonText ( ) . trim ( ) , font , colour ) ;
textLayout . createLayout ( s , length ) ;
}
void CustomLookAndFeel : : 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 ( ) ) ;
const Colour selcol = Colour : : fromFloatRGBA ( 0.0f , 0.2f , 0.4f , 1.0f ) ;
// DBG("Sono draw tab button");
if ( button . getToggleState ( ) & & bkg ! = Colours : : black )
{
//g.setColour (bkg);
g . setColour ( selcol ) ;
}
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 . setColour ( isMouseDown ? bkg . brighter ( 0.1 ) : bkg ) ;
//g.setGradientFill (ColourGradient (bkg.darker (0.1f), (float) p1.x, (float) p1.y,
// bkg.darker (0.5f), (float) p2.x, (float) p2.y, false));
}
Rectangle < int > p ( activeArea . reduced ( 1 ) ) ;
g . fillRect ( p ) ;
//g.fillRect (activeArea);
#if 0
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 ) ) ;
# endif
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 ( float_Pi * - 0.5f ) . translated ( area . getX ( ) , area . getBottom ( ) ) ; break ;
case TabbedButtonBar : : TabsAtRight : t = t . rotated ( 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 CustomLookAndFeel : : drawTabButton ( TabBarButton & button , Graphics & g , bool isMouseOver , bool isMouseDown )
{
const Rectangle < int > activeArea ( button . getActiveArea ( ) ) ;
const Colour bkg ( getTabBackgroundColour ( button ) ) ;
g . setGradientFill ( ColourGradient ( bkg . brighter ( 0.1f ) , 0 , ( float ) activeArea . getY ( ) ,
bkg . darker ( 0.1f ) , 0 , ( float ) activeArea . getBottom ( ) , false ) ) ;
g . fillRect ( activeArea ) ;
g . setColour ( button . findColour ( TabbedComponent : : backgroundColourId ) . darker ( 0.3f ) ) ;
g . drawRect ( activeArea ) ;
const float alpha = button . isEnabled ( ) ? ( ( isMouseOver | | isMouseDown ) ? 1.0f : 0.8f ) : 0.3f ;
const Colour col ( bkg . contrasting ( ) . withMultipliedAlpha ( alpha ) ) ;
TextLayout textLayout ;
LookAndFeel_V3 : : createTabTextLayout ( button , ( float ) activeArea . getWidth ( ) , ( float ) activeArea . getHeight ( ) , col , textLayout ) ;
textLayout . draw ( g , button . getTextArea ( ) . toFloat ( ) ) ;
}
*/
void CustomLookAndFeel : : drawTabbedButtonBarBackground ( TabbedButtonBar & , Graphics & ) { }
void CustomLookAndFeel : : 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 = 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 = 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 = 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 = 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 CustomLookAndFeel : : drawTabButtonText ( TabBarButton & button , Graphics & g , bool isMouseOver , bool isMouseDown )
{
const Rectangle < float > area ( button . getTextArea ( ) . toFloat ( ) ) ;
//DBG("Sono look and feel drawtabbutton text: " << button.getButtonText());
float length = area . getWidth ( ) ;
float depth = area . getHeight ( ) ;
if ( button . getTabbedButtonBar ( ) . isVertical ( ) )
std : : swap ( length , depth ) ;
Font font = myFont . withHeight ( jmin ( depth , 30.0f ) * 0.6f * fontScale ) ;
font . setUnderline ( button . hasKeyboardFocus ( false ) ) ;
AffineTransform t ;
switch ( button . getTabbedButtonBar ( ) . getOrientation ( ) )
{
case TabbedButtonBar : : TabsAtLeft : t = t . rotated ( float_Pi * - 0.5f ) . translated ( area . getX ( ) , area . getBottom ( ) ) ; break ;
case TabbedButtonBar : : TabsAtRight : t = t . rotated ( 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 ;
}
Colour col ;
if ( button . isFrontTab ( ) & & ( button . isColourSpecified ( TabbedButtonBar : : frontTextColourId )
| | isColourSpecified ( TabbedButtonBar : : frontTextColourId ) ) )
col = findColour ( TabbedButtonBar : : frontTextColourId ) ;
else if ( button . isColourSpecified ( TabbedButtonBar : : tabTextColourId )
| | isColourSpecified ( TabbedButtonBar : : tabTextColourId ) )
col = findColour ( TabbedButtonBar : : tabTextColourId ) ;
else
col = button . getTabBackgroundColour ( ) . contrasting ( ) ;
const float alpha = button . isEnabled ( ) ? ( ( isMouseOver | | isMouseDown ) ? 1.0f : 0.8f ) : 0.3f ;
g . setColour ( col . withMultipliedAlpha ( alpha ) ) ;
g . setFont ( font ) ;
g . addTransform ( t ) ;
g . drawFittedText ( button . getButtonText ( ) . trim ( ) ,
0 , 0 , ( int ) length , ( int ) depth ,
Justification : : centred ,
//jmax (1, ((int) depth) / 12), 0.5f);
1 , 0.5f ) ;
}
static Range < float > getBrightnessRange ( const Image & im )
{
float minB = 1.0f , maxB = 0 ;
const int w = im . getWidth ( ) ;
const int h = im . getHeight ( ) ;
for ( int y = 0 ; y < h ; + + y )
{
for ( int x = 0 ; x < w ; + + x )
{
const float b = im . getPixelAt ( x , y ) . getBrightness ( ) ;
minB = jmin ( minB , b ) ;
maxB = jmax ( maxB , b ) ;
}
}
return Range < float > ( minB , maxB ) ;
}
Font CustomLookAndFeel : : getLabelFont ( Label & label )
{
if ( fontScale = = 1.0f ) {
return label . getFont ( ) ;
}
else {
return label . getFont ( ) . withHeight ( label . getFont ( ) . getHeight ( ) * fontScale ) ;
}
}
void CustomLookAndFeel : : drawLabel ( Graphics & g , Label & label )
{
Colour olcolor = label . findColour ( Label : : backgroundColourId ) ;
g . setColour ( olcolor ) ;
if ( ! olcolor . isTransparent ( ) ) {
if ( labelCornerRadius > 0.0f ) {
g . fillRoundedRectangle ( label . getLocalBounds ( ) . reduced ( 1 ) . toFloat ( ) , labelCornerRadius ) ;
} else {
g . fillAll ( olcolor ) ;
}
}
if ( ! label . isBeingEdited ( ) )
{
auto alpha = label . isEnabled ( ) ? 1.0f : 0.5f ;
const Font font ( getLabelFont ( label ) ) ;
g . setColour ( label . findColour ( Label : : textColourId ) . withMultipliedAlpha ( alpha ) ) ;
g . setFont ( font ) ;
auto textArea = getLabelBorderSize ( label ) . subtractedFrom ( label . getLocalBounds ( ) ) ;
g . drawFittedText ( label . getText ( ) , textArea , label . getJustificationType ( ) ,
jmax ( 1 , ( int ) ( textArea . getHeight ( ) / font . getHeight ( ) ) ) ,
label . getMinimumHorizontalScale ( ) ) ;
olcolor = label . findColour ( Label : : outlineColourId ) . withMultipliedAlpha ( alpha ) ;
}
else if ( label . isEnabled ( ) )
{
olcolor = label . findColour ( Label : : outlineColourId ) ;
}
if ( ! olcolor . isTransparent ( ) ) {
g . setColour ( olcolor ) ;
if ( labelCornerRadius > 0.0f ) {
g . drawRoundedRectangle ( label . getLocalBounds ( ) . reduced ( 1 ) . toFloat ( ) , labelCornerRadius , 1.0f ) ;
} else {
g . drawRect ( label . getLocalBounds ( ) ) ;
}
}
}
Font CustomLookAndFeel : : getTextButtonFont ( TextButton & button , int buttonHeight )
{
// DBG("GetTextButton font with height: " << buttonHeight);
float textRatio = 0.5f ;
//if (SonoTextButton* const textbutt = dynamic_cast<SonoTextButton*> (&button)) {
// textRatio = textbutt->getTextHeightRatio();
//}
return myFont . withHeight ( jmin ( 16.0f , buttonHeight * textRatio ) * fontScale ) ;
}
Button * CustomLookAndFeel : : createSliderButton ( Slider & , const bool isIncrement )
{
TextButton * butt = new TextButton ( isIncrement ? " + " : " - " , { } ) ;
return butt ;
}
Label * CustomLookAndFeel : : createSliderTextBox ( Slider & slider )
{
Label * lab = LookAndFeel_V4 : : createSliderTextBox ( slider ) ;
lab - > setKeyboardType ( TextInputTarget : : decimalKeyboard ) ;
lab - > setFont ( myFont . withHeight ( 16.0 * fontScale ) ) ;
lab - > setMinimumHorizontalScale ( 0.5 ) ;
lab - > setJustificationType ( Justification : : centredRight ) ;
return lab ;
}
Font CustomLookAndFeel : : getSliderPopupFont ( Slider & )
{
return Font ( 18.0f , Font : : bold ) ;
}
int CustomLookAndFeel : : getSliderPopupPlacement ( Slider & )
{
return BubbleComponent : : above
//| BubbleComponent::below
| BubbleComponent : : left
| BubbleComponent : : right
;
}
void CustomLookAndFeel : : drawButtonTextWithAlignment ( Graphics & g , TextButton & button , bool /*isMouseOverButton*/ , bool /*isButtonDown*/ , Justification textjust )
{
Font font ( getTextButtonFont ( button , button . getHeight ( ) ) ) ;
g . setFont ( font ) ;
g . setColour ( button . findColour ( button . getToggleState ( ) ? TextButton : : textColourOnId
: TextButton : : textColourOffId )
. withMultipliedAlpha ( button . isEnabled ( ) ? 1.0f : 0.5f ) ) ;
float textRatio = 0.7f ;
//if (SonoTextButton* const textbutt = dynamic_cast<SonoTextButton*> (&button)) {
// textRatio = textbutt->getTextHeightRatio();
//}
const int yIndent = jmin ( 2 , button . proportionOfHeight ( ( 1.0 - textRatio ) * 0.5 ) ) ;
const int cornerSize = jmin ( button . getHeight ( ) , button . getWidth ( ) ) / 2 ;
const int fontHeight = roundToInt ( font . getHeight ( ) * 0.3 ) ;
const int leftIndent = jmin ( fontHeight , 2 + cornerSize / ( button . isConnectedOnLeft ( ) ? 4 : 2 ) ) ;
const int rightIndent = jmin ( fontHeight , 2 + cornerSize / ( button . isConnectedOnRight ( ) ? 4 : 2 ) ) ;
g . drawFittedText ( button . getButtonText ( ) ,
leftIndent ,
yIndent ,
button . getWidth ( ) - leftIndent - rightIndent ,
button . getHeight ( ) - yIndent * 2 ,
textjust , 2 , 0.7f ) ;
}
void CustomLookAndFeel : : drawButtonText ( Graphics & g , TextButton & button , bool isMouseOverButton , bool isButtonDown )
{
drawButtonTextWithAlignment ( g , button , isMouseOverButton , isButtonDown ) ;
}
void CustomLookAndFeel : : drawFileBrowserRow ( Graphics & g , 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 & dcc )
{
Component * const fileListComp = dynamic_cast < Component * > ( & dcc ) ;
if ( isItemSelected )
g . fillAll ( fileListComp ! = nullptr ? fileListComp - > findColour ( DirectoryContentsDisplayComponent : : highlightColourId )
: findColour ( DirectoryContentsDisplayComponent : : highlightColourId ) ) ;
int x = 32 ;
g . setColour ( Colours : : black ) ;
if ( isDirectory ) {
if ( icon ! = nullptr & & icon - > isValid ( ) )
{
g . drawImageWithin ( * icon , 2 , 2 , x - 4 , height - 4 ,
RectanglePlacement : : centred | RectanglePlacement : : onlyReduceInSize ,
false ) ;
}
else
{
if ( const Drawable * d = isDirectory ? getDefaultFolderImage ( )
: getDefaultDocumentFileImage ( ) )
d - > drawWithin ( g , Rectangle < float > ( 2.0f , 2.0f , x - 4.0f , height - 4.0f ) ,
RectanglePlacement : : centred | RectanglePlacement : : onlyReduceInSize , 1.0f ) ;
}
}
else {
x = 4 ;
}
g . setColour ( fileListComp ! = nullptr ? fileListComp - > findColour ( DirectoryContentsDisplayComponent : : textColourId )
: findColour ( DirectoryContentsDisplayComponent : : textColourId ) ) ;
g . setFont ( myFont . withHeight ( height * 0.5f ) ) ;
if ( width > 450 & & ! isDirectory )
{
const int sizeX = roundToInt ( width * 0.7f ) ;
const int dateX = roundToInt ( width * 0.8f ) ;
g . drawFittedText ( filename ,
x , 0 , sizeX - x , height ,
Justification : : centredLeft , 1 ) ;
g . setFont ( myFont . withHeight ( height * 0.5f ) ) ;
g . setColour ( Colours : : darkgrey ) ;
if ( ! isDirectory )
{
g . drawFittedText ( fileSizeDescription ,
sizeX , 0 , dateX - sizeX - 8 , height ,
Justification : : centredRight , 1 ) ;
g . drawFittedText ( fileTimeDescription ,
dateX , 0 , width - 8 - dateX , height ,
Justification : : centredRight , 1 ) ;
}
}
else
{
g . drawFittedText ( filename ,
x , 0 , width - x , height ,
Justification : : centredLeft , 1 ) ;
}
}
Button * CustomLookAndFeel : : createFileBrowserGoUpButton ( )
{
DrawableButton * goUpButton = new DrawableButton ( " up " , DrawableButton : : ImageOnButtonBackground ) ;
Path arrowPath ;
arrowPath . addArrow ( Line < float > ( 50.0f , 100.0f , 50.0f , 0.0f ) , 40.0f , 100.0f , 50.0f ) ;
DrawablePath arrowImage ;
arrowImage . setFill ( Colours : : white . withAlpha ( 0.4f ) ) ;
arrowImage . setPath ( arrowPath ) ;
goUpButton - > setImages ( & arrowImage ) ;
return goUpButton ;
}
void CustomLookAndFeel : : layoutFileBrowserComponent ( FileBrowserComponent & browserComp ,
DirectoryContentsDisplayComponent * fileListComponent ,
FilePreviewComponent * previewComp ,
ComboBox * currentPathBox ,
TextEditor * filenameBox ,
Button * goUpButton )
{
const int x = 8 ;
int w = browserComp . getWidth ( ) - x - x ;
if ( previewComp ! = nullptr )
{
const int previewWidth = w / 3 ;
previewComp - > setBounds ( x + w - previewWidth , 0 , previewWidth , browserComp . getHeight ( ) ) ;
w - = previewWidth + 4 ;
}
int y = 4 ;
const int controlsHeight = 22 ;
const int bottomSectionHeight = controlsHeight + 8 ;
const int upButtonWidth = 50 ;
currentPathBox - > setBounds ( x , y , w - upButtonWidth - 6 , controlsHeight ) ;
goUpButton - > setBounds ( x + w - upButtonWidth , y , upButtonWidth , controlsHeight ) ;
y + = controlsHeight + 4 ;
if ( Component * const listAsComp = dynamic_cast < Component * > ( fileListComponent ) )
{
listAsComp - > setBounds ( x , y , w , browserComp . getHeight ( ) - y - bottomSectionHeight ) ;
y = listAsComp - > getBottom ( ) + 4 ;
}
filenameBox - > setBounds ( x + 50 , y , w - 50 , controlsHeight ) ;
}
PopupMenu : : Options CustomLookAndFeel : : getOptionsForComboBoxPopupMenu ( ComboBox & box , Label & label )
{
auto options = PopupMenu : : Options ( ) . withTargetComponent ( & box )
. withItemThatMustBeVisible ( box . getSelectedId ( ) )
. withMinimumWidth ( box . getWidth ( ) )
. withMaximumNumColumns ( 1 )
. withStandardItemHeight ( label . getHeight ( ) ) ;
# if JUCE_IOS || JUCE_ANDROID
auto * dw = box . findParentComponentOfClass < AudioProcessorEditor > ( ) ;
if ( dw ) {
options = options . withParentComponent ( dw ) ;
}
# endif
return options ;
}
void CustomLookAndFeel : : 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 ) ;
DBG ( " draw plus minus ours " ) ;
//g.setColour (backgroundColour.contrasting().withAlpha (isMouseOver ? 0.5f : 0.3f));
g . setColour ( Colours : : white . withAlpha ( isMouseOver ? 0.5f : 0.3f ) ) ;
g . fillPath ( p , p . getTransformToScaleToFit ( area . reduced ( 2 , area . getHeight ( ) / 4 ) , true ) ) ;
}
void CustomLookAndFeel : : drawToggleButton ( Graphics & g , ToggleButton & button ,
bool isMouseOverButton , bool isButtonDown )
{
/*
if ( button . hasKeyboardFocus ( true ) )
{
g . setColour ( button . findColour ( TextEditor : : focusedOutlineColourId ) ) ;
g . drawRect ( 0 , 0 , button . getWidth ( ) , button . getHeight ( ) ) ;
}
*/
float fontSize = jmin ( 15.0f , button . getHeight ( ) * 0.75f ) * fontScale ;
const float tickWidth = fontSize * 1.1f ;
drawTickBox ( g , button , 4.0f , ( button . getHeight ( ) - tickWidth ) * 0.5f ,
tickWidth , tickWidth ,
button . getToggleState ( ) ,
button . isEnabled ( ) ,
isMouseOverButton ,
isButtonDown ) ;
g . setColour ( button . findColour ( ToggleButton : : textColourId ) ) ;
g . setFont ( myFont . withHeight ( fontSize ) ) ;
if ( ! button . isEnabled ( ) )
g . setOpacity ( 0.5f ) ;
const int textX = ( int ) tickWidth + 10 ;
g . drawFittedText ( button . getButtonText ( ) ,
textX , 0 ,
button . getWidth ( ) - textX - 2 , button . getHeight ( ) ,
Justification : : centredLeft , 10 ) ;
}
void CustomLookAndFeel : : drawTickBox ( Graphics & g , Component & component ,
float x , float y , float w , float h ,
const bool ticked ,
const bool isEnabled ,
const bool isMouseOverButton ,
const bool isButtonDown )
{
const float boxSize = w * 1.0f ;
g . setColour ( component . findColour ( TextEditor : : focusedOutlineColourId ) ) ;
g . drawRect ( x , y + ( h - boxSize ) * 0.5f , boxSize , boxSize ) ;
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 ? component . findColour ( ToggleButton : : tickColourId ) : Colours : : grey ) ;
const AffineTransform trans ( AffineTransform : : scale ( w / 9.0f , h / 9.0f )
. translated ( x + 2 , y + 1 ) ) ;
g . strokePath ( tick , PathStrokeType ( 2.5f ) , trans ) ;
}
}
void CustomLookAndFeel : : drawRotarySlider ( Graphics & g , int x , int y , int width , int height , float sliderPos ,
const float rotaryStartAngle , const float rotaryEndAngle , Slider & slider )
{
const auto outline = findColour ( Slider : : rotarySliderOutlineColourId ) ;
const auto fill = findColour ( Slider : : rotarySliderFillColourId ) ;
const auto bounds = Rectangle < int > ( x , y , width , height ) . toFloat ( ) . reduced ( 3 ) ;
auto radius = jmin ( bounds . getWidth ( ) , bounds . getHeight ( ) ) / 2.0f ;
const auto toAngle = rotaryStartAngle + sliderPos * ( rotaryEndAngle - rotaryStartAngle ) ;
auto lineW = jmin ( 8.0f , radius * 0.3f ) ;
auto arcRadius = radius - lineW * 0.5f ;
Path backgroundArc ;
backgroundArc . addCentredArc ( bounds . getCentreX ( ) ,
bounds . getCentreY ( ) ,
arcRadius ,
arcRadius ,
0.0f ,
rotaryStartAngle ,
rotaryEndAngle ,
true ) ;
g . setColour ( outline ) ;
g . strokePath ( backgroundArc , PathStrokeType ( lineW , PathStrokeType : : curved , PathStrokeType : : rounded ) ) ;
auto rotStartAngle = rotaryStartAngle ;
if ( slider . getProperties ( ) . contains ( " fromCentre " ) )
{
rotStartAngle = ( rotStartAngle + rotaryEndAngle ) / 2 ;
}
if ( slider . isEnabled ( ) )
{
Path valueArc ;
valueArc . addCentredArc ( bounds . getCentreX ( ) ,
bounds . getCentreY ( ) ,
arcRadius ,
arcRadius ,
0.0f ,
rotStartAngle ,
toAngle ,
true ) ;
g . setColour ( fill ) ;
g . strokePath ( valueArc , PathStrokeType ( lineW , PathStrokeType : : curved , PathStrokeType : : rounded ) ) ;
}
const auto thumbWidth = lineW ; // * 1.5f;
const Point < float > thumbPoint ( bounds . getCentreX ( ) + arcRadius * std : : cos ( toAngle - float_Pi * 0.5f ) ,
bounds . getCentreY ( ) + arcRadius * std : : sin ( toAngle - float_Pi * 0.5f ) ) ;
g . setColour ( findColour ( Slider : : thumbColourId ) ) ;
g . fillEllipse ( Rectangle < float > ( thumbWidth , thumbWidth ) . withCentre ( thumbPoint ) ) ;
}
//==============================================================================
int CustomLookAndFeel : : getSliderThumbRadius ( Slider & slider )
{
if ( slider . isTwoValue ( ) | | slider . isThreeValue ( ) ) {
return jmin ( 14 , slider . isHorizontal ( ) ? static_cast < int > ( slider . getHeight ( ) * 0.25f )
: static_cast < int > ( slider . getWidth ( ) * 0.5f ) ) ;
}
return jmin ( 16 , slider . isHorizontal ( ) ? static_cast < int > ( slider . getHeight ( ) * 0.5f )
: static_cast < int > ( slider . getWidth ( ) * 0.5f ) ) ;
}
Slider : : SliderLayout CustomLookAndFeel : : getSliderLayout ( Slider & slider )
{
// 1. compute the actually visible textBox size from the slider textBox size and some additional constraints
int minXSpace = 0 ;
int minYSpace = 0 ;
auto textBoxPos = slider . getTextBoxPosition ( ) ;
if ( textBoxPos = = Slider : : TextBoxLeft | | textBoxPos = = Slider : : TextBoxRight )
minXSpace = 30 ;
else
minYSpace = 15 ;
auto localBounds = slider . getLocalBounds ( ) ;
auto textBoxWidth = jmax ( 0 , jmin ( slider . getTextBoxWidth ( ) , localBounds . getWidth ( ) - minXSpace ) ) ;
auto textBoxHeight = jmax ( 0 , jmin ( slider . getTextBoxHeight ( ) , localBounds . getHeight ( ) - minYSpace ) ) ;
Slider : : SliderLayout layout ;
// 2. set the textBox bounds
if ( textBoxPos ! = Slider : : NoTextBox )
{
if ( slider . isBar ( ) )
{
layout . textBoxBounds = localBounds ;
}
else
{
layout . textBoxBounds . setWidth ( textBoxWidth ) ;
layout . textBoxBounds . setHeight ( textBoxHeight ) ;
const int thumbIndent = getSliderThumbRadius ( slider ) ;
if ( textBoxPos = = Slider : : TextBoxLeft ) layout . textBoxBounds . setX ( 0 ) ;
else if ( textBoxPos = = Slider : : TextBoxRight ) layout . textBoxBounds . setX ( localBounds . getWidth ( ) - textBoxWidth ) ;
else if ( sliderTextJustification . testFlags ( Justification : : right ) ) /* above or below -> right */ layout . textBoxBounds . setX ( ( localBounds . getWidth ( ) - textBoxWidth - 1 ) ) ;
else if ( sliderTextJustification . testFlags ( Justification : : left ) ) /* above or below -> left */ layout . textBoxBounds . setX ( 1 ) ;
else /* above or below -> centre horizontally */ layout . textBoxBounds . setX ( ( localBounds . getWidth ( ) - textBoxWidth ) / 2 ) ;
if ( textBoxPos = = Slider : : TextBoxAbove ) layout . textBoxBounds . setY ( 0 ) ;
else if ( textBoxPos = = Slider : : TextBoxBelow ) layout . textBoxBounds . setY ( localBounds . getHeight ( ) - textBoxHeight ) ;
else if ( sliderTextJustification . testFlags ( Justification : : top ) ) /* left or right -> top */ layout . textBoxBounds . setY ( 0 ) ;
else if ( sliderTextJustification . testFlags ( Justification : : bottom ) ) /* left or right -> bottom */ layout . textBoxBounds . setY ( localBounds . getHeight ( ) - textBoxHeight ) ;
else /* left or right -> centre vertically */ layout . textBoxBounds . setY ( ( localBounds . getHeight ( ) - textBoxHeight ) / 2 ) ;
}
}
// 3. set the slider bounds
layout . sliderBounds = localBounds ;
if ( slider . isBar ( ) )
{
layout . sliderBounds . reduce ( 1 , 1 ) ; // bar border
}
else
{
if ( textBoxPos = = Slider : : TextBoxLeft ) layout . sliderBounds . removeFromLeft ( textBoxWidth ) ;
else if ( textBoxPos = = Slider : : TextBoxRight ) layout . sliderBounds . removeFromRight ( textBoxWidth ) ;
else if ( textBoxPos = = Slider : : TextBoxAbove ) layout . sliderBounds . removeFromTop ( textBoxHeight ) ;
else if ( textBoxPos = = Slider : : TextBoxBelow ) layout . sliderBounds . removeFromBottom ( textBoxHeight ) ;
const int thumbIndent = getSliderThumbRadius ( slider ) ;
if ( slider . isHorizontal ( ) ) layout . sliderBounds . reduce ( thumbIndent , 0 ) ;
else if ( slider . isVertical ( ) ) layout . sliderBounds . reduce ( 0 , thumbIndent ) ;
}
return layout ;
}
void CustomLookAndFeel : : drawLinearSlider ( Graphics & g , int x , int y , int width , int height ,
float sliderPos ,
float minSliderPos ,
float maxSliderPos ,
const Slider : : SliderStyle style , Slider & slider )
{
if ( slider . isBar ( ) )
{
if ( slider . getProperties ( ) . contains ( " fromCentre " ) ) {
auto centrex = x + width * 0.5f ;
auto centrey = y + height * 0.5f ;
if ( ! slider . getProperties ( ) . contains ( " noFill " ) ) {
g . setColour ( slider . findColour ( Slider : : trackColourId ) ) ;
g . fillRect ( slider . isHorizontal ( ) ? Rectangle < float > ( sliderPos > centrex ? centrex : sliderPos , y + 0.5f , sliderPos > centrex ? sliderPos - centrex : centrex - sliderPos , height - 1.0f )
: Rectangle < float > ( x + 0.5f , sliderPos < centrey ? sliderPos : centrey , width - 1.0f , sliderPos < centrey ? centrey - sliderPos : sliderPos - centrey ) ) ;
}
// draw line
g . setColour ( slider . findColour ( Slider : : thumbColourId ) ) ;
g . fillRect ( slider . isHorizontal ( ) ? Rectangle < float > ( sliderPos - 1 , y + 0.5f , 2 , height - 1.0f )
: Rectangle < float > ( x + 0.5f , sliderPos - 1 , width - 1.0f , 2 ) ) ;
}
else {
if ( ! slider . getProperties ( ) . contains ( " noFill " ) ) {
g . setColour ( slider . findColour ( Slider : : trackColourId ) ) ;
g . fillRect ( slider . isHorizontal ( ) ? Rectangle < float > ( static_cast < float > ( x ) , y + 0.5f , sliderPos - x , height - 1.0f )
: Rectangle < float > ( x + 0.5f , sliderPos , width - 1.0f , y + ( height - sliderPos ) ) ) ;
}
//else
g . setColour ( slider . findColour ( Slider : : thumbColourId ) ) ;
{
// draw line
g . fillRect ( slider . isHorizontal ( ) ? Rectangle < float > ( sliderPos - 1 , y + 0.5f , 3 , height - 1.0f )
: Rectangle < float > ( x + 0.5f , sliderPos - 1 , width - 1.0f , 3 ) ) ;
}
}
}
else
{
auto isTwoVal = ( style = = Slider : : SliderStyle : : TwoValueVertical | | style = = Slider : : SliderStyle : : TwoValueHorizontal ) ;
auto isThreeVal = ( style = = Slider : : SliderStyle : : ThreeValueVertical | | style = = Slider : : SliderStyle : : ThreeValueHorizontal ) ;
auto trackWidth = jmin ( 10.0f , slider . isHorizontal ( ) ? height * 0.25f : width * 0.25f ) ;
Point < float > startPoint ( slider . isHorizontal ( ) ? x : x + width * 0.5f ,
slider . isHorizontal ( ) ? y + height * 0.5f : height + y ) ;
Point < float > endPoint ( slider . isHorizontal ( ) ? width + x : startPoint . x ,
slider . isHorizontal ( ) ? startPoint . y : y ) ;
Path backgroundTrack ;
backgroundTrack . startNewSubPath ( startPoint ) ;
backgroundTrack . lineTo ( endPoint ) ;
g . setColour ( slider . findColour ( Slider : : backgroundColourId ) ) ;
g . strokePath ( backgroundTrack , { trackWidth , PathStrokeType : : curved , PathStrokeType : : rounded } ) ;
Path valueTrack ;
Point < float > minPoint , maxPoint , thumbPoint ;
if ( isTwoVal | | isThreeVal )
{
minPoint = { slider . isHorizontal ( ) ? minSliderPos : width * 0.5f ,
slider . isHorizontal ( ) ? height * 0.5f : minSliderPos } ;
if ( isThreeVal )
thumbPoint = { slider . isHorizontal ( ) ? sliderPos : width * 0.5f ,
slider . isHorizontal ( ) ? height * 0.5f : sliderPos } ;
maxPoint = { slider . isHorizontal ( ) ? maxSliderPos : width * 0.5f ,
slider . isHorizontal ( ) ? height * 0.5f : maxSliderPos } ;
}
else
{
auto kx = slider . isHorizontal ( ) ? sliderPos : ( x + width * 0.5f ) ;
auto ky = slider . isHorizontal ( ) ? ( y + height * 0.5f ) : sliderPos ;
minPoint = startPoint ;
maxPoint = { kx , ky } ;
}
auto thumbWidth = getSliderThumbRadius ( slider ) ;
valueTrack . startNewSubPath ( minPoint ) ;
valueTrack . lineTo ( isThreeVal ? thumbPoint : maxPoint ) ;
g . setColour ( slider . findColour ( Slider : : trackColourId ) ) ;
g . strokePath ( valueTrack , { trackWidth , PathStrokeType : : curved , PathStrokeType : : rounded } ) ;
if ( ! isTwoVal )
{
g . setColour ( slider . findColour ( Slider : : thumbColourId ) ) ;
g . fillEllipse ( Rectangle < float > ( static_cast < float > ( thumbWidth ) , static_cast < float > ( thumbWidth ) ) . withCentre ( isThreeVal ? thumbPoint : maxPoint ) ) ;
}
if ( isTwoVal | | isThreeVal )
{
auto sr = jmin ( trackWidth , ( slider . isHorizontal ( ) ? height : width ) * 0.4f ) ;
auto pointerColour = slider . findColour ( Slider : : thumbColourId ) ;
auto wscale = 1.5f ;
if ( slider . isHorizontal ( ) )
{
/*
drawPointer ( g , minSliderPos - sr ,
height * 0.5f - trackWidth * wscale * 0.5 , //jmax (0.0f, y + height * 0.5f - trackWidth * 0.5f),
trackWidth * wscale , pointerColour , 1 ) ; // 2
drawPointer ( g , maxSliderPos - trackWidth ,
height * 0.5f - trackWidth * wscale * 0.5 , //jmin (y + height - trackWidth * 2.0f, (float)y + height * 0.5f),
trackWidth * wscale , pointerColour , 3 ) ; // 4
*/
drawPointer ( g , minSliderPos - sr ,
jmax ( 0.0f , y + height * 0.5f - trackWidth * wscale ) ,
trackWidth * wscale , pointerColour , 2 ) ; // 2
drawPointer ( g , maxSliderPos - trackWidth * 0.5 * wscale ,
jmin ( y + height - trackWidth * wscale , ( float ) y + height * 0.5f ) ,
trackWidth * wscale , pointerColour , 4 ) ; // 4
}
else
{
drawPointer ( g , jmax ( 0.0f , x + width * 0.5f - trackWidth * 2.0f ) ,
minSliderPos - trackWidth ,
trackWidth * wscale , pointerColour , 1 ) ;
drawPointer ( g , jmin ( x + width - trackWidth * 2.0f , x + width * 0.5f ) , maxSliderPos - sr ,
trackWidth * wscale , pointerColour , 3 ) ;
}
}
}
}
void CustomLookAndFeel : : drawDrawableButton ( Graphics & g , DrawableButton & button ,
bool isMouseOverButton , bool isButtonDown )
{
const auto cornerSize = 6.0f ;
bool toggleState = button . getToggleState ( ) ;
;
//Rectangle<float> bounds = g.getClipBounds().toFloat();
Rectangle < float > bounds = button . getLocalBounds ( ) . toFloat ( ) ;
g . setColour ( button . findColour ( toggleState ? DrawableButton : : backgroundOnColourId
: DrawableButton : : backgroundColourId ) ) ;
//g.fillAll();
g . fillRoundedRectangle ( bounds , cornerSize ) ;
if ( isButtonDown ) {
//setColour (SonoDrawableButton::overOverlayColourId, Colour::fromFloatRGBA(0.8, 0.8, 0.8, 0.08));
//setColour (SonoDrawableButton::downOverlayColourId, Colour::fromFloatRGBA(0.8, 0.8, 0.8, 0.3));
g . setColour ( Colour : : fromFloatRGBA ( 0.8 , 0.8 , 0.8 , 0.3 ) ) ;
//g.setColour(findColour(SonoDrawableButton::downOverlayColourId));
//g.fillAll();
g . fillRoundedRectangle ( bounds , cornerSize ) ;
}
else if ( isMouseOverButton ) {
//g.setColour(findColour(SonoDrawableButton::overOverlayColourId));
g . setColour ( Colour : : fromFloatRGBA ( 0.8 , 0.8 , 0.8 , 0.08 ) ) ;
//g.fillAll();
g . fillRoundedRectangle ( bounds , cornerSize ) ;
}
//g.fillAll (button.findColour (toggleState ? DrawableButton::backgroundOnColourId
// : DrawableButton::backgroundColourId));
int textH = 0 ;
int textW = 0 ;
float imageratio = 0.75f ;
//if (SonoDrawableButton* const sonobutt = dynamic_cast<SonoDrawableButton*> (&button)) {
// imageratio = sonobutt->getForegroundImageRatio();
//}
if ( button . getStyle ( ) = = DrawableButton : : ImageAboveTextLabel | | button . getStyle ( ) = = DrawableButton : : ImageBelowTextLabel ) {
textH = jmin ( 14 , button . proportionOfHeight ( 0.2f ) ) ;
} else if ( button . getStyle ( ) = = DrawableButton : : ImageLeftOfTextLabel | | button . getStyle ( ) = = DrawableButton : : ImageRightOfTextLabel ) {
textH = jmin ( 14 , button . proportionOfHeight ( 0.8f ) ) ;
textW = jmax ( 20 , button . proportionOfWidth ( 1.0f - imageratio ) ) ;
}
if ( textH > 0 )
{
g . setFont ( myFont . withHeight ( ( float ) textH * fontScale ) ) ;
g . setColour ( button . findColour ( toggleState ? DrawableButton : : textColourOnId
: DrawableButton : : textColourId )
. withMultipliedAlpha ( button . isEnabled ( ) ? 1.0f : 0.4f ) ) ;
if ( button . getStyle ( ) = = DrawableButton : : ImageAboveTextLabel ) {
g . drawFittedText ( button . getButtonText ( ) ,
2 , button . getHeight ( ) - textH - 1 ,
button . getWidth ( ) - 4 , textH ,
Justification : : centred , 1 ) ;
}
else if ( button . getStyle ( ) = = DrawableButton : : ImageBelowTextLabel ) {
g . drawFittedText ( button . getButtonText ( ) ,
2 , 1 ,
button . getWidth ( ) - 4 , textH ,
Justification : : centred , 1 ) ;
}
else if ( button . getStyle ( ) = = DrawableButton : : ImageRightOfTextLabel ) {
g . drawFittedText ( button . getButtonText ( ) ,
2 , 1 ,
textW , button . getHeight ( ) - 2 ,
Justification : : centred , 2 , 0.6f ) ;
}
else if ( button . getStyle ( ) = = DrawableButton : : ImageLeftOfTextLabel ) {
g . drawFittedText ( button . getButtonText ( ) ,
button . getWidth ( ) - textW - 4 , 1 ,
textW , button . getHeight ( ) - 2 ,
Justification : : centred , 2 , 0.6f ) ;
}
}
}
void CustomLookAndFeel : : drawBubble ( Graphics & g , BubbleComponent & comp ,
const Point < float > & tip , const Rectangle < float > & body )
{
Path p ;
p . addBubble ( body . reduced ( 0.5f ) , body . getUnion ( Rectangle < float > ( tip . x , tip . y , 1.0f , 1.0f ) ) ,
tip , 5.0f , jmin ( 10.0f , body . getWidth ( ) * 0.2f , body . getHeight ( ) * 0.2f ) ) ;
g . setColour ( comp . findColour ( BubbleComponent : : backgroundColourId ) ) ;
g . fillPath ( p ) ;
g . setColour ( comp . findColour ( BubbleComponent : : outlineColourId ) ) ;
g . strokePath ( p , PathStrokeType ( 1.0f ) ) ;
}
CustomBigTextLookAndFeel : : CustomBigTextLookAndFeel ( float maxTextSize )
: maxSize ( maxTextSize )
{
}
Font CustomBigTextLookAndFeel : : getTextButtonFont ( TextButton & button , int buttonHeight )
{
// DBG("GetTextButton font with height: " << buttonHeight << " maxsize: " << maxSize);
float textRatio = 0.8f ;
//if (SonoTextButton* const textbutt = dynamic_cast<SonoTextButton*> (&button)) {
// textRatio = textbutt->getTextHeightRatio();
//}
return myFont . withHeight ( jmin ( maxSize , buttonHeight * textRatio ) * fontScale ) ;
}
Label * CustomBigTextLookAndFeel : : createSliderTextBox ( Slider & slider )
{
Label * lab = LookAndFeel_V4 : : createSliderTextBox ( slider ) ;
lab - > setKeyboardType ( TextInputTarget : : decimalKeyboard ) ;
lab - > setFont ( myFont . withHeight ( maxSize * fontScale ) ) ;
lab - > setJustificationType ( textJustification ) ;
lab - > setMinimumHorizontalScale ( 0.5 ) ;
return lab ;
}
Button * CustomBigTextLookAndFeel : : createSliderButton ( Slider & , const bool isIncrement )
{
TextButton * butt = new TextButton ( isIncrement ? " + " : " - " , { } ) ;
butt - > setLookAndFeel ( this ) ;
return butt ;
}
void CustomBigTextLookAndFeel : : drawToggleButton ( Graphics & g , ToggleButton & button ,
bool isMouseOverButton , bool isButtonDown )
{
/*
if ( button . hasKeyboardFocus ( true ) )
{
g . setColour ( button . findColour ( TextEditor : : focusedOutlineColourId ) ) ;
g . drawRect ( 0 , 0 , button . getWidth ( ) , button . getHeight ( ) ) ;
}
*/
float fontSize = jmin ( maxSize , button . getHeight ( ) * 0.75f ) * fontScale ;
const float tickWidth = fontSize * 1.1f ;
drawTickBox ( g , button , 4.0f , ( button . getHeight ( ) - tickWidth ) * 0.5f ,
tickWidth , tickWidth ,
button . getToggleState ( ) ,
button . isEnabled ( ) ,
isMouseOverButton ,
isButtonDown ) ;
g . setColour ( button . findColour ( ToggleButton : : textColourId ) ) ;
g . setFont ( myFont . withHeight ( fontSize ) ) ;
if ( ! button . isEnabled ( ) )
g . setOpacity ( 0.5f ) ;
const int textX = ( int ) tickWidth + 10 ;
g . drawFittedText ( button . getButtonText ( ) ,
textX , 0 ,
button . getWidth ( ) - textX - 2 , button . getHeight ( ) ,
Justification : : centredLeft , 10 ) ;
}