bigdataviewer / bigdataviewer-core

ImgLib2-based viewer for registered SPIM stacks and more
BSD 2-Clause "Simplified" License
33 stars 35 forks source link

improve support for modern scaled high-dpi LAFs #116

Closed axtimwalde closed 2 years ago

axtimwalde commented 3 years ago

This PR is a start to improve support for modern auto-scaling high-dpi Swing Look and Feels like the fabulous https://www.formdev.com/flatlaf/.

Screenshot from 2021-01-18 19-09-06

FlatIntelliJLaf

Screenshot from 2021-01-18 19-05-57

FlatDarculaLaf

TODO

tpietzsch commented 3 years ago

There is a weird issue: The background of the "current" radio buttons in the table is not set. (That's also visible in your screenshots). This happens here: https://github.com/bigdataviewer/bigdataviewer-core/blob/152b743ce91e93e878c679374484af68f0a8b4c0/src/main/java/bdv/ui/sourcetable/RadioButtonRenderer.java#L58

For the FlatLaf it just doesn't work for that specific color.

Screenshot 2021-01-19 at 18 04 35

The weird thing is, that if I slightly modify the color, e.g., instead of

setBackground( table.getSelectionBackground() );

I do

final Color c = table.getSelectionBackground();
setBackground( new Color( c.getRGB() + 1 ) );

then it works. Screenshot 2021-01-19 at 18 04 08

DevCharly commented 3 years ago

The problem is probably that the radio renderer is not opaque. setOpaque(true) should fix it.

See also: https://github.com/JFormDesigner/FlatLaf/blob/c6fec0a131c6f04345b3f4aec5b06d09c25c7d33/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTableUI.java#L141-L145

The problem is that radiobuttons (and checkboxes) are non-opaque in FlatLaf and therefore do not paint selection background when used as renderer. In other Lafs (Windows, Metal, ...), they are opaque and do not have this problem.

DevCharly commented 3 years ago

The weird thing is, that if I slightly modify the color, e.g., instead of

setBackground( table.getSelectionBackground() );

I do

final Color c = table.getSelectionBackground();
setBackground( new Color( c.getRGB() + 1 ) );

then it works.

Yes, the reason is that there is a check in FlatRadioButtonUI that paints the background if the color does not implement interface UIResource: https://github.com/JFormDesigner/FlatLaf/blob/c6fec0a131c6f04345b3f4aec5b06d09c25c7d33/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatRadioButtonUI.java#L118-L127

I think I should change this and paint the background as soon as the backgound color is different to default color (UI key RadioButton.background). Then this should work without setOpaque(true).

DevCharly commented 3 years ago

Regarding scaling: There is a class com.formdev.flatlaf.util.UIScale in FlatLaf that is used for scaling. Useful methods are e.g. float getUserScaleFactor() or int scale( int value ). This class is Laf independent and works also with other Lafs.

User scale factor is based on font size: https://github.com/JFormDesigner/FlatLaf/blob/c6fec0a131c6f04345b3f4aec5b06d09c25c7d33/flatlaf-core/src/main/java/com/formdev/flatlaf/util/UIScale.java#L222-L241

See class header for description of system/user scaling modes: https://github.com/JFormDesigner/FlatLaf/blob/master/flatlaf-core/src/main/java/com/formdev/flatlaf/util/UIScale.java#L39-L62

Let me know if there are problems or questions. BTW I'm the author of FlatLaf 😉

tpietzsch commented 3 years ago

@DevCharly thanks a lot for the pointer! setOpaque(true) indeed fixes the radio-button highlighting.

DevCharly commented 3 years ago

FYI if you need to use custom colors for different themes (light/dark), there is some new documentation online that could be interesting for you: https://www.formdev.com/flatlaf/how-to-customize/#application_properties

There is also a UI Defaults Inspector available, which might be useful for development: https://github.com/JFormDesigner/FlatLaf/tree/master/flatlaf-extras#ui-defaults-inspector

tpietzsch commented 3 years ago

@axtimwalde in branch laf-switching I worked on making the UI adapt nicely to changing Look-And-Feel

Could you try it out, whether it works for you on Linux as well?

There is still stuff to do for HighDPI scaling, which I cannot test here. Here are some places which I suspect would need to be looked at: https://github.com/bigdataviewer/bigdataviewer-core/blob/89da3ccb7859f6d32572c0834119c13aabd05300/src/main/java/bdv/ui/convertersetupeditor/ColorPanel.java#L94-L95 https://github.com/bigdataviewer/bigdataviewer-core/blob/89da3ccb7859f6d32572c0834119c13aabd05300/src/main/java/bdv/ui/convertersetupeditor/ColorPanel.java#L148 https://github.com/bigdataviewer/bigdataviewer-core/blob/0b57883714e03575a787abe24490e06e3cbac27b/src/main/java/bdv/ui/CardPanel.java#L227-L230

Tobias Pietzsch @tpietzsch Mar 02 23:54 https://github.com/bigdataviewer/bigdataviewer-core/blob/c4ca7e01a067102f15ff04b6aedf85dbb8d506d0/src/main/java/bdv/ui/rangeslider/RangeSliderUI.java#L233 Maybe you can find a method that is called when a window is moved from highDPI to normal screen and update stuff from there? (For the LAF changes, JComponent.updateUI() is called. That's where I put the relevant updates for colors etc.)

imagesc-bot commented 2 years ago

This pull request has been mentioned on Image.sc Forum. There might be relevant details there:

https://forum.image.sc/t/new-bigdataviewer-version-10-4-1/68818/1