Compare commits
109 Commits
2.5
...
fonts/inte
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09c7f15364 | ||
|
|
b879b393ad | ||
|
|
e4503c2a54 | ||
|
|
7e2d02b997 | ||
|
|
d286550572 | ||
|
|
4e44e25d30 | ||
|
|
9fef2f9d05 | ||
|
|
04f1f5921d | ||
|
|
f9ecffb850 | ||
|
|
c9b5274ccf | ||
|
|
d209d47b9e | ||
|
|
21baaf810c | ||
|
|
95b4366270 | ||
|
|
c3adadfe2f | ||
|
|
adf7753617 | ||
|
|
d491847754 | ||
|
|
6afc747790 | ||
|
|
ff46935448 | ||
|
|
78c2f98f1f | ||
|
|
91be9aa2fe | ||
|
|
13e5da584f | ||
|
|
1762e0b7a6 | ||
|
|
05240abfe0 | ||
|
|
b515e8be04 | ||
|
|
24bc7fb0b5 | ||
|
|
0d2e1e6d18 | ||
|
|
f23c523baf | ||
|
|
76fee29f5b | ||
|
|
ec77746a43 | ||
|
|
92cd6f8f34 | ||
|
|
e7d2b5cbb6 | ||
|
|
4d175da3a0 | ||
|
|
5f047ddda9 | ||
|
|
ccca6fe88e | ||
|
|
a1f18e1ec9 | ||
|
|
afdaf7a0a5 | ||
|
|
62f0ef19f4 | ||
|
|
b736502c27 | ||
|
|
2be2dae3d6 | ||
|
|
aefe104ca4 | ||
|
|
3e6bce9cec | ||
|
|
a6394cac38 | ||
|
|
1e09ddfc93 | ||
|
|
664f5c98e9 | ||
|
|
c7bfd2ea82 | ||
|
|
9ce7ddd088 | ||
|
|
cca8d427d2 | ||
|
|
aa9263a2e7 | ||
|
|
5eaebde437 | ||
|
|
7f15f557a5 | ||
|
|
b459715cb5 | ||
|
|
bfede219d0 | ||
|
|
ef21efecf5 | ||
|
|
2bfbc9dc12 | ||
|
|
c3a1b45546 | ||
|
|
b72508f920 | ||
|
|
22bb80218d | ||
|
|
873a7e8572 | ||
|
|
0c5016fe89 | ||
|
|
607b084697 | ||
|
|
9d8ffec276 | ||
|
|
15f08e9b7c | ||
|
|
08aa6b1894 | ||
|
|
06b02c4f7c | ||
|
|
b56acd271f | ||
|
|
b24e2db59e | ||
|
|
f215356629 | ||
|
|
069a7c809c | ||
|
|
883b4d735a | ||
|
|
9f39b269bb | ||
|
|
36c405c708 | ||
|
|
bc7c68ebe4 | ||
|
|
6c502ad4c5 | ||
|
|
100aa0b621 | ||
|
|
8e42b19934 | ||
|
|
1a456d5d68 | ||
|
|
e83c26a76a | ||
|
|
6e7c2a616b | ||
|
|
0699454df8 | ||
|
|
92c110548a | ||
|
|
ca88023560 | ||
|
|
12fc2299ec | ||
|
|
2089c77b84 | ||
|
|
95522846ac | ||
|
|
f7be12df67 | ||
|
|
a1d1e221ae | ||
|
|
0a4dc54fb9 | ||
|
|
b8c7801365 | ||
|
|
a7099c039f | ||
|
|
a4d2d347e3 | ||
|
|
829c537fd3 | ||
|
|
28437f99cf | ||
|
|
c1402d85e1 | ||
|
|
32e071ab89 | ||
|
|
01125e030e | ||
|
|
b43278439a | ||
|
|
7a445aabd7 | ||
|
|
380dae1017 | ||
|
|
fb15cdc546 | ||
|
|
a525fe29db | ||
|
|
bf0685cee2 | ||
|
|
8262793751 | ||
|
|
5ec7848fb0 | ||
|
|
450fc123ff | ||
|
|
3802c64be3 | ||
|
|
7bf1b26812 | ||
|
|
f1792e46c6 | ||
|
|
84e9c36280 | ||
|
|
2ef6a2c3c9 |
2
.gitattributes
vendored
@@ -20,7 +20,9 @@
|
|||||||
*.gif binary
|
*.gif binary
|
||||||
*.jar binary
|
*.jar binary
|
||||||
*.lib binary
|
*.lib binary
|
||||||
|
*.otf binary
|
||||||
*.png binary
|
*.png binary
|
||||||
*.sketch binary
|
*.sketch binary
|
||||||
*.so binary
|
*.so binary
|
||||||
|
*.ttf binary
|
||||||
*.zip binary
|
*.zip binary
|
||||||
|
|||||||
1
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
custom: https://www.formdev.com/flatlaf/sponsor/
|
||||||
17
.github/workflows/ci.yml
vendored
@@ -1,4 +1,5 @@
|
|||||||
# https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
|
||||||
|
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
|
||||||
|
|
||||||
name: CI
|
name: CI
|
||||||
|
|
||||||
@@ -8,9 +9,6 @@ on:
|
|||||||
- '*'
|
- '*'
|
||||||
tags:
|
tags:
|
||||||
- '[0-9]*'
|
- '[0-9]*'
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- '*'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -26,6 +24,10 @@ jobs:
|
|||||||
- 8
|
- 8
|
||||||
- 11 # LTS
|
- 11 # LTS
|
||||||
- 17 # LTS
|
- 17 # LTS
|
||||||
|
toolchain: [""]
|
||||||
|
include:
|
||||||
|
- java: 17
|
||||||
|
toolchain: 19 # latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -41,7 +43,7 @@ jobs:
|
|||||||
cache: gradle
|
cache: gradle
|
||||||
|
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: ./gradlew build
|
run: ./gradlew build -Dtoolchain=${{ matrix.toolchain }}
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
@@ -50,6 +52,7 @@ jobs:
|
|||||||
name: FlatLaf-build-artifacts
|
name: FlatLaf-build-artifacts
|
||||||
path: |
|
path: |
|
||||||
flatlaf-*/build/libs
|
flatlaf-*/build/libs
|
||||||
|
flatlaf-*/flatlaf-*/build/libs
|
||||||
!**/*-javadoc.jar
|
!**/*-javadoc.jar
|
||||||
!**/*-sources.jar
|
!**/*-sources.jar
|
||||||
|
|
||||||
@@ -73,7 +76,7 @@ jobs:
|
|||||||
cache: gradle
|
cache: gradle
|
||||||
|
|
||||||
- name: Publish snapshot to oss.sonatype.org
|
- name: Publish snapshot to oss.sonatype.org
|
||||||
run: ./gradlew publish :flatlaf-theme-editor:build -Dorg.gradle.internal.publish.checksums.insecure=true
|
run: ./gradlew publish :flatlaf-theme-editor:build -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true
|
||||||
env:
|
env:
|
||||||
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||||
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||||
@@ -109,7 +112,7 @@ jobs:
|
|||||||
cache: gradle
|
cache: gradle
|
||||||
|
|
||||||
- name: Release a new stable version to Maven Central
|
- name: Release a new stable version to Maven Central
|
||||||
run: ./gradlew publish :flatlaf-demo:build :flatlaf-theme-editor:build -Drelease=true
|
run: ./gradlew publish :flatlaf-demo:build :flatlaf-theme-editor:build -PskipFonts -Prelease
|
||||||
env:
|
env:
|
||||||
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||||
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||||
|
|||||||
59
.github/workflows/fonts.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
|
||||||
|
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
|
||||||
|
|
||||||
|
name: Fonts
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- '*'
|
||||||
|
tags:
|
||||||
|
- 'fonts/*-[0-9]*'
|
||||||
|
paths:
|
||||||
|
- 'flatlaf-fonts/**'
|
||||||
|
- '.github/workflows/fonts.yml'
|
||||||
|
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Fonts:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
font:
|
||||||
|
- inter
|
||||||
|
- jetbrains-mono
|
||||||
|
- roboto
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: |
|
||||||
|
github.event_name == 'push' &&
|
||||||
|
github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Setup Java 11
|
||||||
|
uses: actions/setup-java@v3
|
||||||
|
with:
|
||||||
|
java-version: 11
|
||||||
|
distribution: adopt # pre-installed on ubuntu-latest
|
||||||
|
cache: gradle
|
||||||
|
|
||||||
|
- name: Build with Gradle
|
||||||
|
run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build
|
||||||
|
if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) ) != true
|
||||||
|
|
||||||
|
- name: Publish snapshot to oss.sonatype.org
|
||||||
|
run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:publish -Dorg.gradle.internal.publish.checksums.insecure=true
|
||||||
|
env:
|
||||||
|
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||||
|
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||||
|
if: github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' )
|
||||||
|
|
||||||
|
- name: Release a new stable version to Maven Central
|
||||||
|
run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build :flatlaf-fonts-${{ matrix.font }}:publish -Prelease
|
||||||
|
env:
|
||||||
|
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||||
|
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||||
|
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||||
|
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
|
||||||
|
if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) )
|
||||||
10
.github/workflows/natives.yml
vendored
@@ -1,4 +1,5 @@
|
|||||||
# https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
|
||||||
|
# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
|
||||||
|
|
||||||
name: Native Libraries
|
name: Native Libraries
|
||||||
|
|
||||||
@@ -12,13 +13,6 @@ on:
|
|||||||
- 'flatlaf-natives/**'
|
- 'flatlaf-natives/**'
|
||||||
- '.github/workflows/natives.yml'
|
- '.github/workflows/natives.yml'
|
||||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- '*'
|
|
||||||
paths:
|
|
||||||
- 'flatlaf-natives/**'
|
|
||||||
- '.github/workflows/natives.yml'
|
|
||||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Natives:
|
Natives:
|
||||||
|
|||||||
2
.gitignore
vendored
@@ -9,5 +9,7 @@ out/
|
|||||||
*.iml
|
*.iml
|
||||||
*.ipr
|
*.ipr
|
||||||
*.iws
|
*.iws
|
||||||
|
*.xcuserstate
|
||||||
|
*.xcworkspacedata
|
||||||
.vs/
|
.vs/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|||||||
63
CHANGELOG.md
@@ -1,6 +1,69 @@
|
|||||||
FlatLaf Change Log
|
FlatLaf Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
## 3.0
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- **macOS light and dark themes**: The two new themes `FlatMacLightLaf` and
|
||||||
|
`FlatMacDarkLaf` use macOS colors and look similar to native macOS controls.
|
||||||
|
(PRs #533, #612 and #607)
|
||||||
|
- **Fonts**: Packaged some fonts into JARs and provide an easy way to use them
|
||||||
|
with FlatLaf. (PRs #545, #614 and #615) At the moment there are three fonts:
|
||||||
|
- **Inter** (https://rsms.me/inter/) - a typeface carefully crafted & designed
|
||||||
|
for computer screens
|
||||||
|
- **Roboto** (https://fonts.google.com/specimen/Roboto) - default font on
|
||||||
|
Android and recommended for Material Design
|
||||||
|
- **JetBrains Mono** (https://www.jetbrains.com/mono) - a monospaced typeface
|
||||||
|
- **Rounded selection**: Optionally use rounded selection in:
|
||||||
|
- Menus (PR #536)
|
||||||
|
- ComboBox (PR #548)
|
||||||
|
- List (PR #547)
|
||||||
|
- Tree (PR #546)
|
||||||
|
- Tree: Hide default closed/opened/leaf icons by default. Set UI value
|
||||||
|
`Tree.showDefaultIcons` to `true` to show them.
|
||||||
|
- ToolBar: Hover effect for button groups. (PR #534)
|
||||||
|
- Icons: New modern **rounded outlined icons** for `JFileChooser`,
|
||||||
|
`JOptionPane`, `JPasswordField` and `JTree`. (PR #577)
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- FileChooser: Fixed layout of (optional) accessory component and fixed too
|
||||||
|
large right margin. (issue #604; regression since implementing PR #522 in
|
||||||
|
FlatLaf 2.3)
|
||||||
|
- Tree:
|
||||||
|
- Fixed missing tree lines (if enabled) for wide-selected rows. (issue #598)
|
||||||
|
- Fixed scaling of tree lines and fixed alignment to expand/collapse arrows.
|
||||||
|
- Removed support for dashed tree lines. `Tree.lineTypeDashed` is now ignored.
|
||||||
|
- SwingX: Fonts in `JXHeader`, `JXMonthView`, `JXTaskPane` and `JXTitledPanel`
|
||||||
|
were not updated when changing default font.
|
||||||
|
|
||||||
|
|
||||||
|
## 2.6
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- If value of system property `flatlaf.nativeLibraryPath` is `system`, then
|
||||||
|
`System.loadLibrary(String)` is used to load the native library.
|
||||||
|
- TabbedPane: Switch and close tabs on left mouse click only. (PR #595)
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- ComboBox and Spinner: Fixed missing arrow buttons if preferred height is zero.
|
||||||
|
Minimum width of arrow buttons is 3/4 of default width.
|
||||||
|
- MenuBar: Fixed NPE in `FlatMenuItemRenderer.getTopLevelFont()` if menu item
|
||||||
|
does not have a parent. (issue #600; regression since implementing #589 in
|
||||||
|
FlatLaf 2.5)
|
||||||
|
- ScrollBar: Show "pressed" feedback on track/thumb only for left mouse button.
|
||||||
|
If absolute positioning is enabled (the default), then also for middle mouse
|
||||||
|
button.
|
||||||
|
- Arrow buttons in ComboBox, Spinner, ScrollBar and TabbedPane: Show "pressed"
|
||||||
|
feedback only for left mouse button.
|
||||||
|
- ScaledImageIcon: Do not throw exceptions if image was has invalid size (e.g.
|
||||||
|
not found). Instead, paint a red rectangle (similar to `FlatSVGIcon`).
|
||||||
|
- Fixed NPE in `FlatUIUtils.isCellEditor()`. (issue #601)
|
||||||
|
|
||||||
|
|
||||||
## 2.5
|
## 2.5
|
||||||
|
|
||||||
#### New features and improvements
|
#### New features and improvements
|
||||||
|
|||||||
85
README.md
@@ -25,6 +25,17 @@ FlatLaf can use 3rd party themes created for IntelliJ Platform (see
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
Sponsors
|
||||||
|
--------
|
||||||
|
|
||||||
|
<a href="https://www.ej-technologies.com/"><img src="https://www.formdev.com/flatlaf/sponsor/ej-technologies.png" width="200" alt="ej-technologies" title="ej-technologies - Java APM, Java Profiler, Java Installer Builder"></a>
|
||||||
|
|
||||||
|
<a href="https://www.dbvis.com/"><img src="https://www.formdev.com/flatlaf/sponsor/dbvisualizer.svg" width="200" alt="DbVisualizer" title="DbVisualizer - SQL Client and Editor"></a>
|
||||||
|
|
||||||
|
<a href="https://www.dscsag.com/"><img src="https://www.formdev.com/flatlaf/sponsor/DSC.png" height="48" alt="DSC Software AG" title="DSC Software AG - Your Companion for Integrative PLM"></a>
|
||||||
|
|
||||||
|
[Become a Sponsor](https://www.formdev.com/flatlaf/sponsor/)
|
||||||
|
|
||||||
Demo
|
Demo
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -74,6 +85,8 @@ Addons
|
|||||||
- [SwingX](flatlaf-swingx) - support for SwingX components
|
- [SwingX](flatlaf-swingx) - support for SwingX components
|
||||||
- [JIDE Common Layer](flatlaf-jide-oss) - support for JIDE Common Layer
|
- [JIDE Common Layer](flatlaf-jide-oss) - support for JIDE Common Layer
|
||||||
components
|
components
|
||||||
|
- [Fonts](flatlaf-fonts) - some font families bundled in easy-to-use and
|
||||||
|
redistributable JARs
|
||||||
|
|
||||||
|
|
||||||
Getting started
|
Getting started
|
||||||
@@ -126,42 +139,64 @@ Buzz
|
|||||||
Applications using FlatLaf
|
Applications using FlatLaf
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
-  [Ultorg](https://www.ultorg.com/) (**commercial**) - a
|
- 
|
||||||
|
[JProfiler](https://www.ej-technologies.com/products/jprofiler/overview.html)
|
||||||
|
12 (**commercial**) - the award-winning all-in-one Java profiler
|
||||||
|
-  [JFormDesigner](https://www.formdev.com/) 8
|
||||||
|
(**commercial**) - Java/Swing GUI Designer
|
||||||
|
-  [Jeyla Studio](https://www.jeylastudio.com/) - Salon
|
||||||
|
Software
|
||||||
|
-  [Fanurio](https://www.fanuriotimetracking.com/) 3.3.2
|
||||||
|
(**commercial**) - time tracking and billing for freelancers and teams
|
||||||
|
-  [Antares](https://www.antarescircuit.io/) - a free,
|
||||||
|
powerful platform for designing, simulating and explaining digital circuits
|
||||||
|
- 
|
||||||
|
[Logisim-evolution](https://github.com/logisim-evolution/logisim-evolution)
|
||||||
|
3.6 - Digital logic design tool and simulator
|
||||||
|
-  [Cinecred](https://loadingbyte.com/cinecred/) - create
|
||||||
|
beautiful film credit sequences
|
||||||
|
-  [tinyMediaManager](https://www.tinymediamanager.org/)
|
||||||
|
v4 (**commercial**) - a media management tool
|
||||||
|
-  [Weasis](https://nroduit.github.io/) - medical DICOM
|
||||||
|
viewer used in healthcare by hospitals, health networks, etc
|
||||||
|
- 
|
||||||
|
[Makelangelo Software](https://github.com/MarginallyClever/Makelangelo-software)
|
||||||
|
7.3.0 - for plotters, especially the wall-hanging polargraph
|
||||||
|
-  [Ultorg](https://www.ultorg.com/) (**commercial**) - a
|
||||||
visual query system for relational databases
|
visual query system for relational databases
|
||||||
-  [MooInfo](https://github.com/rememberber/MooInfo) -
|
- [MooInfo](https://github.com/rememberber/MooInfo) - visual implementation of
|
||||||
visual implementation of OSHI, to view information about the system and
|
OSHI, to view information about the system and hardware
|
||||||
hardware
|
- [Jailer](https://github.com/Wisser/Jailer) 11.2 - database subsetting and
|
||||||
-  [Jailer](https://github.com/Wisser/Jailer) 11.2 -
|
relational data browsing tool
|
||||||
database subsetting and relational data browsing tool
|
-  [Apache NetBeans](https://netbeans.apache.org/) 11.3 -
|
||||||
- [Apache NetBeans](https://netbeans.apache.org/) 11.3 - IDE for Java, PHP, HTML
|
IDE for Java, PHP, HTML and much more
|
||||||
and much more
|
|
||||||
- [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) 5.5
|
- [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) 5.5
|
||||||
- [KeyStore Explorer](https://keystore-explorer.org/) 5.4.3
|
- [KeyStore Explorer](https://keystore-explorer.org/) 5.4.3
|
||||||
- 
|
- 
|
||||||
[install4j](https://www.ej-technologies.com/products/install4j/overview.html)
|
[install4j](https://www.ej-technologies.com/products/install4j/overview.html)
|
||||||
9.0 (**commercial**) - the powerful multi-platform Java installer builder
|
9.0 (**commercial**) - the powerful multi-platform Java installer builder
|
||||||
-  [DbVisualizer](https://www.dbvis.com/) 12.0
|
-  [DbVisualizer](https://www.dbvis.com/) 12.0
|
||||||
(**commercial**) - the universal database tool for developers, analysts and
|
(**commercial**) - the universal database tool for developers, analysts and
|
||||||
DBAs
|
DBAs
|
||||||
-  [MagicPlot](https://magicplot.com/) 3.0
|
-  [MagicPlot](https://magicplot.com/) 3.0
|
||||||
(**commercial**) - Software for nonlinear fitting, plotting and data analysis
|
(**commercial**) - Software for nonlinear fitting, plotting and data analysis
|
||||||
- 
|
- 
|
||||||
[Thermo-Calc](https://thermocalc.com/products/thermo-calc/) 2021a
|
[Thermo-Calc](https://thermocalc.com/products/thermo-calc/) 2021a
|
||||||
(**commercial**) - Thermodynamics and Properties Software
|
(**commercial**) - Thermodynamics and Properties Software
|
||||||
- [OWASP ZAP](https://www.zaproxy.org/) 2.10 - the worlds most widely used web
|
-  [OWASP ZAP](https://www.zaproxy.org/) 2.10 - the worlds
|
||||||
app scanner
|
most widely used web app scanner
|
||||||
- 
|
- 
|
||||||
[Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro)
|
[Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro)
|
||||||
2020.11.2 (**commercial**) - the leading software for web security testing
|
2020.11.2 (**commercial**) - the leading software for web security testing
|
||||||
- 
|
- [BurpCustomizer](https://github.com/CoreyD97/BurpCustomizer) - adds more
|
||||||
[BurpCustomizer](https://github.com/CoreyD97/BurpCustomizer) - adds more
|
|
||||||
FlatLaf themes to Burp Suite
|
FlatLaf themes to Burp Suite
|
||||||
- [JOSM](https://josm.openstreetmap.de/) - an extensible editor for
|
-  [JOSM](https://josm.openstreetmap.de/) - an extensible
|
||||||
[OpenStreetMap](https://www.openstreetmap.org/) (requires FlatLaf JOSM plugin)
|
editor for [OpenStreetMap](https://www.openstreetmap.org/) (requires FlatLaf
|
||||||
- [jAlbum](https://jalbum.net/) 21 (**commercial**) - creates photo album
|
JOSM plugin)
|
||||||
websites
|
-  [jAlbum](https://jalbum.net/) 21 (**commercial**) -
|
||||||
-  [PDF Studio](https://www.qoppa.com/pdfstudio/) 2021
|
creates photo album websites
|
||||||
(**commercial**) - create, review and edit PDF documents
|
- [PDF Studio](https://www.qoppa.com/pdfstudio/) 2021 (**commercial**) - create,
|
||||||
|
review and edit PDF documents
|
||||||
- [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) 9.3 (**commercial**)
|
- [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) 9.3 (**commercial**)
|
||||||
- [Total Validator](https://www.totalvalidator.com/) 15 (**commercial**) -
|
- [Total Validator](https://www.totalvalidator.com/) 15 (**commercial**) -
|
||||||
checks your website
|
checks your website
|
||||||
@@ -187,8 +222,8 @@ Applications using FlatLaf
|
|||||||
[mendelson AS2](https://mendelson-e-c.com/as2/),
|
[mendelson AS2](https://mendelson-e-c.com/as2/),
|
||||||
[AS4](https://mendelson-e-c.com/as4/) and
|
[AS4](https://mendelson-e-c.com/as4/) and
|
||||||
[OFTP2](https://mendelson-e-c.com/oftp2) (**commercial**)
|
[OFTP2](https://mendelson-e-c.com/oftp2) (**commercial**)
|
||||||
-  [IGMAS+](https://www.gfz-potsdam.de/igmas) -
|
- [IGMAS+](https://www.gfz-potsdam.de/igmas) - Interactive Gravity and Magnetic
|
||||||
Interactive Gravity and Magnetic Application System
|
Application System
|
||||||
- [MeteoInfo](https://github.com/meteoinfo/MeteoInfo) 2.2 - GIS and scientific
|
- [MeteoInfo](https://github.com/meteoinfo/MeteoInfo) 2.2 - GIS and scientific
|
||||||
computation environment for meteorological community
|
computation environment for meteorological community
|
||||||
- [lsfusion platform](https://github.com/lsfusion/platform) 4 - information
|
- [lsfusion platform](https://github.com/lsfusion/platform) 4 - information
|
||||||
|
|||||||
@@ -14,10 +14,10 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val releaseVersion = "2.5"
|
val releaseVersion = "3.0"
|
||||||
val developmentVersion = "3.0-SNAPSHOT"
|
val developmentVersion = "3.1-SNAPSHOT"
|
||||||
|
|
||||||
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
version = if( rootProject.hasProperty( "release" ) ) releaseVersion else developmentVersion
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
version = rootProject.version
|
version = rootProject.version
|
||||||
@@ -37,6 +37,9 @@ println( "----------------------------------------------------------------------
|
|||||||
println( "FlatLaf Version: ${version}" )
|
println( "FlatLaf Version: ${version}" )
|
||||||
println( "Gradle ${gradle.gradleVersion} at ${gradle.gradleHomeDir}" )
|
println( "Gradle ${gradle.gradleVersion} at ${gradle.gradleHomeDir}" )
|
||||||
println( "Java ${System.getProperty( "java.version" )}" )
|
println( "Java ${System.getProperty( "java.version" )}" )
|
||||||
|
val toolchainJavaVersion = System.getProperty( "toolchain" )
|
||||||
|
if( !toolchainJavaVersion.isNullOrEmpty() )
|
||||||
|
println( "Java toolchain ${toolchainJavaVersion}" )
|
||||||
println()
|
println()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ publishing {
|
|||||||
|
|
||||||
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
||||||
val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
|
val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||||
url = uri( if( java.lang.Boolean.getBoolean( "release" ) ) releasesRepoUrl else snapshotsRepoUrl )
|
url = uri( if( rootProject.hasProperty( "release" ) ) releasesRepoUrl else snapshotsRepoUrl )
|
||||||
|
|
||||||
credentials {
|
credentials {
|
||||||
// get from gradle.properties
|
// get from gradle.properties
|
||||||
@@ -108,5 +108,5 @@ signing {
|
|||||||
|
|
||||||
// disable signing of snapshots
|
// disable signing of snapshots
|
||||||
tasks.withType<Sign>().configureEach {
|
tasks.withType<Sign>().configureEach {
|
||||||
onlyIf { java.lang.Boolean.getBoolean( "release" ) }
|
onlyIf { rootProject.hasProperty( "release" ) }
|
||||||
}
|
}
|
||||||
|
|||||||
26
buildSrc/src/main/kotlin/flatlaf-toolchain.gradle.kts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
java
|
||||||
|
}
|
||||||
|
|
||||||
|
val toolchainJavaVersion = System.getProperty( "toolchain" )
|
||||||
|
if( !toolchainJavaVersion.isNullOrEmpty() ) {
|
||||||
|
java.toolchain {
|
||||||
|
languageVersion.set( JavaLanguageVersion.of( toolchainJavaVersion ) )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
|
`flatlaf-toolchain`
|
||||||
`flatlaf-module-info`
|
`flatlaf-module-info`
|
||||||
`flatlaf-java9`
|
`flatlaf-java9`
|
||||||
`flatlaf-publish`
|
`flatlaf-publish`
|
||||||
@@ -86,7 +87,7 @@ tasks {
|
|||||||
"action" to "generate",
|
"action" to "generate",
|
||||||
"fileName" to "${project.name}-sigtest.txt",
|
"fileName" to "${project.name}-sigtest.txt",
|
||||||
"classpath" to jar.get().outputs.files.asPath,
|
"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,
|
"version" to version,
|
||||||
"release" to "1.8", // Java version
|
"release" to "1.8", // Java version
|
||||||
"failonerror" to "true" )
|
"failonerror" to "true" )
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Signature file v4.1
|
#Signature file v4.1
|
||||||
#Version 2.4
|
#Version 2.6
|
||||||
|
|
||||||
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
||||||
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
|
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
|
||||||
@@ -11,6 +11,7 @@ fld public final static java.lang.String BUTTON_TYPE_TAB = "tab"
|
|||||||
fld public final static java.lang.String BUTTON_TYPE_TOOLBAR_BUTTON = "toolBarButton"
|
fld public final static java.lang.String BUTTON_TYPE_TOOLBAR_BUTTON = "toolBarButton"
|
||||||
fld public final static java.lang.String COMPONENT_FOCUS_OWNER = "JComponent.focusOwner"
|
fld public final static java.lang.String COMPONENT_FOCUS_OWNER = "JComponent.focusOwner"
|
||||||
fld public final static java.lang.String COMPONENT_ROUND_RECT = "JComponent.roundRect"
|
fld public final static java.lang.String COMPONENT_ROUND_RECT = "JComponent.roundRect"
|
||||||
|
fld public final static java.lang.String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption"
|
||||||
fld public final static java.lang.String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded"
|
fld public final static java.lang.String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded"
|
||||||
fld public final static java.lang.String MINIMUM_HEIGHT = "JComponent.minimumHeight"
|
fld public final static java.lang.String MINIMUM_HEIGHT = "JComponent.minimumHeight"
|
||||||
fld public final static java.lang.String MINIMUM_WIDTH = "JComponent.minimumWidth"
|
fld public final static java.lang.String MINIMUM_WIDTH = "JComponent.minimumWidth"
|
||||||
@@ -185,6 +186,7 @@ meth public java.lang.String getID()
|
|||||||
meth public java.util.Map<java.lang.String,java.lang.String> getExtraDefaults()
|
meth public java.util.Map<java.lang.String,java.lang.String> getExtraDefaults()
|
||||||
meth public javax.swing.Icon getDisabledIcon(javax.swing.JComponent,javax.swing.Icon)
|
meth public javax.swing.Icon getDisabledIcon(javax.swing.JComponent,javax.swing.Icon)
|
||||||
meth public javax.swing.UIDefaults getDefaults()
|
meth public javax.swing.UIDefaults getDefaults()
|
||||||
|
meth public static <%0 extends java.lang.Object> {%%0} getStyleableValue(javax.swing.JComponent,java.lang.String)
|
||||||
meth public static boolean install(javax.swing.LookAndFeel)
|
meth public static boolean install(javax.swing.LookAndFeel)
|
||||||
anno 0 java.lang.Deprecated()
|
anno 0 java.lang.Deprecated()
|
||||||
meth public static boolean isLafDark()
|
meth public static boolean isLafDark()
|
||||||
@@ -193,6 +195,7 @@ meth public static boolean isUseNativeWindowDecorations()
|
|||||||
meth public static boolean setup(javax.swing.LookAndFeel)
|
meth public static boolean setup(javax.swing.LookAndFeel)
|
||||||
meth public static boolean supportsNativeWindowDecorations()
|
meth public static boolean supportsNativeWindowDecorations()
|
||||||
meth public static java.lang.Object parseDefaultsValue(java.lang.String,java.lang.String,java.lang.Class<?>)
|
meth public static java.lang.Object parseDefaultsValue(java.lang.String,java.lang.String,java.lang.Class<?>)
|
||||||
|
meth public static java.util.Map<java.lang.String,java.lang.Class<?>> getStyleableInfos(javax.swing.JComponent)
|
||||||
meth public static java.util.Map<java.lang.String,java.lang.String> getGlobalExtraDefaults()
|
meth public static java.util.Map<java.lang.String,java.lang.String> getGlobalExtraDefaults()
|
||||||
meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float)
|
meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float)
|
||||||
meth public static void hideMnemonics()
|
meth public static void hideMnemonics()
|
||||||
@@ -220,7 +223,7 @@ meth public void setExtraDefaults(java.util.Map<java.lang.String,java.lang.Strin
|
|||||||
meth public void uninitialize()
|
meth public void uninitialize()
|
||||||
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
||||||
supr javax.swing.plaf.basic.BasicLookAndFeel
|
supr javax.swing.plaf.basic.BasicLookAndFeel
|
||||||
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,subMenuUsabilityHelperInstalled,uiDefaultsGetters,updateUIPending
|
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,getUIMethod,getUIMethodInitialized,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,subMenuUsabilityHelperInstalled,uiDefaultsGetters,updateUIPending
|
||||||
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
|
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
|
||||||
|
|
||||||
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
|
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
|
||||||
@@ -259,6 +262,7 @@ fld public final static java.lang.String NATIVE_LIBRARY_PATH = "flatlaf.nativeLi
|
|||||||
fld public final static java.lang.String UI_SCALE = "flatlaf.uiScale"
|
fld public final static java.lang.String UI_SCALE = "flatlaf.uiScale"
|
||||||
fld public final static java.lang.String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.uiScale.allowScaleDown"
|
fld public final static java.lang.String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.uiScale.allowScaleDown"
|
||||||
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
|
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
|
||||||
|
fld public final static java.lang.String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange"
|
||||||
fld public final static java.lang.String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations"
|
fld public final static java.lang.String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations"
|
||||||
fld public final static java.lang.String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection"
|
fld public final static java.lang.String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection"
|
||||||
fld public final static java.lang.String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont"
|
fld public final static java.lang.String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont"
|
||||||
@@ -600,6 +604,7 @@ supr java.lang.Object
|
|||||||
|
|
||||||
CLSS public com.formdev.flatlaf.util.NativeLibrary
|
CLSS public com.formdev.flatlaf.util.NativeLibrary
|
||||||
cons public init(java.io.File,boolean)
|
cons public init(java.io.File,boolean)
|
||||||
|
cons public init(java.lang.String,boolean)
|
||||||
cons public init(java.lang.String,java.lang.ClassLoader,boolean)
|
cons public init(java.lang.String,java.lang.ClassLoader,boolean)
|
||||||
meth public boolean isLoaded()
|
meth public boolean isLoaded()
|
||||||
supr java.lang.Object
|
supr java.lang.Object
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ public interface FlatClientProperties
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether the window icon should be shown in the window title bar
|
* Specifies whether the window icon should be shown in the window title bar
|
||||||
* (requires enabled window decorations).
|
* (requires enabled window decorations). Default is UI property {@code TitlePane.showIcon}.
|
||||||
* <p>
|
* <p>
|
||||||
* Setting this shows/hides the windows icon
|
* Setting this shows/hides the windows icon
|
||||||
* for the {@code JFrame} or {@code JDialog} that contains the root pane.
|
* for the {@code JFrame} or {@code JDialog} that contains the root pane.
|
||||||
@@ -362,6 +362,62 @@ public interface FlatClientProperties
|
|||||||
*/
|
*/
|
||||||
String TITLE_BAR_SHOW_ICON = "JRootPane.titleBarShowIcon";
|
String TITLE_BAR_SHOW_ICON = "JRootPane.titleBarShowIcon";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the window title should be shown in the window title bar
|
||||||
|
* (requires enabled window decorations). Default is {@code true}.
|
||||||
|
* <p>
|
||||||
|
* Setting this shows/hides the windows title
|
||||||
|
* for the {@code JFrame} or {@code JDialog} that contains the root pane.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
String TITLE_BAR_SHOW_TITLE = "JRootPane.titleBarShowTitle";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the "iconfify" button should be shown in the window title bar
|
||||||
|
* (requires enabled window decorations). Default is {@code true}.
|
||||||
|
* <p>
|
||||||
|
* Setting this shows/hides the "iconfify" button
|
||||||
|
* for the {@code JFrame} that contains the root pane.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
String TITLE_BAR_SHOW_ICONIFFY = "JRootPane.titleBarShowIconify";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the "maximize/restore" button should be shown in the window title bar
|
||||||
|
* (requires enabled window decorations). Default is {@code true}.
|
||||||
|
* <p>
|
||||||
|
* Setting this shows/hides the "maximize/restore" button
|
||||||
|
* for the {@code JFrame} that contains the root pane.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
String TITLE_BAR_SHOW_MAXIMIZE = "JRootPane.titleBarShowMaximize";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the "close" button should be shown in the window title bar
|
||||||
|
* (requires enabled window decorations). Default is {@code true}.
|
||||||
|
* <p>
|
||||||
|
* Setting this shows/hides the "close" button
|
||||||
|
* for the {@code JFrame} or {@code JDialog} that contains the root pane.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
String TITLE_BAR_SHOW_CLOSE = "JRootPane.titleBarShowClose";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Background color of window title bar (requires enabled window decorations).
|
* Background color of window title bar (requires enabled window decorations).
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -78,6 +78,7 @@ import com.formdev.flatlaf.ui.FlatPopupFactory;
|
|||||||
import com.formdev.flatlaf.ui.FlatRootPaneUI;
|
import com.formdev.flatlaf.ui.FlatRootPaneUI;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
|
import com.formdev.flatlaf.util.FontUtils;
|
||||||
import com.formdev.flatlaf.util.GrayFilter;
|
import com.formdev.flatlaf.util.GrayFilter;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
||||||
@@ -98,6 +99,7 @@ public abstract class FlatLaf
|
|||||||
private static List<Object> customDefaultsSources;
|
private static List<Object> customDefaultsSources;
|
||||||
private static Map<String, String> globalExtraDefaults;
|
private static Map<String, String> globalExtraDefaults;
|
||||||
private Map<String, String> extraDefaults;
|
private Map<String, String> extraDefaults;
|
||||||
|
private static Function<String, Color> systemColorGetter;
|
||||||
|
|
||||||
private String desktopPropertyName;
|
private String desktopPropertyName;
|
||||||
private String desktopPropertyName2;
|
private String desktopPropertyName2;
|
||||||
@@ -113,6 +115,11 @@ public abstract class FlatLaf
|
|||||||
private Consumer<UIDefaults> postInitialization;
|
private Consumer<UIDefaults> postInitialization;
|
||||||
private List<Function<Object, Object>> uiDefaultsGetters;
|
private List<Function<Object, Object>> uiDefaultsGetters;
|
||||||
|
|
||||||
|
private static String preferredFontFamily;
|
||||||
|
private static String preferredLightFontFamily;
|
||||||
|
private static String preferredSemiboldFontFamily;
|
||||||
|
private static String preferredMonospacedFontFamily;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the application look and feel to the given LaF
|
* Sets the application look and feel to the given LaF
|
||||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||||
@@ -630,6 +637,13 @@ public abstract class FlatLaf
|
|||||||
if( uiFont == null )
|
if( uiFont == null )
|
||||||
uiFont = createCompositeFont( Font.SANS_SERIF, Font.PLAIN, 12 );
|
uiFont = createCompositeFont( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||||
|
|
||||||
|
// use preferred font family (if specified)
|
||||||
|
if( preferredFontFamily != null ) {
|
||||||
|
FontUIResource preferredFont = createCompositeFont( preferredFontFamily, uiFont.getStyle(), uiFont.getSize() );
|
||||||
|
if( !ActiveFont.isFallbackFont( preferredFont ) || ActiveFont.isDialogFamily( preferredFontFamily ) )
|
||||||
|
uiFont = preferredFont;
|
||||||
|
}
|
||||||
|
|
||||||
// get/remove "defaultFont" from defaults if set in properties files
|
// get/remove "defaultFont" from defaults if set in properties files
|
||||||
// (use remove() to avoid that ActiveFont.createValue() gets invoked)
|
// (use remove() to avoid that ActiveFont.createValue() gets invoked)
|
||||||
Object defaultFont = defaults.remove( "defaultFont" );
|
Object defaultFont = defaults.remove( "defaultFont" );
|
||||||
@@ -650,6 +664,9 @@ public abstract class FlatLaf
|
|||||||
}
|
}
|
||||||
|
|
||||||
static FontUIResource createCompositeFont( String family, int style, int size ) {
|
static FontUIResource createCompositeFont( String family, int style, int size ) {
|
||||||
|
// load lazy font family
|
||||||
|
FontUtils.loadFontFamily( family );
|
||||||
|
|
||||||
// using StyleContext.getFont() here because it uses
|
// using StyleContext.getFont() here because it uses
|
||||||
// sun.font.FontUtilities.getCompositeFontUIResource()
|
// sun.font.FontUtilities.getCompositeFontUIResource()
|
||||||
// and creates a composite font that is able to display all Unicode characters
|
// and creates a composite font that is able to display all Unicode characters
|
||||||
@@ -897,14 +914,14 @@ public abstract class FlatLaf
|
|||||||
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The global extra defaults are useful for smaller additional defaults that may change.
|
* The global extra defaults are useful for smaller additional defaults that may change.
|
||||||
* E.g. accent color. Otherwise, FlatLaf properties files should be used.
|
* Otherwise, FlatLaf properties files should be used.
|
||||||
* See {@link #registerCustomDefaultsSource(String)}.
|
* See {@link #registerCustomDefaultsSource(String)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The keys and values are strings in same format as in FlatLaf properties files.
|
* The keys and values are strings in same format as in FlatLaf properties files.
|
||||||
* <p>
|
* <p>
|
||||||
* Sample that setups "FlatLaf Light" theme with red accent color:
|
* Sample that setups "FlatLaf Light" theme with white background color:
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* FlatLaf.setGlobalExtraDefaults( Collections.singletonMap( "@accentColor", "#f00" ) );
|
* FlatLaf.setGlobalExtraDefaults( Collections.singletonMap( "@background", "#fff" ) );
|
||||||
* FlatLightLaf.setup();
|
* FlatLightLaf.setup();
|
||||||
* }</pre>
|
* }</pre>
|
||||||
*
|
*
|
||||||
@@ -929,15 +946,15 @@ public abstract class FlatLaf
|
|||||||
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The extra defaults are useful for smaller additional defaults that may change.
|
* The extra defaults are useful for smaller additional defaults that may change.
|
||||||
* E.g. accent color. Otherwise, FlatLaf properties files should be used.
|
* Otherwise, FlatLaf properties files should be used.
|
||||||
* See {@link #registerCustomDefaultsSource(String)}.
|
* See {@link #registerCustomDefaultsSource(String)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The keys and values are strings in same format as in FlatLaf properties files.
|
* The keys and values are strings in same format as in FlatLaf properties files.
|
||||||
* <p>
|
* <p>
|
||||||
* Sample that setups "FlatLaf Light" theme with red accent color:
|
* Sample that setups "FlatLaf Light" theme with white background color:
|
||||||
* <pre>{@code
|
* <pre>{@code
|
||||||
* FlatLaf laf = new FlatLightLaf();
|
* FlatLaf laf = new FlatLightLaf();
|
||||||
* laf.setExtraDefaults( Collections.singletonMap( "@accentColor", "#f00" ) );
|
* laf.setExtraDefaults( Collections.singletonMap( "@background", "#fff" ) );
|
||||||
* FlatLaf.setup( laf );
|
* FlatLaf.setup( laf );
|
||||||
* }</pre>
|
* }</pre>
|
||||||
*
|
*
|
||||||
@@ -979,6 +996,36 @@ public abstract class FlatLaf
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the system color getter function, or {@code null}.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static Function<String, Color> getSystemColorGetter() {
|
||||||
|
return systemColorGetter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a system color getter function that is invoked when function
|
||||||
|
* {@code systemColor()} is used in FlatLaf properties files.
|
||||||
|
* <p>
|
||||||
|
* The name of the system color is passed as parameter to the function.
|
||||||
|
* The function should return {@code null} for unknown system colors.
|
||||||
|
* <p>
|
||||||
|
* Can be used to change the accent color:
|
||||||
|
* <pre>{@code
|
||||||
|
* FlatLaf.setSystemColorGetter( name -> {
|
||||||
|
* return name.equals( "accent" ) ? Color.red : null;
|
||||||
|
* } );
|
||||||
|
* FlatLightLaf.setup();
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static void setSystemColorGetter( Function<String, Color> systemColorGetter ) {
|
||||||
|
FlatLaf.systemColorGetter = systemColorGetter;
|
||||||
|
}
|
||||||
|
|
||||||
private static void reSetLookAndFeel() {
|
private static void reSetLookAndFeel() {
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||||
@@ -1292,6 +1339,90 @@ public abstract class FlatLaf
|
|||||||
private static boolean getUIMethodInitialized;
|
private static boolean getUIMethodInitialized;
|
||||||
private static MethodHandle getUIMethod;
|
private static MethodHandle getUIMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the preferred font family to be used for (nearly) all fonts; or {@code null}.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static String getPreferredFontFamily() {
|
||||||
|
return preferredFontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred font family to be used for (nearly) all fonts.
|
||||||
|
* <p>
|
||||||
|
* <strong>Note</strong>: This must be invoked <strong>before</strong> setting
|
||||||
|
* the application look and feel.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static void setPreferredFontFamily( String preferredFontFamily ) {
|
||||||
|
FlatLaf.preferredFontFamily = preferredFontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the preferred font family to be used for "light" fonts; or {@code null}.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static String getPreferredLightFontFamily() {
|
||||||
|
return preferredLightFontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred font family to be used for "light" fonts.
|
||||||
|
* <p>
|
||||||
|
* <strong>Note</strong>: This must be invoked <strong>before</strong> setting
|
||||||
|
* the application look and feel.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static void setPreferredLightFontFamily( String preferredLightFontFamily ) {
|
||||||
|
FlatLaf.preferredLightFontFamily = preferredLightFontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the preferred font family to be used for "semibold" fonts; or {@code null}.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static String getPreferredSemiboldFontFamily() {
|
||||||
|
return preferredSemiboldFontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred font family to be used for "semibold" fonts.
|
||||||
|
* <p>
|
||||||
|
* <strong>Note</strong>: This must be invoked <strong>before</strong> setting
|
||||||
|
* the application look and feel.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static void setPreferredSemiboldFontFamily( String preferredSemiboldFontFamily ) {
|
||||||
|
FlatLaf.preferredSemiboldFontFamily = preferredSemiboldFontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the preferred font family to be used for monospaced fonts; or {@code null}.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static String getPreferredMonospacedFontFamily() {
|
||||||
|
return preferredMonospacedFontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred font family to be used for monospaced fonts.
|
||||||
|
* <p>
|
||||||
|
* <strong>Note</strong>: This must be invoked <strong>before</strong> setting
|
||||||
|
* the application look and feel.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static void setPreferredMonospacedFontFamily( String preferredMonospacedFontFamily ) {
|
||||||
|
FlatLaf.preferredMonospacedFontFamily = preferredMonospacedFontFamily;
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatUIDefaults -----------------------------------------------
|
//---- class FlatUIDefaults -----------------------------------------------
|
||||||
|
|
||||||
private class FlatUIDefaults
|
private class FlatUIDefaults
|
||||||
@@ -1426,9 +1557,16 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
// create font for family
|
// create font for family
|
||||||
if( families != null && !families.isEmpty() ) {
|
if( families != null && !families.isEmpty() ) {
|
||||||
|
String preferredFamily = preferredFamily( families );
|
||||||
|
if( preferredFamily != null ) {
|
||||||
|
Font font = createCompositeFont( preferredFamily, newStyle, newSize );
|
||||||
|
if( !isFallbackFont( font ) || isDialogFamily( preferredFamily ) )
|
||||||
|
return toUIResource( font );
|
||||||
|
}
|
||||||
|
|
||||||
for( String family : families ) {
|
for( String family : families ) {
|
||||||
Font font = createCompositeFont( family, newStyle, newSize );
|
Font font = createCompositeFont( family, newStyle, newSize );
|
||||||
if( !isFallbackFont( font ) || family.equalsIgnoreCase( Font.DIALOG ) )
|
if( !isFallbackFont( font ) || isDialogFamily( family ) )
|
||||||
return toUIResource( font );
|
return toUIResource( font );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1457,9 +1595,26 @@ public abstract class FlatLaf
|
|||||||
: new FontUIResource( font );
|
: new FontUIResource( font );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isFallbackFont( Font font ) {
|
private static boolean isFallbackFont( Font font ) {
|
||||||
return Font.DIALOG.equalsIgnoreCase( font.getFamily() );
|
return Font.DIALOG.equalsIgnoreCase( font.getFamily() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isDialogFamily( String family ) {
|
||||||
|
return family.equalsIgnoreCase( Font.DIALOG );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String preferredFamily( List<String> families ) {
|
||||||
|
for( String family : families ) {
|
||||||
|
family = family.toLowerCase( Locale.ENGLISH );
|
||||||
|
if( family.endsWith( " light" ) || family.endsWith( "-thin" ) )
|
||||||
|
return preferredLightFontFamily;
|
||||||
|
if( family.endsWith( " semibold" ) || family.endsWith( "-medium" ) )
|
||||||
|
return preferredSemiboldFontFamily;
|
||||||
|
if( family.equals( "monospaced" ) )
|
||||||
|
return preferredMonospacedFontFamily;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class ImageIconUIResource ------------------------------------------
|
//---- class ImageIconUIResource ------------------------------------------
|
||||||
|
|||||||
@@ -155,9 +155,19 @@ public interface FlatSystemProperties
|
|||||||
String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange";
|
String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies a directory in which the native FlatLaf library have been extracted.
|
* Specifies a directory in which the native FlatLaf libraries have been extracted.
|
||||||
* The path can be absolute or relative to current application working directory.
|
* The path can be absolute or relative to current application working directory.
|
||||||
* This can be used to avoid extraction of the native libraries to the temporary directory at runtime.
|
* This can be used to avoid extraction of the native libraries to the temporary directory at runtime.
|
||||||
|
* <p>
|
||||||
|
* If the value is {@code "system"}, then {@link System#loadLibrary(String)} is
|
||||||
|
* used to load the native library.
|
||||||
|
* Searches for the native library in classloader of caller
|
||||||
|
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
||||||
|
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
||||||
|
* (supported since FlatLaf 2.6)
|
||||||
|
* <p>
|
||||||
|
* If the native library can not loaded from the given path (or via {@link System#loadLibrary(String)}),
|
||||||
|
* then the embedded native library is extracted to the temporary directory and loaded from there.
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ public class IntelliJTheme
|
|||||||
|
|
||||||
for( Map.Entry<String, String> e : colors.entrySet() ) {
|
for( Map.Entry<String, String> e : colors.entrySet() ) {
|
||||||
String value = e.getValue();
|
String value = e.getValue();
|
||||||
ColorUIResource color = UIDefaultsLoader.parseColor( value );
|
ColorUIResource color = parseColor( value );
|
||||||
if( color != null ) {
|
if( color != null ) {
|
||||||
String key = e.getKey();
|
String key = e.getKey();
|
||||||
namedColors.put( key, color );
|
namedColors.put( key, color );
|
||||||
@@ -448,7 +448,15 @@ public class IntelliJTheme
|
|||||||
ColorUIResource color = namedColors.get( value );
|
ColorUIResource color = namedColors.get( value );
|
||||||
|
|
||||||
// parse color
|
// parse color
|
||||||
return (color != null) ? color : UIDefaultsLoader.parseColor( value );
|
return (color != null) ? color : parseColor( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
private ColorUIResource parseColor( String value ) {
|
||||||
|
try {
|
||||||
|
return UIDefaultsLoader.parseColor( value );
|
||||||
|
} catch( IllegalArgumentException ex ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -540,7 +548,7 @@ public class IntelliJTheme
|
|||||||
// radioFocused.svg and radioSelectedFocused.svg
|
// radioFocused.svg and radioSelectedFocused.svg
|
||||||
// use opacity=".65" for the border
|
// use opacity=".65" for the border
|
||||||
// --> add alpha to focused border colors
|
// --> add alpha to focused border colors
|
||||||
String[] focusedBorderColorKeys = new String[] {
|
String[] focusedBorderColorKeys = {
|
||||||
"CheckBox.icon.focusedBorderColor",
|
"CheckBox.icon.focusedBorderColor",
|
||||||
"CheckBox.icon.focusedSelectedBorderColor",
|
"CheckBox.icon.focusedSelectedBorderColor",
|
||||||
"CheckBox.icon[filled].focusedBorderColor",
|
"CheckBox.icon[filled].focusedBorderColor",
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ class UIDefaultsLoader
|
|||||||
|
|
||||||
private static int parseColorDepth;
|
private static int parseColorDepth;
|
||||||
|
|
||||||
|
private static Map<String, ColorUIResource> systemColorCache;
|
||||||
private static final SoftCache<String, Object> fontCache = new SoftCache<>();
|
private static final SoftCache<String, Object> fontCache = new SoftCache<>();
|
||||||
|
|
||||||
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
|
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
|
||||||
@@ -105,6 +106,10 @@ class UIDefaultsLoader
|
|||||||
Properties additionalDefaults, boolean dark, UIDefaults defaults )
|
Properties additionalDefaults, boolean dark, UIDefaults defaults )
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
// temporary cache system colors while loading defaults,
|
||||||
|
// which avoids that system color getter is invoked multiple times
|
||||||
|
systemColorCache = (FlatLaf.getSystemColorGetter() != null) ? new HashMap<>() : null;
|
||||||
|
|
||||||
// load core properties files
|
// load core properties files
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
for( Class<?> lafClass : lafClasses ) {
|
for( Class<?> lafClass : lafClasses ) {
|
||||||
@@ -276,6 +281,9 @@ class UIDefaultsLoader
|
|||||||
|
|
||||||
// remember variables in defaults to allow using them in styles
|
// remember variables in defaults to allow using them in styles
|
||||||
defaults.put( KEY_VARIABLES, variables );
|
defaults.put( KEY_VARIABLES, variables );
|
||||||
|
|
||||||
|
// clear/disable system color cache
|
||||||
|
systemColorCache = null;
|
||||||
} catch( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load properties files.", ex );
|
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load properties files.", ex );
|
||||||
}
|
}
|
||||||
@@ -525,14 +533,14 @@ class UIDefaultsLoader
|
|||||||
case STRING: return value;
|
case STRING: return value;
|
||||||
case BOOLEAN: return parseBoolean( value );
|
case BOOLEAN: return parseBoolean( value );
|
||||||
case CHARACTER: return parseCharacter( value );
|
case CHARACTER: return parseCharacter( value );
|
||||||
case INTEGER: return parseInteger( value, true );
|
case INTEGER: return parseInteger( value );
|
||||||
case INTEGERORFLOAT:return parseIntegerOrFloat( value, true );
|
case INTEGERORFLOAT:return parseIntegerOrFloat( value );
|
||||||
case FLOAT: return parseFloat( value, true );
|
case FLOAT: return parseFloat( value );
|
||||||
case BORDER: return parseBorder( value, resolver, addonClassLoaders );
|
case BORDER: return parseBorder( value, resolver, addonClassLoaders );
|
||||||
case ICON: return parseInstance( value, addonClassLoaders );
|
case ICON: return parseInstance( value, addonClassLoaders );
|
||||||
case INSETS: return parseInsets( value );
|
case INSETS: return parseInsets( value );
|
||||||
case DIMENSION: return parseDimension( value );
|
case DIMENSION: return parseDimension( value );
|
||||||
case COLOR: return parseColorOrFunction( value, resolver, true );
|
case COLOR: return parseColorOrFunction( value, resolver );
|
||||||
case FONT: return parseFont( value );
|
case FONT: return parseFont( value );
|
||||||
case SCALEDINTEGER: return parseScaledInteger( value );
|
case SCALEDINTEGER: return parseScaledInteger( value );
|
||||||
case SCALEDFLOAT: return parseScaledFloat( value );
|
case SCALEDFLOAT: return parseScaledFloat( value );
|
||||||
@@ -550,24 +558,34 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
// colors
|
// colors
|
||||||
Object color = parseColorOrFunction( value, resolver, false );
|
if( value.startsWith( "#" ) || value.endsWith( ")" ) ) {
|
||||||
if( color != null ) {
|
Object color = parseColorOrFunction( value, resolver );
|
||||||
resultValueType[0] = ValueType.COLOR;
|
resultValueType[0] = (color != null) ? ValueType.COLOR : ValueType.NULL;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
// integer
|
// integer or float
|
||||||
Integer integer = parseInteger( value, false );
|
char firstChar = value.charAt( 0 );
|
||||||
if( integer != null ) {
|
if( (firstChar >= '0' && firstChar <= '9') ||
|
||||||
resultValueType[0] = ValueType.INTEGER;
|
firstChar == '-' || firstChar == '+' || firstChar == '.' )
|
||||||
return integer;
|
{
|
||||||
}
|
// integer
|
||||||
|
try {
|
||||||
|
Integer integer = parseInteger( value );
|
||||||
|
resultValueType[0] = ValueType.INTEGER;
|
||||||
|
return integer;
|
||||||
|
} catch( NumberFormatException ex ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
|
||||||
// float
|
// float
|
||||||
Float f = parseFloat( value, false );
|
try {
|
||||||
if( f != null ) {
|
Float f = parseFloat( value );
|
||||||
resultValueType[0] = ValueType.FLOAT;
|
resultValueType[0] = ValueType.FLOAT;
|
||||||
return f;
|
return f;
|
||||||
|
} catch( NumberFormatException ex ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// string
|
// string
|
||||||
@@ -596,10 +614,10 @@ class UIDefaultsLoader
|
|||||||
List<String> parts = splitFunctionParams( value, ',' );
|
List<String> parts = splitFunctionParams( value, ',' );
|
||||||
Insets insets = parseInsets( value );
|
Insets insets = parseInsets( value );
|
||||||
ColorUIResource lineColor = (parts.size() >= 5)
|
ColorUIResource lineColor = (parts.size() >= 5)
|
||||||
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver, true )
|
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver )
|
||||||
: null;
|
: null;
|
||||||
float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) ? parseFloat( parts.get( 5 ), true ) : 1f;
|
float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) ? parseFloat( parts.get( 5 ) ) : 1f;
|
||||||
int arc = (parts.size() >= 7) ? parseInteger( parts.get( 6 ), true ) : 0;
|
int arc = (parts.size() >= 7) ? parseInteger( parts.get( 6 ) ) : 0;
|
||||||
|
|
||||||
return (LazyValue) t -> {
|
return (LazyValue) t -> {
|
||||||
return (lineColor != null)
|
return (lineColor != null)
|
||||||
@@ -674,30 +692,24 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object parseColorOrFunction( String value, Function<String, String> resolver, boolean reportError ) {
|
private static Object parseColorOrFunction( String value, Function<String, String> resolver ) {
|
||||||
if( value.endsWith( ")" ) )
|
if( value.endsWith( ")" ) )
|
||||||
return parseColorFunctions( value, resolver, reportError );
|
return parseColorFunctions( value, resolver );
|
||||||
|
|
||||||
return parseColor( value, reportError );
|
return parseColor( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a hex color in {@code #RGB}, {@code #RGBA}, {@code #RRGGBB} or {@code #RRGGBBAA}
|
||||||
|
* format and returns it as color object.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
*/
|
||||||
static ColorUIResource parseColor( String value ) {
|
static ColorUIResource parseColor( String value ) {
|
||||||
return parseColor( value, false );
|
int rgba = parseColorRGBA( value );
|
||||||
}
|
return ((rgba & 0xff000000) == 0xff000000)
|
||||||
|
? new ColorUIResource( rgba )
|
||||||
private static ColorUIResource parseColor( String value, boolean reportError ) {
|
: new ColorUIResource( new Color( rgba, true ) );
|
||||||
try {
|
|
||||||
int rgba = parseColorRGBA( value );
|
|
||||||
return ((rgba & 0xff000000) == 0xff000000)
|
|
||||||
? new ColorUIResource( rgba )
|
|
||||||
: new ColorUIResource( new Color( rgba, true ) );
|
|
||||||
} catch( IllegalArgumentException ex ) {
|
|
||||||
if( reportError )
|
|
||||||
throw new IllegalArgumentException( "invalid color '" + value + "'" );
|
|
||||||
|
|
||||||
// not a color --> ignore
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -710,7 +722,7 @@ class UIDefaultsLoader
|
|||||||
static int parseColorRGBA( String value ) {
|
static int parseColorRGBA( String value ) {
|
||||||
int len = value.length();
|
int len = value.length();
|
||||||
if( (len != 4 && len != 5 && len != 7 && len != 9) || value.charAt( 0 ) != '#' )
|
if( (len != 4 && len != 5 && len != 7 && len != 9) || value.charAt( 0 ) != '#' )
|
||||||
throw new IllegalArgumentException();
|
throw newInvalidColorException( value );
|
||||||
|
|
||||||
// parse hex
|
// parse hex
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@@ -725,7 +737,7 @@ class UIDefaultsLoader
|
|||||||
else if( ch >= 'A' && ch <= 'F' )
|
else if( ch >= 'A' && ch <= 'F' )
|
||||||
digit = ch - 'A' + 10;
|
digit = ch - 'A' + 10;
|
||||||
else
|
else
|
||||||
throw new IllegalArgumentException();
|
throw newInvalidColorException( value );
|
||||||
|
|
||||||
n = (n << 4) | digit;
|
n = (n << 4) | digit;
|
||||||
}
|
}
|
||||||
@@ -744,13 +756,14 @@ class UIDefaultsLoader
|
|||||||
: (((n >> 8) & 0xffffff) | ((n & 0xff) << 24)); // move alpha from lowest to highest byte
|
: (((n >> 8) & 0xffffff) | ((n & 0xff) << 24)); // move alpha from lowest to highest byte
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object parseColorFunctions( String value, Function<String, String> resolver, boolean reportError ) {
|
private static IllegalArgumentException newInvalidColorException( String value ) {
|
||||||
|
return new IllegalArgumentException( "invalid color '" + value + "'" );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object parseColorFunctions( String value, Function<String, String> resolver ) {
|
||||||
int paramsStart = value.indexOf( '(' );
|
int paramsStart = value.indexOf( '(' );
|
||||||
if( paramsStart < 0 ) {
|
if( paramsStart < 0 )
|
||||||
if( reportError )
|
throw new IllegalArgumentException( "missing opening parenthesis in function '" + value + "'" );
|
||||||
throw new IllegalArgumentException( "missing opening parenthesis in function '" + value + "'" );
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
String function = StringUtils.substringTrimmed( value, 0, paramsStart );
|
String function = StringUtils.substringTrimmed( value, 0, paramsStart );
|
||||||
List<String> params = splitFunctionParams( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
|
List<String> params = splitFunctionParams( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
|
||||||
@@ -763,28 +776,29 @@ class UIDefaultsLoader
|
|||||||
parseColorDepth++;
|
parseColorDepth++;
|
||||||
try {
|
try {
|
||||||
switch( function ) {
|
switch( function ) {
|
||||||
case "if": return parseColorIf( value, params, resolver, reportError );
|
case "if": return parseColorIf( value, params, resolver );
|
||||||
case "rgb": return parseColorRgbOrRgba( false, params, resolver, reportError );
|
case "systemColor": return parseColorSystemColor( value, params, resolver );
|
||||||
case "rgba": return parseColorRgbOrRgba( true, params, resolver, reportError );
|
case "rgb": return parseColorRgbOrRgba( false, params, resolver );
|
||||||
|
case "rgba": return parseColorRgbOrRgba( true, params, resolver );
|
||||||
case "hsl": return parseColorHslOrHsla( false, params );
|
case "hsl": return parseColorHslOrHsla( false, params );
|
||||||
case "hsla": return parseColorHslOrHsla( true, params );
|
case "hsla": return parseColorHslOrHsla( true, params );
|
||||||
case "lighten": return parseColorHSLIncreaseDecrease( 2, true, params, resolver, reportError );
|
case "lighten": return parseColorHSLIncreaseDecrease( 2, true, params, resolver );
|
||||||
case "darken": return parseColorHSLIncreaseDecrease( 2, false, params, resolver, reportError );
|
case "darken": return parseColorHSLIncreaseDecrease( 2, false, params, resolver );
|
||||||
case "saturate": return parseColorHSLIncreaseDecrease( 1, true, params, resolver, reportError );
|
case "saturate": return parseColorHSLIncreaseDecrease( 1, true, params, resolver );
|
||||||
case "desaturate": return parseColorHSLIncreaseDecrease( 1, false, params, resolver, reportError );
|
case "desaturate": return parseColorHSLIncreaseDecrease( 1, false, params, resolver );
|
||||||
case "fadein": return parseColorHSLIncreaseDecrease( 3, true, params, resolver, reportError );
|
case "fadein": return parseColorHSLIncreaseDecrease( 3, true, params, resolver );
|
||||||
case "fadeout": return parseColorHSLIncreaseDecrease( 3, false, params, resolver, reportError );
|
case "fadeout": return parseColorHSLIncreaseDecrease( 3, false, params, resolver );
|
||||||
case "fade": return parseColorFade( params, resolver, reportError );
|
case "fade": return parseColorFade( params, resolver );
|
||||||
case "spin": return parseColorSpin( params, resolver, reportError );
|
case "spin": return parseColorSpin( params, resolver );
|
||||||
case "changeHue": return parseColorChange( 0, params, resolver, reportError );
|
case "changeHue": return parseColorChange( 0, params, resolver );
|
||||||
case "changeSaturation":return parseColorChange( 1, params, resolver, reportError );
|
case "changeSaturation":return parseColorChange( 1, params, resolver );
|
||||||
case "changeLightness": return parseColorChange( 2, params, resolver, reportError );
|
case "changeLightness": return parseColorChange( 2, params, resolver );
|
||||||
case "changeAlpha": return parseColorChange( 3, params, resolver, reportError );
|
case "changeAlpha": return parseColorChange( 3, params, resolver );
|
||||||
case "mix": return parseColorMix( null, params, resolver, reportError );
|
case "mix": return parseColorMix( null, params, resolver );
|
||||||
case "tint": return parseColorMix( "#fff", params, resolver, reportError );
|
case "tint": return parseColorMix( "#fff", params, resolver );
|
||||||
case "shade": return parseColorMix( "#000", params, resolver, reportError );
|
case "shade": return parseColorMix( "#000", params, resolver );
|
||||||
case "contrast": return parseColorContrast( params, resolver, reportError );
|
case "contrast": return parseColorContrast( params, resolver );
|
||||||
case "over": return parseColorOver( params, resolver, reportError );
|
case "over": return parseColorOver( params, resolver );
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
parseColorDepth--;
|
parseColorDepth--;
|
||||||
@@ -799,13 +813,51 @@ class UIDefaultsLoader
|
|||||||
* This "if" function is only used if the "if" is passed as parameter to another
|
* This "if" function is only used if the "if" is passed as parameter to another
|
||||||
* color function. Otherwise, the general "if" function is used.
|
* color function. Otherwise, the general "if" function is used.
|
||||||
*/
|
*/
|
||||||
private static Object parseColorIf( String value, List<String> params, Function<String, String> resolver, boolean reportError ) {
|
private static Object parseColorIf( String value, List<String> params, Function<String, String> resolver ) {
|
||||||
if( params.size() != 3 )
|
if( params.size() != 3 )
|
||||||
throwMissingParametersException( value );
|
throwMissingParametersException( value );
|
||||||
|
|
||||||
boolean ifCondition = parseCondition( params.get( 0 ), resolver, Collections.emptyList() );
|
boolean ifCondition = parseCondition( params.get( 0 ), resolver, Collections.emptyList() );
|
||||||
String ifValue = params.get( ifCondition ? 1 : 2 );
|
String ifValue = params.get( ifCondition ? 1 : 2 );
|
||||||
return parseColorOrFunction( resolver.apply( ifValue ), resolver, reportError );
|
return parseColorOrFunction( resolver.apply( ifValue ), resolver );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syntax: systemColor(name[,defaultValue])
|
||||||
|
* - name: system color name
|
||||||
|
* - defaultValue: default color value used if system color is not available
|
||||||
|
*/
|
||||||
|
private static Object parseColorSystemColor( String value, List<String> params, Function<String, String> resolver ) {
|
||||||
|
if( params.size() < 1 )
|
||||||
|
throwMissingParametersException( value );
|
||||||
|
|
||||||
|
ColorUIResource systemColor = getSystemColor( params.get( 0 ) );
|
||||||
|
if( systemColor != null )
|
||||||
|
return systemColor;
|
||||||
|
|
||||||
|
String defaultValue = (params.size() > 1) ? params.get( 1 ) : "";
|
||||||
|
if( defaultValue.equals( "null" ) || defaultValue.isEmpty() )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return parseColorOrFunction( resolver.apply( defaultValue ), resolver );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ColorUIResource getSystemColor( String name ) {
|
||||||
|
Function<String, Color> systemColorGetter = FlatLaf.getSystemColorGetter();
|
||||||
|
if( systemColorGetter == null )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// use containsKey() because value may be null
|
||||||
|
if( systemColorCache != null && systemColorCache.containsKey( name ) )
|
||||||
|
return systemColorCache.get( name );
|
||||||
|
|
||||||
|
Color color = systemColorGetter.apply( name );
|
||||||
|
ColorUIResource uiColor = (color != null) ? new ColorUIResource( color ) : null;
|
||||||
|
|
||||||
|
if( systemColorCache != null )
|
||||||
|
systemColorCache.put( name, uiColor );
|
||||||
|
|
||||||
|
return uiColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -816,7 +868,7 @@ class UIDefaultsLoader
|
|||||||
* - alpha: an integer 0-255 or a percentage 0-100%
|
* - alpha: an integer 0-255 or a percentage 0-100%
|
||||||
*/
|
*/
|
||||||
private static ColorUIResource parseColorRgbOrRgba( boolean hasAlpha, List<String> params,
|
private static ColorUIResource parseColorRgbOrRgba( boolean hasAlpha, List<String> params,
|
||||||
Function<String, String> resolver, boolean reportError )
|
Function<String, String> resolver )
|
||||||
{
|
{
|
||||||
if( hasAlpha && params.size() == 2 ) {
|
if( hasAlpha && params.size() == 2 ) {
|
||||||
// syntax rgba(color,alpha), which allows adding alpha to any color
|
// syntax rgba(color,alpha), which allows adding alpha to any color
|
||||||
@@ -825,7 +877,7 @@ class UIDefaultsLoader
|
|||||||
String colorStr = params.get( 0 );
|
String colorStr = params.get( 0 );
|
||||||
int alpha = parseInteger( params.get( 1 ), 0, 255, true );
|
int alpha = parseInteger( params.get( 1 ), 0, 255, true );
|
||||||
|
|
||||||
ColorUIResource color = (ColorUIResource) parseColorOrFunction( resolver.apply( colorStr ), resolver, reportError );
|
ColorUIResource color = (ColorUIResource) parseColorOrFunction( resolver.apply( colorStr ), resolver );
|
||||||
return new ColorUIResource( new Color( ((alpha & 0xff) << 24) | (color.getRGB() & 0xffffff), true ) );
|
return new ColorUIResource( new Color( ((alpha & 0xff) << 24) | (color.getRGB() & 0xffffff), true ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -865,7 +917,7 @@ class UIDefaultsLoader
|
|||||||
* - options: [relative] [autoInverse] [noAutoInverse] [lazy] [derived]
|
* - options: [relative] [autoInverse] [noAutoInverse] [lazy] [derived]
|
||||||
*/
|
*/
|
||||||
private static Object parseColorHSLIncreaseDecrease( int hslIndex, boolean increase,
|
private static Object parseColorHSLIncreaseDecrease( int hslIndex, boolean increase,
|
||||||
List<String> params, Function<String, String> resolver, boolean reportError )
|
List<String> params, Function<String, String> resolver )
|
||||||
{
|
{
|
||||||
String colorStr = params.get( 0 );
|
String colorStr = params.get( 0 );
|
||||||
int amount = parsePercentage( params.get( 1 ) );
|
int amount = parsePercentage( params.get( 1 ) );
|
||||||
@@ -900,7 +952,7 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse base color, apply function and create derived color
|
// parse base color, apply function and create derived color
|
||||||
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
|
return parseFunctionBaseColor( colorStr, function, derived, resolver );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -909,7 +961,7 @@ class UIDefaultsLoader
|
|||||||
* - amount: percentage 0-100%
|
* - amount: percentage 0-100%
|
||||||
* - options: [derived] [lazy]
|
* - options: [derived] [lazy]
|
||||||
*/
|
*/
|
||||||
private static Object parseColorFade( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
private static Object parseColorFade( List<String> params, Function<String, String> resolver ) {
|
||||||
String colorStr = params.get( 0 );
|
String colorStr = params.get( 0 );
|
||||||
int amount = parsePercentage( params.get( 1 ) );
|
int amount = parsePercentage( params.get( 1 ) );
|
||||||
boolean derived = false;
|
boolean derived = false;
|
||||||
@@ -934,7 +986,7 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
// parse base color, apply function and create derived color
|
// parse base color, apply function and create derived color
|
||||||
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
|
return parseFunctionBaseColor( colorStr, function, derived, resolver );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -943,9 +995,9 @@ class UIDefaultsLoader
|
|||||||
* - angle: number of degrees to rotate
|
* - angle: number of degrees to rotate
|
||||||
* - options: [derived]
|
* - options: [derived]
|
||||||
*/
|
*/
|
||||||
private static Object parseColorSpin( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
private static Object parseColorSpin( List<String> params, Function<String, String> resolver ) {
|
||||||
String colorStr = params.get( 0 );
|
String colorStr = params.get( 0 );
|
||||||
int amount = parseInteger( params.get( 1 ), true );
|
int amount = parseInteger( params.get( 1 ) );
|
||||||
boolean derived = false;
|
boolean derived = false;
|
||||||
|
|
||||||
if( params.size() > 2 ) {
|
if( params.size() > 2 ) {
|
||||||
@@ -957,7 +1009,7 @@ class UIDefaultsLoader
|
|||||||
ColorFunction function = new ColorFunctions.HSLIncreaseDecrease( 0, true, amount, false, false );
|
ColorFunction function = new ColorFunctions.HSLIncreaseDecrease( 0, true, amount, false, false );
|
||||||
|
|
||||||
// parse base color, apply function and create derived color
|
// parse base color, apply function and create derived color
|
||||||
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
|
return parseFunctionBaseColor( colorStr, function, derived, resolver );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -970,11 +1022,11 @@ class UIDefaultsLoader
|
|||||||
* - options: [derived]
|
* - options: [derived]
|
||||||
*/
|
*/
|
||||||
private static Object parseColorChange( int hslIndex,
|
private static Object parseColorChange( int hslIndex,
|
||||||
List<String> params, Function<String, String> resolver, boolean reportError )
|
List<String> params, Function<String, String> resolver )
|
||||||
{
|
{
|
||||||
String colorStr = params.get( 0 );
|
String colorStr = params.get( 0 );
|
||||||
int value = (hslIndex == 0)
|
int value = (hslIndex == 0)
|
||||||
? parseInteger( params.get( 1 ), true )
|
? parseInteger( params.get( 1 ) )
|
||||||
: parsePercentage( params.get( 1 ) );
|
: parsePercentage( params.get( 1 ) );
|
||||||
boolean derived = false;
|
boolean derived = false;
|
||||||
|
|
||||||
@@ -987,7 +1039,7 @@ class UIDefaultsLoader
|
|||||||
ColorFunction function = new ColorFunctions.HSLChange( hslIndex, value );
|
ColorFunction function = new ColorFunctions.HSLChange( hslIndex, value );
|
||||||
|
|
||||||
// parse base color, apply function and create derived color
|
// parse base color, apply function and create derived color
|
||||||
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
|
return parseFunctionBaseColor( colorStr, function, derived, resolver );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -999,7 +1051,7 @@ class UIDefaultsLoader
|
|||||||
* - weight: the weight (in range 0-100%) to mix the two colors
|
* - weight: the weight (in range 0-100%) to mix the two colors
|
||||||
* larger weight uses more of first color, smaller weight more of second color
|
* larger weight uses more of first color, smaller weight more of second color
|
||||||
*/
|
*/
|
||||||
private static Object parseColorMix( String color1Str, List<String> params, Function<String, String> resolver, boolean reportError ) {
|
private static Object parseColorMix( String color1Str, List<String> params, Function<String, String> resolver ) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if( color1Str == null )
|
if( color1Str == null )
|
||||||
color1Str = params.get( i++ );
|
color1Str = params.get( i++ );
|
||||||
@@ -1007,7 +1059,7 @@ class UIDefaultsLoader
|
|||||||
int weight = (params.size() > i) ? parsePercentage( params.get( i ) ) : 50;
|
int weight = (params.size() > i) ? parsePercentage( params.get( i ) ) : 50;
|
||||||
|
|
||||||
// parse second color
|
// parse second color
|
||||||
ColorUIResource color2 = (ColorUIResource) parseColorOrFunction( resolver.apply( color2Str ), resolver, reportError );
|
ColorUIResource color2 = (ColorUIResource) parseColorOrFunction( resolver.apply( color2Str ), resolver );
|
||||||
if( color2 == null )
|
if( color2 == null )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -1015,7 +1067,7 @@ class UIDefaultsLoader
|
|||||||
ColorFunction function = new ColorFunctions.Mix( color2, weight );
|
ColorFunction function = new ColorFunctions.Mix( color2, weight );
|
||||||
|
|
||||||
// parse first color, apply function and create mixed color
|
// parse first color, apply function and create mixed color
|
||||||
return parseFunctionBaseColor( color1Str, function, false, resolver, reportError );
|
return parseFunctionBaseColor( color1Str, function, false, resolver );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1026,14 +1078,14 @@ class UIDefaultsLoader
|
|||||||
* - threshold: the threshold (in range 0-100%) to specify where the transition
|
* - threshold: the threshold (in range 0-100%) to specify where the transition
|
||||||
* from "dark" to "light" is (default is 43%)
|
* from "dark" to "light" is (default is 43%)
|
||||||
*/
|
*/
|
||||||
private static Object parseColorContrast( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
private static Object parseColorContrast( List<String> params, Function<String, String> resolver ) {
|
||||||
String colorStr = params.get( 0 );
|
String colorStr = params.get( 0 );
|
||||||
String darkStr = params.get( 1 );
|
String darkStr = params.get( 1 );
|
||||||
String lightStr = params.get( 2 );
|
String lightStr = params.get( 2 );
|
||||||
int threshold = (params.size() > 3) ? parsePercentage( params.get( 3 ) ) : 43;
|
int threshold = (params.size() > 3) ? parsePercentage( params.get( 3 ) ) : 43;
|
||||||
|
|
||||||
// parse color to compare against
|
// parse color to compare against
|
||||||
ColorUIResource color = (ColorUIResource) parseColorOrFunction( resolver.apply( colorStr ), resolver, reportError );
|
ColorUIResource color = (ColorUIResource) parseColorOrFunction( resolver.apply( colorStr ), resolver );
|
||||||
if( color == null )
|
if( color == null )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -1043,7 +1095,7 @@ class UIDefaultsLoader
|
|||||||
: darkStr;
|
: darkStr;
|
||||||
|
|
||||||
// parse dark or light color
|
// parse dark or light color
|
||||||
return parseColorOrFunction( resolver.apply( darkOrLightColor ), resolver, reportError );
|
return parseColorOrFunction( resolver.apply( darkOrLightColor ), resolver );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1052,12 +1104,12 @@ class UIDefaultsLoader
|
|||||||
* the alpha of this color is used as weight to mix the two colors
|
* the alpha of this color is used as weight to mix the two colors
|
||||||
* - background: a background color (e.g. #f00) or a color function
|
* - background: a background color (e.g. #f00) or a color function
|
||||||
*/
|
*/
|
||||||
private static ColorUIResource parseColorOver( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
private static ColorUIResource parseColorOver( List<String> params, Function<String, String> resolver ) {
|
||||||
String foregroundStr = params.get( 0 );
|
String foregroundStr = params.get( 0 );
|
||||||
String backgroundStr = params.get( 1 );
|
String backgroundStr = params.get( 1 );
|
||||||
|
|
||||||
// parse foreground color
|
// parse foreground color
|
||||||
ColorUIResource foreground = (ColorUIResource) parseColorOrFunction( resolver.apply( foregroundStr ), resolver, reportError );
|
ColorUIResource foreground = (ColorUIResource) parseColorOrFunction( resolver.apply( foregroundStr ), resolver );
|
||||||
if( foreground == null || foreground.getAlpha() == 255 )
|
if( foreground == null || foreground.getAlpha() == 255 )
|
||||||
return foreground;
|
return foreground;
|
||||||
|
|
||||||
@@ -1065,7 +1117,7 @@ class UIDefaultsLoader
|
|||||||
ColorUIResource foreground2 = new ColorUIResource( foreground.getRGB() );
|
ColorUIResource foreground2 = new ColorUIResource( foreground.getRGB() );
|
||||||
|
|
||||||
// parse background color
|
// parse background color
|
||||||
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver, reportError );
|
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver );
|
||||||
if( background == null )
|
if( background == null )
|
||||||
return foreground2;
|
return foreground2;
|
||||||
|
|
||||||
@@ -1075,11 +1127,11 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
|
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
|
||||||
boolean derived, Function<String, String> resolver, boolean reportError )
|
boolean derived, Function<String, String> resolver )
|
||||||
{
|
{
|
||||||
// parse base color
|
// parse base color
|
||||||
String resolvedColorStr = resolver.apply( colorStr );
|
String resolvedColorStr = resolver.apply( colorStr );
|
||||||
ColorUIResource baseColor = (ColorUIResource) parseColorOrFunction( resolvedColorStr, resolver, reportError );
|
ColorUIResource baseColor = (ColorUIResource) parseColorOrFunction( resolvedColorStr, resolver );
|
||||||
if( baseColor == null )
|
if( baseColor == null )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -1163,11 +1215,11 @@ class UIDefaultsLoader
|
|||||||
throw new IllegalArgumentException( "size specified more than once in '" + value + "'" );
|
throw new IllegalArgumentException( "size specified more than once in '" + value + "'" );
|
||||||
|
|
||||||
if( firstChar == '+' || firstChar == '-' )
|
if( firstChar == '+' || firstChar == '-' )
|
||||||
relativeSize = parseInteger( param, true );
|
relativeSize = parseInteger( param );
|
||||||
else if( param.endsWith( "%" ) )
|
else if( param.endsWith( "%" ) )
|
||||||
scaleSize = parseInteger( param.substring( 0, param.length() - 1 ), true ) / 100f;
|
scaleSize = parseInteger( param.substring( 0, param.length() - 1 ) ) / 100f;
|
||||||
else
|
else
|
||||||
absoluteSize = parseInteger( param, true );
|
absoluteSize = parseInteger( param );
|
||||||
} else if( firstChar == '$' ) {
|
} else if( firstChar == '$' ) {
|
||||||
// reference to base font
|
// reference to base font
|
||||||
if( baseFontKey != null )
|
if( baseFontKey != null )
|
||||||
@@ -1241,55 +1293,49 @@ class UIDefaultsLoader
|
|||||||
return (max * percent) / 100;
|
return (max * percent) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer integer = parseInteger( value, true );
|
Integer integer = parseInteger( value );
|
||||||
if( integer < min || integer > max )
|
if( integer < min || integer > max )
|
||||||
throw new NumberFormatException( "integer '" + value + "' out of range (" + min + '-' + max + ')' );
|
throw new NumberFormatException( "integer '" + value + "' out of range (" + min + '-' + max + ')' );
|
||||||
return integer;
|
return integer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Integer parseInteger( String value, boolean reportError ) {
|
private static Integer parseInteger( String value ) {
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt( value );
|
return Integer.parseInt( value );
|
||||||
} catch( NumberFormatException ex ) {
|
} catch( NumberFormatException ex ) {
|
||||||
if( reportError )
|
throw new NumberFormatException( "invalid integer '" + value + "'" );
|
||||||
throw new NumberFormatException( "invalid integer '" + value + "'" );
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Number parseIntegerOrFloat( String value, boolean reportError ) {
|
private static Number parseIntegerOrFloat( String value ) {
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt( value );
|
return Integer.parseInt( value );
|
||||||
} catch( NumberFormatException ex ) {
|
} catch( NumberFormatException ex ) {
|
||||||
try {
|
try {
|
||||||
return Float.parseFloat( value );
|
return Float.parseFloat( value );
|
||||||
} catch( NumberFormatException ex2 ) {
|
} catch( NumberFormatException ex2 ) {
|
||||||
if( reportError )
|
throw new NumberFormatException( "invalid integer or float '" + value + "'" );
|
||||||
throw new NumberFormatException( "invalid integer or float '" + value + "'" );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Float parseFloat( String value, boolean reportError ) {
|
private static Float parseFloat( String value ) {
|
||||||
try {
|
try {
|
||||||
return Float.parseFloat( value );
|
return Float.parseFloat( value );
|
||||||
} catch( NumberFormatException ex ) {
|
} catch( NumberFormatException ex ) {
|
||||||
if( reportError )
|
throw new NumberFormatException( "invalid float '" + value + "'" );
|
||||||
throw new NumberFormatException( "invalid float '" + value + "'" );
|
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActiveValue parseScaledInteger( String value ) {
|
private static ActiveValue parseScaledInteger( String value ) {
|
||||||
int val = parseInteger( value, true );
|
int val = parseInteger( value );
|
||||||
return t -> {
|
return t -> {
|
||||||
return UIScale.scale( val );
|
return UIScale.scale( val );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActiveValue parseScaledFloat( String value ) {
|
private static ActiveValue parseScaledFloat( String value ) {
|
||||||
float val = parseFloat( value, true );
|
float val = parseFloat( value );
|
||||||
return t -> {
|
return t -> {
|
||||||
return UIScale.scale( val );
|
return UIScale.scale( val );
|
||||||
};
|
};
|
||||||
@@ -1344,7 +1390,11 @@ class UIDefaultsLoader
|
|||||||
start = i + 1;
|
start = i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strs.add( StringUtils.substringTrimmed( str, start ) );
|
|
||||||
|
// last param
|
||||||
|
String s = StringUtils.substringTrimmed( str, start );
|
||||||
|
if( !s.isEmpty() || !strs.isEmpty() )
|
||||||
|
strs.add( s );
|
||||||
|
|
||||||
return strs;
|
return strs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Area;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.geom.RoundRectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
@@ -36,6 +39,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatCapsLockIcon
|
public class FlatCapsLockIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatCapsLockIcon() {
|
public FlatCapsLockIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "PasswordField.capsLockIconColor" ) );
|
super( 16, 16, UIManager.getColor( "PasswordField.capsLockIconColor" ) );
|
||||||
}
|
}
|
||||||
@@ -63,16 +68,22 @@ public class FlatCapsLockIcon
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
|
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
|
||||||
<rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
|
<rect width="5" height="2" x="5.5" y="11.5" stroke="#FFF" stroke-linejoin="round"/>
|
||||||
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
|
<path stroke="#FFF" stroke-linejoin="round" d="M2.5,7.5 L8,2 L13.5,7.5 L10.5,7.5 L10.5,9.5 L5.5,9.5 L5.5,7.5 L2.5,7.5 Z"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
|
BasicStroke stroke = new BasicStroke( 1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND );
|
||||||
path.append( new Rectangle2D.Float( 5, 11.5f, 6, 2 ), false );
|
|
||||||
path.append( FlatUIUtils.createPath( 2,8, 8,2, 14,8, 11,8, 11,10, 5,10, 5,8 ), false );
|
if( path == null ) {
|
||||||
|
path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
|
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
|
||||||
|
path.append( new Area( stroke.createStrokedShape( new Rectangle2D.Float( 5.5f, 11.5f, 5, 2 ) ) ), false );
|
||||||
|
path.append( new Area( stroke.createStrokedShape( FlatUIUtils.createPath(
|
||||||
|
2.5,7.5, 8,2, 13.5,7.5, 10.5,7.5, 10.5,9.5, 5.5,9.5, 5.5,7.5, 2.5,7.5 ) ) ), false );
|
||||||
|
}
|
||||||
g.fill( path );
|
g.fill( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ public class FlatCheckBoxIcon
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void paintCheckmark( Component c, Graphics2D g ) {
|
protected void paintCheckmark( Component c, Graphics2D g ) {
|
||||||
Path2D.Float path = new Path2D.Float();
|
Path2D.Float path = new Path2D.Float( Path2D.WIND_NON_ZERO, 3 );
|
||||||
path.moveTo( 4.5f, 7.5f );
|
path.moveTo( 4.5f, 7.5f );
|
||||||
path.lineTo( 6.6f, 10f );
|
path.lineTo( 6.6f, 10f );
|
||||||
path.lineTo( 11.25f, 3.5f );
|
path.lineTo( 11.25f, 3.5f );
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class FlatCheckBoxMenuItemIcon
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void paintCheckmark( Graphics2D g2 ) {
|
protected void paintCheckmark( Graphics2D g2 ) {
|
||||||
Path2D.Float path = new Path2D.Float();
|
Path2D.Float path = new Path2D.Float( Path2D.WIND_NON_ZERO, 3 );
|
||||||
path.moveTo( 4.5f, 7.5f );
|
path.moveTo( 4.5f, 7.5f );
|
||||||
path.lineTo( 6.6f, 10f );
|
path.lineTo( 6.6f, 10f );
|
||||||
path.lineTo( 11.25f, 3.5f );
|
path.lineTo( 11.25f, 3.5f );
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Line2D;
|
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
@@ -103,9 +102,11 @@ public class FlatClearIcon
|
|||||||
|
|
||||||
// paint cross
|
// paint cross
|
||||||
g.setColor( clearIconColor );
|
g.setColor( clearIconColor );
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||||
path.append( new Line2D.Float( 5,5, 11,11 ), false );
|
path.moveTo( 5, 5 );
|
||||||
path.append( new Line2D.Float( 5,11, 11,5 ), false );
|
path.lineTo( 11, 11 );
|
||||||
|
path.moveTo( 5, 11 );
|
||||||
|
path.lineTo( 11, 5 );
|
||||||
g.draw( path );
|
g.draw( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,21 +39,25 @@ public class FlatFileChooserDetailsViewIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="2" height="2" x="2" y="3" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="3" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="2" height="2" x="2" y="7" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="6" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="2" height="2" x="2" y="11" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="9" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="3" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="12" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="7" fill="#6E6E6E"/>
|
<rect width="8" height="1" x="6" y="3" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="11" fill="#6E6E6E"/>
|
<rect width="8" height="1" x="6" y="6" fill="#6E6E6E" rx=".5"/>
|
||||||
|
<rect width="8" height="1" x="6" y="9" fill="#6E6E6E" rx=".5"/>
|
||||||
|
<rect width="8" height="1" x="6" y="12" fill="#6E6E6E" rx=".5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fillRect( 2, 3, 2, 2 );
|
g.fillRoundRect( 2, 3, 2, 1, 1, 1 );
|
||||||
g.fillRect( 2, 7, 2, 2 );
|
g.fillRoundRect( 2, 6, 2, 1, 1, 1 );
|
||||||
g.fillRect( 2, 11, 2, 2 );
|
g.fillRoundRect( 2, 9, 2, 1, 1, 1 );
|
||||||
g.fillRect( 6, 3, 8, 2 );
|
g.fillRoundRect( 2, 12, 2, 1, 1, 1 );
|
||||||
g.fillRect( 6, 7, 8, 2 );
|
g.fillRoundRect( 6, 3, 8, 1, 1, 1 );
|
||||||
g.fillRect( 6, 11, 8, 2 );
|
g.fillRoundRect( 6, 6, 8, 1, 1, 1 );
|
||||||
|
g.fillRoundRect( 6, 9, 8, 1, 1, 1 );
|
||||||
|
g.fillRoundRect( 6, 12, 8, 1, 1, 1 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,10 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
@@ -39,10 +41,22 @@ public class FlatFileChooserHomeFolderIcon
|
|||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<polygon fill="#6E6E6E" fill-rule="evenodd" points="2 8 8 2 14 8 12 8 12 13 9 13 9 10 7 10 7 13 4 13 4 8"/>
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<polyline stroke="#6E6E6E" stroke-linejoin="round" points="6.5 13 6.5 9.5 9.5 9.5 9.5 13"/>
|
||||||
|
<path stroke="#6E6E6E" d="M3.5,6.5 L3.5,12.5 C3.5,13.0522847 3.94771525,13.5 4.5,13.5 L11.5,13.5 C12.0522847,13.5 12.5,13.0522847 12.5,12.5 L12.5,6.5 L12.5,6.5"/>
|
||||||
|
<polyline stroke="#6E6E6E" stroke-linecap="round" stroke-linejoin="round" points="1.5 8.5 8 2 14.5 8.5"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 2,8, 8,2, 14,8, 12,8, 12,13, 9,13, 9,10, 7,10, 7,13, 4,13, 4,8 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 6.5,13, 6.5,9.5, 9.5,9.5, 9.5,13 ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 3.5,6.5,
|
||||||
|
3.5,12.5, FlatUIUtils.QUAD_TO, 3.5,13.5, 4.5,13.5,
|
||||||
|
11.5,13.5, FlatUIUtils.QUAD_TO, 12.5,13.5, 12.5,12.5,
|
||||||
|
12.5,6.5 ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 1.5,8.5, 8,2, 14.5,8.5 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,17 +42,20 @@ public class FlatFileChooserListViewIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="4" height="4" x="3" y="3" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="2.5" y="2.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="3" y="9" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="2.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="9" y="9" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="9.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="9" y="3" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="9.5" y="2.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fillRect( 3, 3, 4, 4 );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fillRect( 3, 9, 4, 4 );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
g.fillRect( 9, 9, 4, 4 );
|
|
||||||
g.fillRect( 9, 3, 4, 4 );
|
g.draw( new RoundRectangle2D.Float( 2.5f, 2.5f, 4, 4, 2, 2 ) );
|
||||||
|
g.draw( new RoundRectangle2D.Float( 2.5f, 9.5f, 4, 4, 2, 2 ) );
|
||||||
|
g.draw( new RoundRectangle2D.Float( 9.5f, 9.5f, 4, 4, 2, 2 ) );
|
||||||
|
g.draw( new RoundRectangle2D.Float( 9.5f, 2.5f, 4, 4, 2, 2 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,13 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
||||||
@@ -31,6 +34,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatFileChooserNewFolderIcon
|
public class FlatFileChooserNewFolderIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private final Color greenColor = UIManager.getColor( "Actions.Green" );
|
||||||
|
|
||||||
public FlatFileChooserNewFolderIcon() {
|
public FlatFileChooserNewFolderIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
@@ -40,13 +45,20 @@ public class FlatFileChooserNewFolderIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#6E6E6E" points="2 3 5.5 3 7 5 14 5 14 8 11 8 11 10 9 10 9 13 2 13"/>
|
<path stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
<path fill="#59A869" d="M14,11 L16,11 L16,13 L14,13 L14,15 L12,15 L12,13 L10,13 L10,11 L12,11 L12,9 L14,9 L14,11 Z"/>
|
<line x1="5.5" x2="10.5" y1="9" y2="9" stroke="#59A869" stroke-linecap="round"/>
|
||||||
|
<line x1="8" x2="8" y1="6.5" y2="11.5" stroke="#59A869" stroke-linecap="round"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 2,3, 5.5,3, 7,5, 14,5, 14,8, 11,8, 11,10, 9,10, 9,13, 2,13 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 14,11, 16,11, 16,13, 14,13, 14,15, 12,15, 12,13, 10,13, 10,11, 12,11, 12,9, 14,9, 14,11 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
g.draw( FlatFileViewDirectoryIcon.createFolderPath() );
|
||||||
|
|
||||||
|
g.setColor( greenColor );
|
||||||
|
g.draw( new Line2D.Float( 5.5f, 9, 10.5f, 9 ) );
|
||||||
|
g.draw( new Line2D.Float( 8, 6.5f, 8, 11.5f ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
@@ -44,15 +47,20 @@ public class FlatFileChooserUpFolderIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#6E6E6E" points="2 3 5.5 3 7 5 9 5 9 9 13 9 13 5 14 5 14 13 2 13"/>
|
<path stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
<path fill="#389FD6" d="M12,4 L12,8 L10,8 L10,4 L8,4 L11,1 L14,4 L12,4 Z"/>
|
<line x1="8" x2="8" y1="6.5" y2="11.5" stroke="#389FD6" stroke-linecap="round"/>
|
||||||
|
<polyline stroke="#389FD6" stroke-linecap="round" stroke-linejoin="round" points="5.5 9 8 6.5 10.5 9"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 2,3, 5.5,3, 7,5, 9,5, 9,9, 13,9, 13,5, 14,5, 14,13, 2,13 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
g.draw( FlatFileViewDirectoryIcon.createFolderPath() );
|
||||||
|
|
||||||
g.setColor( blueColor );
|
g.setColor( blueColor );
|
||||||
g.fill( FlatUIUtils.createPath( 12,4, 12,8, 10,8, 10,4, 8,4, 11,1, 14,4, 12,4 ) );
|
g.draw( new Line2D.Float( 8, 6.5f, 8, 11.5f ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 5.5,9, 8,6.5, 10.5,9 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,17 +43,18 @@ public class FlatFileViewComputerIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<path fill="#6E6E6E" d="M2,3 L14,3 L14,11 L2,11 L2,3 Z M4,5 L4,9 L12,9 L12,5 L4,5 Z"/>
|
<rect width="11" height="7" x="2.5" y="3.5" stroke="#6E6E6E" rx="1"/>
|
||||||
<rect width="12" height="2" x="2" y="12" fill="#6E6E6E"/>
|
<line x1="8" x2="8" y1="11" y2="12" stroke="#6E6E6E"/>
|
||||||
|
<line x1="4.5" x2="11.5" y1="12.5" y2="12.5" stroke="#6E6E6E" stroke-linecap="round"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
path.append( new Rectangle2D.Float( 2, 3, 12, 8 ), false );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
path.append( new Rectangle2D.Float( 4, 5, 8, 4 ), false );
|
|
||||||
g.fill( path );
|
|
||||||
|
|
||||||
g.fillRect( 2, 12, 12, 2 );
|
g.draw( new RoundRectangle2D.Float( 2.5f, 3.5f, 11, 7, 2, 2 ) );
|
||||||
|
g.drawLine( 8, 11, 8, 12 );
|
||||||
|
g.draw( new Line2D.Float( 4.5f, 12.5f, 11.5f, 12.5f ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package com.formdev.flatlaf.icons;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
@@ -31,6 +33,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatFileViewDirectoryIcon
|
public class FlatFileViewDirectoryIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatFileViewDirectoryIcon() {
|
public FlatFileViewDirectoryIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
@@ -39,10 +43,32 @@ public class FlatFileViewDirectoryIcon
|
|||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<polygon fill="#6E6E6E" fill-rule="evenodd" points="1 2 6 2 8 4 15 4 15 13 1 13"/>
|
<path fill="none" stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 1,2, 6,2, 8,4, 15,4, 15,13, 1,13 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
|
||||||
|
if( path == null )
|
||||||
|
path = createFolderPath();
|
||||||
|
g.draw( path );
|
||||||
|
}
|
||||||
|
|
||||||
|
static Path2D createFolderPath() {
|
||||||
|
double arc = 1.5;
|
||||||
|
double arc2 = 0.5;
|
||||||
|
return FlatUIUtils.createPath(
|
||||||
|
// bottom-right
|
||||||
|
14.5,13.5-arc, FlatUIUtils.QUAD_TO, 14.5,13.5, 14.5-arc,13.5,
|
||||||
|
// bottom-left
|
||||||
|
1.5+arc,13.5, FlatUIUtils.QUAD_TO, 1.5,13.5, 1.5,13.5-arc,
|
||||||
|
// top-left
|
||||||
|
1.5,2.5+arc, FlatUIUtils.QUAD_TO, 1.5,2.5, 1.5+arc,2.5,
|
||||||
|
// top-mid-left
|
||||||
|
6.5-arc2,2.5, FlatUIUtils.QUAD_TO, 6.5,2.5, 6.5+arc2,2.5+arc2,
|
||||||
|
// top-mid-right
|
||||||
|
8.5,4.5,
|
||||||
|
// top-right
|
||||||
|
14.5-arc,4.5, FlatUIUtils.QUAD_TO, 14.5,4.5, 14.5,4.5+arc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
@@ -31,6 +34,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatFileViewFileIcon
|
public class FlatFileViewFileIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatFileViewFileIcon() {
|
public FlatFileViewFileIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
@@ -39,14 +44,33 @@ public class FlatFileViewFileIcon
|
|||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||||
<polygon fill="#6E6E6E" points="8 6 8 1 13 1 13 15 3 15 3 6"/>
|
<path stroke="#6E6E6E" d="M4,1.5 L8.8,1.5 L8.8,1.5 L13.5,6.2 L13.5,13 C13.5,13.8284271 12.8284271,14.5 12,14.5 L4,14.5 C3.17157288,14.5 2.5,13.8284271 2.5,13 L2.5,3 C2.5,2.17157288 3.17157288,1.5 4,1.5 Z"/>
|
||||||
<polygon fill="#6E6E6E" points="3 5 7 5 7 1"/>
|
<path stroke="#6E6E6E" d="M8.5,2 L8.5,5 C8.5,5.82842712 9.17157288,6.5 10,6.5 L13,6.5 L13,6.5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 8,6, 8,1, 13,1, 13,15, 3,15, 3,6 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 3,5, 7,5, 7,1 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
if( path == null ) {
|
||||||
|
double arc = 1.5;
|
||||||
|
path = FlatUIUtils.createPath( false,
|
||||||
|
// top-left
|
||||||
|
2.5,1.5+arc, FlatUIUtils.QUAD_TO, 2.5,1.5, 2.5+arc,1.5,
|
||||||
|
// top-right
|
||||||
|
8.8,1.5, 13.5,6.2,
|
||||||
|
// bottom-right
|
||||||
|
13.5,14.5-arc, FlatUIUtils.QUAD_TO, 13.5,14.5, 13.5-arc,14.5,
|
||||||
|
// bottom-left
|
||||||
|
2.5+arc,14.5, FlatUIUtils.QUAD_TO, 2.5,14.5, 2.5,14.5-arc,
|
||||||
|
FlatUIUtils.CLOSE_PATH,
|
||||||
|
|
||||||
|
FlatUIUtils.MOVE_TO, 8.5,2,
|
||||||
|
8.5,6.5-arc, FlatUIUtils.QUAD_TO, 8.5,6.5, 8.5+arc,6.5,
|
||||||
|
13,6.5 );
|
||||||
|
}
|
||||||
|
g.draw( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,10 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.RenderingHints;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
@@ -40,18 +41,22 @@ public class FlatFileViewFloppyDriveIcon
|
|||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||||
<path fill="#6E6E6E" d="M11,14 L11,11 L5,11 L5,14 L2,14 L2,2 L14,2 L14,14 L11,14 Z M4,4 L4,8 L12,8 L12,4 L4,4 Z"/>
|
<path stroke="#6E6E6E" d="M3.5,2.5 L11.5,2.5 L11.5,2.5 L13.5,4.5 L13.5,12.5 C13.5,13.0522847 13.0522847,13.5 12.5,13.5 L3.5,13.5 C2.94771525,13.5 2.5,13.0522847 2.5,12.5 L2.5,3.5 C2.5,2.94771525 2.94771525,2.5 3.5,2.5 Z"/>
|
||||||
<rect width="4" height="2" x="6" y="12" fill="#6E6E6E"/>
|
<polyline stroke="#6E6E6E" points="4.5 13 4.5 9.5 11.5 9.5 11.5 13"/>
|
||||||
|
<polyline stroke="#6E6E6E" points="5.5 3 5.5 5.5 10.5 5.5 10.5 3"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
path.append( FlatUIUtils.createPath( 11,14, 11,11, 5,11, 5,14, 2,14, 2,2, 14,2, 14,14, 11,14 ), false );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
path.append( FlatUIUtils.createPath( 4,4, 4,8, 12,8, 12,4, 4,4 ), false );
|
|
||||||
g.fill( path );
|
|
||||||
|
|
||||||
g.fillRect( 6, 12, 4, 2 );
|
g.draw( FlatUIUtils.createPath( 3.5,2.5, 11.5,2.5, 11.5,2.5, 13.5,4.5,
|
||||||
|
13.5,12.5, FlatUIUtils.QUAD_TO, 13.5,13.5, 12.5,13.5,
|
||||||
|
3.5,13.5, FlatUIUtils.QUAD_TO, 2.5,13.5, 2.5,12.5,
|
||||||
|
2.5,3.5, FlatUIUtils.QUAD_TO, 2.5,2.5, 3.5,2.5 ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 4.5,13, 4.5,9.5, 11.5,9.5, 11.5,13 ) );
|
||||||
|
g.draw( FlatUIUtils.createPath( false, 5.5,3, 5.5,5.5, 10.5,5.5, 10.5,3 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,14 +42,19 @@ public class FlatFileViewHardDriveIcon
|
|||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<path fill="#6E6E6E" fill-rule="evenodd" d="M2,6 L14,6 L14,10 L2,10 L2,6 Z M12,8 L12,9 L13,9 L13,8 L12,8 Z M10,8 L10,9 L11,9 L11,8 L10,8 Z"/>
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<rect width="11" height="5" x="2.5" y="5.5" stroke="#6E6E6E" rx="1"/>
|
||||||
|
<circle cx="11.5" cy="8.5" r="1" fill="#6E6E6E"/>
|
||||||
|
<circle cx="9.5" cy="8.5" r="1" fill="#6E6E6E"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
path.append( new Rectangle2D.Float( 2, 6, 12, 4 ), false );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
path.append( new Rectangle2D.Float( 12, 8, 1, 1 ), false );
|
|
||||||
path.append( new Rectangle2D.Float( 10, 8, 1, 1 ), false );
|
g.draw( new RoundRectangle2D.Float( 2.5f, 5.5f, 11, 5, 2, 2 ) );
|
||||||
g.fill( path );
|
g.fill( new Ellipse2D.Float( 10.8f, 7.8f, 1.4f, 1.4f ) );
|
||||||
|
g.fill( new Ellipse2D.Float( 8.8f, 7.8f, 1.4f, 1.4f ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,11 @@
|
|||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.*;
|
import static com.formdev.flatlaf.util.UIScale.*;
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -96,7 +98,8 @@ public class FlatHelpButtonIcon
|
|||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="11" cy="11" r="10.5" fill="#6E6E6E"/>
|
<circle cx="11" cy="11" r="10.5" fill="#6E6E6E"/>
|
||||||
<circle cx="11" cy="11" r="9.5" fill="#FFF"/>
|
<circle cx="11" cy="11" r="9.5" fill="#FFF"/>
|
||||||
<path fill="#6E6E6E" d="M10,17 L12,17 L12,15 L10,15 L10,17 Z M11,5 C8.8,5 7,6.8 7,9 L9,9 C9,7.9 9.9,7 11,7 C12.1,7 13,7.9 13,9 C13,11 10,10.75 10,14 L12,14 C12,11.75 15,11.5 15,9 C15,6.8 13.2,5 11,5 Z"/>
|
<path stroke="#6E6E6E" stroke-linecap="round" stroke-width="2" d="M8,8.5 C8.25,7 9.66585007,6 11,6 C12.5,6 14,7 14,8.5 C14,10.5 11,11 11,13"/>
|
||||||
|
<circle cx="11" cy="16" r="1.2" fill="#6E6E6E"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
@@ -147,22 +150,19 @@ public class FlatHelpButtonIcon
|
|||||||
g2.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
g2.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
||||||
|
|
||||||
// paint question mark
|
// paint question mark
|
||||||
Path2D q = new Path2D.Float();
|
Path2D q = new Path2D.Float( Path2D.WIND_NON_ZERO, 10 );
|
||||||
q.moveTo( 11, 5 );
|
q.moveTo( 8,8.5 );
|
||||||
q.curveTo( 8.8,5, 7,6.8, 7,9 );
|
q.curveTo( 8.25,7, 9.66585007,6, 11,6 );
|
||||||
q.lineTo( 9, 9 );
|
q.curveTo( 12.5,6, 14,7, 14,8.5 );
|
||||||
q.curveTo( 9,7.9, 9.9,7, 11,7 );
|
q.curveTo( 14,10.5, 11,11, 11,13 );
|
||||||
q.curveTo( 12.1,7, 13,7.9, 13,9 );
|
|
||||||
q.curveTo( 13,11, 10,10.75, 10,14 );
|
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
q.lineTo( 12, 14 );
|
g2.setStroke( new BasicStroke( 2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
q.curveTo( 12,11.75, 15,11.5, 15,9 );
|
|
||||||
q.curveTo( 15,6.8, 13.2,5, 11,5 );
|
|
||||||
q.closePath();
|
|
||||||
|
|
||||||
g2.translate( focusWidth, focusWidth );
|
g2.translate( focusWidth, focusWidth );
|
||||||
g2.setColor( enabled ? questionMarkColor : disabledQuestionMarkColor );
|
g2.setColor( enabled ? questionMarkColor : disabledQuestionMarkColor );
|
||||||
g2.fill( q );
|
g2.draw( q );
|
||||||
g2.fillRect( 10, 15, 2, 2 );
|
g2.fill( new Ellipse2D.Float( 9.8f, 14.8f, 2.4f, 2.4f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import java.awt.BasicStroke;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Line2D;
|
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||||
@@ -58,9 +57,11 @@ public class FlatInternalFrameCloseIcon
|
|||||||
float my = height / 2;
|
float my = height / 2;
|
||||||
float r = 3.25f;
|
float r = 3.25f;
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||||
path.append( new Line2D.Float( mx - r, my - r, mx + r, my + r ), false );
|
path.moveTo( mx - r, my - r );
|
||||||
path.append( new Line2D.Float( mx - r, my + r, mx + r, my - r ), false );
|
path.lineTo( mx + r, my + r );
|
||||||
|
path.moveTo( mx - r, my + r );
|
||||||
|
path.lineTo( mx + r, my - r );
|
||||||
g.setStroke( new BasicStroke( 1f ) );
|
g.setStroke( new BasicStroke( 1f ) );
|
||||||
g.draw( path );
|
g.draw( path );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package com.formdev.flatlaf.icons;
|
|||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Error" icon for {@link javax.swing.JOptionPane}.
|
* "Error" icon for {@link javax.swing.JOptionPane}.
|
||||||
@@ -40,8 +40,8 @@ public class FlatOptionPaneErrorIcon
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#DB5860"/>
|
<circle cx="16" cy="16" r="14" fill="#DB5860"/>
|
||||||
<rect width="4" height="11" x="14" y="7" fill="#FFF"/>
|
<rect width="4" height="12" x="14" y="7" fill="#FFF" rx="2"/>
|
||||||
<rect width="4" height="4" x="14" y="21" fill="#FFF"/>
|
<circle cx="16" cy="23" r="2" fill="#FFF"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
@@ -54,8 +54,8 @@ public class FlatOptionPaneErrorIcon
|
|||||||
@Override
|
@Override
|
||||||
protected Shape createInside() {
|
protected Shape createInside() {
|
||||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
inside.append( new Rectangle2D.Float( 14, 7, 4, 11 ), false );
|
inside.append( new RoundRectangle2D.Float( 14, 7, 4, 12, 4, 4 ), false );
|
||||||
inside.append( new Rectangle2D.Float( 14, 21, 4, 4 ), false );
|
inside.append( new Ellipse2D.Float( 14, 21, 4, 4 ), false );
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package com.formdev.flatlaf.icons;
|
|||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Information" icon for {@link javax.swing.JOptionPane}.
|
* "Information" icon for {@link javax.swing.JOptionPane}.
|
||||||
@@ -40,8 +40,8 @@ public class FlatOptionPaneInformationIcon
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
||||||
<rect width="4" height="11" x="14" y="14" fill="#FFF"/>
|
<rect width="4" height="12" x="14" y="13" fill="#FFF" rx="2"/>
|
||||||
<rect width="4" height="4" x="14" y="7" fill="#FFF"/>
|
<circle cx="16" cy="9" r="2" fill="#FFF"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
@@ -54,8 +54,8 @@ public class FlatOptionPaneInformationIcon
|
|||||||
@Override
|
@Override
|
||||||
protected Shape createInside() {
|
protected Shape createInside() {
|
||||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
inside.append( new Rectangle2D.Float( 14, 14, 4, 11 ), false );
|
inside.append( new RoundRectangle2D.Float( 14, 13, 4, 12, 4, 4 ), false );
|
||||||
inside.append( new Rectangle2D.Float( 14, 7, 4, 4 ), false );
|
inside.append( new Ellipse2D.Float( 14, 7, 4, 4 ), false );
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Question" icon for {@link javax.swing.JOptionPane}.
|
* "Question" icon for {@link javax.swing.JOptionPane}.
|
||||||
@@ -40,8 +40,8 @@ public class FlatOptionPaneQuestionIcon
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
||||||
<rect width="4" height="4" x="14" y="22" fill="#FFF"/>
|
<circle cx="16" cy="24" r="1.7" fill="#FFF"/>
|
||||||
<path fill="#FFF" d="M14,20 C14,20 18,20 18,20 C18,16 23,16 23,12 C23,8 20,6 16,6 C12,6 9,8 9,12 C9,12 13,12 13,12 C13,10 14,9 16,9 C18,9 19,10 19,12 C19,15 14,15 14,20 Z"/>
|
<path stroke="#FFF" stroke-linecap="round" stroke-width="3" d="M11.5,11.75 C11.75,9.5 13.75,8 16,8 C18.25,8 20.5,9.5 20.5,11.75 C20.5,14.75 16,15.5 16,19"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
@@ -53,21 +53,17 @@ public class FlatOptionPaneQuestionIcon
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Shape createInside() {
|
protected Shape createInside() {
|
||||||
Path2D q = new Path2D.Float();
|
Path2D q = new Path2D.Float( Path2D.WIND_NON_ZERO, 10 );
|
||||||
q.moveTo( 14, 20 );
|
q.moveTo( 11.5,11.75 );
|
||||||
q.lineTo( 18, 20 );
|
q.curveTo( 11.75,9.5, 13.75,8, 16,8 );
|
||||||
q.curveTo( 18, 16, 23, 16, 23, 12 );
|
q.curveTo( 18.25,8, 20.5,9.5, 20.5,11.75 );
|
||||||
q.curveTo( 23, 8, 20, 6, 16, 6 );
|
q.curveTo( 20.5,14.75, 16,15.5, 16,19 );
|
||||||
q.curveTo( 12, 6, 9, 8, 9, 12 );
|
|
||||||
q.curveTo( 9, 12, 13, 12, 13, 12 );
|
BasicStroke stroke = new BasicStroke( 3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER );
|
||||||
q.curveTo( 13, 10, 14, 9, 16, 9 );
|
|
||||||
q.curveTo( 18, 9, 19, 10, 19, 12 );
|
|
||||||
q.curveTo( 19, 15, 14, 15, 14, 20 );
|
|
||||||
q.closePath();
|
|
||||||
|
|
||||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
inside.append( new Rectangle2D.Float( 14, 22, 4, 4 ), false );
|
inside.append( new Ellipse2D.Float( 14.3f, 22.3f, 3.4f, 3.4f ), false );
|
||||||
inside.append( q, false );
|
inside.append( stroke.createStrokedShape( q ), false );
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,9 @@
|
|||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,23 +40,24 @@ public class FlatOptionPaneWarningIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#EDA200" points="16 2 31 28 1 28"/>
|
<path fill="#EDA200" d="M17.7364863,3.038851 L30.2901269,25.0077221 C30.8381469,25.966757 30.5049534,27.1884663 29.5459185,27.7364863 C29.2437231,27.9091694 28.9016945,28 28.5536406,28 L3.44635936,28 C2.34178986,28 1.44635936,27.1045695 1.44635936,26 C1.44635936,25.6519461 1.53718999,25.3099175 1.70987307,25.0077221 L14.2635137,3.038851 C14.8115337,2.0798161 16.033243,1.74662265 16.9922779,2.29464259 C17.3023404,2.47182119 17.5593077,2.72878844 17.7364863,3.038851 Z"/>
|
||||||
<rect width="4" height="8" x="14" y="10" fill="#FFF"/>
|
<rect width="4" height="11" x="14" y="8" fill="#FFF" rx="2"/>
|
||||||
<rect width="4" height="4" x="14" y="21" fill="#FFF"/>
|
<circle cx="16" cy="23" r="2" fill="#FFF"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Shape createOutside() {
|
protected Shape createOutside() {
|
||||||
return FlatUIUtils.createPath( 16,2, 31,28, 1,28 );
|
return FlatUIUtils.createRoundTrianglePath( 16,0, 32,28, 0,28, 4 );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Shape createInside() {
|
protected Shape createInside() {
|
||||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
inside.append( new Rectangle2D.Float( 14, 10, 4, 8 ), false );
|
inside.append( new RoundRectangle2D.Float( 14, 8, 4, 11, 4, 4 ), false );
|
||||||
inside.append( new Rectangle2D.Float( 14, 21, 4, 4 ), false );
|
inside.append( new Ellipse2D.Float( 14, 21, 4, 4 ), false );
|
||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ public class FlatSearchIcon
|
|||||||
@Styleable protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
|
@Styleable protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
|
||||||
|
|
||||||
private final boolean ignoreButtonState;
|
private final boolean ignoreButtonState;
|
||||||
|
private Area area;
|
||||||
|
|
||||||
public FlatSearchIcon() {
|
public FlatSearchIcon() {
|
||||||
this( false );
|
this( false );
|
||||||
@@ -89,9 +90,11 @@ public class FlatSearchIcon
|
|||||||
null, searchIconHoverColor, searchIconPressedColor ) );
|
null, searchIconHoverColor, searchIconPressedColor ) );
|
||||||
|
|
||||||
// paint magnifier
|
// paint magnifier
|
||||||
Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
|
if( area == null ) {
|
||||||
area.subtract( new Area( new Ellipse2D.Float( 3, 3, 8, 8 ) ) );
|
area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
|
||||||
area.add( new Area( FlatUIUtils.createPath( 10.813,9.75, 14,12.938, 12.938,14, 9.75,10.813 ) ) );
|
area.subtract( new Area( new Ellipse2D.Float( 3, 3, 8, 8 ) ) );
|
||||||
|
area.add( new Area( FlatUIUtils.createPath( 10.813,9.75, 14,12.938, 12.938,14, 9.75,10.813 ) ) );
|
||||||
|
}
|
||||||
g.fill( area );
|
g.fill( area );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Line2D;
|
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
@@ -100,9 +99,11 @@ public class FlatTabbedPaneCloseIcon
|
|||||||
float r = ((bg != null) ? closeCrossFilledSize : closeCrossPlainSize) / 2;
|
float r = ((bg != null) ? closeCrossFilledSize : closeCrossPlainSize) / 2;
|
||||||
|
|
||||||
// paint cross
|
// paint cross
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||||
path.append( new Line2D.Float( mx - r, my - r, mx + r, my + r ), false );
|
path.moveTo( mx - r, my - r );
|
||||||
path.append( new Line2D.Float( mx - r, my + r, mx + r, my - r ), false );
|
path.lineTo( mx + r, my + r );
|
||||||
|
path.moveTo( mx - r, my + r );
|
||||||
|
path.lineTo( mx + r, my - r );
|
||||||
g.setStroke( new BasicStroke( closeCrossLineWidth ) );
|
g.setStroke( new BasicStroke( closeCrossLineWidth ) );
|
||||||
g.draw( path );
|
g.draw( path );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ package com.formdev.flatlaf.icons;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "closed" icon for {@link javax.swing.JTree} used by {@link javax.swing.tree.DefaultTreeCellRenderer}.
|
* "closed" icon for {@link javax.swing.JTree} used by {@link javax.swing.tree.DefaultTreeCellRenderer}.
|
||||||
@@ -31,6 +32,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatTreeClosedIcon
|
public class FlatTreeClosedIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatTreeClosedIcon() {
|
public FlatTreeClosedIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "Tree.icon.closedColor" ) );
|
super( 16, 16, UIManager.getColor( "Tree.icon.closedColor" ) );
|
||||||
}
|
}
|
||||||
@@ -41,10 +44,14 @@ public class FlatTreeClosedIcon
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<polygon fill="#6E6E6E" fill-rule="evenodd" points="1 2 6 2 8 4 15 4 15 13 1 13"/>
|
<path fill="none" stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 1,2, 6,2, 8,4, 15,4, 15,13, 1,13 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
|
||||||
|
if( path == null )
|
||||||
|
path = FlatFileViewDirectoryIcon.createFolderPath();
|
||||||
|
g.draw( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import javax.swing.JTree;
|
import javax.swing.JTree;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
@@ -39,6 +41,7 @@ public class FlatTreeCollapsedIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
private final boolean chevron;
|
private final boolean chevron;
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatTreeCollapsedIcon() {
|
public FlatTreeCollapsedIcon() {
|
||||||
this( UIManager.getColor( "Tree.icon.collapsedColor" ) );
|
this( UIManager.getColor( "Tree.icon.collapsedColor" ) );
|
||||||
@@ -59,10 +62,15 @@ public class FlatTreeCollapsedIcon
|
|||||||
|
|
||||||
if( chevron ) {
|
if( chevron ) {
|
||||||
// chevron arrow
|
// chevron arrow
|
||||||
g.fill( FlatUIUtils.createPath( 3,1, 3,2.5, 6,5.5, 3,8.5, 3,10, 4.5,10, 9,5.5, 4.5,1 ) );
|
g.setStroke( new BasicStroke( 1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER ) );
|
||||||
|
if( path == null )
|
||||||
|
path = FlatUIUtils.createPath( false, 3.5,1.5, 7.5,5.5, 3.5,9.5 );
|
||||||
|
g.draw( path );
|
||||||
} else {
|
} else {
|
||||||
// triangle arrow
|
// triangle arrow
|
||||||
g.fill( FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 ) );
|
if( path == null )
|
||||||
|
path = FlatUIUtils.createPath( 2,1, 2,10, 10,5.5 );
|
||||||
|
g.fill( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,14 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.util.ColorFunctions;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "leaf" icon for {@link javax.swing.JTree} used by {@link javax.swing.tree.DefaultTreeCellRenderer}.
|
* "leaf" icon for {@link javax.swing.JTree} used by {@link javax.swing.tree.DefaultTreeCellRenderer}.
|
||||||
@@ -42,13 +46,22 @@ public class FlatTreeLeafIcon
|
|||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#6E6E6E" points="8 6 8 1 13 1 13 15 3 15 3 6"/>
|
<rect width="11" height="13" x="2.5" y="1.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<polygon fill="#6E6E6E" points="3 5 7 5 7 1"/>
|
<line x1="5.5" x2="10.5" y1="5.5" y2="5.5" stroke="#6E6E6E" stroke-linecap="round" stroke-opacity=".6"/>
|
||||||
|
<line x1="5.5" x2="10.5" y1="8" y2="8" stroke="#6E6E6E" stroke-linecap="round" stroke-opacity=".6"/>
|
||||||
|
<line x1="5.5" x2="10.5" y1="10.5" y2="10.5" stroke="#6E6E6E" stroke-linecap="round" stroke-opacity=".6"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 8,6, 8,1, 13,1, 13,15, 3,15, 3,6 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 3,5, 7,5, 7,1 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||||
|
|
||||||
|
g.draw( new RoundRectangle2D.Float( 2.5f, 1.5f, 11, 13, 3, 3 ) );
|
||||||
|
|
||||||
|
g.setColor( ColorFunctions.fade( g.getColor(), 0.6f ) );
|
||||||
|
g.draw( new Line2D.Float( 5.5f, 5.5f, 10.5f, 5.5f ) );
|
||||||
|
g.draw( new Line2D.Float( 5.5f, 8, 10.5f, 8 ) );
|
||||||
|
g.draw( new Line2D.Float( 5.5f, 10.5f, 10.5f, 10.5f ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,11 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
@@ -31,6 +34,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatTreeOpenIcon
|
public class FlatTreeOpenIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private Path2D path;
|
||||||
|
|
||||||
public FlatTreeOpenIcon() {
|
public FlatTreeOpenIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "Tree.icon.openColor" ) );
|
super( 16, 16, UIManager.getColor( "Tree.icon.openColor" ) );
|
||||||
}
|
}
|
||||||
@@ -41,14 +46,38 @@ public class FlatTreeOpenIcon
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<path fill="none" stroke="#6E6E6E" d="M2,13.5 L4.11538462,8.42307692 C4.34828895,7.86410651 4.89444872,7.5 5.5,7.5 L14.75,7.5 C15.0261424,7.5 15.25,7.72385763 15.25,8 C15.25,8.06601301 15.2369281,8.13137261 15.2115385,8.19230769 L13.3846154,12.5769231 C13.151711,13.1358935 12.6055513,13.5 12,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L12,4.5 C12.8284271,4.5 13.5,5.17157288 13.5,6 L13.5,6.5 L13.5,6.5"/>
|
||||||
<polygon fill="#6E6E6E" points="1 2 6 2 8 4 14 4 14 6 3.5 6 1 11"/>
|
|
||||||
<polygon fill="#6E6E6E" points="4 7 16 7 13 13 1 13"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
</svg>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 1,2, 6,2, 8,4, 14,4, 14,6, 3.5,6, 1,11 ) );
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
g.fill( FlatUIUtils.createPath( 4,7, 16,7, 13,13, 1,13 ) );
|
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER ) );
|
||||||
|
|
||||||
|
if( path == null ) {
|
||||||
|
double arc = 1.5;
|
||||||
|
double arc2 = 0.5;
|
||||||
|
path = FlatUIUtils.createPath( false,
|
||||||
|
// bottom-left of opend part
|
||||||
|
2,13.5,
|
||||||
|
// top-left of opend part
|
||||||
|
FlatUIUtils.ROUNDED, 4.5,7.5, arc,
|
||||||
|
// top-right of opend part
|
||||||
|
FlatUIUtils.ROUNDED, 15.5,7.5, arc2,
|
||||||
|
|
||||||
|
// bottom-right
|
||||||
|
FlatUIUtils.ROUNDED, 13,13.5, arc,
|
||||||
|
// bottom-left
|
||||||
|
1.5+arc,13.5, FlatUIUtils.QUAD_TO, 1.5,13.5, 1.5,13.5-arc,
|
||||||
|
// top-left
|
||||||
|
1.5,2.5+arc, FlatUIUtils.QUAD_TO, 1.5,2.5, 1.5+arc,2.5,
|
||||||
|
// top-mid-left
|
||||||
|
6.5-arc2,2.5, FlatUIUtils.QUAD_TO, 6.5,2.5, 6.5+arc2,2.5+arc2,
|
||||||
|
// top-mid-right
|
||||||
|
8.5,4.5,
|
||||||
|
// top-right
|
||||||
|
13.5-arc,4.5, FlatUIUtils.QUAD_TO, 13.5,4.5, 13.5,4.5+arc,
|
||||||
|
13.5,6.5 );
|
||||||
|
}
|
||||||
|
g.draw( path );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import java.awt.BasicStroke;
|
|||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.geom.Line2D;
|
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||||
@@ -57,9 +56,11 @@ public class FlatWindowCloseIcon
|
|||||||
int iy2 = iy + iwh - 1;
|
int iy2 = iy + iwh - 1;
|
||||||
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||||
path.append( new Line2D.Float( ix, iy, ix2, iy2 ), false );
|
path.moveTo( ix, iy );
|
||||||
path.append( new Line2D.Float( ix, iy2, ix2, iy ), false );
|
path.lineTo( ix2, iy2 );
|
||||||
|
path.moveTo( ix, iy2 );
|
||||||
|
path.lineTo( ix2, iy );
|
||||||
g.setStroke( new BasicStroke( thickness ) );
|
g.setStroke( new BasicStroke( thickness ) );
|
||||||
g.draw( path );
|
g.draw( path );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicArrowButton;
|
import javax.swing.plaf.basic.BasicArrowButton;
|
||||||
|
|
||||||
@@ -48,8 +49,10 @@ public class FlatArrowButton
|
|||||||
protected Color pressedBackground;
|
protected Color pressedBackground;
|
||||||
|
|
||||||
private int arrowWidth = DEFAULT_ARROW_WIDTH;
|
private int arrowWidth = DEFAULT_ARROW_WIDTH;
|
||||||
|
private float arrowThickness = 1;
|
||||||
private float xOffset = 0;
|
private float xOffset = 0;
|
||||||
private float yOffset = 0;
|
private float yOffset = 0;
|
||||||
|
private boolean roundBorderAutoXOffset = true;
|
||||||
|
|
||||||
private boolean hover;
|
private boolean hover;
|
||||||
private boolean pressed;
|
private boolean pressed;
|
||||||
@@ -82,14 +85,18 @@ public class FlatArrowButton
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed( MouseEvent e ) {
|
public void mousePressed( MouseEvent e ) {
|
||||||
pressed = true;
|
if( SwingUtilities.isLeftMouseButton( e ) ) {
|
||||||
repaint();
|
pressed = true;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased( MouseEvent e ) {
|
public void mouseReleased( MouseEvent e ) {
|
||||||
pressed = false;
|
if( SwingUtilities.isLeftMouseButton( e ) ) {
|
||||||
repaint();
|
pressed = false;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
@@ -116,6 +123,16 @@ public class FlatArrowButton
|
|||||||
this.arrowWidth = arrowWidth;
|
this.arrowWidth = arrowWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
public float getArrowThickness() {
|
||||||
|
return arrowThickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
public void setArrowThickness( float arrowThickness ) {
|
||||||
|
this.arrowThickness = arrowThickness;
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isHover() {
|
protected boolean isHover() {
|
||||||
return hover;
|
return hover;
|
||||||
}
|
}
|
||||||
@@ -140,6 +157,16 @@ public class FlatArrowButton
|
|||||||
this.yOffset = yOffset;
|
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 ) {
|
protected Color deriveBackground( Color background ) {
|
||||||
return background;
|
return background;
|
||||||
}
|
}
|
||||||
@@ -203,14 +230,17 @@ public class FlatArrowButton
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void paintArrow( Graphics2D g ) {
|
protected void paintArrow( Graphics2D g ) {
|
||||||
boolean vert = (direction == NORTH || direction == SOUTH);
|
|
||||||
int x = 0;
|
int x = 0;
|
||||||
|
|
||||||
// move arrow for round borders
|
// move arrow for round borders
|
||||||
Container parent = getParent();
|
if( isRoundBorderAutoXOffset() ) {
|
||||||
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
|
Container parent = getParent();
|
||||||
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
|
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() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import static com.formdev.flatlaf.FlatClientProperties.*;
|
|||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
@@ -45,8 +46,10 @@ import javax.swing.LookAndFeel;
|
|||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.plaf.ButtonUI;
|
import javax.swing.plaf.ButtonUI;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.ToolBarUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicButtonListener;
|
import javax.swing.plaf.basic.BasicButtonListener;
|
||||||
import javax.swing.plaf.basic.BasicButtonUI;
|
import javax.swing.plaf.basic.BasicButtonUI;
|
||||||
@@ -797,5 +800,20 @@ public class FlatButtonUI
|
|||||||
super.propertyChange( e );
|
super.propertyChange( e );
|
||||||
FlatButtonUI.this.propertyChange( b, e );
|
FlatButtonUI.this.propertyChange( b, e );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged( ChangeEvent e ) {
|
||||||
|
super.stateChanged( e );
|
||||||
|
|
||||||
|
// if button is in toolbar, repaint button groups
|
||||||
|
AbstractButton b = (AbstractButton) e.getSource();
|
||||||
|
Container parent = b.getParent();
|
||||||
|
if( parent instanceof JToolBar ) {
|
||||||
|
JToolBar toolBar = (JToolBar) parent;
|
||||||
|
ToolBarUI ui = toolBar.getUI();
|
||||||
|
if( ui instanceof FlatToolBarUI )
|
||||||
|
((FlatToolBarUI)ui).repaintButtonGroup( b );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import javax.swing.plaf.basic.BasicComboBoxUI;
|
|||||||
import javax.swing.plaf.basic.BasicComboPopup;
|
import javax.swing.plaf.basic.BasicComboPopup;
|
||||||
import javax.swing.plaf.basic.ComboPopup;
|
import javax.swing.plaf.basic.ComboPopup;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
|
import com.formdev.flatlaf.icons.FlatCheckBoxMenuItemIcon;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||||
@@ -99,7 +100,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
* @uiDefault ComboBox.minimumWidth int
|
* @uiDefault ComboBox.minimumWidth int
|
||||||
* @uiDefault ComboBox.editorColumns int
|
* @uiDefault ComboBox.editorColumns int
|
||||||
* @uiDefault ComboBox.maximumRowCount 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.arrowType String chevron (default) or triangle
|
||||||
* @uiDefault Component.isIntelliJTheme boolean
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
|
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
|
||||||
@@ -117,6 +118,9 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
* @uiDefault ComboBox.buttonHoverArrowColor Color
|
* @uiDefault ComboBox.buttonHoverArrowColor Color
|
||||||
* @uiDefault ComboBox.buttonPressedArrowColor Color
|
* @uiDefault ComboBox.buttonPressedArrowColor Color
|
||||||
* @uiDefault ComboBox.popupBackground Color optional
|
* @uiDefault ComboBox.popupBackground Color optional
|
||||||
|
* @uiDefault ComboBox.popupInsets Insets
|
||||||
|
* @uiDefault ComboBox.selectionInsets Insets
|
||||||
|
* @uiDefault ComboBox.selectionArc int
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -150,6 +154,9 @@ public class FlatComboBoxUI
|
|||||||
@Styleable protected Color buttonPressedArrowColor;
|
@Styleable protected Color buttonPressedArrowColor;
|
||||||
|
|
||||||
@Styleable protected Color popupBackground;
|
@Styleable protected Color popupBackground;
|
||||||
|
/** @since 3 */ @Styleable protected Insets popupInsets;
|
||||||
|
/** @since 3 */ @Styleable protected Insets selectionInsets;
|
||||||
|
/** @since 3 */ @Styleable protected int selectionArc;
|
||||||
|
|
||||||
private MouseListener hoverListener;
|
private MouseListener hoverListener;
|
||||||
protected boolean hover;
|
protected boolean hover;
|
||||||
@@ -253,6 +260,9 @@ public class FlatComboBoxUI
|
|||||||
buttonPressedArrowColor = UIManager.getColor( "ComboBox.buttonPressedArrowColor" );
|
buttonPressedArrowColor = UIManager.getColor( "ComboBox.buttonPressedArrowColor" );
|
||||||
|
|
||||||
popupBackground = UIManager.getColor( "ComboBox.popupBackground" );
|
popupBackground = UIManager.getColor( "ComboBox.popupBackground" );
|
||||||
|
popupInsets = UIManager.getInsets( "ComboBox.popupInsets" );
|
||||||
|
selectionInsets = UIManager.getInsets( "ComboBox.selectionInsets" );
|
||||||
|
selectionArc = UIManager.getInt( "ComboBox.selectionArc" );
|
||||||
|
|
||||||
// set maximumRowCount
|
// set maximumRowCount
|
||||||
int maximumRowCount = UIManager.getInt( "ComboBox.maximumRowCount" );
|
int maximumRowCount = UIManager.getInt( "ComboBox.maximumRowCount" );
|
||||||
@@ -308,11 +318,14 @@ public class FlatComboBoxUI
|
|||||||
// limit button width to height of a raw combobox (without insets)
|
// limit button width to height of a raw combobox (without insets)
|
||||||
FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() );
|
FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() );
|
||||||
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
||||||
|
int minButtonWidth = (maxButtonWidth * 3) / 4;
|
||||||
|
|
||||||
|
// make button square (except if width is limited)
|
||||||
Insets insets = getInsets();
|
Insets insets = getInsets();
|
||||||
int buttonWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
|
int buttonWidth = Math.min( Math.max( parent.getHeight() - insets.top - insets.bottom, minButtonWidth ), maxButtonWidth );
|
||||||
|
|
||||||
if( buttonWidth != arrowButton.getWidth() ) {
|
if( buttonWidth != arrowButton.getWidth() ) {
|
||||||
// set width of arrow button to preferred height of combobox
|
// set width of arrow button
|
||||||
int xOffset = comboBox.getComponentOrientation().isLeftToRight()
|
int xOffset = comboBox.getComponentOrientation().isLeftToRight()
|
||||||
? arrowButton.getWidth() - buttonWidth
|
? arrowButton.getWidth() - buttonWidth
|
||||||
: 0;
|
: 0;
|
||||||
@@ -556,7 +569,9 @@ public class FlatComboBoxUI
|
|||||||
int height = c.getHeight();
|
int height = c.getHeight();
|
||||||
int arrowX = arrowButton.getX();
|
int arrowX = arrowButton.getX();
|
||||||
int arrowWidth = arrowButton.getWidth();
|
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 enabled = comboBox.isEnabled();
|
||||||
boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight();
|
boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight();
|
||||||
|
|
||||||
@@ -574,13 +589,21 @@ public class FlatComboBoxUI
|
|||||||
: buttonBackground;
|
: buttonBackground;
|
||||||
if( buttonColor != null ) {
|
if( buttonColor != null ) {
|
||||||
g2.setColor( buttonColor );
|
g2.setColor( buttonColor );
|
||||||
Shape oldClip = g2.getClip();
|
if( isMacStyle() ) {
|
||||||
if( isLeftToRight )
|
Insets insets = comboBox.getInsets();
|
||||||
g2.clipRect( arrowX, 0, width - arrowX, height );
|
int gap = scale( 2 );
|
||||||
else
|
FlatUIUtils.paintComponentBackground( g2, arrowX + gap, insets.top + gap,
|
||||||
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
|
arrowWidth - (gap * 2), height - insets.top - insets.bottom - (gap * 2),
|
||||||
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
0, arc - focusWidth );
|
||||||
g2.setClip( oldClip );
|
} 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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,6 +742,10 @@ public class FlatComboBoxUI
|
|||||||
return parentParent != null && !comboBox.getBackground().equals( parentParent.getBackground() );
|
return parentParent != null && !comboBox.getBackground().equals( parentParent.getBackground() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isMacStyle() {
|
||||||
|
return "mac".equals( buttonStyle );
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 1.3 */
|
/** @since 1.3 */
|
||||||
public static boolean isPermanentFocusOwner( JComboBox<?> comboBox ) {
|
public static boolean isPermanentFocusOwner( JComboBox<?> comboBox ) {
|
||||||
if( comboBox.isEditable() ) {
|
if( comboBox.isEditable() ) {
|
||||||
@@ -753,6 +780,21 @@ public class FlatComboBoxUI
|
|||||||
buttonHoverArrowColor, null, buttonPressedArrowColor, null );
|
buttonHoverArrowColor, null, buttonPressedArrowColor, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getArrowWidth() {
|
||||||
|
return isMacStyle() ? (getWidth() % 2 == 0 ? 6 : 7) : super.getArrowWidth();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getArrowThickness() {
|
||||||
|
return isMacStyle() ? 1.5f : super.getArrowThickness();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRoundBorderAutoXOffset() {
|
||||||
|
return isMacStyle() ? false : super.isRoundBorderAutoXOffset();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isHover() {
|
protected boolean isHover() {
|
||||||
return super.isHover() || (!comboBox.isEditable() ? hover : false);
|
return super.isHover() || (!comboBox.isEditable() ? hover : false);
|
||||||
@@ -770,6 +812,20 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
return super.getArrowColor();
|
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 -----------------------------------------------
|
//---- class FlatComboPopup -----------------------------------------------
|
||||||
@@ -804,12 +860,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
|
// add width of vertical scroll bar
|
||||||
JScrollBar verticalScrollBar = scroller.getVerticalScrollBar();
|
JScrollBar verticalScrollBar = scroller.getVerticalScrollBar();
|
||||||
if( verticalScrollBar != null )
|
if( verticalScrollBar != null )
|
||||||
displayWidth += verticalScrollBar.getPreferredSize().width;
|
displayWidth += verticalScrollBar.getPreferredSize().width;
|
||||||
|
|
||||||
// make popup wider if necessary
|
// make popup wider if necessary
|
||||||
|
int pw0 = pw;
|
||||||
if( displayWidth > pw ) {
|
if( displayWidth > pw ) {
|
||||||
// limit popup width to screen width
|
// limit popup width to screen width
|
||||||
GraphicsConfiguration gc = comboBox.getGraphicsConfiguration();
|
GraphicsConfiguration gc = comboBox.getGraphicsConfiguration();
|
||||||
@@ -829,6 +892,30 @@ public class FlatComboBoxUI
|
|||||||
px -= diff;
|
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 );
|
return super.computePopupBounds( px, py, pw, ph );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -839,17 +926,12 @@ public class FlatComboBoxUI
|
|||||||
// make opaque to avoid that background shines thru border (e.g. at 150% scaling)
|
// make opaque to avoid that background shines thru border (e.g. at 150% scaling)
|
||||||
setOpaque( true );
|
setOpaque( true );
|
||||||
|
|
||||||
// set popup border
|
// set popup border
|
||||||
// use non-UIResource to avoid that it is overwritten when making
|
// use non-UIResource to avoid that it is overwritten when making
|
||||||
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
||||||
Border border = UIManager.getBorder( "PopupMenu.border" );
|
Border border = UIManager.getBorder( "PopupMenu.border" );
|
||||||
if( border != null )
|
if( border != null )
|
||||||
setBorder( FlatUIUtils.nonUIResource( border ) );
|
setBorder( FlatUIUtils.nonUIResource( border ) );
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void configureList() {
|
|
||||||
super.configureList();
|
|
||||||
|
|
||||||
list.setCellRenderer( new PopupListCellRenderer() );
|
list.setCellRenderer( new PopupListCellRenderer() );
|
||||||
updateStyle();
|
updateStyle();
|
||||||
@@ -857,12 +939,21 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
void updateStyle() {
|
void updateStyle() {
|
||||||
if( popupBackground != null )
|
if( popupBackground != null )
|
||||||
list.setBackground( popupBackground );
|
list.setBackground( popupBackground );
|
||||||
|
|
||||||
// set popup background because it may shine thru when scaled (e.g. at 150%)
|
// set popup background because it may shine thru when scaled (e.g. at 150%)
|
||||||
// use non-UIResource to avoid that it is overwritten when making
|
// use non-UIResource to avoid that it is overwritten when making
|
||||||
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
||||||
setBackground( FlatUIUtils.nonUIResource( list.getBackground() ) );
|
setBackground( FlatUIUtils.nonUIResource( list.getBackground() ) );
|
||||||
|
|
||||||
|
scroller.setViewportBorder( (popupInsets != null) ? new FlatEmptyBorder( popupInsets ) : null );
|
||||||
|
scroller.setOpaque( false );
|
||||||
|
|
||||||
|
if( list.getUI() instanceof FlatListUI ) {
|
||||||
|
FlatListUI ui = (FlatListUI) list.getUI();
|
||||||
|
ui.selectionInsets = selectionInsets;
|
||||||
|
ui.selectionArc = selectionArc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -904,6 +995,15 @@ public class FlatComboBoxUI
|
|||||||
paddingBorder.uninstall();
|
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 -----
|
//---- class PopupListCellRenderer -----
|
||||||
|
|
||||||
private class PopupListCellRenderer
|
private class PopupListCellRenderer
|
||||||
@@ -921,6 +1021,13 @@ public class FlatComboBoxUI
|
|||||||
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
||||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
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 ) ) );
|
paddingBorder.install( c, Math.round( FlatUIUtils.getBorderFocusWidth( comboBox ) ) );
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
@@ -937,10 +1044,16 @@ public class FlatComboBoxUI
|
|||||||
* which vertically aligns text in popup list with text in combobox.
|
* which vertically aligns text in popup list with text in combobox.
|
||||||
* <p>
|
* <p>
|
||||||
* The renderer border is painted on the outer side of this border.
|
* 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
|
private static class CellPaddingBorder
|
||||||
extends AbstractBorder
|
extends AbstractBorder
|
||||||
{
|
{
|
||||||
|
static final String KEY_MAC_STYLE_HINT = "FlatLaf.internal.FlatComboBoxUI.macStyleHint";
|
||||||
|
static final int MAC_STYLE_GAP = 4;
|
||||||
|
|
||||||
private Insets padding;
|
private Insets padding;
|
||||||
private JComponent rendererComponent;
|
private JComponent rendererComponent;
|
||||||
private Border rendererBorder;
|
private Border rendererBorder;
|
||||||
@@ -990,6 +1103,8 @@ public class FlatComboBoxUI
|
|||||||
if( rendererComponent == null )
|
if( rendererComponent == null )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
rendererComponent.putClientProperty( KEY_MAC_STYLE_HINT, null );
|
||||||
|
|
||||||
if( rendererComponent.getBorder() == this )
|
if( rendererComponent.getBorder() == this )
|
||||||
rendererComponent.setBorder( rendererBorder );
|
rendererComponent.setBorder( rendererBorder );
|
||||||
rendererComponent = null;
|
rendererComponent = null;
|
||||||
@@ -1017,6 +1132,18 @@ public class FlatComboBoxUI
|
|||||||
insets.left += focusWidth;
|
insets.left += focusWidth;
|
||||||
insets.right += 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;
|
return insets;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1024,6 +1151,35 @@ public class FlatComboBoxUI
|
|||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
if( rendererBorder != null )
|
if( rendererBorder != null )
|
||||||
rendererBorder.paintBorder( c, g, x, y, width, height );
|
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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -243,11 +243,13 @@ public class FlatFileChooserUI
|
|||||||
borderLayout.setHgap( 8 );
|
borderLayout.setHgap( 8 );
|
||||||
|
|
||||||
Component north = borderLayout.getLayoutComponent( BorderLayout.NORTH );
|
Component north = borderLayout.getLayoutComponent( BorderLayout.NORTH );
|
||||||
|
Component lineEnd = borderLayout.getLayoutComponent( BorderLayout.LINE_END );
|
||||||
Component center = borderLayout.getLayoutComponent( BorderLayout.CENTER );
|
Component center = borderLayout.getLayoutComponent( BorderLayout.CENTER );
|
||||||
Component south = borderLayout.getLayoutComponent( BorderLayout.SOUTH );
|
Component south = borderLayout.getLayoutComponent( BorderLayout.SOUTH );
|
||||||
if( north != null && center != null && south != null ) {
|
if( north != null && lineEnd != null && center != null && south != null ) {
|
||||||
JPanel p = new JPanel( new BorderLayout( 0, 11 ) );
|
JPanel p = new JPanel( new BorderLayout( 0, 11 ) );
|
||||||
p.add( north, BorderLayout.NORTH );
|
p.add( north, BorderLayout.NORTH );
|
||||||
|
p.add( lineEnd, BorderLayout.LINE_END );
|
||||||
p.add( center, BorderLayout.CENTER );
|
p.add( center, BorderLayout.CENTER );
|
||||||
p.add( south, BorderLayout.SOUTH );
|
p.add( south, BorderLayout.SOUTH );
|
||||||
fc.add( p, BorderLayout.CENTER );
|
fc.add( p, BorderLayout.CENTER );
|
||||||
|
|||||||
@@ -17,20 +17,34 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.swing.DefaultListCellRenderer;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.ListCellRenderer;
|
||||||
|
import javax.swing.ListModel;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.basic.BasicComboBoxRenderer;
|
||||||
import javax.swing.plaf.basic.BasicListUI;
|
import javax.swing.plaf.basic.BasicListUI;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
|
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JList}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JList}.
|
||||||
@@ -59,6 +73,8 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
*
|
*
|
||||||
* @uiDefault List.selectionInactiveBackground Color
|
* @uiDefault List.selectionInactiveBackground Color
|
||||||
* @uiDefault List.selectionInactiveForeground Color
|
* @uiDefault List.selectionInactiveForeground Color
|
||||||
|
* @uiDefault List.selectionInsets Insets
|
||||||
|
* @uiDefault List.selectionArc int
|
||||||
*
|
*
|
||||||
* <!-- FlatListCellBorder -->
|
* <!-- FlatListCellBorder -->
|
||||||
*
|
*
|
||||||
@@ -76,6 +92,8 @@ public class FlatListUI
|
|||||||
@Styleable protected Color selectionForeground;
|
@Styleable protected Color selectionForeground;
|
||||||
@Styleable protected Color selectionInactiveBackground;
|
@Styleable protected Color selectionInactiveBackground;
|
||||||
@Styleable protected Color selectionInactiveForeground;
|
@Styleable protected Color selectionInactiveForeground;
|
||||||
|
/** @since 3 */ @Styleable protected Insets selectionInsets;
|
||||||
|
/** @since 3 */ @Styleable protected int selectionArc;
|
||||||
|
|
||||||
// for FlatListCellBorder
|
// for FlatListCellBorder
|
||||||
/** @since 2 */ @Styleable protected Insets cellMargins;
|
/** @since 2 */ @Styleable protected Insets cellMargins;
|
||||||
@@ -110,6 +128,8 @@ public class FlatListUI
|
|||||||
selectionForeground = UIManager.getColor( "List.selectionForeground" );
|
selectionForeground = UIManager.getColor( "List.selectionForeground" );
|
||||||
selectionInactiveBackground = UIManager.getColor( "List.selectionInactiveBackground" );
|
selectionInactiveBackground = UIManager.getColor( "List.selectionInactiveBackground" );
|
||||||
selectionInactiveForeground = UIManager.getColor( "List.selectionInactiveForeground" );
|
selectionInactiveForeground = UIManager.getColor( "List.selectionInactiveForeground" );
|
||||||
|
selectionInsets = UIManager.getInsets( "List.selectionInsets" );
|
||||||
|
selectionArc = UIManager.getInt( "List.selectionArc" );
|
||||||
|
|
||||||
toggleSelectionColors();
|
toggleSelectionColors();
|
||||||
}
|
}
|
||||||
@@ -168,6 +188,29 @@ public class FlatListUI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ListSelectionListener createListSelectionListener() {
|
||||||
|
ListSelectionListener superListener = super.createListSelectionListener();
|
||||||
|
return e -> {
|
||||||
|
superListener.valueChanged( e );
|
||||||
|
|
||||||
|
// for united rounded selection, repaint parts of the rows/columns that adjoin to the changed rows/columns
|
||||||
|
if( useUnitedRoundedSelection( true, true ) &&
|
||||||
|
!list.isSelectionEmpty() &&
|
||||||
|
(list.getMaxSelectionIndex() - list.getMinSelectionIndex()) >= 1 )
|
||||||
|
{
|
||||||
|
int size = list.getModel().getSize();
|
||||||
|
int firstIndex = Math.min( Math.max( e.getFirstIndex(), 0 ), size - 1 );
|
||||||
|
int lastIndex = Math.min( Math.max( e.getLastIndex(), 0 ), size - 1 );
|
||||||
|
Rectangle r = getCellBounds( list, firstIndex, lastIndex );
|
||||||
|
if( r != null ) {
|
||||||
|
int arc = (int) Math.ceil( UIScale.scale( selectionArc / 2f ) );
|
||||||
|
list.repaint( r.x - arc, r.y - arc, r.width + (arc * 2), r.height + (arc * 2) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected void installStyle() {
|
protected void installStyle() {
|
||||||
try {
|
try {
|
||||||
@@ -247,4 +290,164 @@ public class FlatListUI
|
|||||||
list.setSelectionForeground( selectionInactiveForeground );
|
list.setSelectionForeground( selectionInactiveForeground );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings( "rawtypes" )
|
||||||
|
@Override
|
||||||
|
protected void paintCell( Graphics g, int row, Rectangle rowBounds, ListCellRenderer cellRenderer,
|
||||||
|
ListModel dataModel, ListSelectionModel selModel, int leadIndex )
|
||||||
|
{
|
||||||
|
boolean isSelected = selModel.isSelectedIndex( row );
|
||||||
|
|
||||||
|
// get renderer component
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
Component rendererComponent = cellRenderer.getListCellRendererComponent( list,
|
||||||
|
dataModel.getElementAt( row ), row, isSelected, list.hasFocus() && (row == leadIndex) );
|
||||||
|
|
||||||
|
//
|
||||||
|
boolean isFileList = Boolean.TRUE.equals( list.getClientProperty( "List.isFileList" ) );
|
||||||
|
int cx, cw;
|
||||||
|
if( isFileList ) {
|
||||||
|
// see BasicListUI.paintCell()
|
||||||
|
cw = Math.min( rowBounds.width, rendererComponent.getPreferredSize().width + 4 );
|
||||||
|
cx = list.getComponentOrientation().isLeftToRight()
|
||||||
|
? rowBounds.x
|
||||||
|
: rowBounds.x + (rowBounds.width - cw);
|
||||||
|
} else {
|
||||||
|
cx = rowBounds.x;
|
||||||
|
cw = rowBounds.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// rounded selection or selection insets
|
||||||
|
if( isSelected &&
|
||||||
|
!isFileList && // rounded selection is not supported for file list
|
||||||
|
(rendererComponent instanceof DefaultListCellRenderer ||
|
||||||
|
rendererComponent instanceof BasicComboBoxRenderer) &&
|
||||||
|
(selectionArc > 0 ||
|
||||||
|
(selectionInsets != null &&
|
||||||
|
(selectionInsets.top != 0 || selectionInsets.left != 0 || selectionInsets.bottom != 0 || selectionInsets.right != 0))) )
|
||||||
|
{
|
||||||
|
// Because selection painting is done in the cell renderer, it would be
|
||||||
|
// necessary to require a FlatLaf specific renderer to implement rounded selection.
|
||||||
|
// Using a LaF specific renderer was avoided because often a custom renderer is
|
||||||
|
// already used in applications. Then either the rounded selection is not used,
|
||||||
|
// or the application has to be changed to extend a FlatLaf renderer.
|
||||||
|
//
|
||||||
|
// To solve this, a graphics proxy is used that paints rounded selection
|
||||||
|
// if row is selected and the renderer wants to fill the background.
|
||||||
|
class RoundedSelectionGraphics extends Graphics2DProxy {
|
||||||
|
// used to avoid endless loop in case that paintCellSelection() invokes
|
||||||
|
// g.fillRect() with full bounds (selectionInsets is 0,0,0,0)
|
||||||
|
private boolean inPaintSelection;
|
||||||
|
|
||||||
|
RoundedSelectionGraphics( Graphics delegate ) {
|
||||||
|
super( (Graphics2D) delegate );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Graphics create() {
|
||||||
|
return new RoundedSelectionGraphics( super.create() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Graphics create( int x, int y, int width, int height ) {
|
||||||
|
return new RoundedSelectionGraphics( super.create( x, y, width, height ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fillRect( int x, int y, int width, int height ) {
|
||||||
|
if( !inPaintSelection &&
|
||||||
|
x == 0 && y == 0 && width == rowBounds.width && height == rowBounds.height &&
|
||||||
|
this.getColor() == rendererComponent.getBackground() )
|
||||||
|
{
|
||||||
|
inPaintSelection = true;
|
||||||
|
paintCellSelection( this, row, x, y, width, height );
|
||||||
|
inPaintSelection = false;
|
||||||
|
} else
|
||||||
|
super.fillRect( x, y, width, height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g = new RoundedSelectionGraphics( g );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint renderer
|
||||||
|
rendererPane.paintComponent( g, rendererComponent, list, cx, rowBounds.y, cw, rowBounds.height, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
protected void paintCellSelection( Graphics g, int row, int x, int y, int width, int height ) {
|
||||||
|
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
|
||||||
|
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
|
||||||
|
|
||||||
|
if( list.getLayoutOrientation() == JList.VERTICAL ) {
|
||||||
|
// layout orientation: VERTICAL
|
||||||
|
if( useUnitedRoundedSelection( true, false ) ) {
|
||||||
|
if( row > 0 && list.isSelectedIndex( row - 1 ) )
|
||||||
|
arcTopLeft = arcTopRight = 0;
|
||||||
|
if( row < list.getModel().getSize() - 1 && list.isSelectedIndex( row + 1 ) )
|
||||||
|
arcBottomLeft = arcBottomRight = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// layout orientation: VERTICAL_WRAP or HORIZONTAL_WRAP
|
||||||
|
Rectangle r = null;
|
||||||
|
if( useUnitedRoundedSelection( true, false ) ) {
|
||||||
|
// vertical: check whether cells above or below are selected
|
||||||
|
r = getCellBounds( list, row, row );
|
||||||
|
|
||||||
|
int topIndex = locationToIndex( list, new Point( r.x, r.y - 1 ) );
|
||||||
|
int bottomIndex = locationToIndex( list, new Point( r.x, r.y + r.height ) );
|
||||||
|
|
||||||
|
if( topIndex >= 0 && topIndex != row && list.isSelectedIndex( topIndex ) )
|
||||||
|
arcTopLeft = arcTopRight = 0;
|
||||||
|
if( bottomIndex >= 0 && bottomIndex != row && list.isSelectedIndex( bottomIndex ) )
|
||||||
|
arcBottomLeft = arcBottomRight = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( useUnitedRoundedSelection( false, true ) ) {
|
||||||
|
// horizontal: check whether cells left or right are selected
|
||||||
|
if( r == null )
|
||||||
|
r = getCellBounds( list, row, row );
|
||||||
|
|
||||||
|
int leftIndex = locationToIndex( list, new Point( r.x - 1, r.y ) );
|
||||||
|
int rightIndex = locationToIndex( list, new Point( r.x + r.width, r.y ) );
|
||||||
|
|
||||||
|
// special handling for the case that last column contains less cells than the other columns
|
||||||
|
boolean ltr = list.getComponentOrientation().isLeftToRight();
|
||||||
|
if( !ltr && leftIndex >= 0 && leftIndex != row && leftIndex == locationToIndex( list, new Point( r.x - 1, r.y - 1 ) ) )
|
||||||
|
leftIndex = -1;
|
||||||
|
if( ltr && rightIndex >= 0 && rightIndex != row && rightIndex == locationToIndex( list, new Point( r.x + r.width, r.y - 1 ) ) )
|
||||||
|
rightIndex = -1;
|
||||||
|
|
||||||
|
if( leftIndex >= 0 && leftIndex != row && list.isSelectedIndex( leftIndex ) )
|
||||||
|
arcTopLeft = arcBottomLeft = 0;
|
||||||
|
if( rightIndex >= 0 && rightIndex != row && list.isSelectedIndex( rightIndex ) )
|
||||||
|
arcTopRight = arcBottomRight = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatUIUtils.paintSelection( (Graphics2D) g, x, y, width, height,
|
||||||
|
UIScale.scale( selectionInsets ), arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean useUnitedRoundedSelection( boolean vertical, boolean horizontal ) {
|
||||||
|
return selectionArc > 0 &&
|
||||||
|
(selectionInsets == null ||
|
||||||
|
(vertical && selectionInsets.top == 0 && selectionInsets.bottom == 0) ||
|
||||||
|
(horizontal && selectionInsets.left == 0 && selectionInsets.right == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paints a cell selection at the given coordinates.
|
||||||
|
* The selection color must be set on the graphics context.
|
||||||
|
* <p>
|
||||||
|
* This method is intended for use in custom cell renderers.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static void paintCellSelection( JList<?> list, Graphics g, int row, int x, int y, int width, int height ) {
|
||||||
|
if( !(list.getUI() instanceof FlatListUI) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
FlatListUI ui = (FlatListUI) list.getUI();
|
||||||
|
ui.paintCellSelection( g, row, x, y, width, height );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,9 @@ public class FlatMenuBarUI
|
|||||||
/** @since 2 */ @Styleable protected Insets itemMargins;
|
/** @since 2 */ @Styleable protected Insets itemMargins;
|
||||||
|
|
||||||
// used in FlatMenuUI
|
// used in FlatMenuUI
|
||||||
|
/** @since 3 */ @Styleable protected Insets selectionInsets;
|
||||||
|
/** @since 3 */ @Styleable protected Insets selectionEmbeddedInsets;
|
||||||
|
/** @since 3 */ @Styleable protected int selectionArc = -1;
|
||||||
/** @since 2 */ @Styleable protected Color hoverBackground;
|
/** @since 2 */ @Styleable protected Color hoverBackground;
|
||||||
/** @since 2.5 */ @Styleable protected Color selectionBackground;
|
/** @since 2.5 */ @Styleable protected Color selectionBackground;
|
||||||
/** @since 2.5 */ @Styleable protected Color selectionForeground;
|
/** @since 2.5 */ @Styleable protected Color selectionForeground;
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
* @uiDefault MenuItem.acceleratorArrowGap int
|
* @uiDefault MenuItem.acceleratorArrowGap int
|
||||||
* @uiDefault MenuItem.checkBackground Color
|
* @uiDefault MenuItem.checkBackground Color
|
||||||
* @uiDefault MenuItem.checkMargins Insets
|
* @uiDefault MenuItem.checkMargins Insets
|
||||||
|
* @uiDefault MenuItem.selectionInsets Insets
|
||||||
|
* @uiDefault MenuItem.selectionArc int
|
||||||
* @uiDefault MenuItem.selectionType String null (default) or underline
|
* @uiDefault MenuItem.selectionType String null (default) or underline
|
||||||
* @uiDefault MenuItem.underlineSelectionBackground Color
|
* @uiDefault MenuItem.underlineSelectionBackground Color
|
||||||
* @uiDefault MenuItem.underlineSelectionCheckBackground Color
|
* @uiDefault MenuItem.underlineSelectionCheckBackground Color
|
||||||
@@ -91,6 +93,9 @@ public class FlatMenuItemRenderer
|
|||||||
@Styleable protected Color checkBackground = UIManager.getColor( "MenuItem.checkBackground" );
|
@Styleable protected Color checkBackground = UIManager.getColor( "MenuItem.checkBackground" );
|
||||||
@Styleable protected Insets checkMargins = UIManager.getInsets( "MenuItem.checkMargins" );
|
@Styleable protected Insets checkMargins = UIManager.getInsets( "MenuItem.checkMargins" );
|
||||||
|
|
||||||
|
/** @since 3 */ @Styleable protected Insets selectionInsets = UIManager.getInsets( "MenuItem.selectionInsets" );
|
||||||
|
/** @since 3 */ @Styleable protected int selectionArc = UIManager.getInt( "MenuItem.selectionArc" );
|
||||||
|
|
||||||
@Styleable protected Color underlineSelectionBackground = UIManager.getColor( "MenuItem.underlineSelectionBackground" );
|
@Styleable protected Color underlineSelectionBackground = UIManager.getColor( "MenuItem.underlineSelectionBackground" );
|
||||||
@Styleable protected Color underlineSelectionCheckBackground = UIManager.getColor( "MenuItem.underlineSelectionCheckBackground" );
|
@Styleable protected Color underlineSelectionCheckBackground = UIManager.getColor( "MenuItem.underlineSelectionCheckBackground" );
|
||||||
@Styleable protected Color underlineSelectionColor = UIManager.getColor( "MenuItem.underlineSelectionColor" );
|
@Styleable protected Color underlineSelectionColor = UIManager.getColor( "MenuItem.underlineSelectionColor" );
|
||||||
@@ -337,10 +342,16 @@ public class FlatMenuItemRenderer
|
|||||||
g.setColor( Color.orange ); g.drawRect( arrowRect.x, arrowRect.y, arrowRect.width - 1, arrowRect.height - 1 );
|
g.setColor( Color.orange ); g.drawRect( arrowRect.x, arrowRect.y, arrowRect.width - 1, arrowRect.height - 1 );
|
||||||
debug*/
|
debug*/
|
||||||
|
|
||||||
|
boolean armedOrSelected = isArmedOrSelected( menuItem );
|
||||||
boolean underlineSelection = isUnderlineSelection();
|
boolean underlineSelection = isUnderlineSelection();
|
||||||
paintBackground( g, underlineSelection ? underlineSelectionBackground : selectionBackground );
|
|
||||||
if( underlineSelection && isArmedOrSelected( menuItem ) )
|
paintBackground( g );
|
||||||
paintUnderlineSelection( g, underlineSelectionColor, underlineSelectionHeight );
|
if( armedOrSelected ) {
|
||||||
|
if( underlineSelection )
|
||||||
|
paintUnderlineSelection( g, underlineSelectionBackground, underlineSelectionColor, underlineSelectionHeight );
|
||||||
|
else
|
||||||
|
paintSelection( g, selectionBackground, selectionInsets, selectionArc );
|
||||||
|
}
|
||||||
paintIcon( g, iconRect, getIconForPainting(), underlineSelection ? underlineSelectionCheckBackground : checkBackground, selectionBackground );
|
paintIcon( g, iconRect, getIconForPainting(), underlineSelection ? underlineSelectionCheckBackground : checkBackground, selectionBackground );
|
||||||
paintText( g, textRect, menuItem.getText(), selectionForeground, disabledForeground );
|
paintText( g, textRect, menuItem.getText(), selectionForeground, disabledForeground );
|
||||||
paintAccelerator( g, accelRect, getAcceleratorText(), acceleratorForeground, acceleratorSelectionForeground, disabledForeground );
|
paintAccelerator( g, accelRect, getAcceleratorText(), acceleratorForeground, acceleratorSelectionForeground, disabledForeground );
|
||||||
@@ -348,21 +359,35 @@ debug*/
|
|||||||
paintArrowIcon( g, arrowRect, arrowIcon );
|
paintArrowIcon( g, arrowRect, arrowIcon );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintBackground( Graphics g, Color selectionBackground ) {
|
/** @since 3 */
|
||||||
boolean armedOrSelected = isArmedOrSelected( menuItem );
|
protected void paintBackground( Graphics g ) {
|
||||||
if( menuItem.isOpaque() || armedOrSelected ) {
|
if( menuItem.isOpaque() ) {
|
||||||
// paint background
|
g.setColor( menuItem.getBackground() );
|
||||||
g.setColor( armedOrSelected
|
|
||||||
? deriveBackground( selectionBackground )
|
|
||||||
: menuItem.getBackground() );
|
|
||||||
g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() );
|
g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) {
|
/** @since 3 */
|
||||||
|
protected void paintSelection( Graphics g, Color selectionBackground, Insets selectionInsets, int selectionArc ) {
|
||||||
|
float arc = scale( selectionArc / 2f );
|
||||||
|
|
||||||
|
g.setColor( deriveBackground( selectionBackground ) );
|
||||||
|
FlatUIUtils.paintSelection( (Graphics2D) g, 0, 0, menuItem.getWidth(), menuItem.getHeight(),
|
||||||
|
scale( selectionInsets ), arc, arc, arc, arc, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
protected void paintUnderlineSelection( Graphics g, Color underlineSelectionBackground,
|
||||||
|
Color underlineSelectionColor, int underlineSelectionHeight )
|
||||||
|
{
|
||||||
int width = menuItem.getWidth();
|
int width = menuItem.getWidth();
|
||||||
int height = menuItem.getHeight();
|
int height = menuItem.getHeight();
|
||||||
|
|
||||||
|
// paint background
|
||||||
|
g.setColor( deriveBackground( underlineSelectionBackground ) );
|
||||||
|
g.fillRect( 0, 0, width, height );
|
||||||
|
|
||||||
|
// paint underline
|
||||||
int underlineHeight = scale( underlineSelectionHeight );
|
int underlineHeight = scale( underlineSelectionHeight );
|
||||||
g.setColor( underlineSelectionColor );
|
g.setColor( underlineSelectionColor );
|
||||||
if( isTopLevelMenu( menuItem ) ) {
|
if( isTopLevelMenu( menuItem ) ) {
|
||||||
@@ -500,7 +525,11 @@ debug*/
|
|||||||
|
|
||||||
private Font getTopLevelFont() {
|
private Font getTopLevelFont() {
|
||||||
Font font = menuItem.getFont();
|
Font font = menuItem.getFont();
|
||||||
return (font != menuFont) ? font : menuItem.getParent().getFont();
|
// menu item parent may be null if JMenu.isTopLevelMenu() is overridden
|
||||||
|
// and does not check parent (e.g. com.jidesoft.swing.JideMenu.isTopLevelMenu())
|
||||||
|
return (font != menuFont || menuItem.getParent() == null)
|
||||||
|
? font
|
||||||
|
: menuItem.getParent().getFont();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Icon getIconForPainting() {
|
private Icon getIconForPainting() {
|
||||||
|
|||||||
@@ -20,7 +20,9 @@ import java.awt.Color;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Insets;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Window;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
@@ -32,7 +34,9 @@ import javax.swing.JComponent;
|
|||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.event.MouseInputListener;
|
import javax.swing.event.MouseInputListener;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
@@ -75,9 +79,12 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
*
|
*
|
||||||
* <!-- FlatMenuRenderer -->
|
* <!-- FlatMenuRenderer -->
|
||||||
*
|
*
|
||||||
|
* @uiDefault MenuBar.selectionInsets Insets
|
||||||
|
* @uiDefault MenuBar.selectionEmbeddedInsets Insets
|
||||||
|
* @uiDefault MenuBar.selectionArc int
|
||||||
* @uiDefault MenuBar.hoverBackground Color
|
* @uiDefault MenuBar.hoverBackground Color
|
||||||
* @uiDefault MenuBar.selectionBackground Color
|
* @uiDefault MenuBar.selectionBackground Color optional; defaults to Menu.selectionBackground
|
||||||
* @uiDefault MenuBar.selectionForeground Color
|
* @uiDefault MenuBar.selectionForeground Color optional; defaults to Menu.selectionForeground
|
||||||
* @uiDefault MenuBar.underlineSelectionBackground Color
|
* @uiDefault MenuBar.underlineSelectionBackground Color
|
||||||
* @uiDefault MenuBar.underlineSelectionColor Color
|
* @uiDefault MenuBar.underlineSelectionColor Color
|
||||||
* @uiDefault MenuBar.underlineSelectionHeight int
|
* @uiDefault MenuBar.underlineSelectionHeight int
|
||||||
@@ -225,12 +232,15 @@ public class FlatMenuUI
|
|||||||
protected class FlatMenuRenderer
|
protected class FlatMenuRenderer
|
||||||
extends FlatMenuItemRenderer
|
extends FlatMenuItemRenderer
|
||||||
{
|
{
|
||||||
|
/** @since 3 */ protected Insets menuBarSelectionInsets = UIManager.getInsets( "MenuBar.selectionInsets" );
|
||||||
|
/** @since 3 */ protected Insets menuBarSelectionEmbeddedInsets = UIManager.getInsets( "MenuBar.selectionEmbeddedInsets" );
|
||||||
|
/** @since 3 */ protected int menuBarSelectionArc = UIManager.getInt( "MenuBar.selectionArc" );
|
||||||
protected Color hoverBackground = UIManager.getColor( "MenuBar.hoverBackground" );
|
protected Color hoverBackground = UIManager.getColor( "MenuBar.hoverBackground" );
|
||||||
protected Color menuBarSelectionBackground = UIManager.getColor( "MenuBar.selectionBackground" );
|
/** @since 2.5 */ protected Color menuBarSelectionBackground = UIManager.getColor( "MenuBar.selectionBackground" );
|
||||||
protected Color menuBarSelectionForeground = UIManager.getColor( "MenuBar.selectionForeground" );
|
/** @since 2.5 */ protected Color menuBarSelectionForeground = UIManager.getColor( "MenuBar.selectionForeground" );
|
||||||
protected Color menuBarUnderlineSelectionBackground = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionBackground", underlineSelectionBackground );
|
protected Color menuBarUnderlineSelectionBackground = UIManager.getColor( "MenuBar.underlineSelectionBackground" );
|
||||||
protected Color menuBarUnderlineSelectionColor = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionColor", underlineSelectionColor );
|
protected Color menuBarUnderlineSelectionColor = UIManager.getColor( "MenuBar.underlineSelectionColor" );
|
||||||
protected int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", underlineSelectionHeight );
|
protected int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", -1 );
|
||||||
|
|
||||||
protected FlatMenuRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon,
|
protected FlatMenuRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon,
|
||||||
Font acceleratorFont, String acceleratorDelimiter )
|
Font acceleratorFont, String acceleratorDelimiter )
|
||||||
@@ -238,46 +248,76 @@ public class FlatMenuUI
|
|||||||
super( menuItem, checkIcon, arrowIcon, acceleratorFont, acceleratorDelimiter );
|
super( menuItem, checkIcon, arrowIcon, acceleratorFont, acceleratorDelimiter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
@Override
|
@Override
|
||||||
protected void paintBackground( Graphics g, Color selectionBackground ) {
|
protected void paintBackground( Graphics g ) {
|
||||||
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
super.paintBackground( g );
|
||||||
if( isUnderlineSelection() )
|
|
||||||
selectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground );
|
|
||||||
else {
|
|
||||||
selectionBackground = getStyleFromMenuBarUI( ui -> ui.selectionBackground,
|
|
||||||
menuBarSelectionBackground != null ? menuBarSelectionBackground : selectionBackground );
|
|
||||||
}
|
|
||||||
|
|
||||||
ButtonModel model = menuItem.getModel();
|
if( ((JMenu)menuItem).isTopLevelMenu() && isHover() ) {
|
||||||
if( model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled() ) {
|
// paint hover background
|
||||||
g.setColor( deriveBackground( getStyleFromMenuBarUI( ui -> ui.hoverBackground, hoverBackground ) ) );
|
Color color = deriveBackground( getStyleFromMenuBarUI( ui -> ui.hoverBackground, hoverBackground ) );
|
||||||
|
if( isUnderlineSelection() ) {
|
||||||
|
g.setColor( color );
|
||||||
g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() );
|
g.fillRect( 0, 0, menuItem.getWidth(), menuItem.getHeight() );
|
||||||
return;
|
} else
|
||||||
}
|
paintSelection( g, color, selectionInsets, selectionArc );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
@Override
|
||||||
|
protected void paintSelection( Graphics g, Color selectionBackground, Insets selectionInsets, int selectionArc ) {
|
||||||
|
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
||||||
|
if( !isHover() )
|
||||||
|
selectionBackground = getStyleFromMenuBarUI( ui -> ui.selectionBackground, menuBarSelectionBackground, selectionBackground );
|
||||||
|
|
||||||
|
JMenuBar menuBar = (JMenuBar) menuItem.getParent();
|
||||||
|
JRootPane rootPane = SwingUtilities.getRootPane( menuBar );
|
||||||
|
if( rootPane != null && rootPane.getParent() instanceof Window &&
|
||||||
|
rootPane.getJMenuBar() == menuBar &&
|
||||||
|
FlatRootPaneUI.isMenuBarEmbedded( rootPane ) )
|
||||||
|
{
|
||||||
|
selectionInsets = getStyleFromMenuBarUI( ui -> ui.selectionEmbeddedInsets, menuBarSelectionEmbeddedInsets );
|
||||||
|
} else
|
||||||
|
selectionInsets = getStyleFromMenuBarUI( ui -> ui.selectionInsets, menuBarSelectionInsets );
|
||||||
|
|
||||||
|
selectionArc = getStyleFromMenuBarUI( ui -> (ui.selectionArc != -1)
|
||||||
|
? ui.selectionArc : null, menuBarSelectionArc );
|
||||||
}
|
}
|
||||||
|
|
||||||
super.paintBackground( g, selectionBackground );
|
super.paintSelection( g, selectionBackground, selectionInsets, selectionArc );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
@Override
|
||||||
|
protected void paintUnderlineSelection( Graphics g, Color underlineSelectionBackground,
|
||||||
|
Color underlineSelectionColor, int underlineSelectionHeight )
|
||||||
|
{
|
||||||
|
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
||||||
|
underlineSelectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground, underlineSelectionBackground );
|
||||||
|
underlineSelectionColor = getStyleFromMenuBarUI( ui -> ui.underlineSelectionColor, menuBarUnderlineSelectionColor, underlineSelectionColor );
|
||||||
|
underlineSelectionHeight = getStyleFromMenuBarUI( ui -> (ui.underlineSelectionHeight != -1) ? ui.underlineSelectionHeight : null,
|
||||||
|
(menuBarUnderlineSelectionHeight != -1) ? menuBarUnderlineSelectionHeight : underlineSelectionHeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintUnderlineSelection( g, underlineSelectionBackground, underlineSelectionColor, underlineSelectionHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintText( Graphics g, Rectangle textRect, String text, Color selectionForeground, Color disabledForeground ) {
|
protected void paintText( Graphics g, Rectangle textRect, String text, Color selectionForeground, Color disabledForeground ) {
|
||||||
if( ((JMenu)menuItem).isTopLevelMenu() && !isUnderlineSelection() ) {
|
if( ((JMenu)menuItem).isTopLevelMenu() && !isUnderlineSelection() )
|
||||||
selectionForeground = getStyleFromMenuBarUI( ui -> ui.selectionForeground,
|
selectionForeground = getStyleFromMenuBarUI( ui -> ui.selectionForeground, menuBarSelectionForeground, selectionForeground );
|
||||||
menuBarSelectionForeground != null ? menuBarSelectionForeground : selectionForeground );
|
|
||||||
}
|
|
||||||
|
|
||||||
super.paintText( g, textRect, text, selectionForeground, disabledForeground );
|
super.paintText( g, textRect, text, selectionForeground, disabledForeground );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private boolean isHover() {
|
||||||
protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) {
|
ButtonModel model = menuItem.getModel();
|
||||||
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
return model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled();
|
||||||
underlineSelectionColor = getStyleFromMenuBarUI( ui -> ui.underlineSelectionColor, menuBarUnderlineSelectionColor );
|
}
|
||||||
underlineSelectionHeight = getStyleFromMenuBarUI( ui -> (ui.underlineSelectionHeight != -1)
|
|
||||||
? ui.underlineSelectionHeight : null, menuBarUnderlineSelectionHeight );
|
|
||||||
}
|
|
||||||
|
|
||||||
super.paintUnderlineSelection( g, underlineSelectionColor, underlineSelectionHeight );
|
private <T> T getStyleFromMenuBarUI( Function<FlatMenuBarUI, T> f, T defaultValue, T defaultValue2 ) {
|
||||||
|
return getStyleFromMenuBarUI( f, (defaultValue != null) ? defaultValue : defaultValue2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T getStyleFromMenuBarUI( Function<FlatMenuBarUI, T> f, T defaultValue ) {
|
private <T> T getStyleFromMenuBarUI( Function<FlatMenuBarUI, T> f, T defaultValue ) {
|
||||||
|
|||||||
@@ -48,27 +48,25 @@ class FlatNativeLibrary
|
|||||||
|
|
||||||
String libraryName;
|
String libraryName;
|
||||||
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) {
|
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) {
|
||||||
// Windows: requires Windows 10 (x86 or x86_64)
|
// Windows: requires Windows 10/11 (x86 or x86_64)
|
||||||
|
|
||||||
libraryName = "flatlaf-windows-x86";
|
libraryName = "flatlaf-windows-x86";
|
||||||
if( SystemInfo.isX86_64 )
|
if( SystemInfo.isX86_64 )
|
||||||
libraryName += "_64";
|
libraryName += "_64";
|
||||||
|
|
||||||
// load jawt native library
|
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
||||||
if( !SystemInfo.isJava_9_orLater ) {
|
// is not found when running application with <jdk>/bin/java.exe.
|
||||||
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
// When using <jdk>/jre/bin/java.exe, it is found.
|
||||||
// is not found when running application with <jdk>/bin/java.exe.
|
// jawt.dll is located in <jdk>/jre/bin/.
|
||||||
// When using <jdk>/jre/bin/java.exe, it is found.
|
// Java 9 and later do not have this problem,
|
||||||
// jawt.dll is located in <jdk>/jre/bin/.
|
// but load jawt.dll anyway to be on the safe side.
|
||||||
// Java 9 and later do not have this problem.
|
loadJAWT();
|
||||||
loadJAWT();
|
|
||||||
}
|
|
||||||
} else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) {
|
} else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) {
|
||||||
// Linux: requires x86_64
|
// Linux: requires x86_64
|
||||||
|
|
||||||
libraryName = "flatlaf-linux-x86_64";
|
libraryName = "flatlaf-linux-x86_64";
|
||||||
|
|
||||||
// Load jawt.so (part of JRE) explicitly because it is not found
|
// Load libjawt.so (part of JRE) explicitly because it is not found
|
||||||
// in all Java versions/distributions.
|
// in all Java versions/distributions.
|
||||||
// E.g. not found in Java 13 and later from openjdk.java.net.
|
// E.g. not found in Java 13 and later from openjdk.java.net.
|
||||||
// There seems to be also differences between distributions.
|
// There seems to be also differences between distributions.
|
||||||
@@ -84,11 +82,19 @@ class FlatNativeLibrary
|
|||||||
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
||||||
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
||||||
if( libraryPath != null ) {
|
if( libraryPath != null ) {
|
||||||
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
if( "system".equals( libraryPath ) ) {
|
||||||
if( libraryFile.exists() )
|
NativeLibrary library = new NativeLibrary( libraryName, true );
|
||||||
return new NativeLibrary( libraryFile, true );
|
if( library.isLoaded() )
|
||||||
else
|
return library;
|
||||||
|
|
||||||
|
LoggingFacade.INSTANCE.logSevere( "Did not find library " + libraryName + " in java.library.path, using extracted library instead", null );
|
||||||
|
} else {
|
||||||
|
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||||
|
if( libraryFile.exists() )
|
||||||
|
return new NativeLibrary( libraryFile, true );
|
||||||
|
|
||||||
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
||||||
@@ -101,9 +107,9 @@ class FlatNativeLibrary
|
|||||||
// log error only if native library jawt.dll not already loaded
|
// log error only if native library jawt.dll not already loaded
|
||||||
String message = ex.getMessage();
|
String message = ex.getMessage();
|
||||||
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( message, ex );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -349,6 +349,14 @@ public class FlatRootPaneUI
|
|||||||
titlePane.updateIcon();
|
titlePane.updateIcon();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FlatClientProperties.TITLE_BAR_SHOW_TITLE:
|
||||||
|
case FlatClientProperties.TITLE_BAR_SHOW_ICONIFFY:
|
||||||
|
case FlatClientProperties.TITLE_BAR_SHOW_MAXIMIZE:
|
||||||
|
case FlatClientProperties.TITLE_BAR_SHOW_CLOSE:
|
||||||
|
if( titlePane != null )
|
||||||
|
titlePane.updateVisibility();
|
||||||
|
break;
|
||||||
|
|
||||||
case FlatClientProperties.TITLE_BAR_BACKGROUND:
|
case FlatClientProperties.TITLE_BAR_BACKGROUND:
|
||||||
case FlatClientProperties.TITLE_BAR_FOREGROUND:
|
case FlatClientProperties.TITLE_BAR_FOREGROUND:
|
||||||
if( titlePane != null )
|
if( titlePane != null )
|
||||||
|
|||||||
@@ -17,7 +17,10 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.plaf.SpinnerUI;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,6 +38,19 @@ public class FlatRoundBorder
|
|||||||
// only used via styling (not in UI defaults, but has likewise client properties)
|
// only used via styling (not in UI defaults, but has likewise client properties)
|
||||||
/** @since 2 */ @Styleable protected Boolean roundRect;
|
/** @since 2 */ @Styleable protected Boolean roundRect;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
|
// make mac style spinner border smaller (border does not surround arrow buttons)
|
||||||
|
if( isMacStyleSpinner( c ) ) {
|
||||||
|
int macStyleButtonsWidth = ((FlatSpinnerUI)((JSpinner)c).getUI()).getMacStyleButtonsWidth();
|
||||||
|
width -= macStyleButtonsWidth;
|
||||||
|
if( !c.getComponentOrientation().isLeftToRight() )
|
||||||
|
x += macStyleButtonsWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintBorder( c, g, x, y, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getArc( Component c ) {
|
protected int getArc( Component c ) {
|
||||||
if( isCellEditor( c ) )
|
if( isCellEditor( c ) )
|
||||||
@@ -43,6 +59,17 @@ public class FlatRoundBorder
|
|||||||
Boolean roundRect = FlatUIUtils.isRoundRect( c );
|
Boolean roundRect = FlatUIUtils.isRoundRect( c );
|
||||||
if( roundRect == null )
|
if( roundRect == null )
|
||||||
roundRect = this.roundRect;
|
roundRect = this.roundRect;
|
||||||
return roundRect != null ? (roundRect ? Short.MAX_VALUE : 0) : arc;
|
return roundRect != null
|
||||||
|
? (roundRect ? Short.MAX_VALUE : 0)
|
||||||
|
: (isMacStyleSpinner( c ) ? 0 : arc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMacStyleSpinner( Component c ) {
|
||||||
|
if( c instanceof JSpinner ) {
|
||||||
|
SpinnerUI ui = ((JSpinner)c).getUI();
|
||||||
|
if( ui instanceof FlatSpinnerUI )
|
||||||
|
return ((FlatSpinnerUI)ui).isMacStyle();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -352,6 +352,9 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintTrack( Graphics g, JComponent c, Rectangle trackBounds ) {
|
protected void paintTrack( Graphics g, JComponent c, Rectangle trackBounds ) {
|
||||||
|
if( trackBounds.isEmpty() || !scrollbar.isEnabled() )
|
||||||
|
return;
|
||||||
|
|
||||||
g.setColor( getTrackColor( c, hoverTrack, isPressed && hoverTrack && !hoverThumb ) );
|
g.setColor( getTrackColor( c, hoverTrack, isPressed && hoverTrack && !hoverThumb ) );
|
||||||
paintTrackOrThumb( g, c, trackBounds, trackInsets, trackArc );
|
paintTrackOrThumb( g, c, trackBounds, trackInsets, trackArc );
|
||||||
}
|
}
|
||||||
@@ -452,18 +455,31 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed( MouseEvent e ) {
|
public void mousePressed( MouseEvent e ) {
|
||||||
isPressed = true;
|
if( SwingUtilities.isLeftMouseButton( e ) || isAbsolutePositioning( e ) ) {
|
||||||
repaint();
|
isPressed = true;
|
||||||
|
repaint();
|
||||||
|
|
||||||
|
// update hover because BasicScrollBarUI.TrackListener.mousePressed()
|
||||||
|
// moves the track on middle-click (if absolute positioning is enabled)
|
||||||
|
if( isAbsolutePositioning( e ) )
|
||||||
|
update( e.getX(), e.getY() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased( MouseEvent e ) {
|
public void mouseReleased( MouseEvent e ) {
|
||||||
isPressed = false;
|
if( SwingUtilities.isLeftMouseButton( e ) || isAbsolutePositioning( e ) ) {
|
||||||
repaint();
|
isPressed = false;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
update( e.getX(), e.getY() );
|
update( e.getX(), e.getY() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isAbsolutePositioning( MouseEvent e ) {
|
||||||
|
return getSupportsAbsolutePositioning() && SwingUtilities.isMiddleMouseButton( e );
|
||||||
|
}
|
||||||
|
|
||||||
private void update( int x, int y ) {
|
private void update( int x, int y ) {
|
||||||
boolean inTrack = getTrackBounds().contains( x, y );
|
boolean inTrack = getTrackBounds().contains( x, y );
|
||||||
boolean inThumb = getThumbBounds().contains( x, y );
|
boolean inThumb = getThumbBounds().contains( x, y );
|
||||||
|
|||||||
@@ -531,7 +531,7 @@ debug*/
|
|||||||
public static Shape createDirectionalThumbShape( float x, float y, float w, float h, float arc ) {
|
public static Shape createDirectionalThumbShape( float x, float y, float w, float h, float arc ) {
|
||||||
float wh = w / 2;
|
float wh = w / 2;
|
||||||
|
|
||||||
Path2D path = new Path2D.Float();
|
Path2D path = new Path2D.Float( Path2D.WIND_NON_ZERO, 9 );
|
||||||
path.moveTo( x + wh, y + h );
|
path.moveTo( x + wh, y + h );
|
||||||
path.lineTo( x, y + (h - wh) );
|
path.lineTo( x, y + (h - wh) );
|
||||||
path.lineTo( x, y + arc );
|
path.lineTo( x, y + arc );
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
* <!-- FlatSpinnerUI -->
|
* <!-- FlatSpinnerUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.minimumWidth int
|
* @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.arrowType String chevron (default) or triangle
|
||||||
* @uiDefault Component.isIntelliJTheme boolean
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
* @uiDefault Spinner.disabledBackground Color
|
* @uiDefault Spinner.disabledBackground Color
|
||||||
@@ -340,7 +340,25 @@ public class FlatSpinnerUI
|
|||||||
|
|
||||||
private Component createArrowButton( int direction, String name ) {
|
private Component createArrowButton( int direction, String name ) {
|
||||||
FlatArrowButton button = new FlatArrowButton( direction, arrowType, buttonArrowColor,
|
FlatArrowButton button = new FlatArrowButton( direction, arrowType, buttonArrowColor,
|
||||||
buttonDisabledArrowColor, buttonHoverArrowColor, null, buttonPressedArrowColor, null );
|
buttonDisabledArrowColor, buttonHoverArrowColor, null, buttonPressedArrowColor, null )
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public int getArrowWidth() {
|
||||||
|
return isMacStyle() ? 7 : super.getArrowWidth();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public float getArrowThickness() {
|
||||||
|
return isMacStyle() ? 1.5f : super.getArrowThickness();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public float getYOffset() {
|
||||||
|
return isMacStyle() ? 0 : super.getYOffset();
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean isRoundBorderAutoXOffset() {
|
||||||
|
return isMacStyle() ? false : super.isRoundBorderAutoXOffset();
|
||||||
|
}
|
||||||
|
};
|
||||||
button.setName( name );
|
button.setName( name );
|
||||||
button.setYOffset( (direction == SwingConstants.NORTH) ? 1.25f : -1.25f );
|
button.setYOffset( (direction == SwingConstants.NORTH) ? 1.25f : -1.25f );
|
||||||
if( direction == SwingConstants.NORTH )
|
if( direction == SwingConstants.NORTH )
|
||||||
@@ -374,10 +392,13 @@ public class FlatSpinnerUI
|
|||||||
int width = c.getWidth();
|
int width = c.getWidth();
|
||||||
int height = c.getHeight();
|
int height = c.getHeight();
|
||||||
boolean enabled = spinner.isEnabled();
|
boolean enabled = spinner.isEnabled();
|
||||||
|
boolean ltr = spinner.getComponentOrientation().isLeftToRight();
|
||||||
|
boolean isMacStyle = isMacStyle();
|
||||||
|
int macStyleButtonsWidth = isMacStyle ? getMacStyleButtonsWidth() : 0;
|
||||||
|
|
||||||
// paint background
|
// paint background
|
||||||
g2.setColor( getBackground( enabled ) );
|
g2.setColor( getBackground( enabled ) );
|
||||||
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
FlatUIUtils.paintComponentBackground( g2, ltr ? 0 : macStyleButtonsWidth, 0, width - macStyleButtonsWidth, height, focusWidth, arc );
|
||||||
|
|
||||||
// paint button background and separator
|
// paint button background and separator
|
||||||
boolean paintButton = !"none".equals( buttonStyle );
|
boolean paintButton = !"none".equals( buttonStyle );
|
||||||
@@ -386,27 +407,49 @@ public class FlatSpinnerUI
|
|||||||
Component button = (handler.nextButton != null) ? handler.nextButton : handler.previousButton;
|
Component button = (handler.nextButton != null) ? handler.nextButton : handler.previousButton;
|
||||||
int arrowX = button.getX();
|
int arrowX = button.getX();
|
||||||
int arrowWidth = button.getWidth();
|
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;
|
Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor;
|
||||||
if( separatorColor != null && buttonSeparatorWidth > 0 ) {
|
|
||||||
g2.setColor( separatorColor );
|
if( isMacStyle ) {
|
||||||
|
Insets insets = spinner.getInsets();
|
||||||
|
int lineWidth = Math.round( FlatUIUtils.getBorderLineWidth( spinner ) );
|
||||||
|
int bx = arrowX;
|
||||||
|
int by = insets.top - lineWidth;
|
||||||
|
int bw = arrowWidth;
|
||||||
|
int bh = height - insets.top - insets.bottom + (lineWidth * 2);
|
||||||
float lw = scale( buttonSeparatorWidth );
|
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, scale( 12 ),
|
||||||
|
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( ltr )
|
||||||
|
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 = ltr ? arrowX : arrowX + arrowWidth - lw;
|
||||||
|
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - 1 - (focusWidth * 2) ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,6 +458,19 @@ public class FlatSpinnerUI
|
|||||||
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isMacStyle() {
|
||||||
|
return "mac".equals( buttonStyle );
|
||||||
|
}
|
||||||
|
|
||||||
|
int getMacStyleButtonsWidth() {
|
||||||
|
return (handler.nextButton != null || handler.previousButton != null)
|
||||||
|
? scale( MAC_STEPPER_GAP ) + scale( MAC_STEPPER_WIDTH )
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final int MAC_STEPPER_WIDTH = 15;
|
||||||
|
private static final int MAC_STEPPER_GAP = 3;
|
||||||
|
|
||||||
//---- class Handler ------------------------------------------------------
|
//---- class Handler ------------------------------------------------------
|
||||||
|
|
||||||
private class Handler
|
private class Handler
|
||||||
@@ -471,6 +527,7 @@ public class FlatSpinnerUI
|
|||||||
Insets insets = parent.getInsets();
|
Insets insets = parent.getInsets();
|
||||||
Rectangle r = FlatUIUtils.subtractInsets( new Rectangle( size ), insets );
|
Rectangle r = FlatUIUtils.subtractInsets( new Rectangle( size ), insets );
|
||||||
|
|
||||||
|
// editor gets all space if there are no buttons
|
||||||
if( nextButton == null && previousButton == null ) {
|
if( nextButton == null && previousButton == null ) {
|
||||||
if( editor != null )
|
if( editor != null )
|
||||||
editor.setBounds( r );
|
editor.setBounds( r );
|
||||||
@@ -483,22 +540,39 @@ public class FlatSpinnerUI
|
|||||||
// limit buttons width to height of a raw spinner (without insets)
|
// limit buttons width to height of a raw spinner (without insets)
|
||||||
FontMetrics fm = spinner.getFontMetrics( spinner.getFont() );
|
FontMetrics fm = spinner.getFontMetrics( spinner.getFont() );
|
||||||
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
||||||
|
int minButtonWidth = (maxButtonWidth * 3) / 4;
|
||||||
|
|
||||||
// make button area square (if spinner has preferred height)
|
// make button area square (except if width is limited)
|
||||||
int buttonsWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
|
boolean isMacStyle = isMacStyle();
|
||||||
|
int buttonsGap = isMacStyle ? scale( MAC_STEPPER_GAP ) : 0;
|
||||||
|
int prefButtonWidth = isMacStyle ? scale( MAC_STEPPER_WIDTH ) : buttonsRect.height;
|
||||||
|
int buttonsWidth = Math.min( Math.max( prefButtonWidth, minButtonWidth ), maxButtonWidth );
|
||||||
|
|
||||||
|
// update editor and buttons bounds
|
||||||
buttonsRect.width = buttonsWidth;
|
buttonsRect.width = buttonsWidth;
|
||||||
|
editorRect.width -= buttonsWidth + buttonsGap;
|
||||||
|
boolean ltr = parent.getComponentOrientation().isLeftToRight();
|
||||||
|
if( ltr )
|
||||||
|
buttonsRect.x += editorRect.width + buttonsGap;
|
||||||
|
else
|
||||||
|
editorRect.x += buttonsWidth + buttonsGap;
|
||||||
|
|
||||||
if( parent.getComponentOrientation().isLeftToRight() ) {
|
// in mac button style increase buttons height and move to the right
|
||||||
editorRect.width -= buttonsWidth;
|
// for exact alignment with border
|
||||||
buttonsRect.x += editorRect.width;
|
if( isMacStyle ) {
|
||||||
} else {
|
int lineWidth = Math.round( FlatUIUtils.getBorderLineWidth( spinner ) );
|
||||||
editorRect.x += buttonsWidth;
|
if( lineWidth > 0 ) {
|
||||||
editorRect.width -= buttonsWidth;
|
buttonsRect.x += ltr ? lineWidth : -lineWidth;
|
||||||
|
buttonsRect.y -= lineWidth;
|
||||||
|
buttonsRect.height += lineWidth * 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set editor bounds
|
||||||
if( editor != null )
|
if( editor != null )
|
||||||
editor.setBounds( editorRect );
|
editor.setBounds( editorRect );
|
||||||
|
|
||||||
|
// set buttons bounds
|
||||||
int nextHeight = (buttonsRect.height / 2) + (buttonsRect.height % 2); // round up
|
int nextHeight = (buttonsRect.height / 2) + (buttonsRect.height % 2); // round up
|
||||||
if( nextButton != null )
|
if( nextButton != null )
|
||||||
nextButton.setBounds( buttonsRect.x, buttonsRect.y, buttonsRect.width, nextHeight );
|
nextButton.setBounds( buttonsRect.x, buttonsRect.y, buttonsRect.width, nextHeight );
|
||||||
|
|||||||
@@ -2589,7 +2589,7 @@ public class FlatTabbedPaneUI
|
|||||||
public void mousePressed( MouseEvent e ) {
|
public void mousePressed( MouseEvent e ) {
|
||||||
updateRollover( e );
|
updateRollover( e );
|
||||||
|
|
||||||
if( !isPressedTabClose() )
|
if( !isPressedTabClose() && SwingUtilities.isLeftMouseButton( e ) )
|
||||||
mouseDelegate.mousePressed( e );
|
mouseDelegate.mousePressed( e );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2644,7 +2644,7 @@ public class FlatTabbedPaneUI
|
|||||||
|
|
||||||
// check whether mouse hit tab close area
|
// check whether mouse hit tab close area
|
||||||
boolean hitClose = isTabClosable( tabIndex ) && getTabCloseHitArea( tabIndex ).contains( x, y );
|
boolean hitClose = isTabClosable( tabIndex ) && getTabCloseHitArea( tabIndex ).contains( x, y );
|
||||||
if( e.getID() == MouseEvent.MOUSE_PRESSED )
|
if( e.getID() == MouseEvent.MOUSE_PRESSED && SwingUtilities.isLeftMouseButton( e ) )
|
||||||
pressedTabIndex = hitClose ? tabIndex : -1;
|
pressedTabIndex = hitClose ? tabIndex : -1;
|
||||||
setRolloverTabClose( hitClose );
|
setRolloverTabClose( hitClose );
|
||||||
setPressedTabClose( hitClose && tabIndex == pressedTabIndex );
|
setPressedTabClose( hitClose && tabIndex == pressedTabIndex );
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
public class FlatTitlePane
|
public class FlatTitlePane
|
||||||
extends JComponent
|
extends JComponent
|
||||||
{
|
{
|
||||||
|
private static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles";
|
||||||
|
|
||||||
/** @since 2.5 */ protected final Font titleFont = UIManager.getFont( "TitlePane.font" );
|
/** @since 2.5 */ protected final Font titleFont = UIManager.getFont( "TitlePane.font" );
|
||||||
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" );
|
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" );
|
||||||
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
|
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
|
||||||
@@ -354,15 +356,12 @@ public class FlatTitlePane
|
|||||||
if( window == null || rootPane.getWindowDecorationStyle() != JRootPane.FRAME )
|
if( window == null || rootPane.getWindowDecorationStyle() != JRootPane.FRAME )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
updateVisibility();
|
||||||
|
|
||||||
if( window instanceof Frame ) {
|
if( window instanceof Frame ) {
|
||||||
Frame frame = (Frame) window;
|
Frame frame = (Frame) window;
|
||||||
boolean resizable = frame.isResizable();
|
|
||||||
boolean maximized = ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0);
|
boolean maximized = ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0);
|
||||||
|
|
||||||
iconifyButton.setVisible( true );
|
|
||||||
maximizeButton.setVisible( resizable && !maximized );
|
|
||||||
restoreButton.setVisible( resizable && maximized );
|
|
||||||
|
|
||||||
if( maximized &&
|
if( maximized &&
|
||||||
!(SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window )) &&
|
!(SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window )) &&
|
||||||
rootPane.getClientProperty( "_flatlaf.maximizedBoundsUpToDate" ) == null )
|
rootPane.getClientProperty( "_flatlaf.maximizedBoundsUpToDate" ) == null )
|
||||||
@@ -383,14 +382,27 @@ public class FlatTitlePane
|
|||||||
frame.setExtendedState( oldExtendedState );
|
frame.setExtendedState( oldExtendedState );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3 */
|
||||||
|
protected void updateVisibility() {
|
||||||
|
titleLabel.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_TITLE, true ) );
|
||||||
|
closeButton.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_CLOSE, true ) );
|
||||||
|
|
||||||
|
if( window instanceof Frame ) {
|
||||||
|
Frame frame = (Frame) window;
|
||||||
|
boolean maximizable = frame.isResizable() && clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_MAXIMIZE, true );
|
||||||
|
boolean maximized = ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0);
|
||||||
|
|
||||||
|
iconifyButton.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICONIFFY, true ) );
|
||||||
|
maximizeButton.setVisible( maximizable && !maximized );
|
||||||
|
restoreButton.setVisible( maximizable && maximized );
|
||||||
} else {
|
} else {
|
||||||
// hide buttons because they are only supported in frames
|
// hide buttons because they are only supported in frames
|
||||||
iconifyButton.setVisible( false );
|
iconifyButton.setVisible( false );
|
||||||
maximizeButton.setVisible( false );
|
maximizeButton.setVisible( false );
|
||||||
restoreButton.setVisible( false );
|
restoreButton.setVisible( false );
|
||||||
|
|
||||||
revalidate();
|
|
||||||
repaint();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,11 +578,13 @@ public class FlatTitlePane
|
|||||||
doLayout();
|
doLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*debug
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g ) {
|
public void paint( Graphics g ) {
|
||||||
super.paint( g );
|
super.paint( g );
|
||||||
|
|
||||||
|
if( !UIManager.getBoolean( KEY_DEBUG_SHOW_RECTANGLES ) )
|
||||||
|
return;
|
||||||
|
|
||||||
if( debugTitleBarHeight > 0 ) {
|
if( debugTitleBarHeight > 0 ) {
|
||||||
g.setColor( Color.green );
|
g.setColor( Color.green );
|
||||||
g.drawLine( 0, debugTitleBarHeight, getWidth(), debugTitleBarHeight );
|
g.drawLine( 0, debugTitleBarHeight, getWidth(), debugTitleBarHeight );
|
||||||
@@ -594,7 +608,6 @@ public class FlatTitlePane
|
|||||||
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
|
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
|
||||||
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
|
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
|
||||||
}
|
}
|
||||||
debug*/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent( Graphics g ) {
|
protected void paintComponent( Graphics g ) {
|
||||||
@@ -923,15 +936,14 @@ debug*/
|
|||||||
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight,
|
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight,
|
||||||
hitTestSpots, appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
|
hitTestSpots, appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
|
||||||
|
|
||||||
/*debug
|
|
||||||
debugTitleBarHeight = titleBarHeight;
|
debugTitleBarHeight = titleBarHeight;
|
||||||
debugHitTestSpots = hitTestSpots;
|
debugHitTestSpots = hitTestSpots;
|
||||||
debugAppIconBounds = appIconBounds;
|
debugAppIconBounds = appIconBounds;
|
||||||
debugMinimizeButtonBounds = minimizeButtonBounds;
|
debugMinimizeButtonBounds = minimizeButtonBounds;
|
||||||
debugMaximizeButtonBounds = maximizeButtonBounds;
|
debugMaximizeButtonBounds = maximizeButtonBounds;
|
||||||
debugCloseButtonBounds = closeButtonBounds;
|
debugCloseButtonBounds = closeButtonBounds;
|
||||||
repaint();
|
if( UIManager.getBoolean( KEY_DEBUG_SHOW_RECTANGLES ) )
|
||||||
debug*/
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Rectangle boundsInWindow( JComponent c ) {
|
private Rectangle boundsInWindow( JComponent c ) {
|
||||||
@@ -950,14 +962,12 @@ debug*/
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*debug
|
|
||||||
private int debugTitleBarHeight;
|
private int debugTitleBarHeight;
|
||||||
private List<Rectangle> debugHitTestSpots;
|
private List<Rectangle> debugHitTestSpots;
|
||||||
private Rectangle debugAppIconBounds;
|
private Rectangle debugAppIconBounds;
|
||||||
private Rectangle debugMinimizeButtonBounds;
|
private Rectangle debugMinimizeButtonBounds;
|
||||||
private Rectangle debugMaximizeButtonBounds;
|
private Rectangle debugMaximizeButtonBounds;
|
||||||
private Rectangle debugCloseButtonBounds;
|
private Rectangle debugCloseButtonBounds;
|
||||||
debug*/
|
|
||||||
|
|
||||||
//---- class FlatTitlePaneBorder ------------------------------------------
|
//---- class FlatTitlePaneBorder ------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -20,15 +20,24 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.FocusTraversalPolicy;
|
import java.awt.FocusTraversalPolicy;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.ContainerEvent;
|
import java.awt.event.ContainerEvent;
|
||||||
import java.awt.event.ContainerListener;
|
import java.awt.event.ContainerListener;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
|
import javax.swing.ButtonGroup;
|
||||||
|
import javax.swing.ButtonModel;
|
||||||
|
import javax.swing.DefaultButtonModel;
|
||||||
import javax.swing.InputMap;
|
import javax.swing.InputMap;
|
||||||
import javax.swing.JComboBox;
|
import javax.swing.JComboBox;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JToolBar;
|
||||||
import javax.swing.LayoutFocusTraversalPolicy;
|
import javax.swing.LayoutFocusTraversalPolicy;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
@@ -37,6 +46,7 @@ import javax.swing.plaf.basic.BasicToolBarUI;
|
|||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar}.
|
||||||
@@ -58,6 +68,8 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
* @uiDefault ToolBar.focusableButtons boolean
|
* @uiDefault ToolBar.focusableButtons boolean
|
||||||
* @uiDefault ToolBar.arrowKeysOnlyNavigation boolean
|
* @uiDefault ToolBar.arrowKeysOnlyNavigation boolean
|
||||||
* @uiDefault ToolBar.floatable boolean
|
* @uiDefault ToolBar.floatable boolean
|
||||||
|
* @uiDefault ToolBar.hoverButtonGroupArc int
|
||||||
|
* @uiDefault ToolBar.hoverButtonGroupBackground Color
|
||||||
*
|
*
|
||||||
* <!-- FlatToolBarBorder -->
|
* <!-- FlatToolBarBorder -->
|
||||||
*
|
*
|
||||||
@@ -72,6 +84,8 @@ public class FlatToolBarUI
|
|||||||
{
|
{
|
||||||
/** @since 1.4 */ @Styleable protected boolean focusableButtons;
|
/** @since 1.4 */ @Styleable protected boolean focusableButtons;
|
||||||
/** @since 2 */ @Styleable protected boolean arrowKeysOnlyNavigation;
|
/** @since 2 */ @Styleable protected boolean arrowKeysOnlyNavigation;
|
||||||
|
/** @since 3 */ @Styleable protected int hoverButtonGroupArc;
|
||||||
|
/** @since 3 */ @Styleable protected Color hoverButtonGroupBackground;
|
||||||
|
|
||||||
// for FlatToolBarBorder
|
// for FlatToolBarBorder
|
||||||
@Styleable protected Insets borderMargins;
|
@Styleable protected Insets borderMargins;
|
||||||
@@ -119,6 +133,8 @@ public class FlatToolBarUI
|
|||||||
|
|
||||||
focusableButtons = UIManager.getBoolean( "ToolBar.focusableButtons" );
|
focusableButtons = UIManager.getBoolean( "ToolBar.focusableButtons" );
|
||||||
arrowKeysOnlyNavigation = UIManager.getBoolean( "ToolBar.arrowKeysOnlyNavigation" );
|
arrowKeysOnlyNavigation = UIManager.getBoolean( "ToolBar.arrowKeysOnlyNavigation" );
|
||||||
|
hoverButtonGroupArc = UIManager.getInt( "ToolBar.hoverButtonGroupArc" );
|
||||||
|
hoverButtonGroupBackground = UIManager.getColor( "ToolBar.hoverButtonGroupBackground" );
|
||||||
|
|
||||||
// floatable
|
// floatable
|
||||||
if( !UIManager.getBoolean( "ToolBar.floatable" ) ) {
|
if( !UIManager.getBoolean( "ToolBar.floatable" ) ) {
|
||||||
@@ -132,6 +148,8 @@ public class FlatToolBarUI
|
|||||||
protected void uninstallDefaults() {
|
protected void uninstallDefaults() {
|
||||||
super.uninstallDefaults();
|
super.uninstallDefaults();
|
||||||
|
|
||||||
|
hoverButtonGroupBackground = null;
|
||||||
|
|
||||||
if( oldFloatable != null ) {
|
if( oldFloatable != null ) {
|
||||||
toolBar.setFloatable( oldFloatable );
|
toolBar.setFloatable( oldFloatable );
|
||||||
oldFloatable = null;
|
oldFloatable = null;
|
||||||
@@ -329,6 +347,99 @@ public class FlatToolBarUI
|
|||||||
super.setOrientation( orientation );
|
super.setOrientation( orientation );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
super.paint( g, c );
|
||||||
|
|
||||||
|
paintButtonGroup( g );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@since 3 */
|
||||||
|
protected void paintButtonGroup( Graphics g ) {
|
||||||
|
if( hoverButtonGroupBackground == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// find hovered button that is part of a button group
|
||||||
|
ButtonGroup group = null;
|
||||||
|
for( Component b : toolBar.getComponents() ) {
|
||||||
|
if( b instanceof AbstractButton && ((AbstractButton)b).getModel().isRollover() ) {
|
||||||
|
group = getButtonGroup( (AbstractButton) b );
|
||||||
|
if( group != null )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( group == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// get bounds of buttons in group
|
||||||
|
ArrayList<Rectangle> rects = new ArrayList<>();
|
||||||
|
Enumeration<AbstractButton> e = group.getElements();
|
||||||
|
while( e.hasMoreElements() ) {
|
||||||
|
AbstractButton gb = e.nextElement();
|
||||||
|
if( gb.getParent() == toolBar )
|
||||||
|
rects.add( gb.getBounds() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort button bounds
|
||||||
|
boolean horizontal = (toolBar.getOrientation() == JToolBar.HORIZONTAL);
|
||||||
|
rects.sort( (r1, r2) -> horizontal ? r1.x - r2.x : r1.y - r2.y );
|
||||||
|
|
||||||
|
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||||
|
g.setColor( FlatUIUtils.deriveColor( hoverButtonGroupBackground, toolBar.getBackground() ) );
|
||||||
|
|
||||||
|
// paint button group hover background
|
||||||
|
int maxSepWidth = UIScale.scale( 10 );
|
||||||
|
Rectangle gr = null;
|
||||||
|
for( Rectangle r : rects ) {
|
||||||
|
if( gr == null ) {
|
||||||
|
// first button
|
||||||
|
gr = r;
|
||||||
|
} else if( horizontal ? (gr.x + gr.width + maxSepWidth >= r.x) : (gr.y + gr.height + maxSepWidth >= r.y) ) {
|
||||||
|
// button joins previous button
|
||||||
|
gr = gr.union( r );
|
||||||
|
} else {
|
||||||
|
// paint group
|
||||||
|
FlatUIUtils.paintComponentBackground( (Graphics2D) g, gr.x, gr.y, gr.width, gr.height, 0, UIScale.scale( hoverButtonGroupArc ) );
|
||||||
|
gr = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( gr != null )
|
||||||
|
FlatUIUtils.paintComponentBackground( (Graphics2D) g, gr.x, gr.y, gr.width, gr.height, 0, UIScale.scale( hoverButtonGroupArc ) );
|
||||||
|
|
||||||
|
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**@since 3 */
|
||||||
|
protected void repaintButtonGroup( AbstractButton b ) {
|
||||||
|
if( hoverButtonGroupBackground == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ButtonGroup group = getButtonGroup( b );
|
||||||
|
if( group == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// compute union bounds of all buttons in group (including separators)
|
||||||
|
Rectangle gr = null;
|
||||||
|
Enumeration<AbstractButton> e = group.getElements();
|
||||||
|
while( e.hasMoreElements() ) {
|
||||||
|
AbstractButton gb = e.nextElement();
|
||||||
|
Container parent = gb.getParent();
|
||||||
|
if( parent == toolBar )
|
||||||
|
gr = (gr != null) ? gr.union( gb.getBounds() ) : gb.getBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
// repaint button group
|
||||||
|
if( gr != null )
|
||||||
|
toolBar.repaint( gr );
|
||||||
|
}
|
||||||
|
|
||||||
|
private ButtonGroup getButtonGroup( AbstractButton b ) {
|
||||||
|
ButtonModel model = b.getModel();
|
||||||
|
return (model instanceof DefaultButtonModel)
|
||||||
|
? ((DefaultButtonModel)model).getGroup()
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatToolBarFocusTraversalPolicy ------------------------------
|
//---- class FlatToolBarFocusTraversalPolicy ------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,15 +17,19 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.CellRendererPane;
|
import javax.swing.CellRendererPane;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
@@ -36,6 +40,7 @@ import javax.swing.LookAndFeel;
|
|||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.JTree.DropLocation;
|
import javax.swing.JTree.DropLocation;
|
||||||
|
import javax.swing.event.TreeSelectionListener;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicTreeUI;
|
import javax.swing.plaf.basic.BasicTreeUI;
|
||||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||||
@@ -96,8 +101,11 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault Tree.selectionForeground Color
|
* @uiDefault Tree.selectionForeground Color
|
||||||
* @uiDefault Tree.selectionInactiveBackground Color
|
* @uiDefault Tree.selectionInactiveBackground Color
|
||||||
* @uiDefault Tree.selectionInactiveForeground Color
|
* @uiDefault Tree.selectionInactiveForeground Color
|
||||||
|
* @uiDefault Tree.selectionInsets Insets
|
||||||
|
* @uiDefault Tree.selectionArc int
|
||||||
* @uiDefault Tree.wideSelection boolean
|
* @uiDefault Tree.wideSelection boolean
|
||||||
* @uiDefault Tree.showCellFocusIndicator boolean
|
* @uiDefault Tree.showCellFocusIndicator boolean
|
||||||
|
* @uiDefault Tree.showDefaultIcons boolean
|
||||||
*
|
*
|
||||||
* <!-- FlatTreeExpandedIcon -->
|
* <!-- FlatTreeExpandedIcon -->
|
||||||
*
|
*
|
||||||
@@ -132,8 +140,11 @@ public class FlatTreeUI
|
|||||||
@Styleable protected Color selectionInactiveBackground;
|
@Styleable protected Color selectionInactiveBackground;
|
||||||
@Styleable protected Color selectionInactiveForeground;
|
@Styleable protected Color selectionInactiveForeground;
|
||||||
@Styleable protected Color selectionBorderColor;
|
@Styleable protected Color selectionBorderColor;
|
||||||
|
/** @since 3 */ @Styleable protected Insets selectionInsets;
|
||||||
|
/** @since 3 */ @Styleable protected int selectionArc;
|
||||||
@Styleable protected boolean wideSelection;
|
@Styleable protected boolean wideSelection;
|
||||||
@Styleable protected boolean showCellFocusIndicator;
|
@Styleable protected boolean showCellFocusIndicator;
|
||||||
|
/** @since 3 */ protected boolean showDefaultIcons;
|
||||||
|
|
||||||
// for icons
|
// for icons
|
||||||
// (needs to be public because icon classes are in another package)
|
// (needs to be public because icon classes are in another package)
|
||||||
@@ -147,6 +158,7 @@ public class FlatTreeUI
|
|||||||
// only used via styling (not in UI defaults, but has likewise client properties)
|
// only used via styling (not in UI defaults, but has likewise client properties)
|
||||||
/** @since 2 */ @Styleable protected boolean paintSelection = true;
|
/** @since 2 */ @Styleable protected boolean paintSelection = true;
|
||||||
|
|
||||||
|
private boolean paintLines;
|
||||||
private Color defaultCellNonSelectionBackground;
|
private Color defaultCellNonSelectionBackground;
|
||||||
private Color defaultSelectionBackground;
|
private Color defaultSelectionBackground;
|
||||||
private Color defaultSelectionForeground;
|
private Color defaultSelectionForeground;
|
||||||
@@ -175,9 +187,13 @@ public class FlatTreeUI
|
|||||||
selectionInactiveBackground = UIManager.getColor( "Tree.selectionInactiveBackground" );
|
selectionInactiveBackground = UIManager.getColor( "Tree.selectionInactiveBackground" );
|
||||||
selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" );
|
selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" );
|
||||||
selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" );
|
selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" );
|
||||||
|
selectionInsets = UIManager.getInsets( "Tree.selectionInsets" );
|
||||||
|
selectionArc = UIManager.getInt( "Tree.selectionArc" );
|
||||||
wideSelection = UIManager.getBoolean( "Tree.wideSelection" );
|
wideSelection = UIManager.getBoolean( "Tree.wideSelection" );
|
||||||
showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" );
|
showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" );
|
||||||
|
showDefaultIcons = UIManager.getBoolean( "Tree.showDefaultIcons" );
|
||||||
|
|
||||||
|
paintLines = UIManager.getBoolean( "Tree.paintLines" );
|
||||||
defaultCellNonSelectionBackground = UIManager.getColor( "Tree.textBackground" );
|
defaultCellNonSelectionBackground = UIManager.getColor( "Tree.textBackground" );
|
||||||
defaultSelectionBackground = selectionBackground;
|
defaultSelectionBackground = selectionBackground;
|
||||||
defaultSelectionForeground = selectionForeground;
|
defaultSelectionForeground = selectionForeground;
|
||||||
@@ -210,6 +226,19 @@ public class FlatTreeUI
|
|||||||
oldStyleValues = null;
|
oldStyleValues = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void updateRenderer() {
|
||||||
|
super.updateRenderer();
|
||||||
|
|
||||||
|
// remove default leaf/closed/opened icons
|
||||||
|
if( !showDefaultIcons && currentCellRenderer instanceof DefaultTreeCellRenderer ) {
|
||||||
|
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) currentCellRenderer;
|
||||||
|
renderer.setLeafIcon( null );
|
||||||
|
renderer.setClosedIcon( null );
|
||||||
|
renderer.setOpenIcon( null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MouseListener createMouseListener() {
|
protected MouseListener createMouseListener() {
|
||||||
return new BasicTreeUI.MouseHandler() {
|
return new BasicTreeUI.MouseHandler() {
|
||||||
@@ -295,6 +324,34 @@ public class FlatTreeUI
|
|||||||
tree.repaint( 0, r.y, tree.getWidth(), r.height );
|
tree.repaint( 0, r.y, tree.getWidth(), r.height );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TreeSelectionListener createTreeSelectionListener() {
|
||||||
|
TreeSelectionListener superListener = super.createTreeSelectionListener();
|
||||||
|
return e -> {
|
||||||
|
superListener.valueChanged( e );
|
||||||
|
|
||||||
|
// for united rounded selection, repaint parts of the rows that adjoin to the changed rows
|
||||||
|
TreePath[] changedPaths;
|
||||||
|
if( useUnitedRoundedSelection() &&
|
||||||
|
tree.getSelectionCount() > 1 &&
|
||||||
|
(changedPaths = e.getPaths()) != null )
|
||||||
|
{
|
||||||
|
if( changedPaths.length > 4 ) {
|
||||||
|
// same is done in BasicTreeUI.Handler.valueChanged()
|
||||||
|
tree.repaint();
|
||||||
|
} else {
|
||||||
|
int arc = (int) Math.ceil( UIScale.scale( selectionArc / 2f ) );
|
||||||
|
|
||||||
|
for( TreePath path : changedPaths ) {
|
||||||
|
Rectangle r = getPathBounds( tree, path );
|
||||||
|
if( r != null )
|
||||||
|
tree.repaint( r.x, r.y - arc, r.width, r.height + (arc * 2) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Rectangle getPathBounds( JTree tree, TreePath path ) {
|
public Rectangle getPathBounds( JTree tree, TreePath path ) {
|
||||||
Rectangle bounds = super.getPathBounds( tree, path );
|
Rectangle bounds = super.getPathBounds( tree, path );
|
||||||
@@ -346,8 +403,127 @@ public class FlatTreeUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
if( treeState == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// use clip bounds to limit painting to needed rows
|
||||||
|
Rectangle clipBounds = g.getClipBounds();
|
||||||
|
TreePath firstPath = getClosestPathForLocation( tree, 0, clipBounds.y );
|
||||||
|
Enumeration<TreePath> visiblePaths = treeState.getVisiblePathsFrom( firstPath );
|
||||||
|
|
||||||
|
if( visiblePaths != null ) {
|
||||||
|
Insets insets = tree.getInsets();
|
||||||
|
|
||||||
|
HashSet<TreePath> verticalLinePaths = paintLines ? new HashSet<>() : null;
|
||||||
|
ArrayList<Runnable> paintLinesLater = paintLines ? new ArrayList<>() : null;
|
||||||
|
ArrayList<Runnable> paintExpandControlsLater = paintLines ? new ArrayList<>() : null;
|
||||||
|
|
||||||
|
// add parents for later painting of vertical lines
|
||||||
|
if( paintLines ) {
|
||||||
|
for( TreePath path = firstPath.getParentPath(); path != null; path = path.getParentPath() )
|
||||||
|
verticalLinePaths.add( path );
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle boundsBuffer = new Rectangle();
|
||||||
|
boolean rootVisible = isRootVisible();
|
||||||
|
int row = treeState.getRowForPath( firstPath );
|
||||||
|
boolean leftToRight = tree.getComponentOrientation().isLeftToRight();
|
||||||
|
int treeWidth = tree.getWidth();
|
||||||
|
|
||||||
|
// iterate over visible rows and paint rows, expand control and lines
|
||||||
|
while( visiblePaths.hasMoreElements() ) {
|
||||||
|
TreePath path = visiblePaths.nextElement();
|
||||||
|
if( path == null )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// compute path bounds
|
||||||
|
Rectangle bounds = treeState.getBounds( path, boundsBuffer );
|
||||||
|
if( bounds == null )
|
||||||
|
break;
|
||||||
|
|
||||||
|
// add tree insets to path bounds
|
||||||
|
if( leftToRight )
|
||||||
|
bounds.x += insets.left;
|
||||||
|
else
|
||||||
|
bounds.x = treeWidth - insets.right - (bounds.x + bounds.width);
|
||||||
|
bounds.y += insets.top;
|
||||||
|
|
||||||
|
boolean isLeaf = treeModel.isLeaf( path.getLastPathComponent() );
|
||||||
|
boolean isExpanded = isLeaf ? false : treeState.getExpandedState( path );
|
||||||
|
boolean hasBeenExpanded = isLeaf ? false : tree.hasBeenExpanded( path );
|
||||||
|
|
||||||
|
// paint row (including selection)
|
||||||
|
paintRow( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
|
||||||
|
|
||||||
|
// collect lines for later painting
|
||||||
|
if( paintLines ) {
|
||||||
|
TreePath parentPath = path.getParentPath();
|
||||||
|
|
||||||
|
// add parent for later painting of vertical lines
|
||||||
|
if( parentPath != null )
|
||||||
|
verticalLinePaths.add( parentPath );
|
||||||
|
|
||||||
|
// paint horizontal line later (for using rendering hints)
|
||||||
|
if( parentPath != null || (rootVisible && row == 0) ) {
|
||||||
|
Rectangle bounds2 = new Rectangle( bounds );
|
||||||
|
int row2 = row;
|
||||||
|
paintLinesLater.add( () -> {
|
||||||
|
paintHorizontalPartOfLeg( g, clipBounds, insets, bounds2, path, row2, isExpanded, hasBeenExpanded, isLeaf );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint expand control
|
||||||
|
if( shouldPaintExpandControl( path, row, isExpanded, hasBeenExpanded, isLeaf ) ) {
|
||||||
|
if( paintLines ) {
|
||||||
|
// need to paint after painting lines
|
||||||
|
Rectangle bounds2 = new Rectangle( bounds );
|
||||||
|
int row2 = row;
|
||||||
|
paintExpandControlsLater.add( () -> {
|
||||||
|
paintExpandControl( g, clipBounds, insets, bounds2, path, row2, isExpanded, hasBeenExpanded, isLeaf );
|
||||||
|
} );
|
||||||
|
} else
|
||||||
|
paintExpandControl( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bounds.y + bounds.height >= clipBounds.y + clipBounds.height )
|
||||||
|
break;
|
||||||
|
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( paintLines ) {
|
||||||
|
// enable antialiasing for line painting
|
||||||
|
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||||
|
|
||||||
|
// paint horizontal lines
|
||||||
|
for( Runnable r : paintLinesLater )
|
||||||
|
r.run();
|
||||||
|
|
||||||
|
// paint vertical lines
|
||||||
|
g.setColor( Color.green );
|
||||||
|
for( TreePath path : verticalLinePaths )
|
||||||
|
paintVerticalPartOfLeg( g, clipBounds, insets, path );
|
||||||
|
|
||||||
|
// restore rendering hints
|
||||||
|
if( oldRenderingHints != null )
|
||||||
|
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||||
|
|
||||||
|
// paint expand controls
|
||||||
|
for( Runnable r : paintExpandControlsLater )
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paintDropLine( g );
|
||||||
|
|
||||||
|
rendererPane.removeAll();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as super.paintRow(), but supports wide selection and uses
|
* Similar to super.paintRow(), but supports wide selection and uses
|
||||||
* inactive selection background/foreground if tree is not focused.
|
* inactive selection background/foreground if tree is not focused.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -428,7 +604,7 @@ public class FlatTreeUI
|
|||||||
paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
|
paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
|
||||||
} else {
|
} else {
|
||||||
// non-wide selection
|
// non-wide selection
|
||||||
paintCellBackground( g, rendererComponent, bounds );
|
paintCellBackground( g, rendererComponent, bounds, row, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is actually not necessary because renderer should always set color
|
// this is actually not necessary because renderer should always set color
|
||||||
@@ -442,7 +618,7 @@ public class FlatTreeUI
|
|||||||
if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
|
if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
|
||||||
Color oldColor = g.getColor();
|
Color oldColor = g.getColor();
|
||||||
g.setColor( bg );
|
g.setColor( bg );
|
||||||
paintCellBackground( g, rendererComponent, bounds );
|
paintCellBackground( g, rendererComponent, bounds, row, false );
|
||||||
g.setColor( oldColor );
|
g.setColor( oldColor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,17 +673,23 @@ public class FlatTreeUI
|
|||||||
private void paintWideSelection( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds,
|
private void paintWideSelection( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds,
|
||||||
TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf )
|
TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf )
|
||||||
{
|
{
|
||||||
g.fillRect( 0, bounds.y, tree.getWidth(), bounds.height );
|
float arcTop, arcBottom;
|
||||||
|
arcTop = arcBottom = UIScale.scale( selectionArc / 2f );
|
||||||
|
|
||||||
// paint expand/collapse icon
|
if( useUnitedRoundedSelection() ) {
|
||||||
// (was already painted before, but painted over with wide selection)
|
if( row > 0 && tree.isRowSelected( row - 1 ) )
|
||||||
if( shouldPaintExpandControl( path, row, isExpanded, hasBeenExpanded, isLeaf ) ) {
|
arcTop = 0;
|
||||||
paintExpandControl( g, clipBounds, insets, bounds,
|
if( row < tree.getRowCount() - 1 && tree.isRowSelected( row + 1 ) )
|
||||||
path, row, isExpanded, hasBeenExpanded, isLeaf );
|
arcBottom = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FlatUIUtils.paintSelection( (Graphics2D) g, 0, bounds.y, tree.getWidth(), bounds.height,
|
||||||
|
UIScale.scale( selectionInsets ), arcTop, arcTop, arcBottom, arcBottom, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void paintCellBackground( Graphics g, Component rendererComponent, Rectangle bounds ) {
|
private void paintCellBackground( Graphics g, Component rendererComponent, Rectangle bounds,
|
||||||
|
int row, boolean paintSelection )
|
||||||
|
{
|
||||||
int xOffset = 0;
|
int xOffset = 0;
|
||||||
int imageOffset = 0;
|
int imageOffset = 0;
|
||||||
|
|
||||||
@@ -520,7 +702,42 @@ public class FlatTreeUI
|
|||||||
xOffset = label.getComponentOrientation().isLeftToRight() ? imageOffset : 0;
|
xOffset = label.getComponentOrientation().isLeftToRight() ? imageOffset : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
g.fillRect( bounds.x + xOffset, bounds.y, bounds.width - imageOffset, bounds.height );
|
if( paintSelection ) {
|
||||||
|
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
|
||||||
|
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
|
||||||
|
|
||||||
|
if( useUnitedRoundedSelection() ) {
|
||||||
|
if( row > 0 && tree.isRowSelected( row - 1 ) ) {
|
||||||
|
Rectangle r = getPathBounds( tree, tree.getPathForRow( row - 1 ) );
|
||||||
|
arcTopLeft = Math.min( arcTopLeft, r.x - bounds.x );
|
||||||
|
arcTopRight = Math.min( arcTopRight, (bounds.x + bounds.width) - (r.x + r.width) );
|
||||||
|
}
|
||||||
|
if( row < tree.getRowCount() - 1 && tree.isRowSelected( row + 1 ) ) {
|
||||||
|
Rectangle r = getPathBounds( tree, tree.getPathForRow( row + 1 ) );
|
||||||
|
arcBottomLeft = Math.min( arcBottomLeft, r.x - bounds.x );
|
||||||
|
arcBottomRight = Math.min( arcBottomRight, (bounds.x + bounds.width) - (r.x + r.width) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatUIUtils.paintSelection( (Graphics2D) g, bounds.x + xOffset, bounds.y, bounds.width - imageOffset, bounds.height,
|
||||||
|
UIScale.scale( selectionInsets ), arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight, 0 );
|
||||||
|
} else
|
||||||
|
g.fillRect( bounds.x + xOffset, bounds.y, bounds.width - imageOffset, bounds.height );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean useUnitedRoundedSelection() {
|
||||||
|
return selectionArc > 0 &&
|
||||||
|
(selectionInsets == null || (selectionInsets.top == 0 && selectionInsets.bottom == 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintVerticalLine( Graphics g, JComponent c, int x, int top, int bottom ) {
|
||||||
|
((Graphics2D)g).fill( new Rectangle2D.Float( x, top, UIScale.scale( 1f ), bottom - top ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintHorizontalLine( Graphics g, JComponent c, int y, int left, int right ) {
|
||||||
|
((Graphics2D)g).fill( new Rectangle2D.Float( left, y, right - left, UIScale.scale( 1f ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import java.awt.event.FocusEvent;
|
|||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
import java.awt.geom.Ellipse2D;
|
import java.awt.geom.Ellipse2D;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
|
import java.awt.geom.Point2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.awt.geom.RoundRectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
@@ -76,8 +77,6 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*/
|
*/
|
||||||
public class FlatUIUtils
|
public class FlatUIUtils
|
||||||
{
|
{
|
||||||
public static final boolean MAC_USE_QUARTZ = Boolean.getBoolean( "apple.awt.graphics.UseQuartz" );
|
|
||||||
|
|
||||||
private static boolean useSharedUIs = true;
|
private static boolean useSharedUIs = true;
|
||||||
private static final WeakHashMap<LookAndFeel, IdentityHashMap<Object, ComponentUI>> sharedUIinstances = new WeakHashMap<>();
|
private static final WeakHashMap<LookAndFeel, IdentityHashMap<Object, ComponentUI>> sharedUIinstances = new WeakHashMap<>();
|
||||||
|
|
||||||
@@ -210,6 +209,9 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isCellEditor( Component c ) {
|
public static boolean isCellEditor( Component c ) {
|
||||||
|
if( c == null )
|
||||||
|
return false;
|
||||||
|
|
||||||
// check whether used in cell editor (check 3 levels up)
|
// check whether used in cell editor (check 3 levels up)
|
||||||
Component c2 = c;
|
Component c2 = c;
|
||||||
for( int i = 0; i <= 2 && c2 != null; i++ ) {
|
for( int i = 0; i <= 2 && c2 != null; i++ ) {
|
||||||
@@ -386,8 +388,7 @@ public class FlatUIUtils
|
|||||||
};
|
};
|
||||||
|
|
||||||
g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
|
g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
|
||||||
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL,
|
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE );
|
||||||
MAC_USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE );
|
|
||||||
|
|
||||||
return oldRenderingHints;
|
return oldRenderingHints;
|
||||||
}
|
}
|
||||||
@@ -440,9 +441,9 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills the background of a component with a round rectangle.
|
* Fills the background of a component with a rounded rectangle.
|
||||||
* <p>
|
* <p>
|
||||||
* The bounds of the painted round rectangle are
|
* The bounds of the painted rounded rectangle are
|
||||||
* {@code x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)}.
|
* {@code x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)}.
|
||||||
* The given arc diameter refers to the painted rectangle (and not to {@code x,y,width,height}).
|
* The given arc diameter refers to the painted rectangle (and not to {@code x,y,width,height}).
|
||||||
*
|
*
|
||||||
@@ -473,7 +474,7 @@ public class FlatUIUtils
|
|||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* <strong>Background</strong>:
|
* <strong>Background</strong>:
|
||||||
* The bounds of the filled round rectangle are
|
* The bounds of the filled rounded rectangle are
|
||||||
* {@code [x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)]}.
|
* {@code [x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)]}.
|
||||||
* The focus border and the border may paint over the background.
|
* The focus border and the border may paint over the background.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -671,6 +672,50 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paints a selection.
|
||||||
|
* <p>
|
||||||
|
* The bounds of the painted selection (rounded) rectangle are
|
||||||
|
* {@code x + insets.left, y + insets.top, width - insets.left - insets.right, height - insets.top - insets.bottom}.
|
||||||
|
* The given arc radius refers to the painted rectangle (and not to {@code x,y,width,height}).
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static void paintSelection( Graphics2D g, int x, int y, int width, int height, Insets insets,
|
||||||
|
float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight, int flags )
|
||||||
|
{
|
||||||
|
if( insets != null ) {
|
||||||
|
x += insets.left;
|
||||||
|
y += insets.top;
|
||||||
|
width -= insets.left + insets.right;
|
||||||
|
height -= insets.top + insets.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( arcTopLeft > 0 || arcTopRight > 0 || arcBottomLeft > 0 || arcBottomRight > 0 ) {
|
||||||
|
double systemScaleFactor = UIScale.getSystemScaleFactor( g );
|
||||||
|
if( systemScaleFactor != 1 && systemScaleFactor != 2 ) {
|
||||||
|
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
|
||||||
|
HiDPIUtils.paintAtScale1x( g, x, y, width, height,
|
||||||
|
(g2d, x2, y2, width2, height2, scaleFactor) -> {
|
||||||
|
paintRoundedSelectionImpl( g2d, x2, y2, width2, height2,
|
||||||
|
(float) (arcTopLeft * scaleFactor), (float) (arcTopRight * scaleFactor),
|
||||||
|
(float) (arcBottomLeft * scaleFactor), (float) (arcBottomRight * scaleFactor) );
|
||||||
|
} );
|
||||||
|
} else
|
||||||
|
paintRoundedSelectionImpl( g, x, y, width, height, arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight );
|
||||||
|
|
||||||
|
} else
|
||||||
|
g.fillRect( x, y, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void paintRoundedSelectionImpl( Graphics2D g, int x, int y, int width, int height,
|
||||||
|
float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight )
|
||||||
|
{
|
||||||
|
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||||
|
g.fill( FlatUIUtils.createRoundRectanglePath( x, y, width, height, arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight ) );
|
||||||
|
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||||
|
}
|
||||||
|
|
||||||
public static void paintGrip( Graphics g, int x, int y, int width, int height,
|
public static void paintGrip( Graphics g, int x, int y, int width, int height,
|
||||||
boolean horizontal, int dotCount, int dotSize, int gap, boolean centerPrecise )
|
boolean horizontal, int dotCount, int dotSize, int gap, boolean centerPrecise )
|
||||||
{
|
{
|
||||||
@@ -762,7 +807,7 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a not-filled rounded rectangle shape and allows specifying the line width and the radius or each corner.
|
* Creates a not-filled rounded rectangle shape and allows specifying the line width and the radius of each corner.
|
||||||
*/
|
*/
|
||||||
public static Path2D createRoundRectangle( float x, float y, float width, float height,
|
public static Path2D createRoundRectangle( float x, float y, float width, float height,
|
||||||
float lineWidth, float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight )
|
float lineWidth, float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight )
|
||||||
@@ -801,7 +846,7 @@ public class FlatUIUtils
|
|||||||
double ciBottomLeft = arcBottomLeft * ci;
|
double ciBottomLeft = arcBottomLeft * ci;
|
||||||
double ciBottomRight = arcBottomRight * ci;
|
double ciBottomRight = arcBottomRight * ci;
|
||||||
|
|
||||||
Path2D rect = new Path2D.Float();
|
Path2D rect = new Path2D.Float( Path2D.WIND_NON_ZERO, 16 );
|
||||||
rect.moveTo( x2 - arcTopRight, y );
|
rect.moveTo( x2 - arcTopRight, y );
|
||||||
rect.curveTo( x2 - ciTopRight, y,
|
rect.curveTo( x2 - ciTopRight, y,
|
||||||
x2, y + ciTopRight,
|
x2, y + ciTopRight,
|
||||||
@@ -823,6 +868,27 @@ public class FlatUIUtils
|
|||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a rounded triangle shape for the given points and arc radius.
|
||||||
|
*
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static Shape createRoundTrianglePath( float x1, float y1, float x2, float y2,
|
||||||
|
float x3, float y3, float arc )
|
||||||
|
{
|
||||||
|
double averageSideLength = (distance( x1,y1, x2,y2 ) + distance( x2,y2, x3,y3 ) + distance( x3,y3, x1,y1 )) / 3;
|
||||||
|
double t1 = (1 / averageSideLength) * arc;
|
||||||
|
double t2 = 1 - t1;
|
||||||
|
|
||||||
|
return createPath(
|
||||||
|
lerp( x3, x1, t2 ), lerp( y3, y1, t2 ),
|
||||||
|
QUAD_TO, x1, y1, lerp( x1, x2, t1 ), lerp( y1, y2, t1 ),
|
||||||
|
lerp( x1, x2, t2 ), lerp( y1, y2, t2 ),
|
||||||
|
QUAD_TO, x2, y2, lerp( x2, x3, t1 ), lerp( y2, y3, t1 ),
|
||||||
|
lerp( x2, x3, t2 ), lerp( y2, y3, t2 ),
|
||||||
|
QUAD_TO, x3, y3, lerp( x3, x1, t1 ), lerp( y3, y1, t1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Paints a chevron or triangle arrow in the center of the given rectangle.
|
* Paints a chevron or triangle arrow in the center of the given rectangle.
|
||||||
*
|
*
|
||||||
@@ -835,13 +901,15 @@ public class FlatUIUtils
|
|||||||
* {@link SwingConstants#WEST} or {@link SwingConstants#EAST})
|
* {@link SwingConstants#WEST} or {@link SwingConstants#EAST})
|
||||||
* @param chevron {@code true} for chevron arrow, {@code false} for triangle arrow
|
* @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 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 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)
|
* @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,
|
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
|
// compute arrow width/height
|
||||||
// - make chevron arrows one pixel smaller because coordinates are based on center of pixels (0.5/0.5)
|
// - make chevron arrows one pixel smaller because coordinates are based on center of pixels (0.5/0.5)
|
||||||
@@ -875,7 +943,7 @@ debug*/
|
|||||||
Shape arrowShape = createArrowShape( direction, chevron, aw, ah );
|
Shape arrowShape = createArrowShape( direction, chevron, aw, ah );
|
||||||
if( chevron ) {
|
if( chevron ) {
|
||||||
Stroke oldStroke = g.getStroke();
|
Stroke oldStroke = g.getStroke();
|
||||||
g.setStroke( new BasicStroke( UIScale.scale( 1f ) ) );
|
g.setStroke( new BasicStroke( UIScale.scale( arrowThickness ) ) );
|
||||||
drawShapePure( g, arrowShape );
|
drawShapePure( g, arrowShape );
|
||||||
g.setStroke( oldStroke );
|
g.setStroke( oldStroke );
|
||||||
} else {
|
} else {
|
||||||
@@ -932,6 +1000,12 @@ debug*/
|
|||||||
}
|
}
|
||||||
debug*/
|
debug*/
|
||||||
|
|
||||||
|
/** @since 3 */ public static final double MOVE_TO = -1_000_000_000_001.;
|
||||||
|
/** @since 3 */ public static final double QUAD_TO = -1_000_000_000_002.;
|
||||||
|
/** @since 3 */ public static final double CURVE_TO = -1_000_000_000_003.;
|
||||||
|
/** @since 3 */ public static final double ROUNDED = -1_000_000_000_004.;
|
||||||
|
/** @since 3 */ public static final double CLOSE_PATH = -1_000_000_000_005.;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a closed path for the given points.
|
* Creates a closed path for the given points.
|
||||||
*/
|
*/
|
||||||
@@ -943,15 +1017,88 @@ debug*/
|
|||||||
* Creates an open or closed path for the given points.
|
* Creates an open or closed path for the given points.
|
||||||
*/
|
*/
|
||||||
public static Path2D createPath( boolean close, double... points ) {
|
public static Path2D createPath( boolean close, double... points ) {
|
||||||
Path2D path = new Path2D.Float();
|
Path2D path = new Path2D.Float( Path2D.WIND_NON_ZERO, points.length / 2 + (close ? 1 : 0) );
|
||||||
path.moveTo( points[0], points[1] );
|
path.moveTo( points[0], points[1] );
|
||||||
for( int i = 2; i < points.length; i += 2 )
|
for( int i = 2; i < points.length; ) {
|
||||||
path.lineTo( points[i], points[i + 1] );
|
double p = points[i];
|
||||||
|
if( p == MOVE_TO ) {
|
||||||
|
// move pointer to
|
||||||
|
// params: x, y
|
||||||
|
path.moveTo( points[i + 1], points[i + 2] );
|
||||||
|
i += 3;
|
||||||
|
} else if( p == QUAD_TO ) {
|
||||||
|
// add quadratic curve
|
||||||
|
// params: x1, y1, x2, y2
|
||||||
|
path.quadTo( points[i + 1], points[i + 2], points[i + 3], points[i + 4] );
|
||||||
|
i += 5;
|
||||||
|
} else if( p == CURVE_TO ) {
|
||||||
|
// add bezier curve
|
||||||
|
// params: x1, y1, x2, y2, x3, y3
|
||||||
|
path.curveTo( points[i + 1], points[i + 2], points[i + 3], points[i + 4], points[i + 5], points[i + 6] );
|
||||||
|
i += 7;
|
||||||
|
} else if( p == ROUNDED ) {
|
||||||
|
// add rounded corner
|
||||||
|
// params: x, y, arc
|
||||||
|
double x = points[i + 1];
|
||||||
|
double y = points[i + 2];
|
||||||
|
double arc = points[i + 3];
|
||||||
|
|
||||||
|
// index of next point
|
||||||
|
int ip2 = i + 4;
|
||||||
|
if( points[ip2] == QUAD_TO || points[ip2] == ROUNDED )
|
||||||
|
ip2++;
|
||||||
|
|
||||||
|
// previous and next points
|
||||||
|
Point2D p1 = path.getCurrentPoint();
|
||||||
|
double x1 = p1.getX();
|
||||||
|
double y1 = p1.getY();
|
||||||
|
double x2 = points[ip2];
|
||||||
|
double y2 = points[ip2 + 1];
|
||||||
|
|
||||||
|
double d1 = distance( x, y, x1, y1 );
|
||||||
|
double d2 = distance( x, y, x2, y2 );
|
||||||
|
double t1 = 1 - ((1 / d1) * arc);
|
||||||
|
double t2 = (1 / d2) * arc;
|
||||||
|
|
||||||
|
path.lineTo( lerp( x1, x, t1 ), lerp( y1, y, t1 ) );
|
||||||
|
path.quadTo( x, y, lerp( x, x2, t2 ), lerp( y, y2, t2 ) );
|
||||||
|
|
||||||
|
i += 4;
|
||||||
|
} else if( p == CLOSE_PATH ) {
|
||||||
|
// close path
|
||||||
|
// params: -
|
||||||
|
path.closePath();
|
||||||
|
i += 1;
|
||||||
|
} else {
|
||||||
|
// add line to
|
||||||
|
// params: x, y
|
||||||
|
path.lineTo( p, points[i + 1] );
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
if( close )
|
if( close )
|
||||||
path.closePath();
|
path.closePath();
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates linear interpolation between two values.
|
||||||
|
*
|
||||||
|
* https://en.wikipedia.org/wiki/Linear_interpolation#Programming_language_support
|
||||||
|
*/
|
||||||
|
private static double lerp( double v1, double v2, double t ) {
|
||||||
|
return (v1 * (1 - t)) + (v2 * t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the distance between two points.
|
||||||
|
*/
|
||||||
|
private static double distance( double x1, double y1, double x2, double y2 ) {
|
||||||
|
double dx = x2 - x1;
|
||||||
|
double dy = y2 - y1;
|
||||||
|
return Math.sqrt( (dx * dx) + (dy * dy) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the given shape with disabled stroke normalization.
|
* Draws the given shape with disabled stroke normalization.
|
||||||
* The x/y coordinates of the shape are translated by a half pixel.
|
* The x/y coordinates of the shape are translated by a half pixel.
|
||||||
|
|||||||
@@ -105,6 +105,19 @@ public class ColorFunctions
|
|||||||
return HSLColor.toRGB( hsl[0], hsl[1], hsl[2], alpha );
|
return HSLColor.toRGB( hsl[0], hsl[1], hsl[2], alpha );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the opacity (alpha) of a color.
|
||||||
|
*
|
||||||
|
* @param color base color
|
||||||
|
* @param amount the amount (in range 0-1) of the new opacity
|
||||||
|
* @return new color
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public static Color fade( Color color, float amount ) {
|
||||||
|
int newAlpha = Math.round( 255 * amount );
|
||||||
|
return new Color( (color.getRGB() & 0xffffff) | (newAlpha << 24), true );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a color that is a mixture of two colors.
|
* Returns a color that is a mixture of two colors.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.FontFormatException;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import javax.swing.plaf.UIResource;
|
||||||
|
import javax.swing.text.StyleContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for fonts.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 3
|
||||||
|
*/
|
||||||
|
public class FontUtils
|
||||||
|
{
|
||||||
|
private static Map<String, Runnable> loadersMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a composite font for the given family, style and size.
|
||||||
|
* A composite font that is able to display all Unicode characters.
|
||||||
|
* The font family is loaded if necessary via {@link #loadFontFamily(String)}.
|
||||||
|
* <p>
|
||||||
|
* To get fonts derived from returned fonts, it is recommended to use one of the
|
||||||
|
* {@link Font#deriveFont} methods instead of invoking this method.
|
||||||
|
*/
|
||||||
|
public static Font getCompositeFont( String family, int style, int size ) {
|
||||||
|
loadFontFamily( family );
|
||||||
|
|
||||||
|
// using StyleContext.getFont() here because it uses
|
||||||
|
// sun.font.FontUtilities.getCompositeFontUIResource()
|
||||||
|
// and creates a composite font that is able to display all Unicode characters
|
||||||
|
Font font = StyleContext.getDefaultStyleContext().getFont( family, style, size );
|
||||||
|
|
||||||
|
// always return non-UIResource font to avoid side effects when using font
|
||||||
|
// because Swing uninstalls UIResource fonts when switching L&F
|
||||||
|
// (StyleContext.getFont() may return a UIResource)
|
||||||
|
if( font instanceof UIResource )
|
||||||
|
font = font.deriveFont( font.getStyle() );
|
||||||
|
|
||||||
|
return font;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a font family for lazy loading via {@link #loadFontFamily(String)}.
|
||||||
|
* <p>
|
||||||
|
* The given runnable is invoked when the given font family should be loaded.
|
||||||
|
* The runnable should invoke {@link #installFont(URL)} to load and register font(s)
|
||||||
|
* for the family.
|
||||||
|
* A family may consist of up to four font files for the supported font styles:
|
||||||
|
* regular (plain), italic, bold and bold-italic.
|
||||||
|
*/
|
||||||
|
public static void registerFontFamilyLoader( String family, Runnable loader ) {
|
||||||
|
if( loadersMap == null )
|
||||||
|
loadersMap = new HashMap<>();
|
||||||
|
loadersMap.put( family, loader );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a font family previously registered via {@link #registerFontFamilyLoader(String, Runnable)}.
|
||||||
|
* If the family is already loaded or no londer is registered for that family, nothing happens.
|
||||||
|
*/
|
||||||
|
public static void loadFontFamily( String family ) {
|
||||||
|
if( !hasLoaders() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Runnable loader = loadersMap.remove( family );
|
||||||
|
if( loader != null )
|
||||||
|
loader.run();
|
||||||
|
|
||||||
|
if( loadersMap.isEmpty() )
|
||||||
|
loadersMap = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a font file from the given url and registers it in the graphics environment.
|
||||||
|
* Uses {@link Font#createFont(int, InputStream)} and {@link GraphicsEnvironment#registerFont(Font)}.
|
||||||
|
*/
|
||||||
|
public static boolean installFont( URL url ) {
|
||||||
|
try( InputStream in = url.openStream() ) {
|
||||||
|
Font font = Font.createFont( Font.TRUETYPE_FONT, in );
|
||||||
|
return GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont( font );
|
||||||
|
} catch( FontFormatException | IOException ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to install font " + url, ex );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all font familiy names available in the graphics environment.
|
||||||
|
* This invokes {@link GraphicsEnvironment#getAvailableFontFamilyNames()} and
|
||||||
|
* appends families registered for lazy loading via {@link #registerFontFamilyLoader(String, Runnable)}
|
||||||
|
* to the result.
|
||||||
|
*/
|
||||||
|
public static String[] getAvailableFontFamilyNames() {
|
||||||
|
String[] availableFontFamilyNames = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
|
||||||
|
if( !hasLoaders() )
|
||||||
|
return availableFontFamilyNames;
|
||||||
|
|
||||||
|
// append families that are not yet loaded
|
||||||
|
ArrayList<String> result = new ArrayList<>( availableFontFamilyNames.length + loadersMap.size() );
|
||||||
|
for( String name : availableFontFamilyNames )
|
||||||
|
result.add( name );
|
||||||
|
for( String name : loadersMap.keySet() ) {
|
||||||
|
if( !result.contains( name ) )
|
||||||
|
result.add( name );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toArray( new String[result.size()] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all fonts available in the graphics environment.
|
||||||
|
* This first loads all families registered for lazy loading via {@link #registerFontFamilyLoader(String, Runnable)}
|
||||||
|
* and then invokes {@link GraphicsEnvironment#getAllFonts()}.
|
||||||
|
*/
|
||||||
|
public static Font[] getAllFonts() {
|
||||||
|
if( hasLoaders() ) {
|
||||||
|
// load all registered families
|
||||||
|
String[] families = loadersMap.keySet().toArray( new String[loadersMap.size()] );
|
||||||
|
for( String family : families )
|
||||||
|
loadFontFamily( family );
|
||||||
|
}
|
||||||
|
|
||||||
|
return GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hasLoaders() {
|
||||||
|
return loadersMap != null && !loadersMap.isEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.util;
|
package com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
import java.awt.Font;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.font.GlyphVector;
|
import java.awt.font.GlyphVector;
|
||||||
@@ -141,37 +142,103 @@ public class HiDPIUtils
|
|||||||
if( !useTextYCorrection() || !SystemInfo.isWindows )
|
if( !useTextYCorrection() || !SystemInfo.isWindows )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if( !SystemInfo.isJava_9_orLater )
|
if( !SystemInfo.isJava_9_orLater ) {
|
||||||
return UIScale.getUserScaleFactor() > 1 ? -UIScale.scale( 0.625f ) : 0;
|
// Java 8
|
||||||
|
float scaleFactor = getUserScaleFactor();
|
||||||
|
if( scaleFactor > 1 ) {
|
||||||
|
switch( g.getFont().getFamily() ) {
|
||||||
|
case "Segoe UI":
|
||||||
|
case "Segoe UI Light":
|
||||||
|
case "Segoe UI Semibold":
|
||||||
|
return -((scaleFactor == 2.25f || scaleFactor == 4f ? 0.875f : 0.625f) * scaleFactor);
|
||||||
|
|
||||||
AffineTransform t = g.getTransform();
|
case "Noto Sans":
|
||||||
double scaleY = t.getScaleY();
|
case "Open Sans":
|
||||||
if( scaleY < 1.25 )
|
return -(0.3f * scaleFactor);
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Text is painted at slightly different Y positions depending on scale factor
|
case "Verdana":
|
||||||
// and Y position of component.
|
return -((scaleFactor < 2 ? 0.4f : 0.3f) * scaleFactor);
|
||||||
// The exact reason is not yet known (to me), but there are several factors:
|
}
|
||||||
// - fractional scale factors result in fractional component Y device coordinates
|
}
|
||||||
// - fractional text Y device coordinates are rounded for horizontal lines of characters
|
} else {
|
||||||
// - maybe different rounding methods for drawing primitives (e.g. rectangle) and text
|
// Java 9 and later
|
||||||
// - Java adds 0.5 to X/Y positions before drawing string in BufferedTextPipe.enqueueGlyphList()
|
|
||||||
|
|
||||||
// this is not the optimal solution, but works very good in most cases
|
// Text is painted at slightly different Y positions depending on scale factor
|
||||||
// (tested with class FlatPaintingStringTest on Windows 10 with font "Segoe UI")
|
// and Y position of component.
|
||||||
if( scaleY <= 1.25 )
|
// The exact reason is not yet known (to me), but there are several factors:
|
||||||
return -0.875f;
|
// - fractional scale factors result in fractional component Y device coordinates
|
||||||
if( scaleY <= 1.5 )
|
// - fractional text Y device coordinates are rounded for horizontal lines of characters
|
||||||
return -0.625f;
|
// - maybe different rounding methods for drawing primitives (e.g. rectangle) and text
|
||||||
if( scaleY <= 1.75 )
|
// - Java adds 0.5 to X/Y positions before drawing string in BufferedTextPipe.enqueueGlyphList()
|
||||||
return -0.875f;
|
|
||||||
if( scaleY <= 2.0 )
|
// this is not the optimal solution, but works very good in most cases
|
||||||
return -0.75f;
|
// (tested with class FlatPaintingStringTest on Windows 11)
|
||||||
if( scaleY <= 2.25 )
|
|
||||||
return -0.875f;
|
switch( g.getFont().getFamily() ) {
|
||||||
if( scaleY <= 3.5 )
|
case "Segoe UI":
|
||||||
return -0.75f;
|
case "Segoe UI Light":
|
||||||
return -0.875f;
|
case "Segoe UI Semibold":
|
||||||
|
case "Verdana":
|
||||||
|
case Font.DIALOG:
|
||||||
|
case Font.SANS_SERIF:
|
||||||
|
return correctionForScaleY( g, CORRECTION_SEGOE_UI );
|
||||||
|
|
||||||
|
case "Tahoma":
|
||||||
|
return correctionForScaleY( g, CORRECTION_TAHOMA );
|
||||||
|
|
||||||
|
case "Inter":
|
||||||
|
case "Inter Light":
|
||||||
|
case "Inter Semi Bold":
|
||||||
|
case "Roboto":
|
||||||
|
case "Roboto Light":
|
||||||
|
case "Roboto Medium":
|
||||||
|
return correctionForScaleY( g, CORRECTION_INTER );
|
||||||
|
|
||||||
|
case "Noto Sans":
|
||||||
|
case "Open Sans":
|
||||||
|
return correctionForScaleY( g, CORRECTION_OPEN_SANS );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final float[]
|
||||||
|
SCALE_FACTORS = { 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 3f, 3.5f, 4f },
|
||||||
|
|
||||||
|
CORRECTION_SEGOE_UI = { -0.5f, -0.5f, -0.625f, -0.75f, -0.75f, -0.75f, -0.75f, -0.75f, -0.875f },
|
||||||
|
CORRECTION_TAHOMA = { -0.25f, -0.25f, -0.25f, -0f, -0.125f, -0.125f, -0.125f, -0.125f, -0f },
|
||||||
|
CORRECTION_INTER = { -0.25f, -0.25f, -0.25f, -0f, -0.125f, -0.125f, -0f, -0.25f, -0f },
|
||||||
|
CORRECTION_OPEN_SANS = { -0.5f, -0.25f, -0.25f, -0f, -0.25f, -0.25f, -0f, -0.25f, -0.25f };
|
||||||
|
|
||||||
|
private static float correctionForScaleY( Graphics2D g, float[] correction ) {
|
||||||
|
if( correction.length != 9 )
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
double scaleY = g.getTransform().getScaleY();
|
||||||
|
return (scaleY < 1.25) ? 0 : correction[scaleFactor2index( (float) scaleY )];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int scaleFactor2index( float scaleFactor ) {
|
||||||
|
for( int i = 0; i < SCALE_FACTORS.length; i++ ) {
|
||||||
|
if( scaleFactor <= SCALE_FACTORS[i] )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return SCALE_FACTORS.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Boolean useDebugScaleFactor;
|
||||||
|
|
||||||
|
private static boolean useDebugScaleFactor() {
|
||||||
|
if( useDebugScaleFactor == null )
|
||||||
|
useDebugScaleFactor = FlatSystemProperties.getBoolean( "FlatLaf.debug.HiDPIUtils.useDebugScaleFactor", false );
|
||||||
|
return useDebugScaleFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float getUserScaleFactor() {
|
||||||
|
return !useDebugScaleFactor()
|
||||||
|
? UIScale.getUserScaleFactor()
|
||||||
|
: Float.parseFloat( System.getProperty( "FlatLaf.debug.HiDPIUtils.debugScaleFactor", "1" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -73,6 +73,22 @@ public class NativeLibrary
|
|||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native library using {@link System#loadLibrary(String)}.
|
||||||
|
* Searches for the library in classloader of caller
|
||||||
|
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
||||||
|
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
||||||
|
*
|
||||||
|
* @param libraryName name of the native library (without "lib" prefix and without extension)
|
||||||
|
* @param supported whether the native library is supported on the current platform
|
||||||
|
* @since 2.6
|
||||||
|
*/
|
||||||
|
public NativeLibrary( String libraryName, boolean supported ) {
|
||||||
|
this.loaded = supported
|
||||||
|
? loadLibraryFromSystem( libraryName )
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the native library is loaded.
|
* Returns whether the native library is loaded.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -92,7 +108,7 @@ public class NativeLibrary
|
|||||||
? classLoader.getResource( libraryName )
|
? classLoader.getResource( libraryName )
|
||||||
: NativeLibrary.class.getResource( "/" + libraryName );
|
: NativeLibrary.class.getResource( "/" + libraryName );
|
||||||
if( libraryUrl == null ) {
|
if( libraryUrl == null ) {
|
||||||
log( "Library '" + libraryName + "' not found", null );
|
LoggingFacade.INSTANCE.logSevere( "Library '" + libraryName + "' not found", null );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +141,7 @@ public class NativeLibrary
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch( Throwable ex ) {
|
} catch( Throwable ex ) {
|
||||||
log( null, ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
|
|
||||||
if( tempFile != null )
|
if( tempFile != null )
|
||||||
deleteOrMarkForDeletion( tempFile );
|
deleteOrMarkForDeletion( tempFile );
|
||||||
@@ -138,7 +154,24 @@ public class NativeLibrary
|
|||||||
System.load( libraryFile.getAbsolutePath() );
|
System.load( libraryFile.getAbsolutePath() );
|
||||||
return true;
|
return true;
|
||||||
} catch( Throwable ex ) {
|
} catch( Throwable ex ) {
|
||||||
log( ex.getMessage(), ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean loadLibraryFromSystem( String libraryName ) {
|
||||||
|
try {
|
||||||
|
System.loadLibrary( libraryName );
|
||||||
|
return true;
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
String message = ex.getMessage();
|
||||||
|
|
||||||
|
// do not log error if library was not found
|
||||||
|
// thrown in ClassLoader.loadLibrary(Class<?> fromClass, String name, boolean isAbsolute)
|
||||||
|
if( ex instanceof UnsatisfiedLinkError && message != null && message.contains( "java.library.path" ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LoggingFacade.INSTANCE.logSevere( message, ex );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,10 +191,6 @@ public class NativeLibrary
|
|||||||
: System.mapLibraryName( libraryName );
|
: System.mapLibraryName( libraryName );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log( String msg, Throwable thrown ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( msg, thrown );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Path createTempFile( String libraryName ) throws IOException {
|
private static Path createTempFile( String libraryName ) throws IOException {
|
||||||
int sep = libraryName.lastIndexOf( '/' );
|
int sep = libraryName.lastIndexOf( '/' );
|
||||||
String name = (sep >= 0) ? libraryName.substring( sep + 1 ) : libraryName;
|
String name = (sep >= 0) ? libraryName.substring( sep + 1 ) : libraryName;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.util;
|
package com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
@@ -102,6 +103,13 @@ debug*/
|
|||||||
int imageWidth = image.getWidth( null );
|
int imageWidth = image.getWidth( null );
|
||||||
int imageHeight = image.getHeight( null );
|
int imageHeight = image.getHeight( null );
|
||||||
|
|
||||||
|
// paint red rectangle if image has invalid size (e.g. not found)
|
||||||
|
if( imageWidth < 0 || imageHeight < 0 ) {
|
||||||
|
g.setColor( Color.red );
|
||||||
|
g.fillRect( x, y, getIconWidth(), getIconHeight() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// scale image if necessary to destination size
|
// scale image if necessary to destination size
|
||||||
if( imageWidth != destImageWidth || imageHeight != destImageHeight ) {
|
if( imageWidth != destImageWidth || imageHeight != destImageHeight ) {
|
||||||
// determine scaling method; default is "quality"
|
// determine scaling method; default is "quality"
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ module com.formdev.flatlaf {
|
|||||||
|
|
||||||
exports com.formdev.flatlaf;
|
exports com.formdev.flatlaf;
|
||||||
exports com.formdev.flatlaf.icons;
|
exports com.formdev.flatlaf.icons;
|
||||||
|
exports com.formdev.flatlaf.themes;
|
||||||
exports com.formdev.flatlaf.ui;
|
exports com.formdev.flatlaf.ui;
|
||||||
exports com.formdev.flatlaf.util;
|
exports com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,9 @@
|
|||||||
@selectionInactiveForeground = @foreground
|
@selectionInactiveForeground = @foreground
|
||||||
|
|
||||||
# menu
|
# menu
|
||||||
|
@menuSelectionBackground = @selectionBackground
|
||||||
@menuHoverBackground = lighten(@menuBackground,10%,derived)
|
@menuHoverBackground = lighten(@menuBackground,10%,derived)
|
||||||
@menuCheckBackground = darken(@selectionBackground,10%,derived noAutoInverse)
|
@menuCheckBackground = darken(@menuSelectionBackground,10%,derived noAutoInverse)
|
||||||
@menuAcceleratorForeground = darken(@foreground,15%)
|
@menuAcceleratorForeground = darken(@foreground,15%)
|
||||||
@menuAcceleratorSelectionForeground = @selectionForeground
|
@menuAcceleratorSelectionForeground = @selectionForeground
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@
|
|||||||
# accent colors (blueish)
|
# accent colors (blueish)
|
||||||
# set @accentColor to use single accent color or
|
# set @accentColor to use single accent color or
|
||||||
# modify @accentBaseColor to use variations of accent base color
|
# modify @accentBaseColor to use variations of accent base color
|
||||||
@accentColor = null
|
@accentColor = systemColor(accent,null)
|
||||||
@accentBaseColor = #4B6EAF
|
@accentBaseColor = #4B6EAF
|
||||||
@accentBase2Color = lighten(saturate(spin(@accentBaseColor,-8),13%),5%)
|
@accentBase2Color = lighten(saturate(spin(@accentBaseColor,-8),13%),5%)
|
||||||
# accent color variations
|
# accent color variations
|
||||||
@@ -349,6 +350,11 @@ ToggleButton.disabledSelectedBackground = lighten($ToggleButton.background,3%,de
|
|||||||
ToggleButton.toolbar.selectedBackground = lighten($ToggleButton.background,7%,derived)
|
ToggleButton.toolbar.selectedBackground = lighten($ToggleButton.background,7%,derived)
|
||||||
|
|
||||||
|
|
||||||
|
#---- ToolBar ----
|
||||||
|
|
||||||
|
ToolBar.hoverButtonGroupBackground = lighten($ToolBar.background,3%,derived)
|
||||||
|
|
||||||
|
|
||||||
#---- ToolTip ----
|
#---- ToolTip ----
|
||||||
|
|
||||||
ToolTip.border = 4,6,4,6
|
ToolTip.border = 4,6,4,6
|
||||||
|
|||||||
@@ -285,6 +285,10 @@ ComboBox.buttonDisabledArrowColor = @buttonDisabledArrowColor
|
|||||||
ComboBox.buttonHoverArrowColor = @buttonHoverArrowColor
|
ComboBox.buttonHoverArrowColor = @buttonHoverArrowColor
|
||||||
ComboBox.buttonPressedArrowColor = @buttonPressedArrowColor
|
ComboBox.buttonPressedArrowColor = @buttonPressedArrowColor
|
||||||
|
|
||||||
|
ComboBox.popupInsets = 0,0,0,0
|
||||||
|
ComboBox.selectionInsets = 0,0,0,0
|
||||||
|
ComboBox.selectionArc = 0
|
||||||
|
|
||||||
|
|
||||||
#---- Component ----
|
#---- Component ----
|
||||||
|
|
||||||
@@ -390,6 +394,8 @@ InternalFrameTitlePane.border = 0,8,0,0
|
|||||||
|
|
||||||
List.border = 0,0,0,0
|
List.border = 0,0,0,0
|
||||||
List.cellMargins = 1,6,1,6
|
List.cellMargins = 1,6,1,6
|
||||||
|
List.selectionInsets = 0,0,0,0
|
||||||
|
List.selectionArc = 0
|
||||||
List.cellFocusColor = @cellFocusColor
|
List.cellFocusColor = @cellFocusColor
|
||||||
List.cellNoFocusBorder = com.formdev.flatlaf.ui.FlatListCellBorder$Default
|
List.cellNoFocusBorder = com.formdev.flatlaf.ui.FlatListCellBorder$Default
|
||||||
List.focusCellHighlightBorder = com.formdev.flatlaf.ui.FlatListCellBorder$Focused
|
List.focusCellHighlightBorder = com.formdev.flatlaf.ui.FlatListCellBorder$Focused
|
||||||
@@ -422,6 +428,9 @@ MenuBar.border = com.formdev.flatlaf.ui.FlatMenuBarBorder
|
|||||||
MenuBar.background = @menuBackground
|
MenuBar.background = @menuBackground
|
||||||
MenuBar.hoverBackground = @menuHoverBackground
|
MenuBar.hoverBackground = @menuHoverBackground
|
||||||
MenuBar.itemMargins = 3,8,3,8
|
MenuBar.itemMargins = 3,8,3,8
|
||||||
|
MenuBar.selectionInsets = $MenuItem.selectionInsets
|
||||||
|
MenuBar.selectionEmbeddedInsets = $MenuItem.selectionInsets
|
||||||
|
MenuBar.selectionArc = $MenuItem.selectionArc
|
||||||
|
|
||||||
|
|
||||||
#---- MenuItem ----
|
#---- MenuItem ----
|
||||||
@@ -444,6 +453,8 @@ MenuItem.textNoAcceleratorGap = 6
|
|||||||
MenuItem.acceleratorArrowGap = 2
|
MenuItem.acceleratorArrowGap = 2
|
||||||
MenuItem.acceleratorDelimiter = "+"
|
MenuItem.acceleratorDelimiter = "+"
|
||||||
[mac]MenuItem.acceleratorDelimiter = ""
|
[mac]MenuItem.acceleratorDelimiter = ""
|
||||||
|
MenuItem.selectionInsets = 0,0,0,0
|
||||||
|
MenuItem.selectionArc = 0
|
||||||
|
|
||||||
# for MenuItem.selectionType = underline
|
# for MenuItem.selectionType = underline
|
||||||
MenuItem.underlineSelectionBackground = @menuHoverBackground
|
MenuItem.underlineSelectionBackground = @menuHoverBackground
|
||||||
@@ -847,6 +858,7 @@ ToolBar.borderMargins = 2,2,2,2
|
|||||||
ToolBar.isRollover = true
|
ToolBar.isRollover = true
|
||||||
ToolBar.focusableButtons = false
|
ToolBar.focusableButtons = false
|
||||||
ToolBar.arrowKeysOnlyNavigation = true
|
ToolBar.arrowKeysOnlyNavigation = true
|
||||||
|
ToolBar.hoverButtonGroupArc = 8
|
||||||
ToolBar.floatable = false
|
ToolBar.floatable = false
|
||||||
ToolBar.gripColor = @icon
|
ToolBar.gripColor = @icon
|
||||||
ToolBar.dockingBackground = darken($ToolBar.background,5%)
|
ToolBar.dockingBackground = darken($ToolBar.background,5%)
|
||||||
@@ -883,10 +895,13 @@ Tree.dropCellForeground = @dropCellForeground
|
|||||||
Tree.dropLineColor = @dropLineColor
|
Tree.dropLineColor = @dropLineColor
|
||||||
Tree.rendererFillBackground = false
|
Tree.rendererFillBackground = false
|
||||||
Tree.rendererMargins = 1,2,1,2
|
Tree.rendererMargins = 1,2,1,2
|
||||||
|
Tree.selectionInsets = 0,0,0,0
|
||||||
|
Tree.selectionArc = 0
|
||||||
Tree.wideSelection = true
|
Tree.wideSelection = true
|
||||||
Tree.repaintWholeRow = true
|
Tree.repaintWholeRow = true
|
||||||
Tree.paintLines = false
|
Tree.paintLines = false
|
||||||
Tree.showCellFocusIndicator = false
|
Tree.showCellFocusIndicator = false
|
||||||
|
Tree.showDefaultIcons = false
|
||||||
Tree.leftChildIndent = 7
|
Tree.leftChildIndent = 7
|
||||||
Tree.rightChildIndent = 11
|
Tree.rightChildIndent = 11
|
||||||
Tree.rowHeight = 0
|
Tree.rowHeight = 0
|
||||||
@@ -904,7 +919,6 @@ Tree.icon.closedColor = @icon
|
|||||||
Tree.icon.openColor = @icon
|
Tree.icon.openColor = @icon
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#---- Styles ------------------------------------------------------------------
|
#---- Styles ------------------------------------------------------------------
|
||||||
|
|
||||||
#---- inTextField ----
|
#---- inTextField ----
|
||||||
|
|||||||
@@ -50,8 +50,9 @@
|
|||||||
@selectionInactiveForeground = @foreground
|
@selectionInactiveForeground = @foreground
|
||||||
|
|
||||||
# menu
|
# menu
|
||||||
|
@menuSelectionBackground = @selectionBackground
|
||||||
@menuHoverBackground = darken(@menuBackground,10%,derived)
|
@menuHoverBackground = darken(@menuBackground,10%,derived)
|
||||||
@menuCheckBackground = lighten(@selectionBackground,40%,derived noAutoInverse)
|
@menuCheckBackground = lighten(@menuSelectionBackground,40%,derived noAutoInverse)
|
||||||
@menuAcceleratorForeground = lighten(@foreground,30%)
|
@menuAcceleratorForeground = lighten(@foreground,30%)
|
||||||
@menuAcceleratorSelectionForeground = @selectionForeground
|
@menuAcceleratorSelectionForeground = @selectionForeground
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@
|
|||||||
# accent colors (blueish)
|
# accent colors (blueish)
|
||||||
# set @accentColor to use single accent color or
|
# set @accentColor to use single accent color or
|
||||||
# modify @accentBaseColor to use variations of accent base color
|
# modify @accentBaseColor to use variations of accent base color
|
||||||
@accentColor = null
|
@accentColor = systemColor(accent,null)
|
||||||
@accentBaseColor = #2675BF
|
@accentBaseColor = #2675BF
|
||||||
@accentBase2Color = lighten(saturate(@accentBaseColor,10%),6%)
|
@accentBase2Color = lighten(saturate(@accentBaseColor,10%),6%)
|
||||||
# accent color variations
|
# accent color variations
|
||||||
@@ -356,6 +357,11 @@ ToggleButton.disabledSelectedBackground = darken($ToggleButton.background,13%,de
|
|||||||
ToggleButton.toolbar.selectedBackground = $ToggleButton.selectedBackground
|
ToggleButton.toolbar.selectedBackground = $ToggleButton.selectedBackground
|
||||||
|
|
||||||
|
|
||||||
|
#---- ToolBar ----
|
||||||
|
|
||||||
|
ToolBar.hoverButtonGroupBackground = darken($ToolBar.background,3%,derived)
|
||||||
|
|
||||||
|
|
||||||
#---- ToolTip ----
|
#---- ToolTip ----
|
||||||
|
|
||||||
ToolTip.border = 4,6,4,6,shade(@background,40%)
|
ToolTip.border = 4,6,4,6,shade(@background,40%)
|
||||||
|
|||||||
@@ -0,0 +1,288 @@
|
|||||||
|
#
|
||||||
|
# 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 = if(systemColor(accent), shade(spin(systemColor(accent),4),20%), @nsSelectedContentBackgroundColor)
|
||||||
|
@selectionForeground = @nsSelectedMenuItemTextColor
|
||||||
|
@selectionInactiveBackground = @nsUnemphasizedSelectedContentBackgroundColor
|
||||||
|
|
||||||
|
# text selection
|
||||||
|
@textSelectionBackground = systemColor(highlight,if(systemColor(accent), darken(desaturate(systemColor(accent),60%),10%), @nsSelectedTextBackgroundColor))
|
||||||
|
@textSelectionForeground = @nsSelectedTextColor
|
||||||
|
|
||||||
|
# menu
|
||||||
|
@menuSelectionBackground = desaturate(@selectionBackground,20%)
|
||||||
|
@menuItemMargin = 3,11,3,11
|
||||||
|
|
||||||
|
# accent colors (blueish)
|
||||||
|
@accentColor = systemColor(accent,@nsControlAccentColor)
|
||||||
|
@accentFocusColor = if(systemColor(accent), fade(spin(systemColor(accent),-10),50%), @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.buttonArrowColor = @foreground
|
||||||
|
Spinner.buttonHoverArrowColor = lighten($Spinner.buttonArrowColor,10%,derived noAutoInverse)
|
||||||
|
Spinner.buttonPressedArrowColor = lighten($Spinner.buttonArrowColor,20%,derived noAutoInverse)
|
||||||
|
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 = if(systemColor(accent), shade(spin(systemColor(accent),4),10%), @nsSelectedContentBackgroundColor)
|
||||||
|
@selectionForeground = @nsSelectedMenuItemTextColor
|
||||||
|
@selectionInactiveBackground = @nsUnemphasizedSelectedContentBackgroundColor
|
||||||
|
|
||||||
|
# text selection
|
||||||
|
@textSelectionBackground = systemColor(highlight,if(systemColor(accent), tint(systemColor(accent),70%), @nsSelectedTextBackgroundColor))
|
||||||
|
@textSelectionForeground = @foreground
|
||||||
|
|
||||||
|
# menu
|
||||||
|
@menuSelectionBackground = lighten(@accentColor,12%)
|
||||||
|
@menuCheckBackground = lighten(@menuSelectionBackground,25%,derived noAutoInverse)
|
||||||
|
@menuItemMargin = 3,11,3,11
|
||||||
|
|
||||||
|
# accent colors (blueish)
|
||||||
|
@accentColor = systemColor(accent,@nsControlAccentColor)
|
||||||
|
@accentFocusColor = if(systemColor(accent), fade(spin(systemColor(accent),4),50%), @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
|
||||||
@@ -185,7 +185,10 @@ public class TestFlatStyleableInfo
|
|||||||
"buttonHoverArrowColor", Color.class,
|
"buttonHoverArrowColor", Color.class,
|
||||||
"buttonPressedArrowColor", Color.class,
|
"buttonPressedArrowColor", Color.class,
|
||||||
|
|
||||||
"popupBackground", Color.class
|
"popupBackground", Color.class,
|
||||||
|
"popupInsets", Insets.class,
|
||||||
|
"selectionInsets", Insets.class,
|
||||||
|
"selectionArc", int.class
|
||||||
);
|
);
|
||||||
|
|
||||||
// border
|
// border
|
||||||
@@ -266,6 +269,8 @@ public class TestFlatStyleableInfo
|
|||||||
"selectionForeground", Color.class,
|
"selectionForeground", Color.class,
|
||||||
"selectionInactiveBackground", Color.class,
|
"selectionInactiveBackground", Color.class,
|
||||||
"selectionInactiveForeground", Color.class,
|
"selectionInactiveForeground", Color.class,
|
||||||
|
"selectionInsets", Insets.class,
|
||||||
|
"selectionArc", int.class,
|
||||||
|
|
||||||
// FlatListCellBorder
|
// FlatListCellBorder
|
||||||
"cellMargins", Insets.class,
|
"cellMargins", Insets.class,
|
||||||
@@ -283,6 +288,9 @@ public class TestFlatStyleableInfo
|
|||||||
|
|
||||||
Map<String, Class<?>> expected = expectedMap(
|
Map<String, Class<?>> expected = expectedMap(
|
||||||
"itemMargins", Insets.class,
|
"itemMargins", Insets.class,
|
||||||
|
"selectionInsets", Insets.class,
|
||||||
|
"selectionEmbeddedInsets", Insets.class,
|
||||||
|
"selectionArc", int.class,
|
||||||
"hoverBackground", Color.class,
|
"hoverBackground", Color.class,
|
||||||
"selectionBackground", Color.class,
|
"selectionBackground", Color.class,
|
||||||
"selectionForeground", Color.class,
|
"selectionForeground", Color.class,
|
||||||
@@ -369,6 +377,9 @@ public class TestFlatStyleableInfo
|
|||||||
"checkBackground", Color.class,
|
"checkBackground", Color.class,
|
||||||
"checkMargins", Insets.class,
|
"checkMargins", Insets.class,
|
||||||
|
|
||||||
|
"selectionInsets", Insets.class,
|
||||||
|
"selectionArc", int.class,
|
||||||
|
|
||||||
"underlineSelectionBackground", Color.class,
|
"underlineSelectionBackground", Color.class,
|
||||||
"underlineSelectionCheckBackground", Color.class,
|
"underlineSelectionCheckBackground", Color.class,
|
||||||
"underlineSelectionColor", Color.class,
|
"underlineSelectionColor", Color.class,
|
||||||
@@ -899,6 +910,8 @@ public class TestFlatStyleableInfo
|
|||||||
Map<String, Class<?>> expected = expectedMap(
|
Map<String, Class<?>> expected = expectedMap(
|
||||||
"focusableButtons", boolean.class,
|
"focusableButtons", boolean.class,
|
||||||
"arrowKeysOnlyNavigation", boolean.class,
|
"arrowKeysOnlyNavigation", boolean.class,
|
||||||
|
"hoverButtonGroupArc", int.class,
|
||||||
|
"hoverButtonGroupBackground", Color.class,
|
||||||
|
|
||||||
"borderMargins", Insets.class,
|
"borderMargins", Insets.class,
|
||||||
"gripColor", Color.class
|
"gripColor", Color.class
|
||||||
@@ -931,6 +944,8 @@ public class TestFlatStyleableInfo
|
|||||||
"selectionInactiveBackground", Color.class,
|
"selectionInactiveBackground", Color.class,
|
||||||
"selectionInactiveForeground", Color.class,
|
"selectionInactiveForeground", Color.class,
|
||||||
"selectionBorderColor", Color.class,
|
"selectionBorderColor", Color.class,
|
||||||
|
"selectionInsets", Insets.class,
|
||||||
|
"selectionArc", int.class,
|
||||||
"wideSelection", boolean.class,
|
"wideSelection", boolean.class,
|
||||||
"showCellFocusIndicator", boolean.class,
|
"showCellFocusIndicator", boolean.class,
|
||||||
|
|
||||||
|
|||||||
@@ -316,6 +316,9 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "buttonPressedArrowColor: #fff" );
|
ui.applyStyle( "buttonPressedArrowColor: #fff" );
|
||||||
|
|
||||||
ui.applyStyle( "popupBackground: #fff" );
|
ui.applyStyle( "popupBackground: #fff" );
|
||||||
|
ui.applyStyle( "popupInsets: 1,2,3,4" );
|
||||||
|
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||||
|
ui.applyStyle( "selectionArc: 8" );
|
||||||
|
|
||||||
// border
|
// border
|
||||||
flatRoundBorder( style -> ui.applyStyle( style ) );
|
flatRoundBorder( style -> ui.applyStyle( style ) );
|
||||||
@@ -413,6 +416,8 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "selectionForeground: #fff" );
|
ui.applyStyle( "selectionForeground: #fff" );
|
||||||
ui.applyStyle( "selectionInactiveBackground: #fff" );
|
ui.applyStyle( "selectionInactiveBackground: #fff" );
|
||||||
ui.applyStyle( "selectionInactiveForeground: #fff" );
|
ui.applyStyle( "selectionInactiveForeground: #fff" );
|
||||||
|
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||||
|
ui.applyStyle( "selectionArc: 8" );
|
||||||
|
|
||||||
// FlatListCellBorder
|
// FlatListCellBorder
|
||||||
ui.applyStyle( "cellMargins: 1,2,3,4" );
|
ui.applyStyle( "cellMargins: 1,2,3,4" );
|
||||||
@@ -435,6 +440,9 @@ public class TestFlatStyling
|
|||||||
FlatMenuBarUI ui = (FlatMenuBarUI) c.getUI();
|
FlatMenuBarUI ui = (FlatMenuBarUI) c.getUI();
|
||||||
|
|
||||||
ui.applyStyle( "itemMargins: 1,2,3,4" );
|
ui.applyStyle( "itemMargins: 1,2,3,4" );
|
||||||
|
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||||
|
ui.applyStyle( "selectionEmbeddedInsets: 1,2,3,4" );
|
||||||
|
ui.applyStyle( "selectionArc: 8" );
|
||||||
ui.applyStyle( "hoverBackground: #fff" );
|
ui.applyStyle( "hoverBackground: #fff" );
|
||||||
ui.applyStyle( "selectionBackground: #fff" );
|
ui.applyStyle( "selectionBackground: #fff" );
|
||||||
ui.applyStyle( "selectionForeground: #fff" );
|
ui.applyStyle( "selectionForeground: #fff" );
|
||||||
@@ -523,6 +531,9 @@ public class TestFlatStyling
|
|||||||
applyStyle.accept( "checkBackground: #fff" );
|
applyStyle.accept( "checkBackground: #fff" );
|
||||||
applyStyle.accept( "checkMargins: 1,2,3,4" );
|
applyStyle.accept( "checkMargins: 1,2,3,4" );
|
||||||
|
|
||||||
|
applyStyle.accept( "selectionInsets: 1,2,3,4" );
|
||||||
|
applyStyle.accept( "selectionArc: 8" );
|
||||||
|
|
||||||
applyStyle.accept( "underlineSelectionBackground: #fff" );
|
applyStyle.accept( "underlineSelectionBackground: #fff" );
|
||||||
applyStyle.accept( "underlineSelectionCheckBackground: #fff" );
|
applyStyle.accept( "underlineSelectionCheckBackground: #fff" );
|
||||||
applyStyle.accept( "underlineSelectionColor: #fff" );
|
applyStyle.accept( "underlineSelectionColor: #fff" );
|
||||||
@@ -1102,6 +1113,8 @@ public class TestFlatStyling
|
|||||||
|
|
||||||
ui.applyStyle( "focusableButtons: true" );
|
ui.applyStyle( "focusableButtons: true" );
|
||||||
ui.applyStyle( "arrowKeysOnlyNavigation: true" );
|
ui.applyStyle( "arrowKeysOnlyNavigation: true" );
|
||||||
|
ui.applyStyle( "hoverButtonGroupArc: 12" );
|
||||||
|
ui.applyStyle( "hoverButtonGroupBackground: #fff" );
|
||||||
|
|
||||||
ui.applyStyle( "borderMargins: 1,2,3,4" );
|
ui.applyStyle( "borderMargins: 1,2,3,4" );
|
||||||
ui.applyStyle( "gripColor: #fff" );
|
ui.applyStyle( "gripColor: #fff" );
|
||||||
@@ -1137,6 +1150,8 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "selectionInactiveBackground: #fff" );
|
ui.applyStyle( "selectionInactiveBackground: #fff" );
|
||||||
ui.applyStyle( "selectionInactiveForeground: #fff" );
|
ui.applyStyle( "selectionInactiveForeground: #fff" );
|
||||||
ui.applyStyle( "selectionBorderColor: #fff" );
|
ui.applyStyle( "selectionBorderColor: #fff" );
|
||||||
|
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||||
|
ui.applyStyle( "selectionArc: 8" );
|
||||||
ui.applyStyle( "wideSelection: true" );
|
ui.applyStyle( "wideSelection: true" );
|
||||||
ui.applyStyle( "showCellFocusIndicator: true" );
|
ui.applyStyle( "showCellFocusIndicator: true" );
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import com.formdev.flatlaf.FlatSystemProperties;
|
|||||||
*/
|
*/
|
||||||
public class TestUtils
|
public class TestUtils
|
||||||
{
|
{
|
||||||
public static final float[] FACTORS = new float[] { 1f, 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 2.75f, 3f, 3.25f, 3.5f, 3.75f, 4f, 5f, 6f };
|
public static final float[] FACTORS = { 1f, 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 2.75f, 3f, 3.25f, 3.5f, 3.75f, 4f, 5f, 6f };
|
||||||
|
|
||||||
public static void setup( boolean withFocus ) {
|
public static void setup( boolean withFocus ) {
|
||||||
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
|
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public class TestColorFunctions
|
|||||||
{
|
{
|
||||||
@Test
|
@Test
|
||||||
void colorFunctions() {
|
void colorFunctions() {
|
||||||
|
// lighten, darken
|
||||||
assertEquals( new Color( 0xff6666 ), ColorFunctions.lighten( Color.red, 0.2f ) );
|
assertEquals( new Color( 0xff6666 ), ColorFunctions.lighten( Color.red, 0.2f ) );
|
||||||
assertEquals( new Color( 0x990000 ), ColorFunctions.darken( Color.red, 0.2f ) );
|
assertEquals( new Color( 0x990000 ), ColorFunctions.darken( Color.red, 0.2f ) );
|
||||||
|
|
||||||
@@ -38,6 +39,11 @@ public class TestColorFunctions
|
|||||||
assertEquals( new Color( 0xffaa00 ), ColorFunctions.spin( Color.red,40 ) );
|
assertEquals( new Color( 0xffaa00 ), ColorFunctions.spin( Color.red,40 ) );
|
||||||
assertEquals( new Color( 0xff00aa ), ColorFunctions.spin( Color.red,-40 ) );
|
assertEquals( new Color( 0xff00aa ), ColorFunctions.spin( Color.red,-40 ) );
|
||||||
|
|
||||||
|
// fade
|
||||||
|
assertEquals( new Color( 0x33ff0000, true ), ColorFunctions.fade( Color.red, 0.2f ) );
|
||||||
|
assertEquals( new Color( 0xccff0000, true ), ColorFunctions.fade( Color.red, 0.8f ) );
|
||||||
|
assertEquals( new Color( 0xccff0000, true ), ColorFunctions.fade( new Color( 0x10ff0000, true ), 0.8f ) );
|
||||||
|
|
||||||
// mix
|
// mix
|
||||||
assertEquals( new Color( 0x1ae600 ), ColorFunctions.mix( Color.red, Color.green, 0.1f ) );
|
assertEquals( new Color( 0x1ae600 ), ColorFunctions.mix( Color.red, Color.green, 0.1f ) );
|
||||||
assertEquals( new Color( 0x40bf00 ), ColorFunctions.mix( Color.red, Color.green, 0.25f ) );
|
assertEquals( new Color( 0x40bf00 ), ColorFunctions.mix( Color.red, Color.green, 0.25f ) );
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
|
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
|
||||||
<rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
|
<rect width="5" height="2" x="5.5" y="11.5" stroke="#FFF" stroke-linejoin="round"/>
|
||||||
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
|
<path stroke="#FFF" stroke-linejoin="round" d="M2.5,7.5 L8,2 L13.5,7.5 L10.5,7.5 L10.5,9.5 L5.5,9.5 L5.5,7.5 L2.5,7.5 Z"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 408 B |
@@ -1,10 +1,12 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="2" height="2" x="2" y="3" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="3" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="2" height="2" x="2" y="7" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="6" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="2" height="2" x="2" y="11" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="9" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="3" fill="#6E6E6E"/>
|
<rect width="2" height="1" x="2" y="12" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="7" fill="#6E6E6E"/>
|
<rect width="8" height="1" x="6" y="3" fill="#6E6E6E" rx=".5"/>
|
||||||
<rect width="8" height="2" x="6" y="11" fill="#6E6E6E"/>
|
<rect width="8" height="1" x="6" y="6" fill="#6E6E6E" rx=".5"/>
|
||||||
|
<rect width="8" height="1" x="6" y="9" fill="#6E6E6E" rx=".5"/>
|
||||||
|
<rect width="8" height="1" x="6" y="12" fill="#6E6E6E" rx=".5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 498 B After Width: | Height: | Size: 682 B |
@@ -1,3 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<polygon fill="#6E6E6E" fill-rule="evenodd" points="2 8 8 2 14 8 12 8 12 13 9 13 9 10 7 10 7 13 4 13 4 8"/>
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<polyline stroke="#6E6E6E" stroke-linejoin="round" points="6.5 13 6.5 9.5 9.5 9.5 9.5 13"/>
|
||||||
|
<path stroke="#6E6E6E" d="M3.5,6.5 L3.5,12.5 C3.5,13.0522847 3.94771525,13.5 4.5,13.5 L11.5,13.5 C12.0522847,13.5 12.5,13.0522847 12.5,12.5 L12.5,6.5 L12.5,6.5"/>
|
||||||
|
<polyline stroke="#6E6E6E" stroke-linecap="round" stroke-linejoin="round" points="1.5 8.5 8 2 14.5 8.5"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 509 B |
@@ -1,8 +1,8 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="4" height="4" x="3" y="3" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="2.5" y="2.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="3" y="9" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="2.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="9" y="9" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="9.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
<rect width="4" height="4" x="9" y="3" fill="#6E6E6E"/>
|
<rect width="4" height="4" x="9.5" y="2.5" stroke="#6E6E6E" rx="1.5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 376 B After Width: | Height: | Size: 436 B |
@@ -1,6 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#6E6E6E" points="2 3 5.5 3 7 5 14 5 14 8 11 8 11 10 9 10 9 13 2 13"/>
|
<path stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
<path fill="#59A869" d="M14,11 L16,11 L16,13 L14,13 L14,15 L12,15 L12,13 L10,13 L10,11 L12,11 L12,9 L14,9 L14,11 Z"/>
|
<line x1="5.5" x2="10.5" y1="9" y2="9" stroke="#59A869" stroke-linecap="round"/>
|
||||||
|
<line x1="8" x2="8" y1="6.5" y2="11.5" stroke="#59A869" stroke-linecap="round"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 632 B |
@@ -1,6 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<polygon fill="#6E6E6E" points="2 3 5.5 3 7 5 9 5 9 9 13 9 13 5 14 5 14 13 2 13"/>
|
<path stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
<path fill="#389FD6" d="M12,4 L12,8 L10,8 L10,4 L8,4 L11,1 L14,4 L12,4 Z"/>
|
<line x1="8" x2="8" y1="6.5" y2="11.5" stroke="#389FD6" stroke-linecap="round"/>
|
||||||
|
<polyline stroke="#389FD6" stroke-linecap="round" stroke-linejoin="round" points="5.5 9 8 6.5 10.5 9"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 303 B After Width: | Height: | Size: 655 B |
@@ -1,6 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<path fill="#6E6E6E" d="M2,3 L14,3 L14,11 L2,11 L2,3 Z M4,5 L4,9 L12,9 L12,5 L4,5 Z"/>
|
<rect width="11" height="7" x="2.5" y="3.5" stroke="#6E6E6E" rx="1"/>
|
||||||
<rect width="12" height="2" x="2" y="12" fill="#6E6E6E"/>
|
<line x1="8" x2="8" y1="11" y2="12" stroke="#6E6E6E"/>
|
||||||
|
<line x1="4.5" x2="11.5" y1="12.5" y2="12.5" stroke="#6E6E6E" stroke-linecap="round"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 289 B After Width: | Height: | Size: 360 B |
@@ -1,3 +1,3 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<polygon fill="#6E6E6E" fill-rule="evenodd" points="1 2 6 2 8 4 15 4 15 13 1 13"/>
|
<path fill="none" stroke="#6E6E6E" d="M13,13.5 L3,13.5 C2.17157288,13.5 1.5,12.8284271 1.5,12 L1.5,4 C1.5,3.17157288 2.17157288,2.5 3,2.5 L6.29289322,2.5 C6.42550146,2.5 6.55267842,2.55267842 6.64644661,2.64644661 L8.5,4.5 L8.5,4.5 L13,4.5 C13.8284271,4.5 14.5,5.17157288 14.5,6 L14.5,12 C14.5,12.8284271 13.8284271,13.5 13,13.5 Z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 176 B After Width: | Height: | Size: 427 B |
@@ -1,6 +1,6 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||||
<polygon fill="#6E6E6E" points="8 6 8 1 13 1 13 15 3 15 3 6"/>
|
<path stroke="#6E6E6E" d="M4,1.5 L8.8,1.5 L8.8,1.5 L13.5,6.2 L13.5,13 C13.5,13.8284271 12.8284271,14.5 12,14.5 L4,14.5 C3.17157288,14.5 2.5,13.8284271 2.5,13 L2.5,3 C2.5,2.17157288 3.17157288,1.5 4,1.5 Z"/>
|
||||||
<polygon fill="#6E6E6E" points="3 5 7 5 7 1"/>
|
<path stroke="#6E6E6E" d="M8.5,2 L8.5,5 C8.5,5.82842712 9.17157288,6.5 10,6.5 L13,6.5 L13,6.5"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 472 B |
@@ -1,6 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||||
<path fill="#6E6E6E" d="M11,14 L11,11 L5,11 L5,14 L2,14 L2,2 L14,2 L14,14 L11,14 Z M4,4 L4,8 L12,8 L12,4 L4,4 Z"/>
|
<path stroke="#6E6E6E" d="M3.5,2.5 L11.5,2.5 L11.5,2.5 L13.5,4.5 L13.5,12.5 C13.5,13.0522847 13.0522847,13.5 12.5,13.5 L3.5,13.5 C2.94771525,13.5 2.5,13.0522847 2.5,12.5 L2.5,3.5 C2.5,2.94771525 2.94771525,2.5 3.5,2.5 Z"/>
|
||||||
<rect width="4" height="2" x="6" y="12" fill="#6E6E6E"/>
|
<polyline stroke="#6E6E6E" points="4.5 13 4.5 9.5 11.5 9.5 11.5 13"/>
|
||||||
|
<polyline stroke="#6E6E6E" points="5.5 3 5.5 5.5 10.5 5.5 10.5 3"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 316 B After Width: | Height: | Size: 533 B |
@@ -1,3 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||||
<path fill="#6E6E6E" fill-rule="evenodd" d="M2,6 L14,6 L14,10 L2,10 L2,6 Z M12,8 L12,9 L13,9 L13,8 L12,8 Z M10,8 L10,9 L11,9 L11,8 L10,8 Z"/>
|
<g fill="none" fill-rule="evenodd">
|
||||||
|
<rect width="11" height="5" x="2.5" y="5.5" stroke="#6E6E6E" rx="1"/>
|
||||||
|
<circle cx="11.5" cy="8.5" r="1" fill="#6E6E6E"/>
|
||||||
|
<circle cx="9.5" cy="8.5" r="1" fill="#6E6E6E"/>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 317 B |
@@ -6,7 +6,7 @@
|
|||||||
</linearGradient>
|
</linearGradient>
|
||||||
</defs>
|
</defs>
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<rect width="16" height="16" fill="url(#flatlaf-a)"/>
|
<rect width="16" height="16" fill="url(#flatlaf-a)" rx="2"/>
|
||||||
<polygon fill="#FFF" points="9 13 13 13 12.5 11.5 10.5 11.5 10.5 6.5 9 6"/>
|
<polygon fill="#FFF" points="9 13 13 13 12.5 11.5 10.5 11.5 10.5 6.5 9 6"/>
|
||||||
<polygon fill="#FFF" points="4 12.5 4 3 9 3 8.5 4.5 5.5 4.5 5.5 7 7.5 7 7 8.5 5.5 8.5 5.5 12"/>
|
<polygon fill="#FFF" points="4 12.5 4 3 9 3 8.5 4.5 5.5 4.5 5.5 7 7.5 7 7 8.5 5.5 8.5 5.5 12"/>
|
||||||
</g>
|
</g>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 583 B After Width: | Height: | Size: 590 B |
@@ -2,6 +2,7 @@
|
|||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="11" cy="11" r="10.5" fill="#6E6E6E"/>
|
<circle cx="11" cy="11" r="10.5" fill="#6E6E6E"/>
|
||||||
<circle cx="11" cy="11" r="9.5" fill="#FFF"/>
|
<circle cx="11" cy="11" r="9.5" fill="#FFF"/>
|
||||||
<path fill="#6E6E6E" d="M10,17 L12,17 L12,15 L10,15 L10,17 Z M11,5 C8.8,5 7,6.8 7,9 L9,9 C9,7.9 9.9,7 11,7 C12.1,7 13,7.9 13,9 C13,11 10,10.75 10,14 L12,14 C12,11.75 15,11.5 15,9 C15,6.8 13.2,5 11,5 Z"/>
|
<path stroke="#6E6E6E" stroke-linecap="round" stroke-width="2" d="M8,8.5 C8.25,7 9.66585007,6 11,6 C12.5,6 14,7 14,8.5 C14,10.5 11,11 11,13"/>
|
||||||
|
<circle cx="11" cy="16" r="1.2" fill="#6E6E6E"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 448 B After Width: | Height: | Size: 440 B |
@@ -1,7 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#DB5860"/>
|
<circle cx="16" cy="16" r="14" fill="#DB5860"/>
|
||||||
<rect width="4" height="11" x="14" y="7" fill="#FFF"/>
|
<rect width="4" height="12" x="14" y="7" fill="#FFF" rx="2"/>
|
||||||
<rect width="4" height="4" x="14" y="21" fill="#FFF"/>
|
<circle cx="16" cy="23" r="2" fill="#FFF"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 302 B |
@@ -1,7 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
||||||
<rect width="4" height="11" x="14" y="14" fill="#FFF"/>
|
<rect width="4" height="12" x="14" y="13" fill="#FFF" rx="2"/>
|
||||||
<rect width="4" height="4" x="14" y="7" fill="#FFF"/>
|
<circle cx="16" cy="9" r="2" fill="#FFF"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 302 B |
@@ -1,7 +1,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
<g fill="none" fill-rule="evenodd">
|
<g fill="none" fill-rule="evenodd">
|
||||||
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
||||||
<rect width="4" height="4" x="14" y="22" fill="#FFF"/>
|
<circle cx="16" cy="24" r="1.7" fill="#FFF"/>
|
||||||
<path fill="#FFF" d="M14,20 C14,20 18,20 18,20 C18,16 23,16 23,12 C23,8 20,6 16,6 C12,6 9,8 9,12 C9,12 13,12 13,12 C13,10 14,9 16,9 C18,9 19,10 19,12 C19,15 14,15 14,20 Z"/>
|
<path stroke="#FFF" stroke-linecap="round" stroke-width="3" d="M11.5,11.75 C11.75,9.5 13.75,8 16,8 C18.25,8 20.5,9.5 20.5,11.75 C20.5,14.75 16,15.5 16,19"/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 399 B |