On Tue, 5 Nov 2024 01:32:16 GMT, Michael Strauß <mstra...@openjdk.org> wrote:

>> This PR is a new take on a highly requested feature: JavaFX controls in the 
>> header bar (see also #594 for an earlier iteration).
>> 
>> This is a feature with many possible ways to skin the cat, and it has taken 
>> quite a bit of effort to come up with a good user model. In contrast to the 
>> previous iteration, the focus has shifted from providing an entirely 
>> undecorated window to providing a window with a user-configurable header bar.
>> 
>> The customizable header bar is a new layout container: 
>> `javafx.scene.layout.HeaderBar`. It has three areas that accept child nodes: 
>> leading, center, and trailing.  `HeaderBar` also automatically adjusts for 
>> the placement of the default window buttons (minimize, maximize, close) on 
>> the left or right side of the window.
>> 
>> The customizable header bar is combined with a new `EXTENDED` stage style, 
>> which extends the client area into the header bar area. The new extended 
>> stage style is supported on Windows, macOS, and Linux. For platforms that 
>> don't support this stage style, it automatically downgrades to `DECORATED`.
>> 
>> This is how it looks like on each of the three operating systems:
>> 
>> ![extendedwindow](https://github.com/user-attachments/assets/9d798af6-09f4-4337-8210-6eae91079d3a)
>> 
>> The window buttons (minimize, maximize, close) are provided by JavaFX, not 
>> by the application developer. This makes it easier to get basic window 
>> functionality without recreating the entirety of the window controls for all 
>> platforms.
>> 
>> ## Usage
>> This is a minimal example that uses a custom header bar with a `TextField` 
>> in the center area. `HeaderBar` is usually placed in the top area of a 
>> `BorderPane` root container:
>> 
>> public class MyApp extends Application {
>>     @Override
>>     public void start(Stage stage) {
>>         var headerBar = new HeaderBar();
>>         headerBar.setCenter(new TextField());
>> 
>>         var root = new BorderPane();
>>         root.setTop(headerBar);
>> 
>>         stage.setScene(new Scene(root));
>>         stage.initStyle(StageStyle.EXTENDED);
>>         stage.show();
>>     }
>> }
>> 
>> To learn more about the details of the API, refer to the documentation of 
>> `StageStyle.EXTENDED` and `HeaderBar`.
>> 
>> ## Platform integration
>> The implementation varies per platform, and ranges from pretty easy to quite 
>> involved:
>> 1. **macOS**: The window buttons are provided by macOS, we just leave an 
>> empty area where the window buttons will appear. The client area is extended 
>> to cover the entire window by setting the `NSW...
>
> Michael Strauß has updated the pull request incrementally with one additional 
> commit since the last revision:
> 
>   stylistic changes

second batch of comments

modules/javafx.graphics/src/main/java/javafx/scene/layout/HeaderBar.java line 
118:

> 116: 
> 117:     private static final String ALIGNMENT = "headerbar-alignment";
> 118:     private static final String MARGIN = "headerbar-margin";

Q: should these be a String or an Object?  String.equals() are more expensive.

(I guess we use Strings elsewhere, so probably ok).

modules/javafx.graphics/src/main/java/javafx/scene/layout/HeaderBar.java line 
170:

> 168:         // Inflate the minHeight property. This is important so that we 
> can track whether a stylesheet or
> 169:         // user code changes the property value before we set it to the 
> height of the native title bar.
> 170:         minHeightProperty();

if that's the case, why not initialize it in L1150 ?

modules/javafx.graphics/src/main/java/javafx/scene/layout/HeaderBar.java line 
262:

> 260:     @Override
> 261:     protected double computeMinWidth(double height) {
> 262:         Node leading = getLeading(), center = getCenter(), trailing = 
> getTrailing();

I think it's a bad practice to have multiple statements on one line.

modules/javafx.graphics/src/main/java/javafx/scene/layout/HeaderBarBase.java 
line 51:

> 49:  * can specify draggable content nodes of the {@code HeaderBarBase} with 
> the {@link #setDraggable} method.
> 50:  *
> 51:  * @apiNote Most application developers should use the {@link HeaderBar} 
> implementation instead of

just curious: what's the reason to split the HB into the two classes?  Can you 
give an example?

modules/javafx.graphics/src/main/java/javafx/scene/layout/HeaderBarBase.java 
line 138:

> 136:     private void updateInsets() {
> 137:         if (currentFullScreen || currentMetrics == null) {
> 138:             leftSystemInset.set(new Dimension2D(0, 0));

Q: would it make sense to declare a
`static final Dimension2D EMPTY = new Dimension2D(0, 0)`
and use it everywhere?

modules/javafx.graphics/src/main/java/javafx/scene/layout/HeaderBarBase.java 
line 190:

> 188:      * independent of layout orientation.
> 189:      */
> 190:     private final ReadOnlyObjectWrapper<Dimension2D> rightSystemInset =

Q: would it make sense to create a class with requestLayout() ?  this will save 
two class objects...

modules/javafx.graphics/src/main/java/javafx/stage/StageStyle.java line 83:

> 81:      * <p>
> 82:      * An extended window has the default window buttons (minimize, 
> maximize, close), but no system-provided
> 83:      * draggable header bar. Applications need to provide their own 
> header bar by placing a single {@link HeaderBar}

I would like to see this expanded just a little bit, to give an example of what 
is (system menu, buttons) and is not rendered (rounded corners, app title), 
similarly to the the table in the JEP.

I would prefer a table or an `<ul>`, and I specifically want to include the 
window title.  Window title is a property, and I think it deserves a mention 
(will it be shown in the tray? in the "running applications" os widget?)

I don't know whether the best place to include that is here or in the 
`HeaderBar`.

modules/javafx.graphics/src/main/native-glass/mac/GlassViewDelegate.m line 1336:

> 1334: }
> 1335: 
> 1336: - (NSEvent*)lastEvent

could there be side effects with exposing this field?
concurrency issues?

modules/javafx.graphics/src/main/resources/com/sun/glass/ui/gtk/WindowDecorationGnome.css
 line 26:

> 24:  */
> 25: 
> 26: .window-button-container {

is it possible for the app dev to alter the styling with an external style 
sheet?

modules/javafx.graphics/src/main/resources/com/sun/glass/ui/gtk/WindowDecorationGnome.css
 line 125:

> 123: 
> 124: .close-button > .glyph {
> 125:     -fx-shape: "m 8.1464844,8.1464844 a 0.5,0.5 0 0 0 0,0.7070312 L 
> 11.292969,12 8.1464844,15.146484 a 0.5,0.5 0 0 0 0,0.707032 0.5,0.5 0 0 0 
> 0.7070312,0 L 12,12.707031 l 3.146484,3.146485 a 0.5,0.5 0 0 0 0.707032,0 
> 0.5,0.5 0 0 0 0,-0.707032 L 12.707031,12 15.853516,8.8535156 a 0.5,0.5 0 0 0 
> 0,-0.7070312 0.5,0.5 0 0 0 -0.707032,0 L 12,11.292969 8.8535156,8.1464844 a 
> 0.5,0.5 0 0 0 -0.7070312,0 z";

minor: we could probably minimize the path by rounding to 2 or 3 decimal points
(same comment for all .css changes)

modules/javafx.graphics/src/main/resources/com/sun/glass/ui/win/WindowDecoration.css
 line 107:

> 105: 
> 106: .maximize-button.restore > .glyph {
> 107:     -fx-shape: "m 7.6491699,2.5192871 q 0,-0.3444824 
> -0.1369629,-0.6495361 Q 7.3752441,1.5646973 7.1407471,1.338501 
> 6.90625,1.1123047 6.5970459,0.98156738 6.2878418,0.85083008 
> 5.9475098,0.85083008 H 1.7722168 Q 1.838623,0.65991211 1.9589844,0.50219727 
> 2.0793457,0.34448242 2.2370605,0.23242188 2.3947754,0.12036133 
> 2.5836182,0.06018066 2.7724609,0 2.9758301,0 H 5.9475098 Q 6.4746094,0 
> 6.9394531,0.20129395 7.4042969,0.40258789 7.7508545,0.74707031 
> 8.0974121,1.0915527 8.2987061,1.5563965 8.5,2.0212402 8.5,2.5483398 V 
> 5.5241699 Q 8.5,5.7275391 8.4398193,5.9163818 8.3796387,6.1052246 
> 8.2675781,6.2629395 8.1555176,6.4206543 7.9978027,6.5410156 
> 7.8400879,6.661377 7.6491699,6.7277832 Z M 1.253418,8.5 Q 1.0043945,8.5 
> 0.77612305,8.3983154 0.54785156,8.2966309 0.37561035,8.1243896 
> 0.20336914,7.9521484 0.10168457,7.723877 0,7.4956055 0,7.246582 V 2.9550781 Q 
> 0,2.7019043 0.10168457,2.475708 0.20336914,2.2495117 0.37561035,2.0772705 
> 0.54785156,1.9050293 0.77404785,1.8033447 1.0002441,1.70166
 02 1.253418,1.7016602 h 4.2915039 q 0.2531738,0 0.4814453,0.1016845 
0.2282715,0.1016846 0.3984375,0.2718506 0.170166,0.170166 0.2718506,0.3984375 
0.1016845,0.2282715 0.1016845,0.4814453 V 7.246582 q 0,0.2531739 
-0.1016845,0.4793701 Q 6.5949707,7.9521484 6.4227295,8.1243896 
6.2504883,8.2966309 6.024292,8.3983154 5.7980957,8.5 5.5449219,8.5 Z M 
5.5241699,7.6491699 q 0.087158,0 0.1639405,-0.033203 0.076782,-0.033203 
0.1369628,-0.091309 0.060181,-0.058105 0.093384,-0.1348877 0.033203,-0.076782 
0.033203,-0.1639404 v -4.25 q 0,-0.087158 -0.033203,-0.1660156 Q 
5.8852539,2.730957 5.8271484,2.6728516 5.769043,2.6147461 5.6901855,2.581543 
5.6113281,2.5483398 5.5241699,2.5483398 h -4.25 q -0.087158,0 
-0.1639404,0.033203 -0.076782,0.033203 -0.1348877,0.093384 -0.0581055,0.060181 
-0.0913086,0.1369628 -0.0332031,0.076782 -0.0332031,0.1639405 v 4.25 q 
0,0.087158 0.0332031,0.1639404 0.0332031,0.076782 0.0913086,0.1348877 
0.0581055,0.058105 0.1348877,0.091309 0.076782,0.033203 0.1639404,0.033203 z";

... especially here

modules/javafx.graphics/src/test/java/test/javafx/scene/layout/HeaderBarTest.java
 line 70:

> 68:         "BOTTOM_CENTER, 10, 10, 100, 80",
> 69:         "BOTTOM_RIGHT, 10, 10, 100, 80"
> 70:     })

these tests can be simplified to avoid parsing with @CsvSource and default 
conversion, example:


    @ParameterizedTest
    @CsvSource(value = {"yo,true,1", 
                        "bah,true,1.1", 
                        "meh,false,2.2"})
    void test(String candidate, boolean expected, double a) {
        System.out.println("candidate=" + candidate + " expected=" + expected + 
" a=" +a );
    }

-------------

PR Review: https://git.openjdk.org/jfx/pull/1605#pullrequestreview-2416113079
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829669611
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829671987
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829674239
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829687841
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829847752
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829849333
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829857742
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829868608
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829874022
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829875372
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829876147
PR Review Comment: https://git.openjdk.org/jfx/pull/1605#discussion_r1829926610

Reply via email to