macOS light and dark themes (issue #497)

This commit is contained in:
Karl Tauber
2022-05-09 23:31:21 +02:00
parent bfede219d0
commit b459715cb5
20 changed files with 4039 additions and 43 deletions

2
.gitignore vendored
View File

@@ -9,5 +9,7 @@ out/
*.iml
*.ipr
*.iws
*.xcuserstate
*.xcworkspacedata
.vs/
.vscode/

View File

@@ -87,7 +87,7 @@ tasks {
"action" to "generate",
"fileName" to "${project.name}-sigtest.txt",
"classpath" to jar.get().outputs.files.asPath,
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.util",
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.themes,com.formdev.flatlaf.util",
"version" to version,
"release" to "1.8", // Java version
"failonerror" to "true" )

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2022 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.themes;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatDarkLaf;
/**
* A Flat LaF that imitates macOS dark look.
* <p>
* The UI defaults are loaded from {@code FlatMacDarkLaf.properties},
* {@code FlatDarkLaf.properties} and {@code FlatLaf.properties}.
*
* @author Karl Tauber
* @since 3
*/
public class FlatMacDarkLaf
extends FlatDarkLaf
{
public static final String NAME = "FlatLaf macOS Dark";
/**
* Sets the application look and feel to this LaF
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
*/
public static boolean setup() {
return setup( new FlatMacDarkLaf() );
}
/**
* Adds this look and feel to the set of available look and feels.
* <p>
* Useful if your application uses {@link UIManager#getInstalledLookAndFeels()}
* to query available LaFs and display them to the user in a combobox.
*/
public static void installLafInfo() {
installLafInfo( NAME, FlatMacDarkLaf.class );
}
@Override
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return "FlatLaf macOS Dark Look and Feel";
}
@Override
public boolean isDark() {
return true;
}
}

View File

@@ -0,0 +1,68 @@
/*
* Copyright 2022 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.themes;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatLightLaf;
/**
* A Flat LaF that imitates macOS light look.
* <p>
* The UI defaults are loaded from {@code FlatMacLightLaf.properties},
* {@code FlatLightLaf.properties} and {@code FlatLaf.properties}.
*
* @author Karl Tauber
* @since 3
*/
public class FlatMacLightLaf
extends FlatLightLaf
{
public static final String NAME = "FlatLaf macOS Light";
/**
* Sets the application look and feel to this LaF
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
*/
public static boolean setup() {
return setup( new FlatMacLightLaf() );
}
/**
* Adds this look and feel to the set of available look and feels.
* <p>
* Useful if your application uses {@link UIManager#getInstalledLookAndFeels()}
* to query available LaFs and display them to the user in a combobox.
*/
public static void installLafInfo() {
installLafInfo( NAME, FlatMacLightLaf.class );
}
@Override
public String getName() {
return NAME;
}
@Override
public String getDescription() {
return "FlatLaf macOS Light Look and Feel";
}
@Override
public boolean isDark() {
return false;
}
}

View File

@@ -49,8 +49,10 @@ public class FlatArrowButton
protected Color pressedBackground;
private int arrowWidth = DEFAULT_ARROW_WIDTH;
private float arrowThickness = 1;
private float xOffset = 0;
private float yOffset = 0;
private boolean roundBorderAutoXOffset = true;
private boolean hover;
private boolean pressed;
@@ -121,6 +123,16 @@ public class FlatArrowButton
this.arrowWidth = arrowWidth;
}
/** @since 3 */
public float getArrowThickness() {
return arrowThickness;
}
/** @since 3 */
public void setArrowThickness( float arrowThickness ) {
this.arrowThickness = arrowThickness;
}
protected boolean isHover() {
return hover;
}
@@ -145,6 +157,16 @@ public class FlatArrowButton
this.yOffset = yOffset;
}
/** @since 3 */
public boolean isRoundBorderAutoXOffset() {
return roundBorderAutoXOffset;
}
/** @since 3 */
public void setRoundBorderAutoXOffset( boolean roundBorderAutoXOffset ) {
this.roundBorderAutoXOffset = roundBorderAutoXOffset;
}
protected Color deriveBackground( Color background ) {
return background;
}
@@ -208,14 +230,17 @@ public class FlatArrowButton
}
protected void paintArrow( Graphics2D g ) {
boolean vert = (direction == NORTH || direction == SOUTH);
int x = 0;
// move arrow for round borders
Container parent = getParent();
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
if( isRoundBorderAutoXOffset() ) {
Container parent = getParent();
boolean vert = (direction == NORTH || direction == SOUTH);
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
}
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron, getArrowWidth(), getXOffset(), getYOffset() );
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron,
getArrowWidth(), getArrowThickness(), getXOffset(), getYOffset() );
}
}

View File

@@ -99,7 +99,7 @@ import com.formdev.flatlaf.util.SystemInfo;
* @uiDefault ComboBox.minimumWidth int
* @uiDefault ComboBox.editorColumns int
* @uiDefault ComboBox.maximumRowCount int
* @uiDefault ComboBox.buttonStyle String auto (default), button or none
* @uiDefault ComboBox.buttonStyle String auto (default), button, mac or none
* @uiDefault Component.arrowType String chevron (default) or triangle
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
@@ -568,7 +568,9 @@ public class FlatComboBoxUI
int height = c.getHeight();
int arrowX = arrowButton.getX();
int arrowWidth = arrowButton.getWidth();
boolean paintButton = (comboBox.isEditable() || "button".equals( buttonStyle )) && !"none".equals( buttonStyle );
boolean paintButton = (comboBox.isEditable() || "button".equals( buttonStyle )) &&
!"none".equals( buttonStyle ) &&
!isMacStyle();
boolean enabled = comboBox.isEnabled();
boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight();
@@ -586,13 +588,21 @@ public class FlatComboBoxUI
: buttonBackground;
if( buttonColor != null ) {
g2.setColor( buttonColor );
Shape oldClip = g2.getClip();
if( isLeftToRight )
g2.clipRect( arrowX, 0, width - arrowX, height );
else
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.setClip( oldClip );
if( isMacStyle() ) {
Insets insets = comboBox.getInsets();
int gap = scale( 2 );
FlatUIUtils.paintComponentBackground( g2, arrowX + gap, insets.top + gap,
arrowWidth - (gap * 2), height - insets.top - insets.bottom - (gap * 2),
0, arc - focusWidth );
} else {
Shape oldClip = g2.getClip();
if( isLeftToRight )
g2.clipRect( arrowX, 0, width - arrowX, height );
else
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.setClip( oldClip );
}
}
}
@@ -731,6 +741,10 @@ public class FlatComboBoxUI
return parentParent != null && !comboBox.getBackground().equals( parentParent.getBackground() );
}
private boolean isMacStyle() {
return "mac".equals( buttonStyle );
}
/** @since 1.3 */
public static boolean isPermanentFocusOwner( JComboBox<?> comboBox ) {
if( comboBox.isEditable() ) {
@@ -751,6 +765,12 @@ public class FlatComboBoxUI
protected FlatComboBoxButton() {
this( SwingConstants.SOUTH, arrowType, buttonArrowColor, buttonDisabledArrowColor,
buttonHoverArrowColor, null, buttonPressedArrowColor, null );
if( isMacStyle() ) {
setArrowWidth( 7 );
setArrowThickness( 1.5f );
setRoundBorderAutoXOffset( false );
}
}
protected FlatComboBoxButton( int direction, String type, Color foreground, Color disabledForeground,
@@ -782,6 +802,20 @@ public class FlatComboBoxUI
return super.getArrowColor();
}
@Override
protected void paintArrow( Graphics2D g ) {
if( isMacStyle() && !comboBox.isEditable() ) {
// for style "mac", paint up and down arrows if combobox is not editable
int height = getHeight();
int h = Math.round( height / 2f );
FlatUIUtils.paintArrow( g, 0, 0, getWidth(), h, SwingConstants.NORTH, chevron,
getArrowWidth(), getArrowThickness(), getXOffset(), getYOffset() + 1.25f );
FlatUIUtils.paintArrow( g, 0, height - h, getWidth(), h, SwingConstants.SOUTH, chevron,
getArrowWidth(), getArrowThickness(), getXOffset(), getYOffset() - 1.25f );
} else
super.paintArrow( g );
}
}
//---- class FlatComboPopup -----------------------------------------------

View File

@@ -65,7 +65,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
* <!-- FlatSpinnerUI -->
*
* @uiDefault Component.minimumWidth int
* @uiDefault Spinner.buttonStyle String button (default) or none
* @uiDefault Spinner.buttonStyle String button (default), mac or none
* @uiDefault Component.arrowType String chevron (default) or triangle
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault Spinner.disabledBackground Color
@@ -347,6 +347,13 @@ public class FlatSpinnerUI
installNextButtonListeners( button );
else
installPreviousButtonListeners( button );
if( "mac".equals( buttonStyle ) ) {
button.setArrowWidth( 7 );
button.setArrowThickness( 1.5f );
button.setYOffset( (direction == SwingConstants.NORTH) ? 0.75f : -0.75f );
button.setRoundBorderAutoXOffset( false );
}
return button;
}
@@ -387,26 +394,50 @@ public class FlatSpinnerUI
int arrowX = button.getX();
int arrowWidth = button.getWidth();
boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight();
// paint arrow buttons background
if( enabled && buttonBackground != null ) {
g2.setColor( buttonBackground );
Shape oldClip = g2.getClip();
if( isLeftToRight )
g2.clipRect( arrowX, 0, width - arrowX, height );
else
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.setClip( oldClip );
}
// paint vertical line between value and arrow buttons
Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor;
if( separatorColor != null && buttonSeparatorWidth > 0 ) {
g2.setColor( separatorColor );
if( "mac".equals( buttonStyle ) ) {
Insets insets = spinner.getInsets();
int gapX = scale( 3 );
int gapY = scale( 1 );
int bx = arrowX + gapX;
int by = insets.top + gapY;
int bw = arrowWidth - (gapX * 2);
int bh = height - insets.top - insets.bottom - (gapY * 2);
float lw = scale( buttonSeparatorWidth );
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - 1 - (focusWidth * 2) ) );
// buttons border
FlatUIUtils.paintOutlinedComponent( g2, bx, by, bw, bh,
0, 0, 0, lw, arc - focusWidth,
null, separatorColor, buttonBackground );
// separator between buttons
if( separatorColor != null ) {
int thickness = scale( 1 );
g2.setColor( separatorColor );
g2.fill( new Rectangle2D.Float( bx + lw, by + ((bh - thickness) / 2f),
bw - (lw * 2), thickness ) );
}
} else {
// paint arrow buttons background
if( enabled && buttonBackground != null ) {
g2.setColor( buttonBackground );
Shape oldClip = g2.getClip();
if( isLeftToRight )
g2.clipRect( arrowX, 0, width - arrowX, height );
else
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.setClip( oldClip );
}
// paint vertical line between value and arrow buttons
if( separatorColor != null && buttonSeparatorWidth > 0 ) {
g2.setColor( separatorColor );
float lw = scale( buttonSeparatorWidth );
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - 1 - (focusWidth * 2) ) );
}
}
}

View File

@@ -904,13 +904,15 @@ public class FlatUIUtils
* {@link SwingConstants#WEST} or {@link SwingConstants#EAST})
* @param chevron {@code true} for chevron arrow, {@code false} for triangle arrow
* @param arrowSize the width of the painted arrow (for vertical direction) (will be scaled)
* @param arrowThickness the thickness of the painted chevron arrow (will be scaled)
* @param xOffset an offset added to the x coordinate of the arrow to paint it out-of-center. Usually zero. (will be scaled)
* @param yOffset an offset added to the y coordinate of the arrow to paint it out-of-center. Usually zero. (will be scaled)
*
* @since 1.1
* @since 3
*/
public static void paintArrow( Graphics2D g, int x, int y, int width, int height,
int direction, boolean chevron, int arrowSize, float xOffset, float yOffset )
int direction, boolean chevron, int arrowSize, float arrowThickness,
float xOffset, float yOffset )
{
// compute arrow width/height
// - make chevron arrows one pixel smaller because coordinates are based on center of pixels (0.5/0.5)
@@ -944,7 +946,7 @@ debug*/
Shape arrowShape = createArrowShape( direction, chevron, aw, ah );
if( chevron ) {
Stroke oldStroke = g.getStroke();
g.setStroke( new BasicStroke( UIScale.scale( 1f ) ) );
g.setStroke( new BasicStroke( UIScale.scale( arrowThickness ) ) );
drawShapePure( g, arrowShape );
g.setStroke( oldStroke );
} else {

View File

@@ -22,6 +22,7 @@ module com.formdev.flatlaf {
exports com.formdev.flatlaf;
exports com.formdev.flatlaf.icons;
exports com.formdev.flatlaf.themes;
exports com.formdev.flatlaf.ui;
exports com.formdev.flatlaf.util;

View File

@@ -0,0 +1,246 @@
#
# Copyright 2022 FormDev Software GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# base theme (light, dark, intellij or darcula); only used by theme editor
@baseTheme = dark
#---- macOS NSColor system colors (in NSColorSpace.deviceRGB) ----
# generated on macOS 12.2 using Xcode and flatlaf-testing/misc/MacOSColorDump.playground
@nsLabelColor = #ffffffd8
@nsSecondaryLabelColor = #ffffff8c
@nsTertiaryLabelColor = #ffffff3f
@nsQuaternaryLabelColor = #ffffff19
@nsSystemRedColor = #ff453a
@nsSystemGreenColor = #32d74b
@nsSystemBlueColor = #0a84ff
@nsSystemOrangeColor = #ff9f0a
@nsSystemYellowColor = #ffd60a
@nsSystemBrownColor = #ac8e68
@nsSystemPinkColor = #ff375f
@nsSystemPurpleColor = #bf5af2
@nsSystemTealColor = #6ac4dc
@nsSystemIndigoColor = #5e5ce6
@nsSystemMintColor = #63e6e2
@nsSystemCyanColor = #5ac8f5
@nsSystemGrayColor = #98989d
@nsLinkColor = #419cff
@nsPlaceholderTextColor = #ffffff3f
@nsWindowFrameTextColor = #ffffffd8
@nsSelectedMenuItemTextColor = #ffffff
@nsAlternateSelectedControlTextColor = #ffffff
@nsHeaderTextColor = #ffffff
@nsSeparatorColor = #ffffff19
@nsGridColor = #1a1a1a
@nsTextColor = #ffffff
@nsTextBackgroundColor = #1e1e1e
@nsSelectedTextColor = #ffffff
@nsSelectedTextBackgroundColor = #3f638b
@nsUnemphasizedSelectedTextBackgroundColor = #464646
@nsUnemphasizedSelectedTextColor = #ffffff
@nsWindowBackgroundColor = #323232
@nsUnderPageBackgroundColor = #282828
@nsControlBackgroundColor = #1e1e1e
@nsSelectedContentBackgroundColor = #0058d0
@nsUnemphasizedSelectedContentBackgroundColor = #464646
@nsFindHighlightColor = #ffff00
@nsControlColor = #ffffff3f
@nsControlTextColor = #ffffffd8
@nsSelectedControlColor = #3f638b
@nsSelectedControlTextColor = #ffffffd8
@nsDisabledControlTextColor = #ffffff3f
@nsKeyboardFocusIndicatorColor = #1aa9ff7f
@nsControlAccentColor = #007aff
# accent colors are:
# @nsSelectedTextBackgroundColor
# @nsSelectedContentBackgroundColor
# @nsSelectedControlColor
# @nsKeyboardFocusIndicatorColor
# @nsControlAccentColor
#---- variables ----
# general background and foreground (text color)
@background = @nsControlBackgroundColor
@foreground = over(@nsControlTextColor,@background)
@disabledForeground = over(@nsSecondaryLabelColor,@background)
# component background
@buttonBackground = over(@nsControlColor,@background)
@componentBackground = darken(over(@nsControlColor,@background),18%)
@disabledComponentBackground = darken(@componentBackground,2%)
@menuBackground = lighten(@background,8%)
# selection
@selectionBackground = @nsSelectedContentBackgroundColor
@selectionForeground = @nsSelectedMenuItemTextColor
@selectionInactiveBackground = @nsUnemphasizedSelectedContentBackgroundColor
# text selection
@textSelectionBackground = @nsSelectedTextBackgroundColor
@textSelectionForeground = @nsSelectedTextColor
# accent colors (blueish)
@accentColor = @nsControlAccentColor
@accentFocusColor = @nsKeyboardFocusIndicatorColor
#---- Button ----
Button.arc = 12
Button.borderWidth = 0
Button.disabledBackground = darken($Button.background,10%)
Button.default.borderWidth = 0
Button.toolbar.hoverBackground = #fff1
Button.toolbar.pressedBackground = #fff2
Button.toolbar.selectedBackground = #fff3
#---- CheckBox ----
CheckBox.iconTextGap = 6
CheckBox.arc = 7
CheckBox.icon.focusWidth = null
CheckBox.icon.style = filled
CheckBox.icon[filled].borderWidth = 0
CheckBox.icon[filled].selectedBorderWidth = 0
CheckBox.icon[filled].background = darken(over(@nsControlColor,@background),3%)
CheckBox.icon[filled].disabledBackground = darken($CheckBox.icon[filled].background,10%)
CheckBox.icon[filled].selectedBackground = @accentColor
CheckBox.icon[filled].checkmarkColor = fadeout(@nsSelectedMenuItemTextColor,15%)
CheckBox.icon[filled].disabledCheckmarkColor = darken($CheckBox.icon[filled].checkmarkColor,45%)
CheckBox.icon.focusedBackground = null
#---- ComboBox ----
ComboBox.buttonStyle = mac
ComboBox.background = over(@nsControlColor,@background)
ComboBox.editableBackground = @componentBackground
ComboBox.disabledBackground = @disabledComponentBackground
ComboBox.buttonBackground = @accentColor
ComboBox.buttonArrowColor = @nsSelectedMenuItemTextColor
ComboBox.buttonHoverArrowColor = darken($ComboBox.buttonArrowColor,15%,derived noAutoInverse)
ComboBox.buttonPressedArrowColor = darken($ComboBox.buttonArrowColor,25%,derived noAutoInverse)
ComboBox.popupBackground = @menuBackground
#---- Component ----
Component.focusWidth = 2
Component.innerFocusWidth = 0
Component.innerOutlineWidth = 0
Component.arc = 12
Component.borderColor = @nsSeparatorColor
Component.disabledBorderColor = fadeout(@nsSeparatorColor,5%)
#---- EditorPane ---
EditorPane.disabledBackground = @disabledComponentBackground
EditorPane.selectionBackground = @textSelectionBackground
EditorPane.selectionForeground = @textSelectionForeground
#---- FormattedTextField ---
FormattedTextField.disabledBackground = @disabledComponentBackground
FormattedTextField.selectionBackground = @textSelectionBackground
FormattedTextField.selectionForeground = @textSelectionForeground
#---- PasswordField ---
PasswordField.disabledBackground = @disabledComponentBackground
PasswordField.selectionBackground = @textSelectionBackground
PasswordField.selectionForeground = @textSelectionForeground
#---- ProgressBar ----
ProgressBar.background = lighten(@background,8%)
#---- RadioButton ----
RadioButton.iconTextGap = 6
RadioButton.icon.style = filled
RadioButton.icon[filled].centerDiameter = 6
#---- ScrollBar ----
ScrollBar.width = 12
ScrollBar.track = @componentBackground
ScrollBar.thumb = @buttonBackground
#---- Separator ----
Separator.foreground = @nsSeparatorColor
#---- Slider ----
Slider.trackWidth = 3
Slider.thumbSize = 14,14
Slider.trackColor = lighten(@background,8%)
Slider.thumbColor = lighten($Slider.trackColor,35%)
Slider.disabledTrackColor = darken($Slider.trackColor,4%)
Slider.disabledThumbColor = darken($Slider.thumbColor,32%)
Slider.focusedColor = $Component.focusColor
#---- Spinner ----
Spinner.buttonStyle = mac
Spinner.disabledBackground = @disabledComponentBackground
Spinner.buttonBackground = @buttonBackground
Spinner.buttonSeparatorWidth = 0
#---- TextArea ---
TextArea.disabledBackground = @disabledComponentBackground
TextArea.selectionBackground = @textSelectionBackground
TextArea.selectionForeground = @textSelectionForeground
#---- TextField ----
TextField.disabledBackground = @disabledComponentBackground
TextField.selectionBackground = @textSelectionBackground
TextField.selectionForeground = @textSelectionForeground
#---- TextPane ---
TextPane.disabledBackground = @disabledComponentBackground
TextPane.selectionBackground = @textSelectionBackground
TextPane.selectionForeground = @textSelectionForeground
#---- ToggleButton ----
ToggleButton.disabledBackground = $Button.disabledBackground
ToggleButton.selectedBackground = lighten($ToggleButton.background,20%,derived)
ToggleButton.toolbar.selectedBackground = #fff3

View File

@@ -0,0 +1,244 @@
#
# Copyright 2022 FormDev Software GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# base theme (light, dark, intellij or darcula); only used by theme editor
@baseTheme = light
#---- macOS NSColor system colors (in NSColorSpace.deviceRGB) ----
# generated on macOS 12.2 using Xcode and flatlaf-testing/misc/MacOSColorDump.playground
@nsLabelColor = #000000d8
@nsSecondaryLabelColor = #0000007f
@nsTertiaryLabelColor = #00000042
@nsQuaternaryLabelColor = #00000019
@nsSystemRedColor = #ff3b30
@nsSystemGreenColor = #28cd41
@nsSystemBlueColor = #007aff
@nsSystemOrangeColor = #ff9500
@nsSystemYellowColor = #ffcc00
@nsSystemBrownColor = #a2845e
@nsSystemPinkColor = #ff2d55
@nsSystemPurpleColor = #af52de
@nsSystemTealColor = #59adc4
@nsSystemIndigoColor = #5856d6
@nsSystemMintColor = #00c7be
@nsSystemCyanColor = #55bef0
@nsSystemGrayColor = #8e8e93
@nsLinkColor = #0068da
@nsPlaceholderTextColor = #0000003f
@nsWindowFrameTextColor = #000000d8
@nsSelectedMenuItemTextColor = #ffffff
@nsAlternateSelectedControlTextColor = #ffffff
@nsHeaderTextColor = #000000d8
@nsSeparatorColor = #00000019
@nsGridColor = #e6e6e6
@nsTextColor = #000000
@nsTextBackgroundColor = #ffffff
@nsSelectedTextColor = #000000
@nsSelectedTextBackgroundColor = #b3d7ff
@nsUnemphasizedSelectedTextBackgroundColor = #dcdcdc
@nsUnemphasizedSelectedTextColor = #000000
@nsWindowBackgroundColor = #ececec
@nsUnderPageBackgroundColor = #969696e5
@nsControlBackgroundColor = #ffffff
@nsSelectedContentBackgroundColor = #0063e1
@nsUnemphasizedSelectedContentBackgroundColor = #dcdcdc
@nsFindHighlightColor = #ffff00
@nsControlColor = #ffffff
@nsControlTextColor = #000000d8
@nsSelectedControlColor = #b3d7ff
@nsSelectedControlTextColor = #000000d8
@nsDisabledControlTextColor = #0000003f
@nsKeyboardFocusIndicatorColor = #0067f47f
@nsControlAccentColor = #007aff
# accent colors are:
# @nsSelectedTextBackgroundColor
# @nsSelectedContentBackgroundColor
# @nsSelectedControlColor
# @nsKeyboardFocusIndicatorColor
# @nsControlAccentColor
#---- variables ----
# general background and foreground (text color)
@background = #f6f6f6
@foreground = over(@nsControlTextColor,@background)
@disabledForeground = over(@nsTertiaryLabelColor,@background)
# component background
@buttonBackground = @nsControlColor
@componentBackground = @nsControlColor
@disabledComponentBackground = darken(@componentBackground,2%)
@menuBackground = darken(@background,4%)
# selection
@selectionBackground = @nsSelectedContentBackgroundColor
@selectionForeground = @nsSelectedMenuItemTextColor
@selectionInactiveBackground = @nsUnemphasizedSelectedContentBackgroundColor
# text selection
@textSelectionBackground = @nsSelectedTextBackgroundColor
@textSelectionForeground = @foreground
# accent colors (blueish)
@accentColor = @nsControlAccentColor
@accentFocusColor = @nsKeyboardFocusIndicatorColor
#---- Button ----
Button.arc = 12
Button.disabledBackground = @disabledComponentBackground
Button.focusedBackground = null
Button.default.borderWidth = 1
Button.default.boldText = true
Button.default.background = @accentColor
Button.default.foreground = contrast($Button.default.background, @background, $Button.foreground, 20%)
#---- CheckBox ----
CheckBox.iconTextGap = 6
CheckBox.arc = 7
CheckBox.icon.focusWidth = null
CheckBox.icon.style = filled
CheckBox.icon[filled].borderWidth = 1
CheckBox.icon[filled].selectedBorderWidth = 0
CheckBox.icon[filled].disabledSelectedBorderWidth = 1
CheckBox.icon[filled].background = @nsControlColor
CheckBox.icon[filled].disabledBackground = @disabledComponentBackground
CheckBox.icon[filled].selectedBackground = @accentColor
CheckBox.icon[filled].borderColor = $Component.borderColor
CheckBox.icon[filled].disabledBorderColor = $Component.disabledBorderColor
CheckBox.icon[filled].checkmarkColor = @nsSelectedMenuItemTextColor
CheckBox.icon[filled].disabledCheckmarkColor = darken($CheckBox.icon[filled].checkmarkColor,25%)
CheckBox.icon.focusedBackground = null
#---- ComboBox ----
ComboBox.buttonStyle = mac
ComboBox.disabledBackground = @disabledComponentBackground
ComboBox.buttonBackground = @accentColor
ComboBox.buttonArrowColor = @nsSelectedMenuItemTextColor
ComboBox.buttonHoverArrowColor = darken($ComboBox.buttonArrowColor,15%,derived noAutoInverse)
ComboBox.buttonPressedArrowColor = darken($ComboBox.buttonArrowColor,25%,derived noAutoInverse)
ComboBox.popupBackground = @menuBackground
#---- Component ----
Component.focusWidth = 2
Component.innerFocusWidth = 0
Component.innerOutlineWidth = 0
Component.arc = 12
Component.borderColor = fadein(@nsSeparatorColor,5%)
Component.disabledBorderColor = @nsSeparatorColor
#---- EditorPane ---
EditorPane.disabledBackground = @disabledComponentBackground
EditorPane.selectionBackground = @textSelectionBackground
EditorPane.selectionForeground = @textSelectionForeground
#---- FormattedTextField ---
FormattedTextField.disabledBackground = @disabledComponentBackground
FormattedTextField.selectionBackground = @textSelectionBackground
FormattedTextField.selectionForeground = @textSelectionForeground
#---- PasswordField ---
PasswordField.disabledBackground = @disabledComponentBackground
PasswordField.selectionBackground = @textSelectionBackground
PasswordField.selectionForeground = @textSelectionForeground
#---- ProgressBar ----
ProgressBar.background = darken(@background,5%)
#---- RadioButton ----
RadioButton.iconTextGap = 6
RadioButton.icon.style = filled
RadioButton.icon[filled].centerDiameter = 6
#---- ScrollBar ----
ScrollBar.width = 12
ScrollBar.track = darken(@componentBackground,2%)
ScrollBar.thumb = darken(@componentBackground,24%)
#---- Separator ----
Separator.foreground = @nsSeparatorColor
#---- Slider ----
Slider.trackWidth = 3
Slider.thumbSize = 14,14
Slider.trackColor = darken(@background,7%)
Slider.thumbColor = @componentBackground
Slider.thumbBorderColor = $Component.borderColor
Slider.disabledTrackColor = lighten($Slider.trackColor,3%)
Slider.disabledThumbColor = darken($Slider.thumbColor,3%)
#---- Spinner ----
Spinner.buttonStyle = mac
Spinner.disabledBackground = @disabledComponentBackground
Spinner.buttonArrowColor = @foreground
Spinner.buttonHoverArrowColor = lighten($Spinner.buttonArrowColor,20%,derived noAutoInverse)
Spinner.buttonPressedArrowColor = lighten($Spinner.buttonArrowColor,30%,derived noAutoInverse)
#---- TextArea ---
TextArea.disabledBackground = @disabledComponentBackground
TextArea.selectionBackground = @textSelectionBackground
TextArea.selectionForeground = @textSelectionForeground
#---- TextField ----
TextField.disabledBackground = @disabledComponentBackground
TextField.selectionBackground = @textSelectionBackground
TextField.selectionForeground = @textSelectionForeground
#---- TextPane ---
TextPane.disabledBackground = @disabledComponentBackground
TextPane.selectionBackground = @textSelectionBackground
TextPane.selectionForeground = @textSelectionForeground
#---- ToggleButton ----
ToggleButton.disabledBackground = $Button.disabledBackground

View File

@@ -54,6 +54,7 @@ import com.formdev.flatlaf.IntelliJTheme;
import com.formdev.flatlaf.demo.DemoPrefs;
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import com.formdev.flatlaf.themes.*;
import com.formdev.flatlaf.ui.FlatListUI;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils;
@@ -185,6 +186,11 @@ public class IJThemesPanel
if( showDark )
themes.add( new IJThemeInfo( "FlatLaf Darcula", null, true, null, null, null, null, null, FlatDarculaLaf.class.getName() ) );
if( showLight )
themes.add( new IJThemeInfo( "FlatLaf macOS Light", null, false, null, null, null, null, null, FlatMacLightLaf.class.getName() ) );
if( showDark )
themes.add( new IJThemeInfo( "FlatLaf macOS Dark", null, true, null, null, null, null, null, FlatMacDarkLaf.class.getName() ) );
// add themes from directory
categories.put( themes.size(), "Current Directory" );
themes.addAll( themesManager.moreThemes );

View File

@@ -121,7 +121,7 @@ public class FlatJideSplitButtonUI
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
FlatUIUtils.paintArrow( (Graphics2D) g, r.x, r.y, r.width, r.height,
SwingConstants.SOUTH, FlatUIUtils.isChevron( arrowType ), 6, 0, 0 );
SwingConstants.SOUTH, FlatUIUtils.isChevron( arrowType ), 6, 1, 0, 0 );
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
}
}

View File

@@ -891,7 +891,7 @@ public class FlatJideTabbedPaneUI
g.setColor( button.isEnabled() ? foreground : disabledForeground );
FlatUIUtils.paintArrow( (Graphics2D) g,
0, 0, button.getWidth(), button.getHeight(),
direction, FlatUIUtils.isChevron( arrowType ), 10, 0, 0 );
direction, FlatUIUtils.isChevron( arrowType ), 10, 1, 0, 0 );
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
import Cocoa
func colorToHex( color: NSColor ) -> String {
return String( format: (color.alphaComponent != 1 ? "#%02x%02x%02x%02x" : "#%02x%02x%02x"),
Int( 255 * color.redComponent ),
Int( 255 * color.greenComponent ),
Int( 255 * color.blueComponent ),
Int( 255 * color.alphaComponent ) )
}
func printColorHex( color: NSColor, space: NSColorSpace ) {
print( "@ns", color.colorNameComponent.prefix(1).capitalized, color.colorNameComponent.dropFirst(),
" = ", colorToHex( color: color.usingColorSpace( space )! ),
separator: "" )
}
func printColorsHex( space: NSColorSpace ) {
print( "#----", space, "----" )
// order is the same as in Xcode color chooser (Color Palettes > Developer)
printColorHex( color: NSColor.labelColor, space: space )
printColorHex( color: NSColor.secondaryLabelColor, space: space )
printColorHex( color: NSColor.tertiaryLabelColor, space: space )
printColorHex( color: NSColor.quaternaryLabelColor, space: space )
printColorHex( color: NSColor.systemRed, space: space )
printColorHex( color: NSColor.systemGreen, space: space )
printColorHex( color: NSColor.systemBlue, space: space )
printColorHex( color: NSColor.systemOrange, space: space )
printColorHex( color: NSColor.systemYellow, space: space )
printColorHex( color: NSColor.systemBrown, space: space )
printColorHex( color: NSColor.systemPink, space: space )
printColorHex( color: NSColor.systemPurple, space: space )
printColorHex( color: NSColor.systemTeal, space: space )
printColorHex( color: NSColor.systemIndigo, space: space )
printColorHex( color: NSColor.systemMint, space: space )
printColorHex( color: NSColor.systemCyan, space: space )
printColorHex( color: NSColor.systemGray, space: space )
printColorHex( color: NSColor.linkColor, space: space )
printColorHex( color: NSColor.placeholderTextColor, space: space )
printColorHex( color: NSColor.windowFrameTextColor, space: space )
printColorHex( color: NSColor.selectedMenuItemTextColor, space: space )
printColorHex( color: NSColor.alternateSelectedControlTextColor, space: space )
printColorHex( color: NSColor.headerTextColor, space: space )
printColorHex( color: NSColor.separatorColor, space: space )
printColorHex( color: NSColor.gridColor, space: space )
printColorHex( color: NSColor.textColor, space: space )
printColorHex( color: NSColor.textBackgroundColor, space: space )
printColorHex( color: NSColor.selectedTextColor, space: space )
printColorHex( color: NSColor.selectedTextBackgroundColor, space: space )
printColorHex( color: NSColor.unemphasizedSelectedTextBackgroundColor, space: space )
printColorHex( color: NSColor.unemphasizedSelectedTextColor, space: space )
printColorHex( color: NSColor.windowBackgroundColor, space: space )
printColorHex( color: NSColor.underPageBackgroundColor, space: space )
printColorHex( color: NSColor.controlBackgroundColor, space: space )
printColorHex( color: NSColor.selectedContentBackgroundColor, space: space )
printColorHex( color: NSColor.unemphasizedSelectedContentBackgroundColor, space: space )
print( "# alternatingContentBackgroundColors =", NSColor.alternatingContentBackgroundColors )
printColorHex( color: NSColor.findHighlightColor, space: space )
printColorHex( color: NSColor.controlColor, space: space )
printColorHex( color: NSColor.controlTextColor, space: space )
printColorHex( color: NSColor.selectedControlColor, space: space )
printColorHex( color: NSColor.selectedControlTextColor, space: space )
printColorHex( color: NSColor.disabledControlTextColor, space: space )
printColorHex( color: NSColor.keyboardFocusIndicatorColor, space: space )
printColorHex( color: NSColor.controlAccentColor, space: space )
print()
}
// printColorsHex( space: NSColorSpace.genericRGB )
printColorsHex( space: NSColorSpace.deviceRGB )

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='macos'>
<timeline fileName='timeline.xctimeline'/>
</playground>

View File

@@ -1077,7 +1077,7 @@ public class FlatPaintingTest
private void paintArrow( Graphics2D g, int width, int height ) {
FlatUIUtils.paintArrow( g, 0, 0, width, height,
direction, chevron, arrowSize, xOffset, yOffset );
direction, chevron, arrowSize, 1, xOffset, yOffset );
if( button ) {
FlatArrowButton arrowButton = new FlatArrowButton( direction,

View File

@@ -65,6 +65,7 @@ import javax.swing.plaf.basic.BasicLookAndFeel;
import com.formdev.flatlaf.*;
import com.formdev.flatlaf.intellijthemes.FlatAllIJThemes;
import com.formdev.flatlaf.testing.FlatTestLaf;
import com.formdev.flatlaf.themes.*;
import com.formdev.flatlaf.ui.FlatLineBorder;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.ColorFunctions.ColorFunction;
@@ -103,6 +104,9 @@ public class UIDefaultsDump
if( SystemInfo.isWindows ) {
dump( FlatIntelliJLaf.class.getName(), dir, false );
dump( FlatDarculaLaf.class.getName(), dir, false );
dump( FlatMacLightLaf.class.getName(), dir, false );
dump( FlatMacDarkLaf.class.getName(), dir, false );
}
dump( FlatTestLaf.class.getName(), dir, false );
@@ -463,9 +467,9 @@ public class UIDefaultsDump
if( resolvedColor != color && resolvedColor.getRGB() != color.getRGB() ) {
if( !isIntelliJTheme ) {
System.err.println( "Key '" + key + "': derived colors not equal" );
System.err.println( " Default color: " + dumpColorHexAndHSL( color ) );
System.err.println( " Resolved color: " + dumpColorHexAndHSL( resolvedColor ) );
System.err.println( " Base of resolved color: " + dumpColorHexAndHSL( retBaseColor[0] ) );
System.err.println( " Default color: " + dumpColorHexAndHSL( color ) );
System.err.println( " Resolved color: " + dumpColorHexAndHSL( resolvedColor ) );
System.err.println( " Base color: " + dumpColorHexAndHSL( retBaseColor[0] ) );
}
out.printf( "%s / ",