-
Notifications
You must be signed in to change notification settings - Fork 504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8267546: Add CSS themes as a first-class concept #511
Conversation
👋 Welcome back mstrauss! A progress list of the required criteria for merging this PR into |
modules/javafx.graphics/src/main/native-glass/win/ThemeSupport.cpp
Outdated
Show resolved
Hide resolved
Looks great! I read through the code and nothing wrong jumped out - all the obvious missing parts were already raised on the mailing list and reasonable arguments provided for why it's about reducing maintenance costs. The only thing that seemed odd is the way you set a theme by providing a special string syntax+class name as a "stylesheet". Is there some reason a more direct API cannot be added instead, where you pass the actual Also the It seems Kevin wanted some more info on cost/benefit analysis on the mailing list, but it's a little unclear what sort of analysis or evidence would be wanted. I'll say that JavaFX apps I've written in the past would definitely have benefited from this. My CSS files always ended up being a mishmash of patches to Modena and actual app-specific styling. Additionally, whilst various JavaFX theme libraries exist and are popular, you normally have to do some manual integration work to use them which is a pity given that theming is, ultimately, entirely subjective and users frequently enjoy theming apps they work with a lot. I'll also say that the whole JavaFX theming system was a point of confusion for me when I first learned the API. It clearly does support themes, yet there's no actual API point called "theme" anywhere and exactly how themes, CSS and so on relate isn't obvious. So this PR has a learning and usability benefit too. Conclusion: to me the code looks really quite small, the benefits large (as most "real" JavaFX apps don't simply use Modena as-is), and it is at any rate mostly a refactoring and exposure of far more complex machinery already in the toolkit. Thumbs up! |
modules/javafx.graphics/src/main/native-glass/win/RoActivationSupport.cpp
Outdated
Show resolved
Hide resolved
modules/javafx.graphics/src/test/java/test/javafx/application/ThemeTest.java
Outdated
Show resolved
Hide resolved
This comment was marked as outdated.
This comment was marked as outdated.
Are there any plans for this to be merged or is there any work remaining for this? I'd love to use this instead of what I'm currently doing which is accessing private API in JavaFX with |
d905361
to
80fa8de
Compare
Webrevs
|
I've iterated on this feature for several months, and I'm quite comfortable with the latest version. The API was changed considerably: there are no "theme URIs" masquerading as user-agent stylesheets any more. Instead there's an application-wide |
This will take a fair bit of discussion regarding how various applications might use such a feature, what the API should look like, etc. /reviewers 3 |
@kevinrushforth |
@kevinrushforth has indicated that a compatibility and specification (CSR) request is needed for this pull request. @mstr2 please create a CSR request for issue JDK-8267546 with the correct fix version. This pull request cannot be integrated until the CSR request is approved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like quite a nice feature, would love to see this in JavaFX.
modules/javafx.controls/src/main/java/javafx/scene/control/theme/StylesheetList.java
Outdated
Show resolved
Hide resolved
* | ||
* @since 20 | ||
*/ | ||
public interface PlatformPreferences extends Map<String, Object> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure it is a good idea to expose these as a Map
? It seems to me that this isn't that good a practice any more to have classes implement or extend lists/maps/sets as they pull in a huge amount of API surface that is mostly useless or too general for the class's purpose.
The addition of the listener management methods also has me wondering, as ObservableMap
does something similar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the mutating methods are useless, since the implementation always returns a read-only map. However, the alternative would be to duplicate APIs to enumerate and inspect the contents of the PlatformPreferences
map (applications might want to show a list of available preferences). I'm not sure that's preferable, mostly because PlatformPreferences
does represent a mapping of keys to values.
It's true that listener management makes it look like an ObservableMap
. The difference is that ObservableMap
doesn't support batch change notifications, which the current implementation relies on to minimize the number of style theme resets. Of course, that could be solved in a different way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The addition of the listener management methods also has me wondering, as
ObservableMap
does something similar.
I've switched to using ObservableMap
.
I think there are basically three categories of how applications might use this feature:
The proposed feature addresses all three categories, with the third option (a dynamic theme) being the most difficult to implement. It requires quite a bit of effort to create such a theme, and a good amount of that effort will be figuring out how OS-level preferences interact with themes (platform independence is a complicating factor). I've made it an explicit non-goal of this feature to provide an API for higher-level concepts like dark mode, high contrast, etc., since I think APIs for OS design trends should be left to third-party libraries instead. |
Hi all, I’ve seen in the mailing list a request for commenting on this PR and as a long-time theme developer (JMetro and other themes) I'd thought I'd give my 2 cents. I think it’s a good idea to add the concept of a theme to the JavaFX API! So, thanks for this. 1 - Reading through the javadocs in this PR and the description, I think it’s not clear whether the stylesheets of a StyleTheme will be used as user agent stylesheets or as author stylesheets. It says that StyleThemes have higher precedence than a user agent stylesheet so I suppose they are going to be author stylesheets (?), but there’s no point in the Javadoc where that is explicitly said. If that’s not the case, then I think the opposite should then be explicitly written. I.e. that it will have higher precedence than a user agent stylesheet but it’s not an author stylesheet. 2 – I think the ability to specify in the StyleTheme whether it is a user agent stylesheet, or an author stylesheet could be of interest. Most of the themes I know are composed of author stylesheets (they use the getStylesheets() API in Scene) so migration to using the StyleTheme API would be easier if one could specify this. Conversely specifying that the StyleTheme is a user agent stylesheet will also be very useful in the cases where we’re creating a theme but don’t want it to override styles specified through code, etc. 3 – I would really love for JavaFX to have first class support for dark and light modes, and I think this would be the ideal place for it. One of the problems with how things are right now is that if you create a dark theme with this API or the previous API (using stylesheets) the frames of windows (main windows and dialogs) will still show with a light theme (I see this on Windows, haven’t tested on Mac but I suppose it will be the same). Thanks |
@mstr2 This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration! |
@mstr2 This pull request has been inactive for more than 16 weeks and will now be automatically closed. If you would like to continue working on this pull request in the future, feel free to reopen it! This can be done using the |
No don't, don't close this omg 🤦 |
I’ll re-open once the prerequisite PRs are integrated. The discussion continues in #1014 |
Oh I see, thanks for your work! |
@mstr2 any news on this feature? |
I've been working on this feature lately, and will soon be sharing more about it. |
@mstr2 First of all thank you very much for your work on this! 👍👍 Are there any news regarding StyleTheme? Thanks again! |
This PR adds style themes as a first-class concept to OpenJFX. A style theme is a collection of stylesheets and the logic that governs them. Style themes can respond to OS notifications and update their stylesheets dynamically. This PR also re-implements Caspian and Modena as style themes.
New APIs in
javafx.graphics
The new theming-related APIs in
javafx.graphics
provide a basic framework to support application-wide style themes. Higher-level theming concepts (for example, "dark mode" detection or accent coloring) are not a part of this basic framework, because any API invented here might soon be out of date. Implementations can build on top of this framework to add useful higher-level features.1. StyleTheme
A style theme is an implementation of the
javafx.css.StyleTheme
interface:A new
userAgentStyleTheme
property is added tojavafx.application.Application
, anduserAgentStylesheet
is promoted to a JavaFX property (currently, this is just a getter/setter pair):userAgentStyleTheme
anduserAgentStylesheet
are correlated to preserve backwards compatibility: settinguserAgentStylesheet
to the magic values "CASPIAN" or "MODENA" will implicitly setuserAgentStyleTheme
to a new instance of theCaspianTheme
orModenaTheme
class. In the CSS cascade,userAgentStylesheet
has a higher precedence thanuserAgentStyleTheme
.2. Preferences
javafx.application.Platform.Preferences
can be used to query UI-related information about the current platform to allow theme implementations to adapt to the operating system. The interface extendsObservableMap
and adds several useful methods, as well as the option to register a listener for change notifications:An instance of
Preferences
can be retrieved viaPlatform.getPreferences()
.Here's a list of the preferences available for Windows, as reported by the SystemParametersInfo, GetSysColor and Windows.UI.ViewManagement.UISettings.GetColorValue APIs. Deprecated colors are not included.
Here is a list of macOS preferences as reported by
NSColor
's UI Element Colors and Adaptable System Colors. Deprecated colors are not included.On Linux, GTK's theme name and public CSS colors are reported:
Built-in themes
The two built-in themes
CaspianTheme
andModenaTheme
are exposed as public API in thejavafx.scene.control.theme
package. Both classes extendThemeBase
, which is a simpleStyleTheme
implementation that allows developers to easily extend the built-in themes.Usage
In its simplest form, a style theme is just a static collection of stylesheets:
A dynamic theme can be created by returning an instance of
ObservableList
:CaspianTheme
andModenaTheme
can be extended by prepending or appending additional stylesheets:Progress
Integration blocker
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/511/head:pull/511
$ git checkout pull/511
Update a local copy of the PR:
$ git checkout pull/511
$ git pull https://git.openjdk.org/jfx.git pull/511/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 511
View PR using the GUI difftool:
$ git pr show -t 511
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/511.diff
Webrev
Link to Webrev Comment