Compare commits
118 Commits
2.5
...
fonts/robo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e34b5eafe1 | ||
|
|
4e1e749094 | ||
|
|
ede9293377 | ||
|
|
9101324a1f | ||
|
|
4b844353ee | ||
|
|
2134c19c58 | ||
|
|
c974784ebb | ||
|
|
5eb6961023 | ||
|
|
07cbd8b97b | ||
|
|
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
|
||||
*.jar binary
|
||||
*.lib binary
|
||||
*.otf binary
|
||||
*.png binary
|
||||
*.sketch binary
|
||||
*.so binary
|
||||
*.ttf 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
|
||||
|
||||
@@ -8,9 +9,6 @@ on:
|
||||
- '*'
|
||||
tags:
|
||||
- '[0-9]*'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -26,6 +24,10 @@ jobs:
|
||||
- 8
|
||||
- 11 # LTS
|
||||
- 17 # LTS
|
||||
toolchain: [""]
|
||||
include:
|
||||
- java: 17
|
||||
toolchain: 19 # latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -41,7 +43,7 @@ jobs:
|
||||
cache: gradle
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
run: ./gradlew build -Dtoolchain=${{ matrix.toolchain }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
@@ -50,6 +52,7 @@ jobs:
|
||||
name: FlatLaf-build-artifacts
|
||||
path: |
|
||||
flatlaf-*/build/libs
|
||||
flatlaf-*/flatlaf-*/build/libs
|
||||
!**/*-javadoc.jar
|
||||
!**/*-sources.jar
|
||||
|
||||
@@ -73,7 +76,7 @@ jobs:
|
||||
cache: gradle
|
||||
|
||||
- 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:
|
||||
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||
@@ -109,7 +112,7 @@ jobs:
|
||||
cache: gradle
|
||||
|
||||
- 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:
|
||||
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||
|
||||
60
.github/workflows/fonts.yml
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
# 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
|
||||
- roboto-mono
|
||||
|
||||
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
|
||||
|
||||
@@ -12,13 +13,6 @@ on:
|
||||
- 'flatlaf-natives/**'
|
||||
- '.github/workflows/natives.yml'
|
||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- 'flatlaf-natives/**'
|
||||
- '.github/workflows/natives.yml'
|
||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||
|
||||
jobs:
|
||||
Natives:
|
||||
|
||||
2
.gitignore
vendored
@@ -9,5 +9,7 @@ out/
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
*.xcuserstate
|
||||
*.xcworkspacedata
|
||||
.vs/
|
||||
.vscode/
|
||||
|
||||
84
CHANGELOG.md
@@ -1,6 +1,90 @@
|
||||
FlatLaf Change Log
|
||||
==================
|
||||
|
||||
## 3.1-SNAPSHOT
|
||||
|
||||
#### New features and improvements
|
||||
|
||||
- Fonts: Added **Roboto
|
||||
Mono** (https://fonts.google.com/specimen/Roboto+Mono). (PR #639, issue #638)
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- FlatLaf window decorations:
|
||||
- Fixed inconsistent size of glass pane depending on whether FlatLaf window
|
||||
decorations are used (e.g. Windows 10/11) or not (e.g. macOS). Now the glass
|
||||
pane no longer overlaps the FlatLaf window title bar. (issue #630)
|
||||
- Linux: Fixed broken window resizing on multi-screen setups. (issue #632)
|
||||
- IntelliJ Themes:
|
||||
- Fixed default button hover background in "Solarized Light" theme. (issue
|
||||
#628)
|
||||
- Avoid that accent color affect some colors in some IntelliJ themes. (issue
|
||||
#625)
|
||||
|
||||
|
||||
## 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
|
||||
|
||||
#### New features and improvements
|
||||
|
||||
90
README.md
@@ -15,6 +15,11 @@ IntelliJ IDEA 2019.2+ and uses almost the same colors and icons.
|
||||
|
||||

|
||||
|
||||
macOS Themes
|
||||
------------
|
||||
|
||||

|
||||
|
||||
|
||||
IntelliJ Platform Themes
|
||||
------------------------
|
||||
@@ -25,6 +30,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
|
||||
----
|
||||
|
||||
@@ -74,6 +90,8 @@ Addons
|
||||
- [SwingX](flatlaf-swingx) - support for SwingX components
|
||||
- [JIDE Common Layer](flatlaf-jide-oss) - support for JIDE Common Layer
|
||||
components
|
||||
- [Fonts](flatlaf-fonts) - some font families bundled in easy-to-use and
|
||||
redistributable JARs
|
||||
|
||||
|
||||
Getting started
|
||||
@@ -126,42 +144,64 @@ Buzz
|
||||
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
|
||||
-  [MooInfo](https://github.com/rememberber/MooInfo) -
|
||||
visual implementation of OSHI, to view information about the system and
|
||||
hardware
|
||||
-  [Jailer](https://github.com/Wisser/Jailer) 11.2 -
|
||||
database subsetting and relational data browsing tool
|
||||
- [Apache NetBeans](https://netbeans.apache.org/) 11.3 - IDE for Java, PHP, HTML
|
||||
and much more
|
||||
- [MooInfo](https://github.com/rememberber/MooInfo) - visual implementation of
|
||||
OSHI, to view information about the system and hardware
|
||||
- [Jailer](https://github.com/Wisser/Jailer) 11.2 - database subsetting and
|
||||
relational data browsing tool
|
||||
-  [Apache NetBeans](https://netbeans.apache.org/) 11.3 -
|
||||
IDE for Java, PHP, HTML and much more
|
||||
- [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) 5.5
|
||||
- [KeyStore Explorer](https://keystore-explorer.org/) 5.4.3
|
||||
- 
|
||||
- 
|
||||
[install4j](https://www.ej-technologies.com/products/install4j/overview.html)
|
||||
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
|
||||
DBAs
|
||||
-  [MagicPlot](https://magicplot.com/) 3.0
|
||||
-  [MagicPlot](https://magicplot.com/) 3.0
|
||||
(**commercial**) - Software for nonlinear fitting, plotting and data analysis
|
||||
- 
|
||||
- 
|
||||
[Thermo-Calc](https://thermocalc.com/products/thermo-calc/) 2021a
|
||||
(**commercial**) - Thermodynamics and Properties Software
|
||||
- [OWASP ZAP](https://www.zaproxy.org/) 2.10 - the worlds most widely used web
|
||||
app scanner
|
||||
- 
|
||||
-  [OWASP ZAP](https://www.zaproxy.org/) 2.10 - the worlds
|
||||
most widely used web app scanner
|
||||
- 
|
||||
[Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro)
|
||||
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
|
||||
- [JOSM](https://josm.openstreetmap.de/) - an extensible editor for
|
||||
[OpenStreetMap](https://www.openstreetmap.org/) (requires FlatLaf JOSM plugin)
|
||||
- [jAlbum](https://jalbum.net/) 21 (**commercial**) - creates photo album
|
||||
websites
|
||||
-  [PDF Studio](https://www.qoppa.com/pdfstudio/) 2021
|
||||
(**commercial**) - create, review and edit PDF documents
|
||||
-  [JOSM](https://josm.openstreetmap.de/) - an extensible
|
||||
editor for [OpenStreetMap](https://www.openstreetmap.org/) (requires FlatLaf
|
||||
JOSM plugin)
|
||||
-  [jAlbum](https://jalbum.net/) 21 (**commercial**) -
|
||||
creates photo album websites
|
||||
- [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**)
|
||||
- [Total Validator](https://www.totalvalidator.com/) 15 (**commercial**) -
|
||||
checks your website
|
||||
@@ -187,8 +227,8 @@ Applications using FlatLaf
|
||||
[mendelson AS2](https://mendelson-e-c.com/as2/),
|
||||
[AS4](https://mendelson-e-c.com/as4/) and
|
||||
[OFTP2](https://mendelson-e-c.com/oftp2) (**commercial**)
|
||||
-  [IGMAS+](https://www.gfz-potsdam.de/igmas) -
|
||||
Interactive Gravity and Magnetic Application System
|
||||
- [IGMAS+](https://www.gfz-potsdam.de/igmas) - Interactive Gravity and Magnetic
|
||||
Application System
|
||||
- [MeteoInfo](https://github.com/meteoinfo/MeteoInfo) 2.2 - GIS and scientific
|
||||
computation environment for meteorological community
|
||||
- [lsfusion platform](https://github.com/lsfusion/platform) 4 - information
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
val releaseVersion = "2.5"
|
||||
val developmentVersion = "3.0-SNAPSHOT"
|
||||
val releaseVersion = "3.0"
|
||||
val developmentVersion = "3.1-SNAPSHOT"
|
||||
|
||||
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
||||
version = if( rootProject.hasProperty( "release" ) ) releaseVersion else developmentVersion
|
||||
|
||||
allprojects {
|
||||
version = rootProject.version
|
||||
@@ -37,6 +37,9 @@ println( "----------------------------------------------------------------------
|
||||
println( "FlatLaf Version: ${version}" )
|
||||
println( "Gradle ${gradle.gradleVersion} at ${gradle.gradleHomeDir}" )
|
||||
println( "Java ${System.getProperty( "java.version" )}" )
|
||||
val toolchainJavaVersion = System.getProperty( "toolchain" )
|
||||
if( !toolchainJavaVersion.isNullOrEmpty() )
|
||||
println( "Java toolchain ${toolchainJavaVersion}" )
|
||||
println()
|
||||
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ publishing {
|
||||
|
||||
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
||||
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 {
|
||||
// get from gradle.properties
|
||||
@@ -108,5 +108,5 @@ signing {
|
||||
|
||||
// disable signing of snapshots
|
||||
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 {
|
||||
`java-library`
|
||||
`flatlaf-toolchain`
|
||||
`flatlaf-module-info`
|
||||
`flatlaf-java9`
|
||||
`flatlaf-publish`
|
||||
@@ -86,7 +87,7 @@ tasks {
|
||||
"action" to "generate",
|
||||
"fileName" to "${project.name}-sigtest.txt",
|
||||
"classpath" to jar.get().outputs.files.asPath,
|
||||
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.util",
|
||||
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.themes,com.formdev.flatlaf.util",
|
||||
"version" to version,
|
||||
"release" to "1.8", // Java version
|
||||
"failonerror" to "true" )
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Signature file v4.1
|
||||
#Version 2.4
|
||||
#Version 3.0
|
||||
|
||||
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
||||
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 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_TITLE_BAR_CAPTION = "JComponent.titleBarCaption"
|
||||
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_WIDTH = "JComponent.minimumWidth"
|
||||
@@ -85,7 +86,11 @@ fld public final static java.lang.String TEXT_FIELD_TRAILING_COMPONENT = "JTextF
|
||||
fld public final static java.lang.String TEXT_FIELD_TRAILING_ICON = "JTextField.trailingIcon"
|
||||
fld public final static java.lang.String TITLE_BAR_BACKGROUND = "JRootPane.titleBarBackground"
|
||||
fld public final static java.lang.String TITLE_BAR_FOREGROUND = "JRootPane.titleBarForeground"
|
||||
fld public final static java.lang.String TITLE_BAR_SHOW_CLOSE = "JRootPane.titleBarShowClose"
|
||||
fld public final static java.lang.String TITLE_BAR_SHOW_ICON = "JRootPane.titleBarShowIcon"
|
||||
fld public final static java.lang.String TITLE_BAR_SHOW_ICONIFFY = "JRootPane.titleBarShowIconify"
|
||||
fld public final static java.lang.String TITLE_BAR_SHOW_MAXIMIZE = "JRootPane.titleBarShowMaximize"
|
||||
fld public final static java.lang.String TITLE_BAR_SHOW_TITLE = "JRootPane.titleBarShowTitle"
|
||||
fld public final static java.lang.String TREE_PAINT_SELECTION = "JTree.paintSelection"
|
||||
fld public final static java.lang.String TREE_WIDE_SELECTION = "JTree.wideSelection"
|
||||
fld public final static java.lang.String USE_WINDOW_DECORATIONS = "JRootPane.useWindowDecorations"
|
||||
@@ -185,6 +190,7 @@ meth public java.lang.String getID()
|
||||
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.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)
|
||||
anno 0 java.lang.Deprecated()
|
||||
meth public static boolean isLafDark()
|
||||
@@ -193,7 +199,13 @@ meth public static boolean isUseNativeWindowDecorations()
|
||||
meth public static boolean setup(javax.swing.LookAndFeel)
|
||||
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.String getPreferredFontFamily()
|
||||
meth public static java.lang.String getPreferredLightFontFamily()
|
||||
meth public static java.lang.String getPreferredMonospacedFontFamily()
|
||||
meth public static java.lang.String getPreferredSemiboldFontFamily()
|
||||
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.function.Function<java.lang.String,java.awt.Color> getSystemColorGetter()
|
||||
meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float)
|
||||
meth public static void hideMnemonics()
|
||||
meth public static void initIconColors(javax.swing.UIDefaults,boolean)
|
||||
@@ -206,6 +218,11 @@ meth public static void repaintAllFramesAndDialogs()
|
||||
meth public static void revalidateAndRepaintAllFramesAndDialogs()
|
||||
meth public static void runWithUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>,java.lang.Runnable)
|
||||
meth public static void setGlobalExtraDefaults(java.util.Map<java.lang.String,java.lang.String>)
|
||||
meth public static void setPreferredFontFamily(java.lang.String)
|
||||
meth public static void setPreferredLightFontFamily(java.lang.String)
|
||||
meth public static void setPreferredMonospacedFontFamily(java.lang.String)
|
||||
meth public static void setPreferredSemiboldFontFamily(java.lang.String)
|
||||
meth public static void setSystemColorGetter(java.util.function.Function<java.lang.String,java.awt.Color>)
|
||||
meth public static void setUseNativeWindowDecorations(boolean)
|
||||
meth public static void showMnemonics(java.awt.Component)
|
||||
meth public static void unregisterCustomDefaultsSource(java.io.File)
|
||||
@@ -220,7 +237,7 @@ meth public void setExtraDefaults(java.util.Map<java.lang.String,java.lang.Strin
|
||||
meth public void uninitialize()
|
||||
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
||||
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,preferredFontFamily,preferredLightFontFamily,preferredMonospacedFontFamily,preferredSemiboldFontFamily,subMenuUsabilityHelperInstalled,systemColorGetter,uiDefaultsGetters,updateUIPending
|
||||
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
|
||||
|
||||
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
|
||||
@@ -259,6 +276,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_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 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_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection"
|
||||
fld public final static java.lang.String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont"
|
||||
@@ -291,6 +309,26 @@ meth public java.lang.String getName()
|
||||
supr com.formdev.flatlaf.FlatLaf
|
||||
hfds theme
|
||||
|
||||
CLSS public com.formdev.flatlaf.themes.FlatMacDarkLaf
|
||||
cons public init()
|
||||
fld public final static java.lang.String NAME = "FlatLaf macOS Dark"
|
||||
meth public boolean isDark()
|
||||
meth public java.lang.String getDescription()
|
||||
meth public java.lang.String getName()
|
||||
meth public static boolean setup()
|
||||
meth public static void installLafInfo()
|
||||
supr com.formdev.flatlaf.FlatDarkLaf
|
||||
|
||||
CLSS public com.formdev.flatlaf.themes.FlatMacLightLaf
|
||||
cons public init()
|
||||
fld public final static java.lang.String NAME = "FlatLaf macOS Light"
|
||||
meth public boolean isDark()
|
||||
meth public java.lang.String getDescription()
|
||||
meth public java.lang.String getName()
|
||||
meth public static boolean setup()
|
||||
meth public static void installLafInfo()
|
||||
supr com.formdev.flatlaf.FlatLightLaf
|
||||
|
||||
CLSS public abstract interface com.formdev.flatlaf.util.AnimatedIcon
|
||||
innr public static AnimationSupport
|
||||
intf javax.swing.Icon
|
||||
@@ -358,6 +396,7 @@ meth public static float clamp(float)
|
||||
meth public static float luma(java.awt.Color)
|
||||
meth public static java.awt.Color darken(java.awt.Color,float)
|
||||
meth public static java.awt.Color desaturate(java.awt.Color,float)
|
||||
meth public static java.awt.Color fade(java.awt.Color,float)
|
||||
meth public static java.awt.Color lighten(java.awt.Color,float)
|
||||
meth public static java.awt.Color mix(java.awt.Color,java.awt.Color,float)
|
||||
meth public static java.awt.Color saturate(java.awt.Color,float)
|
||||
@@ -433,6 +472,17 @@ meth public java.lang.String toString()
|
||||
supr javax.swing.plaf.ColorUIResource
|
||||
hfds baseOfDefaultColorRGB,functions,hasBaseOfDefaultColor
|
||||
|
||||
CLSS public com.formdev.flatlaf.util.FontUtils
|
||||
cons public init()
|
||||
meth public static boolean installFont(java.net.URL)
|
||||
meth public static java.awt.Font getCompositeFont(java.lang.String,int,int)
|
||||
meth public static java.awt.Font[] getAllFonts()
|
||||
meth public static java.lang.String[] getAvailableFontFamilyNames()
|
||||
meth public static void loadFontFamily(java.lang.String)
|
||||
meth public static void registerFontFamilyLoader(java.lang.String,java.lang.Runnable)
|
||||
supr java.lang.Object
|
||||
hfds loadersMap
|
||||
|
||||
CLSS public com.formdev.flatlaf.util.Graphics2DProxy
|
||||
cons public init(java.awt.Graphics2D)
|
||||
meth public boolean drawImage(java.awt.Image,int,int,int,int,int,int,int,int,java.awt.Color,java.awt.image.ImageObserver)
|
||||
@@ -569,7 +619,7 @@ meth public static void drawStringWithYCorrection(javax.swing.JComponent,java.aw
|
||||
meth public static void paintAtScale1x(java.awt.Graphics2D,int,int,int,int,com.formdev.flatlaf.util.HiDPIUtils$Painter)
|
||||
meth public static void paintAtScale1x(java.awt.Graphics2D,javax.swing.JComponent,com.formdev.flatlaf.util.HiDPIUtils$Painter)
|
||||
supr java.lang.Object
|
||||
hfds useTextYCorrection
|
||||
hfds CORRECTION_INTER,CORRECTION_OPEN_SANS,CORRECTION_SEGOE_UI,CORRECTION_TAHOMA,SCALE_FACTORS,useDebugScaleFactor,useTextYCorrection
|
||||
|
||||
CLSS public abstract interface static com.formdev.flatlaf.util.HiDPIUtils$Painter
|
||||
outer com.formdev.flatlaf.util.HiDPIUtils
|
||||
@@ -600,6 +650,7 @@ supr java.lang.Object
|
||||
|
||||
CLSS public com.formdev.flatlaf.util.NativeLibrary
|
||||
cons public init(java.io.File,boolean)
|
||||
cons public init(java.lang.String,boolean)
|
||||
cons public init(java.lang.String,java.lang.ClassLoader,boolean)
|
||||
meth public boolean isLoaded()
|
||||
supr java.lang.Object
|
||||
|
||||
@@ -346,7 +346,7 @@ public interface FlatClientProperties
|
||||
|
||||
/**
|
||||
* 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>
|
||||
* Setting this shows/hides the windows icon
|
||||
* 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";
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* <p>
|
||||
@@ -386,6 +442,17 @@ public interface FlatClientProperties
|
||||
*/
|
||||
String TITLE_BAR_FOREGROUND = "JRootPane.titleBarForeground";
|
||||
|
||||
/**
|
||||
* Specifies whether the glass pane should have full height and overlap the title bar,
|
||||
* if FlatLaf window decorations are enabled. Default is {@code false}.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
String GLASS_PANE_FULL_HEIGHT = "JRootPane.glassPaneFullHeight";
|
||||
|
||||
//---- JScrollBar / JScrollPane -------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -78,6 +78,7 @@ import com.formdev.flatlaf.ui.FlatPopupFactory;
|
||||
import com.formdev.flatlaf.ui.FlatRootPaneUI;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.FontUtils;
|
||||
import com.formdev.flatlaf.util.GrayFilter;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
||||
@@ -98,6 +99,7 @@ public abstract class FlatLaf
|
||||
private static List<Object> customDefaultsSources;
|
||||
private static Map<String, String> globalExtraDefaults;
|
||||
private Map<String, String> extraDefaults;
|
||||
private static Function<String, Color> systemColorGetter;
|
||||
|
||||
private String desktopPropertyName;
|
||||
private String desktopPropertyName2;
|
||||
@@ -113,6 +115,11 @@ public abstract class FlatLaf
|
||||
private Consumer<UIDefaults> postInitialization;
|
||||
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
|
||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||
@@ -630,6 +637,13 @@ public abstract class FlatLaf
|
||||
if( uiFont == null )
|
||||
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
|
||||
// (use remove() to avoid that ActiveFont.createValue() gets invoked)
|
||||
Object defaultFont = defaults.remove( "defaultFont" );
|
||||
@@ -650,6 +664,9 @@ public abstract class FlatLaf
|
||||
}
|
||||
|
||||
static FontUIResource createCompositeFont( String family, int style, int size ) {
|
||||
// load lazy font family
|
||||
FontUtils.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
|
||||
@@ -897,14 +914,14 @@ public abstract class FlatLaf
|
||||
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
||||
* <p>
|
||||
* 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)}.
|
||||
* <p>
|
||||
* The keys and values are strings in same format as in FlatLaf properties files.
|
||||
* <p>
|
||||
* Sample that setups "FlatLaf Light" theme with red accent color:
|
||||
* Sample that setups "FlatLaf Light" theme with white background color:
|
||||
* <pre>{@code
|
||||
* FlatLaf.setGlobalExtraDefaults( Collections.singletonMap( "@accentColor", "#f00" ) );
|
||||
* FlatLaf.setGlobalExtraDefaults( Collections.singletonMap( "@background", "#fff" ) );
|
||||
* FlatLightLaf.setup();
|
||||
* }</pre>
|
||||
*
|
||||
@@ -929,15 +946,15 @@ public abstract class FlatLaf
|
||||
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
||||
* <p>
|
||||
* 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)}.
|
||||
* <p>
|
||||
* The keys and values are strings in same format as in FlatLaf properties files.
|
||||
* <p>
|
||||
* Sample that setups "FlatLaf Light" theme with red accent color:
|
||||
* Sample that setups "FlatLaf Light" theme with white background color:
|
||||
* <pre>{@code
|
||||
* FlatLaf laf = new FlatLightLaf();
|
||||
* laf.setExtraDefaults( Collections.singletonMap( "@accentColor", "#f00" ) );
|
||||
* laf.setExtraDefaults( Collections.singletonMap( "@background", "#fff" ) );
|
||||
* FlatLaf.setup( laf );
|
||||
* }</pre>
|
||||
*
|
||||
@@ -979,6 +996,36 @@ public abstract class FlatLaf
|
||||
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() {
|
||||
EventQueue.invokeLater( () -> {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
@@ -1292,6 +1339,90 @@ public abstract class FlatLaf
|
||||
private static boolean getUIMethodInitialized;
|
||||
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 -----------------------------------------------
|
||||
|
||||
private class FlatUIDefaults
|
||||
@@ -1426,9 +1557,16 @@ public abstract class FlatLaf
|
||||
|
||||
// create font for family
|
||||
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 ) {
|
||||
Font font = createCompositeFont( family, newStyle, newSize );
|
||||
if( !isFallbackFont( font ) || family.equalsIgnoreCase( Font.DIALOG ) )
|
||||
if( !isFallbackFont( font ) || isDialogFamily( family ) )
|
||||
return toUIResource( font );
|
||||
}
|
||||
}
|
||||
@@ -1457,9 +1595,26 @@ public abstract class FlatLaf
|
||||
: new FontUIResource( font );
|
||||
}
|
||||
|
||||
private boolean isFallbackFont( Font font ) {
|
||||
private static boolean isFallbackFont( Font font ) {
|
||||
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 ------------------------------------------
|
||||
|
||||
@@ -155,9 +155,19 @@ public interface FlatSystemProperties
|
||||
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.
|
||||
* 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
|
||||
*/
|
||||
|
||||
@@ -302,7 +302,7 @@ public class IntelliJTheme
|
||||
|
||||
for( Map.Entry<String, String> e : colors.entrySet() ) {
|
||||
String value = e.getValue();
|
||||
ColorUIResource color = UIDefaultsLoader.parseColor( value );
|
||||
ColorUIResource color = parseColor( value );
|
||||
if( color != null ) {
|
||||
String key = e.getKey();
|
||||
namedColors.put( key, color );
|
||||
@@ -448,7 +448,15 @@ public class IntelliJTheme
|
||||
ColorUIResource color = namedColors.get( value );
|
||||
|
||||
// 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
|
||||
// use opacity=".65" for the border
|
||||
// --> add alpha to focused border colors
|
||||
String[] focusedBorderColorKeys = new String[] {
|
||||
String[] focusedBorderColorKeys = {
|
||||
"CheckBox.icon.focusedBorderColor",
|
||||
"CheckBox.icon.focusedSelectedBorderColor",
|
||||
"CheckBox.icon[filled].focusedBorderColor",
|
||||
|
||||
@@ -84,6 +84,7 @@ class UIDefaultsLoader
|
||||
|
||||
private static int parseColorDepth;
|
||||
|
||||
private static Map<String, ColorUIResource> systemColorCache;
|
||||
private static final SoftCache<String, Object> fontCache = new SoftCache<>();
|
||||
|
||||
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
|
||||
@@ -105,6 +106,10 @@ class UIDefaultsLoader
|
||||
Properties additionalDefaults, boolean dark, UIDefaults defaults )
|
||||
{
|
||||
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
|
||||
Properties properties = new Properties();
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
@@ -276,6 +281,9 @@ class UIDefaultsLoader
|
||||
|
||||
// remember variables in defaults to allow using them in styles
|
||||
defaults.put( KEY_VARIABLES, variables );
|
||||
|
||||
// clear/disable system color cache
|
||||
systemColorCache = null;
|
||||
} catch( IOException ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load properties files.", ex );
|
||||
}
|
||||
@@ -525,14 +533,14 @@ class UIDefaultsLoader
|
||||
case STRING: return value;
|
||||
case BOOLEAN: return parseBoolean( value );
|
||||
case CHARACTER: return parseCharacter( value );
|
||||
case INTEGER: return parseInteger( value, true );
|
||||
case INTEGERORFLOAT:return parseIntegerOrFloat( value, true );
|
||||
case FLOAT: return parseFloat( value, true );
|
||||
case INTEGER: return parseInteger( value );
|
||||
case INTEGERORFLOAT:return parseIntegerOrFloat( value );
|
||||
case FLOAT: return parseFloat( value );
|
||||
case BORDER: return parseBorder( value, resolver, addonClassLoaders );
|
||||
case ICON: return parseInstance( value, addonClassLoaders );
|
||||
case INSETS: return parseInsets( 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 SCALEDINTEGER: return parseScaledInteger( value );
|
||||
case SCALEDFLOAT: return parseScaledFloat( value );
|
||||
@@ -550,24 +558,34 @@ class UIDefaultsLoader
|
||||
}
|
||||
|
||||
// colors
|
||||
Object color = parseColorOrFunction( value, resolver, false );
|
||||
if( color != null ) {
|
||||
resultValueType[0] = ValueType.COLOR;
|
||||
if( value.startsWith( "#" ) || value.endsWith( ")" ) ) {
|
||||
Object color = parseColorOrFunction( value, resolver );
|
||||
resultValueType[0] = (color != null) ? ValueType.COLOR : ValueType.NULL;
|
||||
return color;
|
||||
}
|
||||
|
||||
// integer
|
||||
Integer integer = parseInteger( value, false );
|
||||
if( integer != null ) {
|
||||
resultValueType[0] = ValueType.INTEGER;
|
||||
return integer;
|
||||
}
|
||||
// integer or float
|
||||
char firstChar = value.charAt( 0 );
|
||||
if( (firstChar >= '0' && firstChar <= '9') ||
|
||||
firstChar == '-' || firstChar == '+' || firstChar == '.' )
|
||||
{
|
||||
// integer
|
||||
try {
|
||||
Integer integer = parseInteger( value );
|
||||
resultValueType[0] = ValueType.INTEGER;
|
||||
return integer;
|
||||
} catch( NumberFormatException ex ) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// float
|
||||
Float f = parseFloat( value, false );
|
||||
if( f != null ) {
|
||||
resultValueType[0] = ValueType.FLOAT;
|
||||
return f;
|
||||
// float
|
||||
try {
|
||||
Float f = parseFloat( value );
|
||||
resultValueType[0] = ValueType.FLOAT;
|
||||
return f;
|
||||
} catch( NumberFormatException ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
// string
|
||||
@@ -596,10 +614,10 @@ class UIDefaultsLoader
|
||||
List<String> parts = splitFunctionParams( value, ',' );
|
||||
Insets insets = parseInsets( value );
|
||||
ColorUIResource lineColor = (parts.size() >= 5)
|
||||
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver, true )
|
||||
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver )
|
||||
: null;
|
||||
float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) ? parseFloat( parts.get( 5 ), true ) : 1f;
|
||||
int arc = (parts.size() >= 7) ? parseInteger( parts.get( 6 ), true ) : 0;
|
||||
float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) ? parseFloat( parts.get( 5 ) ) : 1f;
|
||||
int arc = (parts.size() >= 7) ? parseInteger( parts.get( 6 ) ) : 0;
|
||||
|
||||
return (LazyValue) t -> {
|
||||
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( ")" ) )
|
||||
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 ) {
|
||||
return parseColor( value, false );
|
||||
}
|
||||
|
||||
private static ColorUIResource parseColor( String value, boolean reportError ) {
|
||||
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;
|
||||
int rgba = parseColorRGBA( value );
|
||||
return ((rgba & 0xff000000) == 0xff000000)
|
||||
? new ColorUIResource( rgba )
|
||||
: new ColorUIResource( new Color( rgba, true ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -710,7 +722,7 @@ class UIDefaultsLoader
|
||||
static int parseColorRGBA( String value ) {
|
||||
int len = value.length();
|
||||
if( (len != 4 && len != 5 && len != 7 && len != 9) || value.charAt( 0 ) != '#' )
|
||||
throw new IllegalArgumentException();
|
||||
throw newInvalidColorException( value );
|
||||
|
||||
// parse hex
|
||||
int n = 0;
|
||||
@@ -725,7 +737,7 @@ class UIDefaultsLoader
|
||||
else if( ch >= 'A' && ch <= 'F' )
|
||||
digit = ch - 'A' + 10;
|
||||
else
|
||||
throw new IllegalArgumentException();
|
||||
throw newInvalidColorException( value );
|
||||
|
||||
n = (n << 4) | digit;
|
||||
}
|
||||
@@ -744,13 +756,14 @@ class UIDefaultsLoader
|
||||
: (((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( '(' );
|
||||
if( paramsStart < 0 ) {
|
||||
if( reportError )
|
||||
throw new IllegalArgumentException( "missing opening parenthesis in function '" + value + "'" );
|
||||
return null;
|
||||
}
|
||||
if( paramsStart < 0 )
|
||||
throw new IllegalArgumentException( "missing opening parenthesis in function '" + value + "'" );
|
||||
|
||||
String function = StringUtils.substringTrimmed( value, 0, paramsStart );
|
||||
List<String> params = splitFunctionParams( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
|
||||
@@ -763,28 +776,29 @@ class UIDefaultsLoader
|
||||
parseColorDepth++;
|
||||
try {
|
||||
switch( function ) {
|
||||
case "if": return parseColorIf( value, params, resolver, reportError );
|
||||
case "rgb": return parseColorRgbOrRgba( false, params, resolver, reportError );
|
||||
case "rgba": return parseColorRgbOrRgba( true, params, resolver, reportError );
|
||||
case "if": return parseColorIf( value, params, resolver );
|
||||
case "systemColor": return parseColorSystemColor( value, params, resolver );
|
||||
case "rgb": return parseColorRgbOrRgba( false, params, resolver );
|
||||
case "rgba": return parseColorRgbOrRgba( true, params, resolver );
|
||||
case "hsl": return parseColorHslOrHsla( false, params );
|
||||
case "hsla": return parseColorHslOrHsla( true, params );
|
||||
case "lighten": return parseColorHSLIncreaseDecrease( 2, true, params, resolver, reportError );
|
||||
case "darken": return parseColorHSLIncreaseDecrease( 2, false, params, resolver, reportError );
|
||||
case "saturate": return parseColorHSLIncreaseDecrease( 1, true, params, resolver, reportError );
|
||||
case "desaturate": return parseColorHSLIncreaseDecrease( 1, false, params, resolver, reportError );
|
||||
case "fadein": return parseColorHSLIncreaseDecrease( 3, true, params, resolver, reportError );
|
||||
case "fadeout": return parseColorHSLIncreaseDecrease( 3, false, params, resolver, reportError );
|
||||
case "fade": return parseColorFade( params, resolver, reportError );
|
||||
case "spin": return parseColorSpin( params, resolver, reportError );
|
||||
case "changeHue": return parseColorChange( 0, params, resolver, reportError );
|
||||
case "changeSaturation":return parseColorChange( 1, params, resolver, reportError );
|
||||
case "changeLightness": return parseColorChange( 2, params, resolver, reportError );
|
||||
case "changeAlpha": return parseColorChange( 3, params, resolver, reportError );
|
||||
case "mix": return parseColorMix( null, params, resolver, reportError );
|
||||
case "tint": return parseColorMix( "#fff", params, resolver, reportError );
|
||||
case "shade": return parseColorMix( "#000", params, resolver, reportError );
|
||||
case "contrast": return parseColorContrast( params, resolver, reportError );
|
||||
case "over": return parseColorOver( params, resolver, reportError );
|
||||
case "lighten": return parseColorHSLIncreaseDecrease( 2, true, params, resolver );
|
||||
case "darken": return parseColorHSLIncreaseDecrease( 2, false, params, resolver );
|
||||
case "saturate": return parseColorHSLIncreaseDecrease( 1, true, params, resolver );
|
||||
case "desaturate": return parseColorHSLIncreaseDecrease( 1, false, params, resolver );
|
||||
case "fadein": return parseColorHSLIncreaseDecrease( 3, true, params, resolver );
|
||||
case "fadeout": return parseColorHSLIncreaseDecrease( 3, false, params, resolver );
|
||||
case "fade": return parseColorFade( params, resolver );
|
||||
case "spin": return parseColorSpin( params, resolver );
|
||||
case "changeHue": return parseColorChange( 0, params, resolver );
|
||||
case "changeSaturation":return parseColorChange( 1, params, resolver );
|
||||
case "changeLightness": return parseColorChange( 2, params, resolver );
|
||||
case "changeAlpha": return parseColorChange( 3, params, resolver );
|
||||
case "mix": return parseColorMix( null, params, resolver );
|
||||
case "tint": return parseColorMix( "#fff", params, resolver );
|
||||
case "shade": return parseColorMix( "#000", params, resolver );
|
||||
case "contrast": return parseColorContrast( params, resolver );
|
||||
case "over": return parseColorOver( params, resolver );
|
||||
}
|
||||
} finally {
|
||||
parseColorDepth--;
|
||||
@@ -799,13 +813,51 @@ class UIDefaultsLoader
|
||||
* This "if" function is only used if the "if" is passed as parameter to another
|
||||
* 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 )
|
||||
throwMissingParametersException( value );
|
||||
|
||||
boolean ifCondition = parseCondition( params.get( 0 ), resolver, Collections.emptyList() );
|
||||
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%
|
||||
*/
|
||||
private static ColorUIResource parseColorRgbOrRgba( boolean hasAlpha, List<String> params,
|
||||
Function<String, String> resolver, boolean reportError )
|
||||
Function<String, String> resolver )
|
||||
{
|
||||
if( hasAlpha && params.size() == 2 ) {
|
||||
// syntax rgba(color,alpha), which allows adding alpha to any color
|
||||
@@ -825,7 +877,7 @@ class UIDefaultsLoader
|
||||
String colorStr = params.get( 0 );
|
||||
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 ) );
|
||||
}
|
||||
|
||||
@@ -865,7 +917,7 @@ class UIDefaultsLoader
|
||||
* - options: [relative] [autoInverse] [noAutoInverse] [lazy] [derived]
|
||||
*/
|
||||
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 );
|
||||
int amount = parsePercentage( params.get( 1 ) );
|
||||
@@ -900,7 +952,7 @@ class UIDefaultsLoader
|
||||
}
|
||||
|
||||
// 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%
|
||||
* - 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 );
|
||||
int amount = parsePercentage( params.get( 1 ) );
|
||||
boolean derived = false;
|
||||
@@ -934,7 +986,7 @@ class UIDefaultsLoader
|
||||
}
|
||||
|
||||
// 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
|
||||
* - 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 );
|
||||
int amount = parseInteger( params.get( 1 ), true );
|
||||
int amount = parseInteger( params.get( 1 ) );
|
||||
boolean derived = false;
|
||||
|
||||
if( params.size() > 2 ) {
|
||||
@@ -957,7 +1009,7 @@ class UIDefaultsLoader
|
||||
ColorFunction function = new ColorFunctions.HSLIncreaseDecrease( 0, true, amount, false, false );
|
||||
|
||||
// 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]
|
||||
*/
|
||||
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 );
|
||||
int value = (hslIndex == 0)
|
||||
? parseInteger( params.get( 1 ), true )
|
||||
? parseInteger( params.get( 1 ) )
|
||||
: parsePercentage( params.get( 1 ) );
|
||||
boolean derived = false;
|
||||
|
||||
@@ -987,7 +1039,7 @@ class UIDefaultsLoader
|
||||
ColorFunction function = new ColorFunctions.HSLChange( hslIndex, value );
|
||||
|
||||
// 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
|
||||
* 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;
|
||||
if( color1Str == null )
|
||||
color1Str = params.get( i++ );
|
||||
@@ -1007,7 +1059,7 @@ class UIDefaultsLoader
|
||||
int weight = (params.size() > i) ? parsePercentage( params.get( i ) ) : 50;
|
||||
|
||||
// parse second color
|
||||
ColorUIResource color2 = (ColorUIResource) parseColorOrFunction( resolver.apply( color2Str ), resolver, reportError );
|
||||
ColorUIResource color2 = (ColorUIResource) parseColorOrFunction( resolver.apply( color2Str ), resolver );
|
||||
if( color2 == null )
|
||||
return null;
|
||||
|
||||
@@ -1015,7 +1067,7 @@ class UIDefaultsLoader
|
||||
ColorFunction function = new ColorFunctions.Mix( color2, weight );
|
||||
|
||||
// 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
|
||||
* 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 darkStr = params.get( 1 );
|
||||
String lightStr = params.get( 2 );
|
||||
int threshold = (params.size() > 3) ? parsePercentage( params.get( 3 ) ) : 43;
|
||||
|
||||
// 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 )
|
||||
return null;
|
||||
|
||||
@@ -1043,7 +1095,7 @@ class UIDefaultsLoader
|
||||
: darkStr;
|
||||
|
||||
// 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
|
||||
* - 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 backgroundStr = params.get( 1 );
|
||||
|
||||
// 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 )
|
||||
return foreground;
|
||||
|
||||
@@ -1065,7 +1117,7 @@ class UIDefaultsLoader
|
||||
ColorUIResource foreground2 = new ColorUIResource( foreground.getRGB() );
|
||||
|
||||
// parse background color
|
||||
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver, reportError );
|
||||
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver );
|
||||
if( background == null )
|
||||
return foreground2;
|
||||
|
||||
@@ -1075,11 +1127,11 @@ class UIDefaultsLoader
|
||||
}
|
||||
|
||||
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
|
||||
String resolvedColorStr = resolver.apply( colorStr );
|
||||
ColorUIResource baseColor = (ColorUIResource) parseColorOrFunction( resolvedColorStr, resolver, reportError );
|
||||
ColorUIResource baseColor = (ColorUIResource) parseColorOrFunction( resolvedColorStr, resolver );
|
||||
if( baseColor == null )
|
||||
return null;
|
||||
|
||||
@@ -1163,11 +1215,11 @@ class UIDefaultsLoader
|
||||
throw new IllegalArgumentException( "size specified more than once in '" + value + "'" );
|
||||
|
||||
if( firstChar == '+' || firstChar == '-' )
|
||||
relativeSize = parseInteger( param, true );
|
||||
relativeSize = parseInteger( param );
|
||||
else if( param.endsWith( "%" ) )
|
||||
scaleSize = parseInteger( param.substring( 0, param.length() - 1 ), true ) / 100f;
|
||||
scaleSize = parseInteger( param.substring( 0, param.length() - 1 ) ) / 100f;
|
||||
else
|
||||
absoluteSize = parseInteger( param, true );
|
||||
absoluteSize = parseInteger( param );
|
||||
} else if( firstChar == '$' ) {
|
||||
// reference to base font
|
||||
if( baseFontKey != null )
|
||||
@@ -1241,55 +1293,49 @@ class UIDefaultsLoader
|
||||
return (max * percent) / 100;
|
||||
}
|
||||
|
||||
Integer integer = parseInteger( value, true );
|
||||
Integer integer = parseInteger( value );
|
||||
if( integer < min || integer > max )
|
||||
throw new NumberFormatException( "integer '" + value + "' out of range (" + min + '-' + max + ')' );
|
||||
return integer;
|
||||
}
|
||||
|
||||
private static Integer parseInteger( String value, boolean reportError ) {
|
||||
private static Integer parseInteger( String value ) {
|
||||
try {
|
||||
return Integer.parseInt( value );
|
||||
} 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 {
|
||||
return Integer.parseInt( value );
|
||||
} catch( NumberFormatException ex ) {
|
||||
try {
|
||||
return Float.parseFloat( value );
|
||||
} 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 {
|
||||
return Float.parseFloat( value );
|
||||
} 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 ) {
|
||||
int val = parseInteger( value, true );
|
||||
int val = parseInteger( value );
|
||||
return t -> {
|
||||
return UIScale.scale( val );
|
||||
};
|
||||
}
|
||||
|
||||
private static ActiveValue parseScaledFloat( String value ) {
|
||||
float val = parseFloat( value, true );
|
||||
float val = parseFloat( value );
|
||||
return t -> {
|
||||
return UIScale.scale( val );
|
||||
};
|
||||
@@ -1344,7 +1390,11 @@ class UIDefaultsLoader
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Area;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
@@ -36,6 +39,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatCapsLockIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private Path2D path;
|
||||
|
||||
public FlatCapsLockIcon() {
|
||||
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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
|
||||
<rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
|
||||
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
|
||||
<rect width="5" height="2" x="5.5" y="11.5" stroke="#FFF" stroke-linejoin="round"/>
|
||||
<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>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
|
||||
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 );
|
||||
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
BasicStroke stroke = new BasicStroke( 1, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND );
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ public class FlatCheckBoxIcon
|
||||
}
|
||||
|
||||
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.lineTo( 6.6f, 10f );
|
||||
path.lineTo( 11.25f, 3.5f );
|
||||
|
||||
@@ -76,7 +76,7 @@ public class FlatCheckBoxMenuItemIcon
|
||||
}
|
||||
|
||||
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.lineTo( 6.6f, 10f );
|
||||
path.lineTo( 11.25f, 3.5f );
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.AbstractButton;
|
||||
@@ -103,9 +102,11 @@ public class FlatClearIcon
|
||||
|
||||
// paint cross
|
||||
g.setColor( clearIconColor );
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( 5,5, 11,11 ), false );
|
||||
path.append( new Line2D.Float( 5,11, 11,5 ), false );
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||
path.moveTo( 5, 5 );
|
||||
path.lineTo( 11, 11 );
|
||||
path.moveTo( 5, 11 );
|
||||
path.lineTo( 11, 5 );
|
||||
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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect width="2" height="2" x="2" y="3" fill="#6E6E6E"/>
|
||||
<rect width="2" height="2" x="2" y="7" fill="#6E6E6E"/>
|
||||
<rect width="2" height="2" x="2" y="11" fill="#6E6E6E"/>
|
||||
<rect width="8" height="2" x="6" y="3" fill="#6E6E6E"/>
|
||||
<rect width="8" height="2" x="6" y="7" fill="#6E6E6E"/>
|
||||
<rect width="8" height="2" x="6" y="11" fill="#6E6E6E"/>
|
||||
<rect width="2" height="1" x="2" y="3" fill="#6E6E6E" rx=".5"/>
|
||||
<rect width="2" height="1" x="2" y="6" fill="#6E6E6E" rx=".5"/>
|
||||
<rect width="2" height="1" x="2" y="9" fill="#6E6E6E" rx=".5"/>
|
||||
<rect width="2" height="1" x="2" y="12" fill="#6E6E6E" rx=".5"/>
|
||||
<rect width="8" height="1" x="6" y="3" fill="#6E6E6E" rx=".5"/>
|
||||
<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>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
g.fillRect( 2, 3, 2, 2 );
|
||||
g.fillRect( 2, 7, 2, 2 );
|
||||
g.fillRect( 2, 11, 2, 2 );
|
||||
g.fillRect( 6, 3, 8, 2 );
|
||||
g.fillRect( 6, 7, 8, 2 );
|
||||
g.fillRect( 6, 11, 8, 2 );
|
||||
g.fillRoundRect( 2, 3, 2, 1, 1, 1 );
|
||||
g.fillRoundRect( 2, 6, 2, 1, 1, 1 );
|
||||
g.fillRoundRect( 2, 9, 2, 1, 1, 1 );
|
||||
g.fillRoundRect( 2, 12, 2, 1, 1, 1 );
|
||||
g.fillRoundRect( 6, 3, 8, 1, 1, 1 );
|
||||
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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
@@ -39,10 +41,22 @@ public class FlatFileChooserHomeFolderIcon
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
/*
|
||||
<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>
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect width="4" height="4" x="3" y="3" fill="#6E6E6E"/>
|
||||
<rect width="4" height="4" x="3" y="9" fill="#6E6E6E"/>
|
||||
<rect width="4" height="4" x="9" y="9" fill="#6E6E6E"/>
|
||||
<rect width="4" height="4" x="9" 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="2.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||
<rect width="4" height="4" x="9.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||
<rect width="4" height="4" x="9.5" y="2.5" stroke="#6E6E6E" rx="1.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
g.fillRect( 3, 3, 4, 4 );
|
||||
g.fillRect( 3, 9, 4, 4 );
|
||||
g.fillRect( 9, 9, 4, 4 );
|
||||
g.fillRect( 9, 3, 4, 4 );
|
||||
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||
|
||||
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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Line2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
||||
@@ -31,6 +34,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatFileChooserNewFolderIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final Color greenColor = UIManager.getColor( "Actions.Green" );
|
||||
|
||||
public FlatFileChooserNewFolderIcon() {
|
||||
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">
|
||||
<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 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"/>
|
||||
<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"/>
|
||||
<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>
|
||||
</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.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.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( 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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Line2D;
|
||||
import javax.swing.UIManager;
|
||||
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">
|
||||
<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 fill="#389FD6" d="M12,4 L12,8 L10,8 L10,4 L8,4 L11,1 L14,4 L12,4 Z"/>
|
||||
<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"/>
|
||||
<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>
|
||||
</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.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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
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">
|
||||
<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="12" height="2" x="2" y="12" fill="#6E6E6E"/>
|
||||
<rect width="11" height="7" x="2.5" y="3.5" stroke="#6E6E6E" rx="1"/>
|
||||
<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>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Rectangle2D.Float( 2, 3, 12, 8 ), false );
|
||||
path.append( new Rectangle2D.Float( 4, 5, 8, 4 ), false );
|
||||
g.fill( path );
|
||||
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||
|
||||
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.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
@@ -31,6 +33,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatFileViewDirectoryIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private Path2D path;
|
||||
|
||||
public FlatFileViewDirectoryIcon() {
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
@@ -39,10 +43,32 @@ public class FlatFileViewDirectoryIcon
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
/*
|
||||
<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>
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
@@ -31,6 +34,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatFileViewFileIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private Path2D path;
|
||||
|
||||
public FlatFileViewFileIcon() {
|
||||
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||
}
|
||||
@@ -39,14 +44,33 @@ public class FlatFileViewFileIcon
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<polygon fill="#6E6E6E" points="8 6 8 1 13 1 13 15 3 15 3 6"/>
|
||||
<polygon fill="#6E6E6E" points="3 5 7 5 7 1"/>
|
||||
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||
<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"/>
|
||||
<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>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
g.fill( FlatUIUtils.createPath( 8,6, 8,1, 13,1, 13,15, 3,15, 3,6 ) );
|
||||
g.fill( FlatUIUtils.createPath( 3,5, 7,5, 7,1 ) );
|
||||
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.RenderingHints;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
@@ -40,18 +41,22 @@ public class FlatFileViewFloppyDriveIcon
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
/*
|
||||
<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="#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"/>
|
||||
<rect width="4" height="2" x="6" y="12" fill="#6E6E6E"/>
|
||||
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||
<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"/>
|
||||
<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>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( FlatUIUtils.createPath( 11,14, 11,11, 5,11, 5,14, 2,14, 2,2, 14,2, 14,14, 11,14 ), false );
|
||||
path.append( FlatUIUtils.createPath( 4,4, 4,8, 12,8, 12,4, 4,4 ), false );
|
||||
g.fill( path );
|
||||
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||
|
||||
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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import javax.swing.UIManager;
|
||||
|
||||
/**
|
||||
@@ -40,14 +42,19 @@ public class FlatFileViewHardDriveIcon
|
||||
protected void paintIcon( Component c, Graphics2D g ) {
|
||||
/*
|
||||
<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>
|
||||
*/
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Rectangle2D.Float( 2, 6, 12, 4 ), false );
|
||||
path.append( new Rectangle2D.Float( 12, 8, 1, 1 ), false );
|
||||
path.append( new Rectangle2D.Float( 10, 8, 1, 1 ), false );
|
||||
g.fill( path );
|
||||
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
g.setStroke( new BasicStroke( 1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||
|
||||
g.draw( new RoundRectangle2D.Float( 2.5f, 5.5f, 11, 5, 2, 2 ) );
|
||||
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;
|
||||
|
||||
import static com.formdev.flatlaf.util.UIScale.*;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.Map;
|
||||
@@ -96,7 +98,8 @@ public class FlatHelpButtonIcon
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<circle cx="11" cy="11" r="10.5" fill="#6E6E6E"/>
|
||||
<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>
|
||||
</svg>
|
||||
*/
|
||||
@@ -147,22 +150,19 @@ public class FlatHelpButtonIcon
|
||||
g2.fill( new Ellipse2D.Float( xy, xy, wh, wh ) );
|
||||
|
||||
// paint question mark
|
||||
Path2D q = new Path2D.Float();
|
||||
q.moveTo( 11, 5 );
|
||||
q.curveTo( 8.8,5, 7,6.8, 7,9 );
|
||||
q.lineTo( 9, 9 );
|
||||
q.curveTo( 9,7.9, 9.9,7, 11,7 );
|
||||
q.curveTo( 12.1,7, 13,7.9, 13,9 );
|
||||
q.curveTo( 13,11, 10,10.75, 10,14 );
|
||||
q.lineTo( 12, 14 );
|
||||
q.curveTo( 12,11.75, 15,11.5, 15,9 );
|
||||
q.curveTo( 15,6.8, 13.2,5, 11,5 );
|
||||
q.closePath();
|
||||
Path2D q = new Path2D.Float( Path2D.WIND_NON_ZERO, 10 );
|
||||
q.moveTo( 8,8.5 );
|
||||
q.curveTo( 8.25,7, 9.66585007,6, 11,6 );
|
||||
q.curveTo( 12.5,6, 14,7, 14,8.5 );
|
||||
q.curveTo( 14,10.5, 11,11, 11,13 );
|
||||
|
||||
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
g2.setStroke( new BasicStroke( 2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND ) );
|
||||
|
||||
g2.translate( focusWidth, focusWidth );
|
||||
g2.setColor( enabled ? questionMarkColor : disabledQuestionMarkColor );
|
||||
g2.fill( q );
|
||||
g2.fillRect( 10, 15, 2, 2 );
|
||||
g2.draw( q );
|
||||
g2.fill( new Ellipse2D.Float( 9.8f, 14.8f, 2.4f, 2.4f ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,6 @@ import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
@@ -58,9 +57,11 @@ public class FlatInternalFrameCloseIcon
|
||||
float my = height / 2;
|
||||
float r = 3.25f;
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( mx - r, my - r, mx + r, my + r ), false );
|
||||
path.append( new Line2D.Float( mx - r, my + r, mx + r, my - r ), false );
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||
path.moveTo( mx - r, my - r );
|
||||
path.lineTo( mx + r, my + r );
|
||||
path.moveTo( mx - r, my + r );
|
||||
path.lineTo( mx + r, my - r );
|
||||
g.setStroke( new BasicStroke( 1f ) );
|
||||
g.draw( path );
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.formdev.flatlaf.icons;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
/**
|
||||
* "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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<circle cx="16" cy="16" r="14" fill="#DB5860"/>
|
||||
<rect width="4" height="11" x="14" y="7" fill="#FFF"/>
|
||||
<rect width="4" height="4" x="14" y="21" fill="#FFF"/>
|
||||
<rect width="4" height="12" x="14" y="7" fill="#FFF" rx="2"/>
|
||||
<circle cx="16" cy="23" r="2" fill="#FFF"/>
|
||||
</g>
|
||||
</svg>
|
||||
*/
|
||||
@@ -54,8 +54,8 @@ public class FlatOptionPaneErrorIcon
|
||||
@Override
|
||||
protected Shape createInside() {
|
||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
inside.append( new Rectangle2D.Float( 14, 7, 4, 11 ), false );
|
||||
inside.append( new Rectangle2D.Float( 14, 21, 4, 4 ), false );
|
||||
inside.append( new RoundRectangle2D.Float( 14, 7, 4, 12, 4, 4 ), false );
|
||||
inside.append( new Ellipse2D.Float( 14, 21, 4, 4 ), false );
|
||||
return inside;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ package com.formdev.flatlaf.icons;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
|
||||
/**
|
||||
* "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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
||||
<rect width="4" height="11" x="14" y="14" fill="#FFF"/>
|
||||
<rect width="4" height="4" x="14" y="7" fill="#FFF"/>
|
||||
<rect width="4" height="12" x="14" y="13" fill="#FFF" rx="2"/>
|
||||
<circle cx="16" cy="9" r="2" fill="#FFF"/>
|
||||
</g>
|
||||
</svg>
|
||||
*/
|
||||
@@ -54,8 +54,8 @@ public class FlatOptionPaneInformationIcon
|
||||
@Override
|
||||
protected Shape createInside() {
|
||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
inside.append( new Rectangle2D.Float( 14, 14, 4, 11 ), false );
|
||||
inside.append( new Rectangle2D.Float( 14, 7, 4, 4 ), false );
|
||||
inside.append( new RoundRectangle2D.Float( 14, 13, 4, 12, 4, 4 ), false );
|
||||
inside.append( new Ellipse2D.Float( 14, 7, 4, 4 ), false );
|
||||
return inside;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
|
||||
/**
|
||||
* "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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<circle cx="16" cy="16" r="14" fill="#389FD6"/>
|
||||
<rect width="4" height="4" x="14" y="22" 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"/>
|
||||
<circle cx="16" cy="24" r="1.7" fill="#FFF"/>
|
||||
<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>
|
||||
</svg>
|
||||
*/
|
||||
@@ -53,21 +53,17 @@ public class FlatOptionPaneQuestionIcon
|
||||
|
||||
@Override
|
||||
protected Shape createInside() {
|
||||
Path2D q = new Path2D.Float();
|
||||
q.moveTo( 14, 20 );
|
||||
q.lineTo( 18, 20 );
|
||||
q.curveTo( 18, 16, 23, 16, 23, 12 );
|
||||
q.curveTo( 23, 8, 20, 6, 16, 6 );
|
||||
q.curveTo( 12, 6, 9, 8, 9, 12 );
|
||||
q.curveTo( 9, 12, 13, 12, 13, 12 );
|
||||
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 q = new Path2D.Float( Path2D.WIND_NON_ZERO, 10 );
|
||||
q.moveTo( 11.5,11.75 );
|
||||
q.curveTo( 11.75,9.5, 13.75,8, 16,8 );
|
||||
q.curveTo( 18.25,8, 20.5,9.5, 20.5,11.75 );
|
||||
q.curveTo( 20.5,14.75, 16,15.5, 16,19 );
|
||||
|
||||
BasicStroke stroke = new BasicStroke( 3, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER );
|
||||
|
||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
inside.append( new Rectangle2D.Float( 14, 22, 4, 4 ), false );
|
||||
inside.append( q, false );
|
||||
inside.append( new Ellipse2D.Float( 14.3f, 22.3f, 3.4f, 3.4f ), false );
|
||||
inside.append( stroke.createStrokedShape( q ), false );
|
||||
return inside;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Shape;
|
||||
import java.awt.geom.Ellipse2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<polygon fill="#EDA200" points="16 2 31 28 1 28"/>
|
||||
<rect width="4" height="8" x="14" y="10" fill="#FFF"/>
|
||||
<rect width="4" height="4" x="14" y="21" fill="#FFF"/>
|
||||
<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="11" x="14" y="8" fill="#FFF" rx="2"/>
|
||||
<circle cx="16" cy="23" r="2" fill="#FFF"/>
|
||||
</g>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
@Override
|
||||
protected Shape createOutside() {
|
||||
return FlatUIUtils.createPath( 16,2, 31,28, 1,28 );
|
||||
return FlatUIUtils.createRoundTrianglePath( 16,0, 32,28, 0,28, 4 );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Shape createInside() {
|
||||
Path2D inside = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
inside.append( new Rectangle2D.Float( 14, 10, 4, 8 ), false );
|
||||
inside.append( new Rectangle2D.Float( 14, 21, 4, 4 ), false );
|
||||
inside.append( new RoundRectangle2D.Float( 14, 8, 4, 11, 4, 4 ), false );
|
||||
inside.append( new Ellipse2D.Float( 14, 21, 4, 4 ), false );
|
||||
return inside;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ public class FlatSearchIcon
|
||||
@Styleable protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
|
||||
|
||||
private final boolean ignoreButtonState;
|
||||
private Area area;
|
||||
|
||||
public FlatSearchIcon() {
|
||||
this( false );
|
||||
@@ -89,9 +90,11 @@ public class FlatSearchIcon
|
||||
null, searchIconHoverColor, searchIconPressedColor ) );
|
||||
|
||||
// paint magnifier
|
||||
Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
|
||||
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 ) ) );
|
||||
if( area == null ) {
|
||||
area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.Map;
|
||||
import javax.swing.UIManager;
|
||||
@@ -100,9 +99,11 @@ public class FlatTabbedPaneCloseIcon
|
||||
float r = ((bg != null) ? closeCrossFilledSize : closeCrossPlainSize) / 2;
|
||||
|
||||
// paint cross
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( mx - r, my - r, mx + r, my + r ), false );
|
||||
path.append( new Line2D.Float( mx - r, my + r, mx + r, my - r ), false );
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||
path.moveTo( mx - r, my - r );
|
||||
path.lineTo( mx + r, my + r );
|
||||
path.moveTo( mx - r, my + r );
|
||||
path.lineTo( mx + r, my - r );
|
||||
g.setStroke( new BasicStroke( closeCrossLineWidth ) );
|
||||
g.draw( path );
|
||||
}
|
||||
|
||||
@@ -18,8 +18,9 @@ package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
/**
|
||||
* "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
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private Path2D path;
|
||||
|
||||
public FlatTreeClosedIcon() {
|
||||
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">
|
||||
<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>
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.SwingUtilities;
|
||||
@@ -39,6 +41,7 @@ public class FlatTreeCollapsedIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final boolean chevron;
|
||||
private Path2D path;
|
||||
|
||||
public FlatTreeCollapsedIcon() {
|
||||
this( UIManager.getColor( "Tree.icon.collapsedColor" ) );
|
||||
@@ -59,10 +62,15 @@ public class FlatTreeCollapsedIcon
|
||||
|
||||
if( chevron ) {
|
||||
// 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 {
|
||||
// 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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
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}.
|
||||
@@ -42,13 +46,22 @@ public class FlatTreeLeafIcon
|
||||
/*
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<polygon fill="#6E6E6E" points="8 6 8 1 13 1 13 15 3 15 3 6"/>
|
||||
<polygon fill="#6E6E6E" points="3 5 7 5 7 1"/>
|
||||
<rect width="11" height="13" x="2.5" y="1.5" stroke="#6E6E6E" rx="1.5"/>
|
||||
<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>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
g.fill( FlatUIUtils.createPath( 8,6, 8,1, 13,1, 13,15, 3,15, 3,6 ) );
|
||||
g.fill( FlatUIUtils.createPath( 3,5, 7,5, 7,1 ) );
|
||||
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
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;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
|
||||
@@ -31,6 +34,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
public class FlatTreeOpenIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private Path2D path;
|
||||
|
||||
public FlatTreeOpenIcon() {
|
||||
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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<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>
|
||||
<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"/>
|
||||
</svg>
|
||||
*/
|
||||
|
||||
g.fill( FlatUIUtils.createPath( 1,2, 6,2, 8,4, 14,4, 14,6, 3.5,6, 1,11 ) );
|
||||
g.fill( FlatUIUtils.createPath( 4,7, 16,7, 13,13, 1,13 ) );
|
||||
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||
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.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Line2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
@@ -57,9 +56,11 @@ public class FlatWindowCloseIcon
|
||||
int iy2 = iy + iwh - 1;
|
||||
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||
path.append( new Line2D.Float( ix, iy, ix2, iy2 ), false );
|
||||
path.append( new Line2D.Float( ix, iy2, ix2, iy ), false );
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||
path.moveTo( ix, iy );
|
||||
path.lineTo( ix2, iy2 );
|
||||
path.moveTo( ix, iy2 );
|
||||
path.lineTo( ix2, iy );
|
||||
g.setStroke( new BasicStroke( thickness ) );
|
||||
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.MouseEvent;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicArrowButton;
|
||||
|
||||
@@ -48,8 +49,10 @@ public class FlatArrowButton
|
||||
protected Color pressedBackground;
|
||||
|
||||
private int arrowWidth = DEFAULT_ARROW_WIDTH;
|
||||
private float arrowThickness = 1;
|
||||
private float xOffset = 0;
|
||||
private float yOffset = 0;
|
||||
private boolean roundBorderAutoXOffset = true;
|
||||
|
||||
private boolean hover;
|
||||
private boolean pressed;
|
||||
@@ -82,14 +85,18 @@ public class FlatArrowButton
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
pressed = true;
|
||||
repaint();
|
||||
if( SwingUtilities.isLeftMouseButton( e ) ) {
|
||||
pressed = true;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
pressed = false;
|
||||
repaint();
|
||||
if( SwingUtilities.isLeftMouseButton( e ) ) {
|
||||
pressed = false;
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
@@ -116,6 +123,16 @@ public class FlatArrowButton
|
||||
this.arrowWidth = arrowWidth;
|
||||
}
|
||||
|
||||
/** @since 3 */
|
||||
public float getArrowThickness() {
|
||||
return arrowThickness;
|
||||
}
|
||||
|
||||
/** @since 3 */
|
||||
public void setArrowThickness( float arrowThickness ) {
|
||||
this.arrowThickness = arrowThickness;
|
||||
}
|
||||
|
||||
protected boolean isHover() {
|
||||
return hover;
|
||||
}
|
||||
@@ -140,6 +157,16 @@ public class FlatArrowButton
|
||||
this.yOffset = yOffset;
|
||||
}
|
||||
|
||||
/** @since 3 */
|
||||
public boolean isRoundBorderAutoXOffset() {
|
||||
return roundBorderAutoXOffset;
|
||||
}
|
||||
|
||||
/** @since 3 */
|
||||
public void setRoundBorderAutoXOffset( boolean roundBorderAutoXOffset ) {
|
||||
this.roundBorderAutoXOffset = roundBorderAutoXOffset;
|
||||
}
|
||||
|
||||
protected Color deriveBackground( Color background ) {
|
||||
return background;
|
||||
}
|
||||
@@ -203,14 +230,17 @@ public class FlatArrowButton
|
||||
}
|
||||
|
||||
protected void paintArrow( Graphics2D g ) {
|
||||
boolean vert = (direction == NORTH || direction == SOUTH);
|
||||
int x = 0;
|
||||
|
||||
// move arrow for round borders
|
||||
Container parent = getParent();
|
||||
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
|
||||
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
|
||||
if( isRoundBorderAutoXOffset() ) {
|
||||
Container parent = getParent();
|
||||
boolean vert = (direction == NORTH || direction == SOUTH);
|
||||
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
|
||||
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
|
||||
}
|
||||
|
||||
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron, getArrowWidth(), getXOffset(), getYOffset() );
|
||||
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron,
|
||||
getArrowWidth(), getArrowThickness(), getXOffset(), getYOffset() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
@@ -45,8 +46,10 @@ import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.plaf.ButtonUI;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.ToolBarUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import javax.swing.plaf.basic.BasicButtonListener;
|
||||
import javax.swing.plaf.basic.BasicButtonUI;
|
||||
@@ -797,5 +800,20 @@ public class FlatButtonUI
|
||||
super.propertyChange( 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.ComboPopup;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import com.formdev.flatlaf.icons.FlatCheckBoxMenuItemIcon;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||
@@ -99,7 +100,7 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
* @uiDefault ComboBox.minimumWidth int
|
||||
* @uiDefault ComboBox.editorColumns int
|
||||
* @uiDefault ComboBox.maximumRowCount int
|
||||
* @uiDefault ComboBox.buttonStyle String auto (default), button or none
|
||||
* @uiDefault ComboBox.buttonStyle String auto (default), button, mac or none
|
||||
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
|
||||
@@ -117,6 +118,9 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
* @uiDefault ComboBox.buttonHoverArrowColor Color
|
||||
* @uiDefault ComboBox.buttonPressedArrowColor Color
|
||||
* @uiDefault ComboBox.popupBackground Color optional
|
||||
* @uiDefault ComboBox.popupInsets Insets
|
||||
* @uiDefault ComboBox.selectionInsets Insets
|
||||
* @uiDefault ComboBox.selectionArc int
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -150,6 +154,9 @@ public class FlatComboBoxUI
|
||||
@Styleable protected Color buttonPressedArrowColor;
|
||||
|
||||
@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;
|
||||
protected boolean hover;
|
||||
@@ -253,6 +260,9 @@ public class FlatComboBoxUI
|
||||
buttonPressedArrowColor = UIManager.getColor( "ComboBox.buttonPressedArrowColor" );
|
||||
|
||||
popupBackground = UIManager.getColor( "ComboBox.popupBackground" );
|
||||
popupInsets = UIManager.getInsets( "ComboBox.popupInsets" );
|
||||
selectionInsets = UIManager.getInsets( "ComboBox.selectionInsets" );
|
||||
selectionArc = UIManager.getInt( "ComboBox.selectionArc" );
|
||||
|
||||
// set 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)
|
||||
FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() );
|
||||
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();
|
||||
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() ) {
|
||||
// set width of arrow button to preferred height of combobox
|
||||
// set width of arrow button
|
||||
int xOffset = comboBox.getComponentOrientation().isLeftToRight()
|
||||
? arrowButton.getWidth() - buttonWidth
|
||||
: 0;
|
||||
@@ -556,7 +569,9 @@ public class FlatComboBoxUI
|
||||
int height = c.getHeight();
|
||||
int arrowX = arrowButton.getX();
|
||||
int arrowWidth = arrowButton.getWidth();
|
||||
boolean paintButton = (comboBox.isEditable() || "button".equals( buttonStyle )) && !"none".equals( buttonStyle );
|
||||
boolean paintButton = (comboBox.isEditable() || "button".equals( buttonStyle )) &&
|
||||
!"none".equals( buttonStyle ) &&
|
||||
!isMacStyle();
|
||||
boolean enabled = comboBox.isEnabled();
|
||||
boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight();
|
||||
|
||||
@@ -574,13 +589,21 @@ public class FlatComboBoxUI
|
||||
: buttonBackground;
|
||||
if( buttonColor != null ) {
|
||||
g2.setColor( buttonColor );
|
||||
Shape oldClip = g2.getClip();
|
||||
if( isLeftToRight )
|
||||
g2.clipRect( arrowX, 0, width - arrowX, height );
|
||||
else
|
||||
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
|
||||
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
||||
g2.setClip( oldClip );
|
||||
if( isMacStyle() ) {
|
||||
Insets insets = comboBox.getInsets();
|
||||
int gap = scale( 2 );
|
||||
FlatUIUtils.paintComponentBackground( g2, arrowX + gap, insets.top + gap,
|
||||
arrowWidth - (gap * 2), height - insets.top - insets.bottom - (gap * 2),
|
||||
0, arc - focusWidth );
|
||||
} else {
|
||||
Shape oldClip = g2.getClip();
|
||||
if( isLeftToRight )
|
||||
g2.clipRect( arrowX, 0, width - arrowX, height );
|
||||
else
|
||||
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
|
||||
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
||||
g2.setClip( oldClip );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,6 +742,10 @@ public class FlatComboBoxUI
|
||||
return parentParent != null && !comboBox.getBackground().equals( parentParent.getBackground() );
|
||||
}
|
||||
|
||||
private boolean isMacStyle() {
|
||||
return "mac".equals( buttonStyle );
|
||||
}
|
||||
|
||||
/** @since 1.3 */
|
||||
public static boolean isPermanentFocusOwner( JComboBox<?> comboBox ) {
|
||||
if( comboBox.isEditable() ) {
|
||||
@@ -753,6 +780,21 @@ public class FlatComboBoxUI
|
||||
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
|
||||
protected boolean isHover() {
|
||||
return super.isHover() || (!comboBox.isEditable() ? hover : false);
|
||||
@@ -770,6 +812,20 @@ public class FlatComboBoxUI
|
||||
|
||||
return super.getArrowColor();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintArrow( Graphics2D g ) {
|
||||
if( isMacStyle() && !comboBox.isEditable() ) {
|
||||
// for style "mac", paint up and down arrows if combobox is not editable
|
||||
int height = getHeight();
|
||||
int h = Math.round( height / 2f );
|
||||
FlatUIUtils.paintArrow( g, 0, 0, getWidth(), h, SwingConstants.NORTH, chevron,
|
||||
getArrowWidth(), getArrowThickness(), getXOffset(), getYOffset() + 1.25f );
|
||||
FlatUIUtils.paintArrow( g, 0, height - h, getWidth(), h, SwingConstants.SOUTH, chevron,
|
||||
getArrowWidth(), getArrowThickness(), getXOffset(), getYOffset() - 1.25f );
|
||||
} else
|
||||
super.paintArrow( g );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatComboPopup -----------------------------------------------
|
||||
@@ -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
|
||||
JScrollBar verticalScrollBar = scroller.getVerticalScrollBar();
|
||||
if( verticalScrollBar != null )
|
||||
displayWidth += verticalScrollBar.getPreferredSize().width;
|
||||
|
||||
// make popup wider if necessary
|
||||
int pw0 = pw;
|
||||
if( displayWidth > pw ) {
|
||||
// limit popup width to screen width
|
||||
GraphicsConfiguration gc = comboBox.getGraphicsConfiguration();
|
||||
@@ -829,6 +892,30 @@ public class FlatComboBoxUI
|
||||
px -= diff;
|
||||
}
|
||||
|
||||
// for style "mac", place popup over combobox
|
||||
Rectangle cellBounds;
|
||||
if( isPopupOverComboBox && selectedIndex >= 0 &&
|
||||
(cellBounds = list.getCellBounds( 0, 0 )) != null )
|
||||
{
|
||||
Insets comboBoxInsets = comboBox.getInsets();
|
||||
Insets listInsets = list.getInsets();
|
||||
Insets popupInsets = getInsets();
|
||||
|
||||
// position popup so that selected item is at same Y position as combobox
|
||||
py -= (cellBounds.height * (selectedIndex + 1)) + comboBoxInsets.top + listInsets.top + popupInsets.top;
|
||||
|
||||
// position popup slightly to the left so that a small part of the right side of the combobox stays visible
|
||||
int offset = Math.min( pw - pw0, MacCheckedItemIcon.INSTANCE.getIconWidth() ) + scale( 4 );
|
||||
if( comboBox.getComponentOrientation().isLeftToRight() )
|
||||
px -= offset + comboBoxInsets.right + listInsets.right;
|
||||
else
|
||||
px += offset + comboBoxInsets.left + listInsets.left;
|
||||
|
||||
// not invoking super.computePopupBounds() here to let
|
||||
// JPopupMenu.adjustPopupLocationToFitScreen() fix the location if necessary
|
||||
return new Rectangle( px, py, pw, ph );
|
||||
}
|
||||
|
||||
return super.computePopupBounds( px, py, pw, ph );
|
||||
}
|
||||
|
||||
@@ -839,17 +926,12 @@ public class FlatComboBoxUI
|
||||
// make opaque to avoid that background shines thru border (e.g. at 150% scaling)
|
||||
setOpaque( true );
|
||||
|
||||
// set popup border
|
||||
// use non-UIResource to avoid that it is overwritten when making
|
||||
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
||||
// set popup border
|
||||
// use non-UIResource to avoid that it is overwritten when making
|
||||
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
||||
Border border = UIManager.getBorder( "PopupMenu.border" );
|
||||
if( border != null )
|
||||
setBorder( FlatUIUtils.nonUIResource( border ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configureList() {
|
||||
super.configureList();
|
||||
|
||||
list.setCellRenderer( new PopupListCellRenderer() );
|
||||
updateStyle();
|
||||
@@ -857,12 +939,21 @@ public class FlatComboBoxUI
|
||||
|
||||
void updateStyle() {
|
||||
if( popupBackground != null )
|
||||
list.setBackground( popupBackground );
|
||||
list.setBackground( popupBackground );
|
||||
|
||||
// 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
|
||||
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
||||
setBackground( FlatUIUtils.nonUIResource( list.getBackground() ) );
|
||||
// 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
|
||||
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
||||
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
|
||||
@@ -904,6 +995,15 @@ public class FlatComboBoxUI
|
||||
paddingBorder.uninstall();
|
||||
}
|
||||
|
||||
private boolean isPopupOverComboBox() {
|
||||
return isMacStyle() &&
|
||||
!comboBox.isEditable() &&
|
||||
comboBox.getItemCount() > 0 &&
|
||||
comboBox.getItemCount() <= comboBox.getMaximumRowCount() &&
|
||||
// for compatibility with Aqua Laf
|
||||
!clientPropertyBoolean( comboBox, "JComboBox.isPopDown", false );
|
||||
}
|
||||
|
||||
//---- class PopupListCellRenderer -----
|
||||
|
||||
private class PopupListCellRenderer
|
||||
@@ -921,6 +1021,13 @@ public class FlatComboBoxUI
|
||||
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||
|
||||
// style "mac"
|
||||
if( isPopupOverComboBox() && c instanceof JComponent ) {
|
||||
int selectedIndex = comboBox.getSelectedIndex();
|
||||
((JComponent)c).putClientProperty( CellPaddingBorder.KEY_MAC_STYLE_HINT,
|
||||
(selectedIndex >= 0) ? (index == selectedIndex) : null );
|
||||
}
|
||||
|
||||
paddingBorder.install( c, Math.round( FlatUIUtils.getBorderFocusWidth( comboBox ) ) );
|
||||
|
||||
return c;
|
||||
@@ -937,10 +1044,16 @@ public class FlatComboBoxUI
|
||||
* which vertically aligns text in popup list with text in combobox.
|
||||
* <p>
|
||||
* The renderer border is painted on the outer side of this border.
|
||||
* <p>
|
||||
* For button style "mac", also used to increase insets on left side for
|
||||
* "checked item" icon and to paint "checked item" icon for selected combobox item.
|
||||
*/
|
||||
private static class CellPaddingBorder
|
||||
extends AbstractBorder
|
||||
{
|
||||
static final String KEY_MAC_STYLE_HINT = "FlatLaf.internal.FlatComboBoxUI.macStyleHint";
|
||||
static final int MAC_STYLE_GAP = 4;
|
||||
|
||||
private Insets padding;
|
||||
private JComponent rendererComponent;
|
||||
private Border rendererBorder;
|
||||
@@ -990,6 +1103,8 @@ public class FlatComboBoxUI
|
||||
if( rendererComponent == null )
|
||||
return;
|
||||
|
||||
rendererComponent.putClientProperty( KEY_MAC_STYLE_HINT, null );
|
||||
|
||||
if( rendererComponent.getBorder() == this )
|
||||
rendererComponent.setBorder( rendererBorder );
|
||||
rendererComponent = null;
|
||||
@@ -1017,6 +1132,18 @@ public class FlatComboBoxUI
|
||||
insets.left += focusWidth;
|
||||
insets.right += focusWidth;
|
||||
|
||||
// style "mac"
|
||||
if( c instanceof JComponent ) {
|
||||
Boolean macStyleHint = clientPropertyBooleanStrict( (JComponent) c, KEY_MAC_STYLE_HINT, null );
|
||||
if( macStyleHint != null ) {
|
||||
int indent = MacCheckedItemIcon.INSTANCE.getIconWidth() + scale( MAC_STYLE_GAP );
|
||||
if( c.getComponentOrientation().isLeftToRight() )
|
||||
insets.left += indent;
|
||||
else
|
||||
insets.right += indent;
|
||||
}
|
||||
}
|
||||
|
||||
return insets;
|
||||
}
|
||||
|
||||
@@ -1024,6 +1151,35 @@ public class FlatComboBoxUI
|
||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||
if( rendererBorder != null )
|
||||
rendererBorder.paintBorder( c, g, x, y, width, height );
|
||||
|
||||
// style "mac"
|
||||
if( c instanceof JComponent ) {
|
||||
Boolean macStyleHint = clientPropertyBooleanStrict( (JComponent) c, KEY_MAC_STYLE_HINT, null );
|
||||
if( macStyleHint == Boolean.TRUE ) {
|
||||
// paint "checked item" icon
|
||||
int ix = c.getComponentOrientation().isLeftToRight()
|
||||
? x + scale( padding.left )
|
||||
: x + width - scale( padding.right ) - MacCheckedItemIcon.INSTANCE.getIconWidth();
|
||||
MacCheckedItemIcon.INSTANCE.paintIcon( c, g, ix, y + ((height - MacCheckedItemIcon.INSTANCE.getIconHeight()) / 2) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---- class MacCheckedItemIcon -------------------------------------------
|
||||
|
||||
/**
|
||||
* Use for style "mac" to mark checked item.
|
||||
*/
|
||||
private static class MacCheckedItemIcon
|
||||
extends FlatCheckBoxMenuItemIcon
|
||||
{
|
||||
static MacCheckedItemIcon INSTANCE = new MacCheckedItemIcon();
|
||||
|
||||
@Override
|
||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||
g2.setColor( c.getForeground() );
|
||||
paintCheckmark( g2 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -243,11 +243,13 @@ public class FlatFileChooserUI
|
||||
borderLayout.setHgap( 8 );
|
||||
|
||||
Component north = borderLayout.getLayoutComponent( BorderLayout.NORTH );
|
||||
Component lineEnd = borderLayout.getLayoutComponent( BorderLayout.LINE_END );
|
||||
Component center = borderLayout.getLayoutComponent( BorderLayout.CENTER );
|
||||
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 ) );
|
||||
p.add( north, BorderLayout.NORTH );
|
||||
p.add( lineEnd, BorderLayout.LINE_END );
|
||||
p.add( center, BorderLayout.CENTER );
|
||||
p.add( south, BorderLayout.SOUTH );
|
||||
fc.add( p, BorderLayout.CENTER );
|
||||
|
||||
@@ -17,20 +17,34 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Map;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
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.event.ListSelectionListener;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicComboBoxRenderer;
|
||||
import javax.swing.plaf.basic.BasicListUI;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* 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.selectionInactiveForeground Color
|
||||
* @uiDefault List.selectionInsets Insets
|
||||
* @uiDefault List.selectionArc int
|
||||
*
|
||||
* <!-- FlatListCellBorder -->
|
||||
*
|
||||
@@ -76,6 +92,8 @@ public class FlatListUI
|
||||
@Styleable protected Color selectionForeground;
|
||||
@Styleable protected Color selectionInactiveBackground;
|
||||
@Styleable protected Color selectionInactiveForeground;
|
||||
/** @since 3 */ @Styleable protected Insets selectionInsets;
|
||||
/** @since 3 */ @Styleable protected int selectionArc;
|
||||
|
||||
// for FlatListCellBorder
|
||||
/** @since 2 */ @Styleable protected Insets cellMargins;
|
||||
@@ -110,6 +128,8 @@ public class FlatListUI
|
||||
selectionForeground = UIManager.getColor( "List.selectionForeground" );
|
||||
selectionInactiveBackground = UIManager.getColor( "List.selectionInactiveBackground" );
|
||||
selectionInactiveForeground = UIManager.getColor( "List.selectionInactiveForeground" );
|
||||
selectionInsets = UIManager.getInsets( "List.selectionInsets" );
|
||||
selectionArc = UIManager.getInt( "List.selectionArc" );
|
||||
|
||||
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 */
|
||||
protected void installStyle() {
|
||||
try {
|
||||
@@ -247,4 +290,164 @@ public class FlatListUI
|
||||
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;
|
||||
|
||||
// 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.5 */ @Styleable protected Color selectionBackground;
|
||||
/** @since 2.5 */ @Styleable protected Color selectionForeground;
|
||||
|
||||
@@ -63,6 +63,8 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
* @uiDefault MenuItem.acceleratorArrowGap int
|
||||
* @uiDefault MenuItem.checkBackground Color
|
||||
* @uiDefault MenuItem.checkMargins Insets
|
||||
* @uiDefault MenuItem.selectionInsets Insets
|
||||
* @uiDefault MenuItem.selectionArc int
|
||||
* @uiDefault MenuItem.selectionType String null (default) or underline
|
||||
* @uiDefault MenuItem.underlineSelectionBackground Color
|
||||
* @uiDefault MenuItem.underlineSelectionCheckBackground Color
|
||||
@@ -91,6 +93,9 @@ public class FlatMenuItemRenderer
|
||||
@Styleable protected Color checkBackground = UIManager.getColor( "MenuItem.checkBackground" );
|
||||
@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 underlineSelectionCheckBackground = UIManager.getColor( "MenuItem.underlineSelectionCheckBackground" );
|
||||
@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 );
|
||||
debug*/
|
||||
|
||||
boolean armedOrSelected = isArmedOrSelected( menuItem );
|
||||
boolean underlineSelection = isUnderlineSelection();
|
||||
paintBackground( g, underlineSelection ? underlineSelectionBackground : selectionBackground );
|
||||
if( underlineSelection && isArmedOrSelected( menuItem ) )
|
||||
paintUnderlineSelection( g, underlineSelectionColor, underlineSelectionHeight );
|
||||
|
||||
paintBackground( g );
|
||||
if( armedOrSelected ) {
|
||||
if( underlineSelection )
|
||||
paintUnderlineSelection( g, underlineSelectionBackground, underlineSelectionColor, underlineSelectionHeight );
|
||||
else
|
||||
paintSelection( g, selectionBackground, selectionInsets, selectionArc );
|
||||
}
|
||||
paintIcon( g, iconRect, getIconForPainting(), underlineSelection ? underlineSelectionCheckBackground : checkBackground, selectionBackground );
|
||||
paintText( g, textRect, menuItem.getText(), selectionForeground, disabledForeground );
|
||||
paintAccelerator( g, accelRect, getAcceleratorText(), acceleratorForeground, acceleratorSelectionForeground, disabledForeground );
|
||||
@@ -348,21 +359,35 @@ debug*/
|
||||
paintArrowIcon( g, arrowRect, arrowIcon );
|
||||
}
|
||||
|
||||
protected void paintBackground( Graphics g, Color selectionBackground ) {
|
||||
boolean armedOrSelected = isArmedOrSelected( menuItem );
|
||||
if( menuItem.isOpaque() || armedOrSelected ) {
|
||||
// paint background
|
||||
g.setColor( armedOrSelected
|
||||
? deriveBackground( selectionBackground )
|
||||
: menuItem.getBackground() );
|
||||
/** @since 3 */
|
||||
protected void paintBackground( Graphics g ) {
|
||||
if( menuItem.isOpaque() ) {
|
||||
g.setColor( menuItem.getBackground() );
|
||||
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 height = menuItem.getHeight();
|
||||
|
||||
// paint background
|
||||
g.setColor( deriveBackground( underlineSelectionBackground ) );
|
||||
g.fillRect( 0, 0, width, height );
|
||||
|
||||
// paint underline
|
||||
int underlineHeight = scale( underlineSelectionHeight );
|
||||
g.setColor( underlineSelectionColor );
|
||||
if( isTopLevelMenu( menuItem ) ) {
|
||||
@@ -500,7 +525,11 @@ debug*/
|
||||
|
||||
private Font getTopLevelFont() {
|
||||
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() {
|
||||
|
||||
@@ -20,7 +20,9 @@ import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
@@ -32,7 +34,9 @@ import javax.swing.JComponent;
|
||||
import javax.swing.JMenu;
|
||||
import javax.swing.JMenuBar;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.MouseInputListener;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
@@ -75,9 +79,12 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
||||
*
|
||||
* <!-- FlatMenuRenderer -->
|
||||
*
|
||||
* @uiDefault MenuBar.selectionInsets Insets
|
||||
* @uiDefault MenuBar.selectionEmbeddedInsets Insets
|
||||
* @uiDefault MenuBar.selectionArc int
|
||||
* @uiDefault MenuBar.hoverBackground Color
|
||||
* @uiDefault MenuBar.selectionBackground Color
|
||||
* @uiDefault MenuBar.selectionForeground Color
|
||||
* @uiDefault MenuBar.selectionBackground Color optional; defaults to Menu.selectionBackground
|
||||
* @uiDefault MenuBar.selectionForeground Color optional; defaults to Menu.selectionForeground
|
||||
* @uiDefault MenuBar.underlineSelectionBackground Color
|
||||
* @uiDefault MenuBar.underlineSelectionColor Color
|
||||
* @uiDefault MenuBar.underlineSelectionHeight int
|
||||
@@ -225,12 +232,15 @@ public class FlatMenuUI
|
||||
protected class FlatMenuRenderer
|
||||
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 menuBarSelectionBackground = UIManager.getColor( "MenuBar.selectionBackground" );
|
||||
protected Color menuBarSelectionForeground = UIManager.getColor( "MenuBar.selectionForeground" );
|
||||
protected Color menuBarUnderlineSelectionBackground = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionBackground", underlineSelectionBackground );
|
||||
protected Color menuBarUnderlineSelectionColor = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionColor", underlineSelectionColor );
|
||||
protected int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", underlineSelectionHeight );
|
||||
/** @since 2.5 */ protected Color menuBarSelectionBackground = UIManager.getColor( "MenuBar.selectionBackground" );
|
||||
/** @since 2.5 */ protected Color menuBarSelectionForeground = UIManager.getColor( "MenuBar.selectionForeground" );
|
||||
protected Color menuBarUnderlineSelectionBackground = UIManager.getColor( "MenuBar.underlineSelectionBackground" );
|
||||
protected Color menuBarUnderlineSelectionColor = UIManager.getColor( "MenuBar.underlineSelectionColor" );
|
||||
protected int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", -1 );
|
||||
|
||||
protected FlatMenuRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon,
|
||||
Font acceleratorFont, String acceleratorDelimiter )
|
||||
@@ -238,46 +248,76 @@ public class FlatMenuUI
|
||||
super( menuItem, checkIcon, arrowIcon, acceleratorFont, acceleratorDelimiter );
|
||||
}
|
||||
|
||||
/** @since 3 */
|
||||
@Override
|
||||
protected void paintBackground( Graphics g, Color selectionBackground ) {
|
||||
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
||||
if( isUnderlineSelection() )
|
||||
selectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground );
|
||||
else {
|
||||
selectionBackground = getStyleFromMenuBarUI( ui -> ui.selectionBackground,
|
||||
menuBarSelectionBackground != null ? menuBarSelectionBackground : selectionBackground );
|
||||
}
|
||||
protected void paintBackground( Graphics g ) {
|
||||
super.paintBackground( g );
|
||||
|
||||
ButtonModel model = menuItem.getModel();
|
||||
if( model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled() ) {
|
||||
g.setColor( deriveBackground( getStyleFromMenuBarUI( ui -> ui.hoverBackground, hoverBackground ) ) );
|
||||
if( ((JMenu)menuItem).isTopLevelMenu() && isHover() ) {
|
||||
// paint hover background
|
||||
Color color = deriveBackground( getStyleFromMenuBarUI( ui -> ui.hoverBackground, hoverBackground ) );
|
||||
if( isUnderlineSelection() ) {
|
||||
g.setColor( color );
|
||||
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
|
||||
protected void paintText( Graphics g, Rectangle textRect, String text, Color selectionForeground, Color disabledForeground ) {
|
||||
if( ((JMenu)menuItem).isTopLevelMenu() && !isUnderlineSelection() ) {
|
||||
selectionForeground = getStyleFromMenuBarUI( ui -> ui.selectionForeground,
|
||||
menuBarSelectionForeground != null ? menuBarSelectionForeground : selectionForeground );
|
||||
}
|
||||
if( ((JMenu)menuItem).isTopLevelMenu() && !isUnderlineSelection() )
|
||||
selectionForeground = getStyleFromMenuBarUI( ui -> ui.selectionForeground, menuBarSelectionForeground, selectionForeground );
|
||||
|
||||
super.paintText( g, textRect, text, selectionForeground, disabledForeground );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) {
|
||||
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
||||
underlineSelectionColor = getStyleFromMenuBarUI( ui -> ui.underlineSelectionColor, menuBarUnderlineSelectionColor );
|
||||
underlineSelectionHeight = getStyleFromMenuBarUI( ui -> (ui.underlineSelectionHeight != -1)
|
||||
? ui.underlineSelectionHeight : null, menuBarUnderlineSelectionHeight );
|
||||
}
|
||||
private boolean isHover() {
|
||||
ButtonModel model = menuItem.getModel();
|
||||
return model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
|
||||
@@ -48,27 +48,25 @@ class FlatNativeLibrary
|
||||
|
||||
String libraryName;
|
||||
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";
|
||||
if( SystemInfo.isX86_64 )
|
||||
libraryName += "_64";
|
||||
|
||||
// load jawt native library
|
||||
if( !SystemInfo.isJava_9_orLater ) {
|
||||
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
||||
// is not found when running application with <jdk>/bin/java.exe.
|
||||
// When using <jdk>/jre/bin/java.exe, it is found.
|
||||
// jawt.dll is located in <jdk>/jre/bin/.
|
||||
// Java 9 and later do not have this problem.
|
||||
loadJAWT();
|
||||
}
|
||||
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
||||
// is not found when running application with <jdk>/bin/java.exe.
|
||||
// When using <jdk>/jre/bin/java.exe, it is found.
|
||||
// jawt.dll is located in <jdk>/jre/bin/.
|
||||
// Java 9 and later do not have this problem,
|
||||
// but load jawt.dll anyway to be on the safe side.
|
||||
loadJAWT();
|
||||
} else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) {
|
||||
// Linux: requires 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.
|
||||
// E.g. not found in Java 13 and later from openjdk.java.net.
|
||||
// There seems to be also differences between distributions.
|
||||
@@ -84,11 +82,19 @@ class FlatNativeLibrary
|
||||
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
||||
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
||||
if( libraryPath != null ) {
|
||||
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||
if( libraryFile.exists() )
|
||||
return new NativeLibrary( libraryFile, true );
|
||||
else
|
||||
if( "system".equals( libraryPath ) ) {
|
||||
NativeLibrary library = new NativeLibrary( libraryName, true );
|
||||
if( library.isLoaded() )
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
String message = ex.getMessage();
|
||||
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
LoggingFacade.INSTANCE.logSevere( message, ex );
|
||||
} catch( Exception ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,11 +349,23 @@ public class FlatRootPaneUI
|
||||
titlePane.updateIcon();
|
||||
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_FOREGROUND:
|
||||
if( titlePane != null )
|
||||
titlePane.titleBarColorsChanged();
|
||||
break;
|
||||
|
||||
case FlatClientProperties.GLASS_PANE_FULL_HEIGHT:
|
||||
rootPane.revalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,11 +446,11 @@ public class FlatRootPaneUI
|
||||
int width = rootPane.getWidth() - insets.left - insets.right;
|
||||
int height = rootPane.getHeight() - insets.top - insets.bottom;
|
||||
|
||||
// layered pane
|
||||
if( rootPane.getLayeredPane() != null )
|
||||
rootPane.getLayeredPane().setBounds( x, y, width, height );
|
||||
if( rootPane.getGlassPane() != null )
|
||||
rootPane.getGlassPane().setBounds( x, y, width, height );
|
||||
|
||||
// title pane
|
||||
int nextY = 0;
|
||||
if( titlePane != null ) {
|
||||
int prefHeight = !isFullScreen ? titlePane.getPreferredSize().height : 0;
|
||||
@@ -446,6 +458,15 @@ public class FlatRootPaneUI
|
||||
nextY += prefHeight;
|
||||
}
|
||||
|
||||
// glass pane
|
||||
if( rootPane.getGlassPane() != null ) {
|
||||
boolean fullHeight = FlatClientProperties.clientPropertyBoolean(
|
||||
rootPane, FlatClientProperties.GLASS_PANE_FULL_HEIGHT, false );
|
||||
int offset = fullHeight ? 0 : nextY;
|
||||
rootPane.getGlassPane().setBounds( x, y + offset, width, height - offset );
|
||||
}
|
||||
|
||||
// menu bar
|
||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||
if( menuBar != null && menuBar.isVisible() ) {
|
||||
boolean embedded = !isFullScreen && titlePane != null && titlePane.isMenuBarEmbedded();
|
||||
@@ -459,10 +480,12 @@ public class FlatRootPaneUI
|
||||
}
|
||||
}
|
||||
|
||||
// content pane
|
||||
Container contentPane = rootPane.getContentPane();
|
||||
if( contentPane != null )
|
||||
contentPane.setBounds( 0, nextY, width, Math.max( height - nextY, 0 ) );
|
||||
|
||||
// title pane
|
||||
if( titlePane != null )
|
||||
titlePane.menuBarLayouted();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.SpinnerUI;
|
||||
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)
|
||||
/** @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
|
||||
protected int getArc( Component c ) {
|
||||
if( isCellEditor( c ) )
|
||||
@@ -43,6 +59,17 @@ public class FlatRoundBorder
|
||||
Boolean roundRect = FlatUIUtils.isRoundRect( c );
|
||||
if( roundRect == null )
|
||||
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
|
||||
protected void paintTrack( Graphics g, JComponent c, Rectangle trackBounds ) {
|
||||
if( trackBounds.isEmpty() || !scrollbar.isEnabled() )
|
||||
return;
|
||||
|
||||
g.setColor( getTrackColor( c, hoverTrack, isPressed && hoverTrack && !hoverThumb ) );
|
||||
paintTrackOrThumb( g, c, trackBounds, trackInsets, trackArc );
|
||||
}
|
||||
@@ -452,18 +455,31 @@ public class FlatScrollBarUI
|
||||
|
||||
@Override
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
isPressed = true;
|
||||
repaint();
|
||||
if( SwingUtilities.isLeftMouseButton( e ) || isAbsolutePositioning( e ) ) {
|
||||
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
|
||||
public void mouseReleased( MouseEvent e ) {
|
||||
isPressed = false;
|
||||
repaint();
|
||||
if( SwingUtilities.isLeftMouseButton( e ) || isAbsolutePositioning( e ) ) {
|
||||
isPressed = false;
|
||||
repaint();
|
||||
}
|
||||
|
||||
update( e.getX(), e.getY() );
|
||||
}
|
||||
|
||||
private boolean isAbsolutePositioning( MouseEvent e ) {
|
||||
return getSupportsAbsolutePositioning() && SwingUtilities.isMiddleMouseButton( e );
|
||||
}
|
||||
|
||||
private void update( int x, int y ) {
|
||||
boolean inTrack = getTrackBounds().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 ) {
|
||||
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.lineTo( x, y + (h - wh) );
|
||||
path.lineTo( x, y + arc );
|
||||
|
||||
@@ -65,7 +65,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
||||
* <!-- FlatSpinnerUI -->
|
||||
*
|
||||
* @uiDefault Component.minimumWidth int
|
||||
* @uiDefault Spinner.buttonStyle String button (default) or none
|
||||
* @uiDefault Spinner.buttonStyle String button (default), mac or none
|
||||
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||
* @uiDefault Component.isIntelliJTheme boolean
|
||||
* @uiDefault Spinner.disabledBackground Color
|
||||
@@ -340,7 +340,25 @@ public class FlatSpinnerUI
|
||||
|
||||
private Component createArrowButton( int direction, String name ) {
|
||||
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.setYOffset( (direction == SwingConstants.NORTH) ? 1.25f : -1.25f );
|
||||
if( direction == SwingConstants.NORTH )
|
||||
@@ -374,10 +392,13 @@ public class FlatSpinnerUI
|
||||
int width = c.getWidth();
|
||||
int height = c.getHeight();
|
||||
boolean enabled = spinner.isEnabled();
|
||||
boolean ltr = spinner.getComponentOrientation().isLeftToRight();
|
||||
boolean isMacStyle = isMacStyle();
|
||||
int macStyleButtonsWidth = isMacStyle ? getMacStyleButtonsWidth() : 0;
|
||||
|
||||
// paint background
|
||||
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
|
||||
boolean paintButton = !"none".equals( buttonStyle );
|
||||
@@ -386,27 +407,49 @@ public class FlatSpinnerUI
|
||||
Component button = (handler.nextButton != null) ? handler.nextButton : handler.previousButton;
|
||||
int arrowX = button.getX();
|
||||
int arrowWidth = button.getWidth();
|
||||
boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight();
|
||||
|
||||
// paint arrow buttons background
|
||||
if( enabled && buttonBackground != null ) {
|
||||
g2.setColor( buttonBackground );
|
||||
Shape oldClip = g2.getClip();
|
||||
if( isLeftToRight )
|
||||
g2.clipRect( arrowX, 0, width - arrowX, height );
|
||||
else
|
||||
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
|
||||
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
||||
g2.setClip( oldClip );
|
||||
}
|
||||
|
||||
// paint vertical line between value and arrow buttons
|
||||
Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor;
|
||||
if( separatorColor != null && buttonSeparatorWidth > 0 ) {
|
||||
g2.setColor( separatorColor );
|
||||
|
||||
if( 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 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 );
|
||||
}
|
||||
|
||||
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 ------------------------------------------------------
|
||||
|
||||
private class Handler
|
||||
@@ -471,6 +527,7 @@ public class FlatSpinnerUI
|
||||
Insets insets = parent.getInsets();
|
||||
Rectangle r = FlatUIUtils.subtractInsets( new Rectangle( size ), insets );
|
||||
|
||||
// editor gets all space if there are no buttons
|
||||
if( nextButton == null && previousButton == null ) {
|
||||
if( editor != null )
|
||||
editor.setBounds( r );
|
||||
@@ -483,22 +540,39 @@ public class FlatSpinnerUI
|
||||
// limit buttons width to height of a raw spinner (without insets)
|
||||
FontMetrics fm = spinner.getFontMetrics( spinner.getFont() );
|
||||
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
||||
int minButtonWidth = (maxButtonWidth * 3) / 4;
|
||||
|
||||
// make button area square (if spinner has preferred height)
|
||||
int buttonsWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
|
||||
// make button area square (except if width is limited)
|
||||
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;
|
||||
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() ) {
|
||||
editorRect.width -= buttonsWidth;
|
||||
buttonsRect.x += editorRect.width;
|
||||
} else {
|
||||
editorRect.x += buttonsWidth;
|
||||
editorRect.width -= buttonsWidth;
|
||||
// in mac button style increase buttons height and move to the right
|
||||
// for exact alignment with border
|
||||
if( isMacStyle ) {
|
||||
int lineWidth = Math.round( FlatUIUtils.getBorderLineWidth( spinner ) );
|
||||
if( lineWidth > 0 ) {
|
||||
buttonsRect.x += ltr ? lineWidth : -lineWidth;
|
||||
buttonsRect.y -= lineWidth;
|
||||
buttonsRect.height += lineWidth * 2;
|
||||
}
|
||||
}
|
||||
|
||||
// set editor bounds
|
||||
if( editor != null )
|
||||
editor.setBounds( editorRect );
|
||||
|
||||
// set buttons bounds
|
||||
int nextHeight = (buttonsRect.height / 2) + (buttonsRect.height % 2); // round up
|
||||
if( nextButton != null )
|
||||
nextButton.setBounds( buttonsRect.x, buttonsRect.y, buttonsRect.width, nextHeight );
|
||||
|
||||
@@ -2589,7 +2589,7 @@ public class FlatTabbedPaneUI
|
||||
public void mousePressed( MouseEvent e ) {
|
||||
updateRollover( e );
|
||||
|
||||
if( !isPressedTabClose() )
|
||||
if( !isPressedTabClose() && SwingUtilities.isLeftMouseButton( e ) )
|
||||
mouseDelegate.mousePressed( e );
|
||||
}
|
||||
|
||||
@@ -2644,7 +2644,7 @@ public class FlatTabbedPaneUI
|
||||
|
||||
// check whether mouse hit tab close area
|
||||
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;
|
||||
setRolloverTabClose( hitClose );
|
||||
setPressedTabClose( hitClose && tabIndex == pressedTabIndex );
|
||||
|
||||
@@ -107,6 +107,8 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
public class FlatTitlePane
|
||||
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" );
|
||||
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" );
|
||||
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
|
||||
@@ -354,15 +356,12 @@ public class FlatTitlePane
|
||||
if( window == null || rootPane.getWindowDecorationStyle() != JRootPane.FRAME )
|
||||
return;
|
||||
|
||||
updateVisibility();
|
||||
|
||||
if( window instanceof Frame ) {
|
||||
Frame frame = (Frame) window;
|
||||
boolean resizable = frame.isResizable();
|
||||
boolean maximized = ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0);
|
||||
|
||||
iconifyButton.setVisible( true );
|
||||
maximizeButton.setVisible( resizable && !maximized );
|
||||
restoreButton.setVisible( resizable && maximized );
|
||||
|
||||
if( maximized &&
|
||||
!(SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window )) &&
|
||||
rootPane.getClientProperty( "_flatlaf.maximizedBoundsUpToDate" ) == null )
|
||||
@@ -383,14 +382,27 @@ public class FlatTitlePane
|
||||
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 {
|
||||
// hide buttons because they are only supported in frames
|
||||
iconifyButton.setVisible( false );
|
||||
maximizeButton.setVisible( false );
|
||||
restoreButton.setVisible( false );
|
||||
|
||||
revalidate();
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,11 +578,13 @@ public class FlatTitlePane
|
||||
doLayout();
|
||||
}
|
||||
|
||||
/*debug
|
||||
@Override
|
||||
public void paint( Graphics g ) {
|
||||
super.paint( g );
|
||||
|
||||
if( !UIManager.getBoolean( KEY_DEBUG_SHOW_RECTANGLES ) )
|
||||
return;
|
||||
|
||||
if( debugTitleBarHeight > 0 ) {
|
||||
g.setColor( Color.green );
|
||||
g.drawLine( 0, debugTitleBarHeight, getWidth(), debugTitleBarHeight );
|
||||
@@ -594,7 +608,6 @@ public class FlatTitlePane
|
||||
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
|
||||
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
|
||||
}
|
||||
debug*/
|
||||
|
||||
@Override
|
||||
protected void paintComponent( Graphics g ) {
|
||||
@@ -923,15 +936,14 @@ debug*/
|
||||
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight,
|
||||
hitTestSpots, appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
|
||||
|
||||
/*debug
|
||||
debugTitleBarHeight = titleBarHeight;
|
||||
debugHitTestSpots = hitTestSpots;
|
||||
debugAppIconBounds = appIconBounds;
|
||||
debugMinimizeButtonBounds = minimizeButtonBounds;
|
||||
debugMaximizeButtonBounds = maximizeButtonBounds;
|
||||
debugCloseButtonBounds = closeButtonBounds;
|
||||
repaint();
|
||||
debug*/
|
||||
if( UIManager.getBoolean( KEY_DEBUG_SHOW_RECTANGLES ) )
|
||||
repaint();
|
||||
}
|
||||
|
||||
private Rectangle boundsInWindow( JComponent c ) {
|
||||
@@ -950,14 +962,12 @@ debug*/
|
||||
return r;
|
||||
}
|
||||
|
||||
/*debug
|
||||
private int debugTitleBarHeight;
|
||||
private List<Rectangle> debugHitTestSpots;
|
||||
private Rectangle debugAppIconBounds;
|
||||
private Rectangle debugMinimizeButtonBounds;
|
||||
private Rectangle debugMaximizeButtonBounds;
|
||||
private Rectangle debugCloseButtonBounds;
|
||||
debug*/
|
||||
|
||||
//---- class FlatTitlePaneBorder ------------------------------------------
|
||||
|
||||
|
||||
@@ -20,15 +20,24 @@ import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.FocusTraversalPolicy;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ContainerEvent;
|
||||
import java.awt.event.ContainerListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Map;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.ButtonGroup;
|
||||
import javax.swing.ButtonModel;
|
||||
import javax.swing.DefaultButtonModel;
|
||||
import javax.swing.InputMap;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JToolBar;
|
||||
import javax.swing.LayoutFocusTraversalPolicy;
|
||||
import javax.swing.UIManager;
|
||||
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.StyleableUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* 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.arrowKeysOnlyNavigation boolean
|
||||
* @uiDefault ToolBar.floatable boolean
|
||||
* @uiDefault ToolBar.hoverButtonGroupArc int
|
||||
* @uiDefault ToolBar.hoverButtonGroupBackground Color
|
||||
*
|
||||
* <!-- FlatToolBarBorder -->
|
||||
*
|
||||
@@ -72,6 +84,8 @@ public class FlatToolBarUI
|
||||
{
|
||||
/** @since 1.4 */ @Styleable protected boolean focusableButtons;
|
||||
/** @since 2 */ @Styleable protected boolean arrowKeysOnlyNavigation;
|
||||
/** @since 3 */ @Styleable protected int hoverButtonGroupArc;
|
||||
/** @since 3 */ @Styleable protected Color hoverButtonGroupBackground;
|
||||
|
||||
// for FlatToolBarBorder
|
||||
@Styleable protected Insets borderMargins;
|
||||
@@ -119,6 +133,8 @@ public class FlatToolBarUI
|
||||
|
||||
focusableButtons = UIManager.getBoolean( "ToolBar.focusableButtons" );
|
||||
arrowKeysOnlyNavigation = UIManager.getBoolean( "ToolBar.arrowKeysOnlyNavigation" );
|
||||
hoverButtonGroupArc = UIManager.getInt( "ToolBar.hoverButtonGroupArc" );
|
||||
hoverButtonGroupBackground = UIManager.getColor( "ToolBar.hoverButtonGroupBackground" );
|
||||
|
||||
// floatable
|
||||
if( !UIManager.getBoolean( "ToolBar.floatable" ) ) {
|
||||
@@ -132,6 +148,8 @@ public class FlatToolBarUI
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
hoverButtonGroupBackground = null;
|
||||
|
||||
if( oldFloatable != null ) {
|
||||
toolBar.setFloatable( oldFloatable );
|
||||
oldFloatable = null;
|
||||
@@ -329,6 +347,99 @@ public class FlatToolBarUI
|
||||
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 ------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,15 +17,19 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.MouseListener;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import javax.swing.CellRendererPane;
|
||||
import javax.swing.Icon;
|
||||
@@ -36,6 +40,7 @@ import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.JTree.DropLocation;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.basic.BasicTreeUI;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
@@ -96,8 +101,11 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Tree.selectionForeground Color
|
||||
* @uiDefault Tree.selectionInactiveBackground Color
|
||||
* @uiDefault Tree.selectionInactiveForeground Color
|
||||
* @uiDefault Tree.selectionInsets Insets
|
||||
* @uiDefault Tree.selectionArc int
|
||||
* @uiDefault Tree.wideSelection boolean
|
||||
* @uiDefault Tree.showCellFocusIndicator boolean
|
||||
* @uiDefault Tree.showDefaultIcons boolean
|
||||
*
|
||||
* <!-- FlatTreeExpandedIcon -->
|
||||
*
|
||||
@@ -132,8 +140,11 @@ public class FlatTreeUI
|
||||
@Styleable protected Color selectionInactiveBackground;
|
||||
@Styleable protected Color selectionInactiveForeground;
|
||||
@Styleable protected Color selectionBorderColor;
|
||||
/** @since 3 */ @Styleable protected Insets selectionInsets;
|
||||
/** @since 3 */ @Styleable protected int selectionArc;
|
||||
@Styleable protected boolean wideSelection;
|
||||
@Styleable protected boolean showCellFocusIndicator;
|
||||
/** @since 3 */ protected boolean showDefaultIcons;
|
||||
|
||||
// for icons
|
||||
// (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)
|
||||
/** @since 2 */ @Styleable protected boolean paintSelection = true;
|
||||
|
||||
private boolean paintLines;
|
||||
private Color defaultCellNonSelectionBackground;
|
||||
private Color defaultSelectionBackground;
|
||||
private Color defaultSelectionForeground;
|
||||
@@ -175,9 +187,13 @@ public class FlatTreeUI
|
||||
selectionInactiveBackground = UIManager.getColor( "Tree.selectionInactiveBackground" );
|
||||
selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" );
|
||||
selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" );
|
||||
selectionInsets = UIManager.getInsets( "Tree.selectionInsets" );
|
||||
selectionArc = UIManager.getInt( "Tree.selectionArc" );
|
||||
wideSelection = UIManager.getBoolean( "Tree.wideSelection" );
|
||||
showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" );
|
||||
showDefaultIcons = UIManager.getBoolean( "Tree.showDefaultIcons" );
|
||||
|
||||
paintLines = UIManager.getBoolean( "Tree.paintLines" );
|
||||
defaultCellNonSelectionBackground = UIManager.getColor( "Tree.textBackground" );
|
||||
defaultSelectionBackground = selectionBackground;
|
||||
defaultSelectionForeground = selectionForeground;
|
||||
@@ -210,6 +226,19 @@ public class FlatTreeUI
|
||||
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
|
||||
protected MouseListener createMouseListener() {
|
||||
return new BasicTreeUI.MouseHandler() {
|
||||
@@ -295,6 +324,34 @@ public class FlatTreeUI
|
||||
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
|
||||
public Rectangle getPathBounds( JTree tree, TreePath path ) {
|
||||
Rectangle bounds = super.getPathBounds( tree, path );
|
||||
@@ -346,8 +403,127 @@ public class FlatTreeUI
|
||||
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.
|
||||
*/
|
||||
@Override
|
||||
@@ -428,7 +604,7 @@ public class FlatTreeUI
|
||||
paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf );
|
||||
} else {
|
||||
// non-wide selection
|
||||
paintCellBackground( g, rendererComponent, bounds );
|
||||
paintCellBackground( g, rendererComponent, bounds, row, true );
|
||||
}
|
||||
|
||||
// this is actually not necessary because renderer should always set color
|
||||
@@ -442,7 +618,7 @@ public class FlatTreeUI
|
||||
if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
|
||||
Color oldColor = g.getColor();
|
||||
g.setColor( bg );
|
||||
paintCellBackground( g, rendererComponent, bounds );
|
||||
paintCellBackground( g, rendererComponent, bounds, row, false );
|
||||
g.setColor( oldColor );
|
||||
}
|
||||
}
|
||||
@@ -497,17 +673,23 @@ public class FlatTreeUI
|
||||
private void paintWideSelection( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds,
|
||||
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
|
||||
// (was already painted before, but painted over with wide selection)
|
||||
if( shouldPaintExpandControl( path, row, isExpanded, hasBeenExpanded, isLeaf ) ) {
|
||||
paintExpandControl( g, clipBounds, insets, bounds,
|
||||
path, row, isExpanded, hasBeenExpanded, isLeaf );
|
||||
if( useUnitedRoundedSelection() ) {
|
||||
if( row > 0 && tree.isRowSelected( row - 1 ) )
|
||||
arcTop = 0;
|
||||
if( row < tree.getRowCount() - 1 && tree.isRowSelected( row + 1 ) )
|
||||
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 imageOffset = 0;
|
||||
|
||||
@@ -520,7 +702,42 @@ public class FlatTreeUI
|
||||
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.geom.Ellipse2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.util.IdentityHashMap;
|
||||
@@ -76,8 +77,6 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
*/
|
||||
public class FlatUIUtils
|
||||
{
|
||||
public static final boolean MAC_USE_QUARTZ = Boolean.getBoolean( "apple.awt.graphics.UseQuartz" );
|
||||
|
||||
private static boolean useSharedUIs = true;
|
||||
private static final WeakHashMap<LookAndFeel, IdentityHashMap<Object, ComponentUI>> sharedUIinstances = new WeakHashMap<>();
|
||||
|
||||
@@ -210,6 +209,9 @@ public class FlatUIUtils
|
||||
}
|
||||
|
||||
public static boolean isCellEditor( Component c ) {
|
||||
if( c == null )
|
||||
return false;
|
||||
|
||||
// check whether used in cell editor (check 3 levels up)
|
||||
Component c2 = c;
|
||||
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_STROKE_CONTROL,
|
||||
MAC_USE_QUARTZ ? RenderingHints.VALUE_STROKE_PURE : RenderingHints.VALUE_STROKE_NORMALIZE );
|
||||
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE );
|
||||
|
||||
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>
|
||||
* 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)}.
|
||||
* 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>
|
||||
*
|
||||
* <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)]}.
|
||||
* The focus border and the border may paint over the background.
|
||||
* <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,
|
||||
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,
|
||||
float lineWidth, float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight )
|
||||
@@ -801,7 +846,7 @@ public class FlatUIUtils
|
||||
double ciBottomLeft = arcBottomLeft * 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.curveTo( x2 - ciTopRight, y,
|
||||
x2, y + ciTopRight,
|
||||
@@ -823,6 +868,27 @@ public class FlatUIUtils
|
||||
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.
|
||||
*
|
||||
@@ -835,13 +901,15 @@ public class FlatUIUtils
|
||||
* {@link SwingConstants#WEST} or {@link SwingConstants#EAST})
|
||||
* @param chevron {@code true} for chevron arrow, {@code false} for triangle arrow
|
||||
* @param arrowSize the width of the painted arrow (for vertical direction) (will be scaled)
|
||||
* @param arrowThickness the thickness of the painted chevron arrow (will be scaled)
|
||||
* @param xOffset an offset added to the x coordinate of the arrow to paint it out-of-center. Usually zero. (will be scaled)
|
||||
* @param yOffset an offset added to the y coordinate of the arrow to paint it out-of-center. Usually zero. (will be scaled)
|
||||
*
|
||||
* @since 1.1
|
||||
* @since 3
|
||||
*/
|
||||
public static void paintArrow( Graphics2D g, int x, int y, int width, int height,
|
||||
int direction, boolean chevron, int arrowSize, float xOffset, float yOffset )
|
||||
int direction, boolean chevron, int arrowSize, float arrowThickness,
|
||||
float xOffset, float yOffset )
|
||||
{
|
||||
// compute arrow width/height
|
||||
// - make chevron arrows one pixel smaller because coordinates are based on center of pixels (0.5/0.5)
|
||||
@@ -875,7 +943,7 @@ debug*/
|
||||
Shape arrowShape = createArrowShape( direction, chevron, aw, ah );
|
||||
if( chevron ) {
|
||||
Stroke oldStroke = g.getStroke();
|
||||
g.setStroke( new BasicStroke( UIScale.scale( 1f ) ) );
|
||||
g.setStroke( new BasicStroke( UIScale.scale( arrowThickness ) ) );
|
||||
drawShapePure( g, arrowShape );
|
||||
g.setStroke( oldStroke );
|
||||
} else {
|
||||
@@ -932,6 +1000,12 @@ 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.
|
||||
*/
|
||||
@@ -943,15 +1017,88 @@ debug*/
|
||||
* Creates an open or closed path for the given 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] );
|
||||
for( int i = 2; i < points.length; i += 2 )
|
||||
path.lineTo( points[i], points[i + 1] );
|
||||
for( int i = 2; i < points.length; ) {
|
||||
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 )
|
||||
path.closePath();
|
||||
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.
|
||||
* The x/y coordinates of the shape are translated by a half pixel.
|
||||
|
||||
@@ -606,9 +606,10 @@ debug*/
|
||||
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR ) {
|
||||
newBounds.height = (yOnScreen + dragBottomOffset) - newBounds.y;
|
||||
if( limitToParentBounds() ) {
|
||||
int parentHeight = getParentBounds().height;
|
||||
if( newBounds.y + newBounds.height > parentHeight )
|
||||
newBounds.height = parentHeight - newBounds.y;
|
||||
Rectangle parentBounds = getParentBounds();
|
||||
int parentBottomY = parentBounds.y + parentBounds.height;
|
||||
if( newBounds.y + newBounds.height > parentBottomY )
|
||||
newBounds.height = parentBottomY - newBounds.y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -624,9 +625,10 @@ debug*/
|
||||
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR ) {
|
||||
newBounds.width = (xOnScreen + dragRightOffset) - newBounds.x;
|
||||
if( limitToParentBounds() ) {
|
||||
int parentWidth = getParentBounds().width;
|
||||
if( newBounds.x + newBounds.width > parentWidth )
|
||||
newBounds.width = parentWidth - newBounds.x;
|
||||
Rectangle parentBounds = getParentBounds();
|
||||
int parentRightX = parentBounds.x + parentBounds.width;
|
||||
if( newBounds.x + newBounds.width > parentRightX )
|
||||
newBounds.width = parentRightX - newBounds.x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,6 +105,19 @@ public class ColorFunctions
|
||||
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.
|
||||
* <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;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.font.GlyphVector;
|
||||
@@ -141,37 +142,103 @@ public class HiDPIUtils
|
||||
if( !useTextYCorrection() || !SystemInfo.isWindows )
|
||||
return 0;
|
||||
|
||||
if( !SystemInfo.isJava_9_orLater )
|
||||
return UIScale.getUserScaleFactor() > 1 ? -UIScale.scale( 0.625f ) : 0;
|
||||
if( !SystemInfo.isJava_9_orLater ) {
|
||||
// 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();
|
||||
double scaleY = t.getScaleY();
|
||||
if( scaleY < 1.25 )
|
||||
return 0;
|
||||
case "Noto Sans":
|
||||
case "Open Sans":
|
||||
return -(0.3f * scaleFactor);
|
||||
|
||||
// Text is painted at slightly different Y positions depending on scale factor
|
||||
// and Y position of component.
|
||||
// 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
|
||||
// - maybe different rounding methods for drawing primitives (e.g. rectangle) and text
|
||||
// - Java adds 0.5 to X/Y positions before drawing string in BufferedTextPipe.enqueueGlyphList()
|
||||
case "Verdana":
|
||||
return -((scaleFactor < 2 ? 0.4f : 0.3f) * scaleFactor);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Java 9 and later
|
||||
|
||||
// this is not the optimal solution, but works very good in most cases
|
||||
// (tested with class FlatPaintingStringTest on Windows 10 with font "Segoe UI")
|
||||
if( scaleY <= 1.25 )
|
||||
return -0.875f;
|
||||
if( scaleY <= 1.5 )
|
||||
return -0.625f;
|
||||
if( scaleY <= 1.75 )
|
||||
return -0.875f;
|
||||
if( scaleY <= 2.0 )
|
||||
return -0.75f;
|
||||
if( scaleY <= 2.25 )
|
||||
return -0.875f;
|
||||
if( scaleY <= 3.5 )
|
||||
return -0.75f;
|
||||
return -0.875f;
|
||||
// Text is painted at slightly different Y positions depending on scale factor
|
||||
// and Y position of component.
|
||||
// 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
|
||||
// - maybe different rounding methods for drawing primitives (e.g. rectangle) and text
|
||||
// - 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
|
||||
// (tested with class FlatPaintingStringTest on Windows 11)
|
||||
|
||||
switch( g.getFont().getFamily() ) {
|
||||
case "Segoe UI":
|
||||
case "Segoe UI Light":
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <p>
|
||||
@@ -92,7 +108,7 @@ public class NativeLibrary
|
||||
? classLoader.getResource( libraryName )
|
||||
: NativeLibrary.class.getResource( "/" + libraryName );
|
||||
if( libraryUrl == null ) {
|
||||
log( "Library '" + libraryName + "' not found", null );
|
||||
LoggingFacade.INSTANCE.logSevere( "Library '" + libraryName + "' not found", null );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -125,7 +141,7 @@ public class NativeLibrary
|
||||
|
||||
return true;
|
||||
} catch( Throwable ex ) {
|
||||
log( null, ex );
|
||||
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||
|
||||
if( tempFile != null )
|
||||
deleteOrMarkForDeletion( tempFile );
|
||||
@@ -138,7 +154,24 @@ public class NativeLibrary
|
||||
System.load( libraryFile.getAbsolutePath() );
|
||||
return true;
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
@@ -158,10 +191,6 @@ public class NativeLibrary
|
||||
: System.mapLibraryName( libraryName );
|
||||
}
|
||||
|
||||
private static void log( String msg, Throwable thrown ) {
|
||||
LoggingFacade.INSTANCE.logSevere( msg, thrown );
|
||||
}
|
||||
|
||||
private static Path createTempFile( String libraryName ) throws IOException {
|
||||
int sep = libraryName.lastIndexOf( '/' );
|
||||
String name = (sep >= 0) ? libraryName.substring( sep + 1 ) : libraryName;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.util;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
@@ -102,6 +103,13 @@ debug*/
|
||||
int imageWidth = image.getWidth( 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
|
||||
if( imageWidth != destImageWidth || imageHeight != destImageHeight ) {
|
||||
// determine scaling method; default is "quality"
|
||||
|
||||
@@ -22,6 +22,7 @@ module com.formdev.flatlaf {
|
||||
|
||||
exports com.formdev.flatlaf;
|
||||
exports com.formdev.flatlaf.icons;
|
||||
exports com.formdev.flatlaf.themes;
|
||||
exports com.formdev.flatlaf.ui;
|
||||
exports com.formdev.flatlaf.util;
|
||||
|
||||
|
||||
@@ -50,8 +50,9 @@
|
||||
@selectionInactiveForeground = @foreground
|
||||
|
||||
# menu
|
||||
@menuSelectionBackground = @selectionBackground
|
||||
@menuHoverBackground = lighten(@menuBackground,10%,derived)
|
||||
@menuCheckBackground = darken(@selectionBackground,10%,derived noAutoInverse)
|
||||
@menuCheckBackground = darken(@menuSelectionBackground,10%,derived noAutoInverse)
|
||||
@menuAcceleratorForeground = darken(@foreground,15%)
|
||||
@menuAcceleratorSelectionForeground = @selectionForeground
|
||||
|
||||
@@ -62,7 +63,7 @@
|
||||
# accent colors (blueish)
|
||||
# set @accentColor to use single accent color or
|
||||
# modify @accentBaseColor to use variations of accent base color
|
||||
@accentColor = null
|
||||
@accentColor = systemColor(accent,null)
|
||||
@accentBaseColor = #4B6EAF
|
||||
@accentBase2Color = lighten(saturate(spin(@accentBaseColor,-8),13%),5%)
|
||||
# accent color variations
|
||||
@@ -349,6 +350,11 @@ ToggleButton.disabledSelectedBackground = lighten($ToggleButton.background,3%,de
|
||||
ToggleButton.toolbar.selectedBackground = lighten($ToggleButton.background,7%,derived)
|
||||
|
||||
|
||||
#---- ToolBar ----
|
||||
|
||||
ToolBar.hoverButtonGroupBackground = lighten($ToolBar.background,3%,derived)
|
||||
|
||||
|
||||
#---- ToolTip ----
|
||||
|
||||
ToolTip.border = 4,6,4,6
|
||||
|
||||
@@ -285,6 +285,10 @@ ComboBox.buttonDisabledArrowColor = @buttonDisabledArrowColor
|
||||
ComboBox.buttonHoverArrowColor = @buttonHoverArrowColor
|
||||
ComboBox.buttonPressedArrowColor = @buttonPressedArrowColor
|
||||
|
||||
ComboBox.popupInsets = 0,0,0,0
|
||||
ComboBox.selectionInsets = 0,0,0,0
|
||||
ComboBox.selectionArc = 0
|
||||
|
||||
|
||||
#---- Component ----
|
||||
|
||||
@@ -390,6 +394,8 @@ InternalFrameTitlePane.border = 0,8,0,0
|
||||
|
||||
List.border = 0,0,0,0
|
||||
List.cellMargins = 1,6,1,6
|
||||
List.selectionInsets = 0,0,0,0
|
||||
List.selectionArc = 0
|
||||
List.cellFocusColor = @cellFocusColor
|
||||
List.cellNoFocusBorder = com.formdev.flatlaf.ui.FlatListCellBorder$Default
|
||||
List.focusCellHighlightBorder = com.formdev.flatlaf.ui.FlatListCellBorder$Focused
|
||||
@@ -422,6 +428,9 @@ MenuBar.border = com.formdev.flatlaf.ui.FlatMenuBarBorder
|
||||
MenuBar.background = @menuBackground
|
||||
MenuBar.hoverBackground = @menuHoverBackground
|
||||
MenuBar.itemMargins = 3,8,3,8
|
||||
MenuBar.selectionInsets = $MenuItem.selectionInsets
|
||||
MenuBar.selectionEmbeddedInsets = $MenuItem.selectionInsets
|
||||
MenuBar.selectionArc = $MenuItem.selectionArc
|
||||
|
||||
|
||||
#---- MenuItem ----
|
||||
@@ -444,6 +453,8 @@ MenuItem.textNoAcceleratorGap = 6
|
||||
MenuItem.acceleratorArrowGap = 2
|
||||
MenuItem.acceleratorDelimiter = "+"
|
||||
[mac]MenuItem.acceleratorDelimiter = ""
|
||||
MenuItem.selectionInsets = 0,0,0,0
|
||||
MenuItem.selectionArc = 0
|
||||
|
||||
# for MenuItem.selectionType = underline
|
||||
MenuItem.underlineSelectionBackground = @menuHoverBackground
|
||||
@@ -847,6 +858,7 @@ ToolBar.borderMargins = 2,2,2,2
|
||||
ToolBar.isRollover = true
|
||||
ToolBar.focusableButtons = false
|
||||
ToolBar.arrowKeysOnlyNavigation = true
|
||||
ToolBar.hoverButtonGroupArc = 8
|
||||
ToolBar.floatable = false
|
||||
ToolBar.gripColor = @icon
|
||||
ToolBar.dockingBackground = darken($ToolBar.background,5%)
|
||||
@@ -883,10 +895,13 @@ Tree.dropCellForeground = @dropCellForeground
|
||||
Tree.dropLineColor = @dropLineColor
|
||||
Tree.rendererFillBackground = false
|
||||
Tree.rendererMargins = 1,2,1,2
|
||||
Tree.selectionInsets = 0,0,0,0
|
||||
Tree.selectionArc = 0
|
||||
Tree.wideSelection = true
|
||||
Tree.repaintWholeRow = true
|
||||
Tree.paintLines = false
|
||||
Tree.showCellFocusIndicator = false
|
||||
Tree.showDefaultIcons = false
|
||||
Tree.leftChildIndent = 7
|
||||
Tree.rightChildIndent = 11
|
||||
Tree.rowHeight = 0
|
||||
@@ -904,7 +919,6 @@ Tree.icon.closedColor = @icon
|
||||
Tree.icon.openColor = @icon
|
||||
|
||||
|
||||
|
||||
#---- Styles ------------------------------------------------------------------
|
||||
|
||||
#---- inTextField ----
|
||||
|
||||
@@ -50,8 +50,9 @@
|
||||
@selectionInactiveForeground = @foreground
|
||||
|
||||
# menu
|
||||
@menuSelectionBackground = @selectionBackground
|
||||
@menuHoverBackground = darken(@menuBackground,10%,derived)
|
||||
@menuCheckBackground = lighten(@selectionBackground,40%,derived noAutoInverse)
|
||||
@menuCheckBackground = lighten(@menuSelectionBackground,40%,derived noAutoInverse)
|
||||
@menuAcceleratorForeground = lighten(@foreground,30%)
|
||||
@menuAcceleratorSelectionForeground = @selectionForeground
|
||||
|
||||
@@ -62,7 +63,7 @@
|
||||
# accent colors (blueish)
|
||||
# set @accentColor to use single accent color or
|
||||
# modify @accentBaseColor to use variations of accent base color
|
||||
@accentColor = null
|
||||
@accentColor = systemColor(accent,null)
|
||||
@accentBaseColor = #2675BF
|
||||
@accentBase2Color = lighten(saturate(@accentBaseColor,10%),6%)
|
||||
# accent color variations
|
||||
@@ -356,6 +357,11 @@ ToggleButton.disabledSelectedBackground = darken($ToggleButton.background,13%,de
|
||||
ToggleButton.toolbar.selectedBackground = $ToggleButton.selectedBackground
|
||||
|
||||
|
||||
#---- ToolBar ----
|
||||
|
||||
ToolBar.hoverButtonGroupBackground = darken($ToolBar.background,3%,derived)
|
||||
|
||||
|
||||
#---- ToolTip ----
|
||||
|
||||
ToolTip.border = 4,6,4,6,shade(@background,40%)
|
||||
|
||||
@@ -44,6 +44,12 @@ info = lazy(ToolTip.background)
|
||||
infoText = lazy(ToolTip.foreground)
|
||||
|
||||
|
||||
#---- variables ----
|
||||
|
||||
# make sure that accent color (set via FlatLaf.setSystemColorGetter()) is ignored
|
||||
@accentColor = null
|
||||
|
||||
|
||||
#---- Button ----
|
||||
|
||||
Button.startBackground = $Button.background
|
||||
@@ -213,6 +219,7 @@ ToggleButton.endBackground = $ToggleButton.background
|
||||
[Solarized_Dark---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||
[Solarized_Dark---4lex4]Slider.focusedColor = fade($Component.focusColor,80%,derived)
|
||||
|
||||
[Solarized_Light---4lex4]Button.default.hoverBackground = darken($Button.default.background,3%,derived)
|
||||
[Solarized_Light---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||
|
||||
[vuesion-theme]Component.accentColor = lazy(Button.default.endBackground)
|
||||
|
||||
@@ -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,
|
||||
"buttonPressedArrowColor", Color.class,
|
||||
|
||||
"popupBackground", Color.class
|
||||
"popupBackground", Color.class,
|
||||
"popupInsets", Insets.class,
|
||||
"selectionInsets", Insets.class,
|
||||
"selectionArc", int.class
|
||||
);
|
||||
|
||||
// border
|
||||
@@ -266,6 +269,8 @@ public class TestFlatStyleableInfo
|
||||
"selectionForeground", Color.class,
|
||||
"selectionInactiveBackground", Color.class,
|
||||
"selectionInactiveForeground", Color.class,
|
||||
"selectionInsets", Insets.class,
|
||||
"selectionArc", int.class,
|
||||
|
||||
// FlatListCellBorder
|
||||
"cellMargins", Insets.class,
|
||||
@@ -283,6 +288,9 @@ public class TestFlatStyleableInfo
|
||||
|
||||
Map<String, Class<?>> expected = expectedMap(
|
||||
"itemMargins", Insets.class,
|
||||
"selectionInsets", Insets.class,
|
||||
"selectionEmbeddedInsets", Insets.class,
|
||||
"selectionArc", int.class,
|
||||
"hoverBackground", Color.class,
|
||||
"selectionBackground", Color.class,
|
||||
"selectionForeground", Color.class,
|
||||
@@ -369,6 +377,9 @@ public class TestFlatStyleableInfo
|
||||
"checkBackground", Color.class,
|
||||
"checkMargins", Insets.class,
|
||||
|
||||
"selectionInsets", Insets.class,
|
||||
"selectionArc", int.class,
|
||||
|
||||
"underlineSelectionBackground", Color.class,
|
||||
"underlineSelectionCheckBackground", Color.class,
|
||||
"underlineSelectionColor", Color.class,
|
||||
@@ -899,6 +910,8 @@ public class TestFlatStyleableInfo
|
||||
Map<String, Class<?>> expected = expectedMap(
|
||||
"focusableButtons", boolean.class,
|
||||
"arrowKeysOnlyNavigation", boolean.class,
|
||||
"hoverButtonGroupArc", int.class,
|
||||
"hoverButtonGroupBackground", Color.class,
|
||||
|
||||
"borderMargins", Insets.class,
|
||||
"gripColor", Color.class
|
||||
@@ -931,6 +944,8 @@ public class TestFlatStyleableInfo
|
||||
"selectionInactiveBackground", Color.class,
|
||||
"selectionInactiveForeground", Color.class,
|
||||
"selectionBorderColor", Color.class,
|
||||
"selectionInsets", Insets.class,
|
||||
"selectionArc", int.class,
|
||||
"wideSelection", boolean.class,
|
||||
"showCellFocusIndicator", boolean.class,
|
||||
|
||||
|
||||
@@ -316,6 +316,9 @@ public class TestFlatStyling
|
||||
ui.applyStyle( "buttonPressedArrowColor: #fff" );
|
||||
|
||||
ui.applyStyle( "popupBackground: #fff" );
|
||||
ui.applyStyle( "popupInsets: 1,2,3,4" );
|
||||
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||
ui.applyStyle( "selectionArc: 8" );
|
||||
|
||||
// border
|
||||
flatRoundBorder( style -> ui.applyStyle( style ) );
|
||||
@@ -413,6 +416,8 @@ public class TestFlatStyling
|
||||
ui.applyStyle( "selectionForeground: #fff" );
|
||||
ui.applyStyle( "selectionInactiveBackground: #fff" );
|
||||
ui.applyStyle( "selectionInactiveForeground: #fff" );
|
||||
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||
ui.applyStyle( "selectionArc: 8" );
|
||||
|
||||
// FlatListCellBorder
|
||||
ui.applyStyle( "cellMargins: 1,2,3,4" );
|
||||
@@ -435,6 +440,9 @@ public class TestFlatStyling
|
||||
FlatMenuBarUI ui = (FlatMenuBarUI) c.getUI();
|
||||
|
||||
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( "selectionBackground: #fff" );
|
||||
ui.applyStyle( "selectionForeground: #fff" );
|
||||
@@ -523,6 +531,9 @@ public class TestFlatStyling
|
||||
applyStyle.accept( "checkBackground: #fff" );
|
||||
applyStyle.accept( "checkMargins: 1,2,3,4" );
|
||||
|
||||
applyStyle.accept( "selectionInsets: 1,2,3,4" );
|
||||
applyStyle.accept( "selectionArc: 8" );
|
||||
|
||||
applyStyle.accept( "underlineSelectionBackground: #fff" );
|
||||
applyStyle.accept( "underlineSelectionCheckBackground: #fff" );
|
||||
applyStyle.accept( "underlineSelectionColor: #fff" );
|
||||
@@ -1102,6 +1113,8 @@ public class TestFlatStyling
|
||||
|
||||
ui.applyStyle( "focusableButtons: true" );
|
||||
ui.applyStyle( "arrowKeysOnlyNavigation: true" );
|
||||
ui.applyStyle( "hoverButtonGroupArc: 12" );
|
||||
ui.applyStyle( "hoverButtonGroupBackground: #fff" );
|
||||
|
||||
ui.applyStyle( "borderMargins: 1,2,3,4" );
|
||||
ui.applyStyle( "gripColor: #fff" );
|
||||
@@ -1137,6 +1150,8 @@ public class TestFlatStyling
|
||||
ui.applyStyle( "selectionInactiveBackground: #fff" );
|
||||
ui.applyStyle( "selectionInactiveForeground: #fff" );
|
||||
ui.applyStyle( "selectionBorderColor: #fff" );
|
||||
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||
ui.applyStyle( "selectionArc: 8" );
|
||||
ui.applyStyle( "wideSelection: true" );
|
||||
ui.applyStyle( "showCellFocusIndicator: true" );
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import com.formdev.flatlaf.FlatSystemProperties;
|
||||
*/
|
||||
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 ) {
|
||||
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
|
||||
|
||||
@@ -27,6 +27,7 @@ public class TestColorFunctions
|
||||
{
|
||||
@Test
|
||||
void colorFunctions() {
|
||||
// lighten, darken
|
||||
assertEquals( new Color( 0xff6666 ), ColorFunctions.lighten( 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( 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
|
||||
assertEquals( new Color( 0x1ae600 ), ColorFunctions.mix( Color.red, Color.green, 0.1f ) );
|
||||
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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect width="16" height="16" fill="#6E6E6E" rx="3"/>
|
||||
<rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
|
||||
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
|
||||
<rect width="5" height="2" x="5.5" y="11.5" stroke="#FFF" stroke-linejoin="round"/>
|
||||
<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>
|
||||
</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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect width="2" height="2" x="2" y="3" fill="#6E6E6E"/>
|
||||
<rect width="2" height="2" x="2" y="7" fill="#6E6E6E"/>
|
||||
<rect width="2" height="2" x="2" y="11" fill="#6E6E6E"/>
|
||||
<rect width="8" height="2" x="6" y="3" fill="#6E6E6E"/>
|
||||
<rect width="8" height="2" x="6" y="7" fill="#6E6E6E"/>
|
||||
<rect width="8" height="2" x="6" y="11" fill="#6E6E6E"/>
|
||||
<rect width="2" height="1" x="2" y="3" fill="#6E6E6E" rx=".5"/>
|
||||
<rect width="2" height="1" x="2" y="6" fill="#6E6E6E" rx=".5"/>
|
||||
<rect width="2" height="1" x="2" y="9" fill="#6E6E6E" rx=".5"/>
|
||||
<rect width="2" height="1" x="2" y="12" fill="#6E6E6E" rx=".5"/>
|
||||
<rect width="8" height="1" x="6" y="3" fill="#6E6E6E" rx=".5"/>
|
||||
<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>
|
||||
</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">
|
||||
<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>
|
||||
|
||||
|
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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<rect width="4" height="4" x="3" y="3" fill="#6E6E6E"/>
|
||||
<rect width="4" height="4" x="3" y="9" fill="#6E6E6E"/>
|
||||
<rect width="4" height="4" x="9" y="9" fill="#6E6E6E"/>
|
||||
<rect width="4" height="4" x="9" 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="2.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||
<rect width="4" height="4" x="9.5" y="9.5" stroke="#6E6E6E" rx="1.5"/>
|
||||
<rect width="4" height="4" x="9.5" y="2.5" stroke="#6E6E6E" rx="1.5"/>
|
||||
</g>
|
||||
</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">
|
||||
<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 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"/>
|
||||
<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"/>
|
||||
<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>
|
||||
</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">
|
||||
<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 fill="#389FD6" d="M12,4 L12,8 L10,8 L10,4 L8,4 L11,1 L14,4 L12,4 Z"/>
|
||||
<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"/>
|
||||
<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>
|
||||
</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">
|
||||
<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="12" height="2" x="2" y="12" fill="#6E6E6E"/>
|
||||
<rect width="11" height="7" x="2.5" y="3.5" stroke="#6E6E6E" rx="1"/>
|
||||
<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>
|
||||
</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">
|
||||
<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>
|
||||
|
||||
|
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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<polygon fill="#6E6E6E" points="8 6 8 1 13 1 13 15 3 15 3 6"/>
|
||||
<polygon fill="#6E6E6E" points="3 5 7 5 7 1"/>
|
||||
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||
<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"/>
|
||||
<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>
|
||||
</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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<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"/>
|
||||
<rect width="4" height="2" x="6" y="12" fill="#6E6E6E"/>
|
||||
<g fill="none" fill-rule="evenodd" stroke-linejoin="round">
|
||||
<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"/>
|
||||
<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>
|
||||
</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">
|
||||
<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>
|
||||
|
||||
|
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 317 B |
@@ -6,7 +6,7 @@
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<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="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>
|
||||
|
||||
|
Before Width: | Height: | Size: 583 B After Width: | Height: | Size: 590 B |
@@ -2,6 +2,7 @@
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<circle cx="11" cy="11" r="10.5" fill="#6E6E6E"/>
|
||||
<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>
|
||||
</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">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<circle cx="16" cy="16" r="14" fill="#DB5860"/>
|
||||
<rect width="4" height="11" x="14" y="7" fill="#FFF"/>
|
||||
<rect width="4" height="4" x="14" y="21" fill="#FFF"/>
|
||||
<rect width="4" height="12" x="14" y="7" fill="#FFF" rx="2"/>
|
||||
<circle cx="16" cy="23" r="2" fill="#FFF"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 306 B After Width: | Height: | Size: 302 B |