mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
Merge PR #533: macOS light and dark themes
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -9,5 +9,7 @@ out/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
*.xcuserstate
|
||||
*.xcworkspacedata
|
||||
.vs/
|
||||
.vscode/
|
||||
|
||||
@@ -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" )
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,7 @@ import javax.swing.plaf.basic.BasicComboBoxUI;
|
||||
import javax.swing.plaf.basic.BasicComboPopup;
|
||||
import javax.swing.plaf.basic.ComboPopup;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import com.formdev.flatlaf.icons.FlatCheckBoxMenuItemIcon;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
@@ -99,7 +100,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 +569,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 +589,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 +742,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 +766,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 +803,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 -----------------------------------------------
|
||||
@@ -816,12 +851,19 @@ public class FlatComboBoxUI
|
||||
}
|
||||
}
|
||||
|
||||
// for style "mac", add width of "checked item" icon
|
||||
boolean isPopupOverComboBox = isPopupOverComboBox();
|
||||
int selectedIndex = -1;
|
||||
if( isPopupOverComboBox && (selectedIndex = comboBox.getSelectedIndex()) >= 0 )
|
||||
displayWidth += MacCheckedItemIcon.INSTANCE.getIconWidth() + scale( CellPaddingBorder.MAC_STYLE_GAP );
|
||||
|
||||
// add width of vertical scroll bar
|
||||
JScrollBar verticalScrollBar = scroller.getVerticalScrollBar();
|
||||
if( verticalScrollBar != null )
|
||||
displayWidth += verticalScrollBar.getPreferredSize().width;
|
||||
|
||||
// make popup wider if necessary
|
||||
int pw0 = pw;
|
||||
if( displayWidth > pw ) {
|
||||
// limit popup width to screen width
|
||||
GraphicsConfiguration gc = comboBox.getGraphicsConfiguration();
|
||||
@@ -841,6 +883,30 @@ public class FlatComboBoxUI
|
||||
px -= diff;
|
||||
}
|
||||
|
||||
// for style "mac", place popup over combobox
|
||||
Rectangle cellBounds;
|
||||
if( isPopupOverComboBox && selectedIndex >= 0 &&
|
||||
(cellBounds = list.getCellBounds( 0, 0 )) != null )
|
||||
{
|
||||
Insets comboBoxInsets = comboBox.getInsets();
|
||||
Insets listInsets = list.getInsets();
|
||||
Insets popupInsets = getInsets();
|
||||
|
||||
// position popup so that selected item is at same Y position as combobox
|
||||
py -= (cellBounds.height * (selectedIndex + 1)) + comboBoxInsets.top + listInsets.top + popupInsets.top;
|
||||
|
||||
// position popup slightly to the left so that a small part of the right side of the combobox stays visible
|
||||
int offset = Math.min( pw - pw0, MacCheckedItemIcon.INSTANCE.getIconWidth() ) + scale( 4 );
|
||||
if( comboBox.getComponentOrientation().isLeftToRight() )
|
||||
px -= offset + comboBoxInsets.right + listInsets.right;
|
||||
else
|
||||
px += offset + comboBoxInsets.left + listInsets.left;
|
||||
|
||||
// not invoking super.computePopupBounds() here to let
|
||||
// JPopupMenu.adjustPopupLocationToFitScreen() fix the location if necessary
|
||||
return new Rectangle( px, py, pw, ph );
|
||||
}
|
||||
|
||||
return super.computePopupBounds( px, py, pw, ph );
|
||||
}
|
||||
|
||||
@@ -920,6 +986,15 @@ public class FlatComboBoxUI
|
||||
paddingBorder.uninstall();
|
||||
}
|
||||
|
||||
private boolean isPopupOverComboBox() {
|
||||
return isMacStyle() &&
|
||||
!comboBox.isEditable() &&
|
||||
comboBox.getItemCount() > 0 &&
|
||||
comboBox.getItemCount() <= comboBox.getMaximumRowCount() &&
|
||||
// for compatibility with Aqua Laf
|
||||
!clientPropertyBoolean( comboBox, "JComboBox.isPopDown", false );
|
||||
}
|
||||
|
||||
//---- class PopupListCellRenderer -----
|
||||
|
||||
private class PopupListCellRenderer
|
||||
@@ -937,6 +1012,13 @@ public class FlatComboBoxUI
|
||||
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||
|
||||
// style "mac"
|
||||
if( isPopupOverComboBox() && c instanceof JComponent ) {
|
||||
int selectedIndex = comboBox.getSelectedIndex();
|
||||
((JComponent)c).putClientProperty( CellPaddingBorder.KEY_MAC_STYLE_HINT,
|
||||
(selectedIndex >= 0) ? (index == selectedIndex) : null );
|
||||
}
|
||||
|
||||
paddingBorder.install( c, Math.round( FlatUIUtils.getBorderFocusWidth( comboBox ) ) );
|
||||
|
||||
return c;
|
||||
@@ -953,10 +1035,16 @@ public class FlatComboBoxUI
|
||||
* which vertically aligns text in popup list with text in combobox.
|
||||
* <p>
|
||||
* The renderer border is painted on the outer side of this border.
|
||||
* <p>
|
||||
* For button style "mac", also used to increase insets on left side for
|
||||
* "checked item" icon and to paint "checked item" icon for selected combobox item.
|
||||
*/
|
||||
private static class CellPaddingBorder
|
||||
extends AbstractBorder
|
||||
{
|
||||
static final String KEY_MAC_STYLE_HINT = "FlatLaf.internal.FlatComboBoxUI.macStyleHint";
|
||||
static final int MAC_STYLE_GAP = 4;
|
||||
|
||||
private Insets padding;
|
||||
private JComponent rendererComponent;
|
||||
private Border rendererBorder;
|
||||
@@ -1006,6 +1094,8 @@ public class FlatComboBoxUI
|
||||
if( rendererComponent == null )
|
||||
return;
|
||||
|
||||
rendererComponent.putClientProperty( KEY_MAC_STYLE_HINT, null );
|
||||
|
||||
if( rendererComponent.getBorder() == this )
|
||||
rendererComponent.setBorder( rendererBorder );
|
||||
rendererComponent = null;
|
||||
@@ -1033,6 +1123,18 @@ public class FlatComboBoxUI
|
||||
insets.left += focusWidth;
|
||||
insets.right += focusWidth;
|
||||
|
||||
// style "mac"
|
||||
if( c instanceof JComponent ) {
|
||||
Boolean macStyleHint = clientPropertyBooleanStrict( (JComponent) c, KEY_MAC_STYLE_HINT, null );
|
||||
if( macStyleHint != null ) {
|
||||
int indent = MacCheckedItemIcon.INSTANCE.getIconWidth() + scale( MAC_STYLE_GAP );
|
||||
if( c.getComponentOrientation().isLeftToRight() )
|
||||
insets.left += indent;
|
||||
else
|
||||
insets.right += indent;
|
||||
}
|
||||
}
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
@@ -1040,6 +1142,35 @@ public class FlatComboBoxUI
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
if( rendererBorder != null )
|
||||
rendererBorder.paintBorder( c, g, x, y, width, height );
|
||||
|
||||
// style "mac"
|
||||
if( c instanceof JComponent ) {
|
||||
Boolean macStyleHint = clientPropertyBooleanStrict( (JComponent) c, KEY_MAC_STYLE_HINT, null );
|
||||
if( macStyleHint == Boolean.TRUE ) {
|
||||
// paint "checked item" icon
|
||||
int ix = c.getComponentOrientation().isLeftToRight()
|
||||
? x + scale( padding.left )
|
||||
: x + width - scale( padding.right ) - MacCheckedItemIcon.INSTANCE.getIconWidth();
|
||||
MacCheckedItemIcon.INSTANCE.paintIcon( c, g, ix, y + ((height - MacCheckedItemIcon.INSTANCE.getIconHeight()) / 2) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---- class MacCheckedItemIcon -------------------------------------------
|
||||
|
||||
/**
|
||||
* Use for style "mac" to mark checked item.
|
||||
*/
|
||||
private static class MacCheckedItemIcon
|
||||
extends FlatCheckBoxMenuItemIcon
|
||||
{
|
||||
static MacCheckedItemIcon INSTANCE = new MacCheckedItemIcon();
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||
g2.setColor( c.getForeground() );
|
||||
paintCheckmark( g2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -50,8 +50,9 @@
|
||||
@selectionInactiveForeground = @foreground
|
||||
|
||||
# menu
|
||||
@menuSelectionBackground = @selectionBackground
|
||||
@menuHoverBackground = lighten(@menuBackground,10%,derived)
|
||||
@menuCheckBackground = darken(@selectionBackground,10%,derived noAutoInverse)
|
||||
@menuCheckBackground = darken(@menuSelectionBackground,10%,derived noAutoInverse)
|
||||
@menuAcceleratorForeground = darken(@foreground,15%)
|
||||
@menuAcceleratorSelectionForeground = @selectionForeground
|
||||
|
||||
|
||||
@@ -50,8 +50,9 @@
|
||||
@selectionInactiveForeground = @foreground
|
||||
|
||||
# menu
|
||||
@menuSelectionBackground = @selectionBackground
|
||||
@menuHoverBackground = darken(@menuBackground,10%,derived)
|
||||
@menuCheckBackground = lighten(@selectionBackground,40%,derived noAutoInverse)
|
||||
@menuCheckBackground = lighten(@menuSelectionBackground,40%,derived noAutoInverse)
|
||||
@menuAcceleratorForeground = lighten(@foreground,30%)
|
||||
@menuAcceleratorSelectionForeground = @selectionForeground
|
||||
|
||||
|
||||
@@ -0,0 +1,285 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
# menu
|
||||
@menuSelectionBackground = desaturate(@selectionBackground,20%)
|
||||
@menuItemMargin = 3,11,3,11
|
||||
|
||||
# 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
|
||||
ComboBox.selectionBackground = @menuSelectionBackground
|
||||
ComboBox.popupInsets = 5,0,5,0
|
||||
ComboBox.selectionInsets = 0,5,0,5
|
||||
ComboBox.selectionArc = 8
|
||||
|
||||
|
||||
#---- 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
|
||||
|
||||
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.selectionInsets = 0,0,0,0
|
||||
MenuBar.selectionEmbeddedInsets = 3,0,3,0
|
||||
MenuBar.selectionArc = 8
|
||||
MenuBar.selectionBackground = lighten(@menuBackground,15%,derived)
|
||||
MenuBar.selectionForeground = @foreground
|
||||
|
||||
|
||||
#---- MenuItem ----
|
||||
|
||||
MenuItem.selectionInsets = 0,5,0,5
|
||||
MenuItem.selectionArc = 8
|
||||
|
||||
Menu.selectionBackground = @menuSelectionBackground
|
||||
MenuItem.selectionBackground = @menuSelectionBackground
|
||||
CheckBoxMenuItem.selectionBackground = @menuSelectionBackground
|
||||
RadioButtonMenuItem.selectionBackground = @menuSelectionBackground
|
||||
|
||||
|
||||
#---- PasswordField ---
|
||||
|
||||
PasswordField.disabledBackground = @disabledComponentBackground
|
||||
PasswordField.selectionBackground = @textSelectionBackground
|
||||
PasswordField.selectionForeground = @textSelectionForeground
|
||||
|
||||
|
||||
#---- PopupMenu ----
|
||||
|
||||
PopupMenu.borderInsets = 6,1,6,1
|
||||
|
||||
|
||||
#---- 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
|
||||
|
||||
# from FlatLaf.properties (when using not on macOS)
|
||||
ScrollBar.minimumThumbSize = 18,18
|
||||
ScrollBar.thumbInsets = 2,2,2,2
|
||||
ScrollBar.thumbArc = 999
|
||||
ScrollBar.hoverThumbWithTrack = true
|
||||
|
||||
|
||||
#---- 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
|
||||
@@ -0,0 +1,284 @@
|
||||
#
|
||||
# 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
|
||||
|
||||
# menu
|
||||
@menuSelectionBackground = lighten(@accentColor,12%)
|
||||
@menuCheckBackground = lighten(@menuSelectionBackground,25%,derived noAutoInverse)
|
||||
@menuItemMargin = 3,11,3,11
|
||||
|
||||
# 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
|
||||
ComboBox.selectionBackground = @menuSelectionBackground
|
||||
ComboBox.popupInsets = 5,0,5,0
|
||||
ComboBox.selectionInsets = 0,5,0,5
|
||||
ComboBox.selectionArc = 8
|
||||
|
||||
|
||||
#---- 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
|
||||
|
||||
|
||||
#---- MenuBar ----
|
||||
|
||||
MenuBar.selectionInsets = 0,0,0,0
|
||||
MenuBar.selectionEmbeddedInsets = 3,0,3,0
|
||||
MenuBar.selectionArc = 8
|
||||
MenuBar.selectionBackground = darken(@menuBackground,15%,derived)
|
||||
MenuBar.selectionForeground = @foreground
|
||||
|
||||
|
||||
#---- MenuItem ----
|
||||
|
||||
MenuItem.selectionInsets = 0,5,0,5
|
||||
MenuItem.selectionArc = 8
|
||||
|
||||
Menu.selectionBackground = @menuSelectionBackground
|
||||
MenuItem.selectionBackground = @menuSelectionBackground
|
||||
CheckBoxMenuItem.selectionBackground = @menuSelectionBackground
|
||||
RadioButtonMenuItem.selectionBackground = @menuSelectionBackground
|
||||
|
||||
|
||||
#---- PasswordField ---
|
||||
|
||||
PasswordField.disabledBackground = @disabledComponentBackground
|
||||
PasswordField.selectionBackground = @textSelectionBackground
|
||||
PasswordField.selectionForeground = @textSelectionForeground
|
||||
|
||||
|
||||
#---- PopupMenu ----
|
||||
|
||||
PopupMenu.borderInsets = 6,1,6,1
|
||||
|
||||
|
||||
#---- 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%)
|
||||
|
||||
# from FlatLaf.properties (when using not on macOS)
|
||||
ScrollBar.minimumThumbSize = 18,18
|
||||
ScrollBar.thumbInsets = 2,2,2,2
|
||||
ScrollBar.thumbArc = 999
|
||||
ScrollBar.hoverThumbWithTrack = true
|
||||
|
||||
|
||||
#---- 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
|
||||
@@ -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 );
|
||||
|
||||
@@ -117,6 +117,7 @@ Menu.selectionBackground = Menu.background
|
||||
|
||||
MenuBar.hoverBackground = Menu.background
|
||||
MenuBar.underlineSelectionBackground = Menu.background
|
||||
MenuBar.selectionBackground = Menu.background
|
||||
|
||||
|
||||
#---- MenuItem ----
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
1604
flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt
Normal file
1604
flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt
Normal file
File diff suppressed because it is too large
Load Diff
1608
flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt
Normal file
1608
flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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 )
|
||||
@@ -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>
|
||||
@@ -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,
|
||||
|
||||
@@ -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 / ",
|
||||
|
||||
@@ -515,13 +515,7 @@ class FlatThemePreviewAll
|
||||
"bb",
|
||||
"ccc",
|
||||
"dd",
|
||||
"e",
|
||||
"ff",
|
||||
"ggg",
|
||||
"hh",
|
||||
"i",
|
||||
"jj",
|
||||
"kkk"
|
||||
"e"
|
||||
}));
|
||||
comboBox3.setMaximumRowCount(6);
|
||||
comboBox3.putClientProperty("FlatLaf.styleClass", "flatlaf-preview-combobox");
|
||||
|
||||
@@ -201,12 +201,6 @@ new FormModel {
|
||||
addElement( "ccc" )
|
||||
addElement( "dd" )
|
||||
addElement( "e" )
|
||||
addElement( "ff" )
|
||||
addElement( "ggg" )
|
||||
addElement( "hh" )
|
||||
addElement( "i" )
|
||||
addElement( "jj" )
|
||||
addElement( "kkk" )
|
||||
}
|
||||
"maximumRowCount": 6
|
||||
"$client.FlatLaf.styleClass": "flatlaf-preview-combobox"
|
||||
|
||||
Reference in New Issue
Block a user