Skip to content
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

MacOS: avoid hiding SceneBuilder menu bar with FXML menu bar when useSystemMenuBar property is enabled #405

Merged
merged 47 commits into from
Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
0fc2a78
Draft of an idea for issue-404.
Oliver-Loeffler Sep 7, 2021
a94233f
Moved the FXML modification code into a separate class. Corrected the…
Oliver-Loeffler Sep 7, 2021
a88229c
Header updated.
Oliver-Loeffler Sep 7, 2021
9e51383
Formatting reworked.
Oliver-Loeffler Sep 7, 2021
1cbe93a
Header added.
Oliver-Loeffler Sep 7, 2021
7195221
Formatting
Oliver-Loeffler Sep 7, 2021
401c6f4
Added tests for changes in FXOMDocument.
Oliver-Loeffler Sep 7, 2021
d946f46
Merge branch 'gluonhq:master' into issue-404-develop
Oliver-Loeffler Jan 5, 2022
bc22b83
FXLMPropertiesDiesabler generalized. Spelling mistakes corrected.
Oliver-Loeffler Jan 5, 2022
e356320
Updated OS specific test.
Oliver-Loeffler Jan 5, 2022
074da20
Added javadoc.
Oliver-Loeffler Jan 5, 2022
043da8c
Formatting.
Oliver-Loeffler Jan 5, 2022
925490d
Applied checkstyle formatting.
Oliver-Loeffler Jan 5, 2022
b074e42
Formatting corrected.
Oliver-Loeffler Jan 9, 2022
c70fd94
Removed the Operating System enum.
Oliver-Loeffler Jan 9, 2022
333c73d
Removed the NON_NORMALIZED FXOMDocumenzSwitch. Previously, normalization
Oliver-Loeffler Jan 9, 2022
55c8cd0
Javadoc rework.
Oliver-Loeffler Jan 9, 2022
448ce01
Merge branch 'gluonhq:master' into issue-404
Oliver-Loeffler Jan 11, 2022
9396b17
Merged master into issue-404
Oliver-Loeffler Jan 12, 2022
d82aee6
Javadoc added.
Oliver-Loeffler Jan 12, 2022
56ec3d1
Merge branch 'master' into issue-404
Oliver-Loeffler Jan 13, 2022
1adc6a5
Introduced OS name enum.
Oliver-Loeffler Jan 13, 2022
ee6c66c
Reworked test to consider new OS enum.
Oliver-Loeffler Jan 13, 2022
e1db7b6
Fixed typo.
Oliver-Loeffler Jan 13, 2022
fc4106a
Copyright updated.
Oliver-Loeffler Jan 13, 2022
44baa62
Reverted formatting changes.
Oliver-Loeffler Jan 13, 2022
afd72f7
Header updated. Merge errors fixed.
Oliver-Loeffler Jan 13, 2022
b36f01d
Spaces removed
Oliver-Loeffler Jan 13, 2022
98d9b57
Replaced platform checks with JUnit Assumptions.
Oliver-Loeffler Jan 13, 2022
6d3453a
Header update
Oliver-Loeffler Jan 13, 2022
dfbeca1
Reverted changes.
Oliver-Loeffler Jan 13, 2022
b9fd009
Added test.
Oliver-Loeffler Jan 13, 2022
1bfe40b
FXMLPropertiesDisabler now uses an approach with a regular expression to
Oliver-Loeffler Jan 13, 2022
e61fd4c
Enabled useSystemMenuBar as an inspectable for MenuBar.
Oliver-Loeffler Jan 13, 2022
93a8a40
Header updated.
Oliver-Loeffler Jan 13, 2022
1a723d7
refactor: constructor chained
Oliver-Loeffler Jan 13, 2022
0e244b9
feat+refactor: useSystemMenuProperty to be treated as node property,
Oliver-Loeffler Jan 13, 2022
3b4c5bc
feat: removed "useSystemMenuBar" from hidden properties
Oliver-Loeffler Jan 13, 2022
97512d5
refactor: removed empty lines between fields
Oliver-Loeffler Jan 13, 2022
82b285b
refator: removed underscore in test file name
Oliver-Loeffler Jan 13, 2022
f6c34ad
Javadoc cleanup
Oliver-Loeffler Jan 14, 2022
1800665
Reverted formatting changes.
Oliver-Loeffler Jan 14, 2022
dfb4f19
Reverted accidental modification of inspector path setting
Oliver-Loeffler Jan 14, 2022
da9738a
Removed underscore from test file names.
Oliver-Loeffler Jan 14, 2022
afa27e0
All FXOMDocument constructor calls updated in order to use the
Oliver-Loeffler Jan 14, 2022
fadf87a
Corrected license headers.
Oliver-Loeffler Jan 16, 2022
bc8ef4a
Set of switches is now defined once.
Oliver-Loeffler Jan 16, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@
* @treatAsPrivate
*/
public class EditorPlatform {

Oliver-Loeffler marked this conversation as resolved.
Show resolved Hide resolved
public enum OS {
LINUX, MAC, WINDOWS;

public static OS get() {
return IS_LINUX ? LINUX : IS_MAC ? MAC : WINDOWS;
}
}

private static final String osName = System.getProperty("os.name").toLowerCase(Locale.ROOT); //NOI18N

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/*
* Copyright (c) 2022, Gluon and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the distribution.
* - Neither the name of Oracle Corporation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.oracle.javafx.scenebuilder.kit.fxom;

import java.util.Objects;

import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform.OS;

/**
* Modifies FXML to be loaded so that properties in the FXML will not interfere
* with Scene Builder.
*/
class FXMLPropertiesDisabler {

private final OS os;

/**
* Creates a new FXMLPropertiesDisable which is aware of the platform and can
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
* according to required platform behavior.
*/
public FXMLPropertiesDisabler() {
this.os = OS.get();
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* @param os Operating system where Scene Builder is executed
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
*/
FXMLPropertiesDisabler(OS os) {
this.os = Objects.requireNonNull(os);
}

/**
* In some cases, during FXML Loading, certain properties must be disabled.
* This method modifies the FXML source accordingly.
*
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
* @param fxmlText FXML source to be modified
* @return FXML source with all properties disabled (=false) where WYSIWYG editing is not suitable.
* @throws NullPointerException in case of fxmlText is null
*/
public String disableProperties(String fxmlText) {
Objects.requireNonNull(fxmlText, "fxmlText must not be null");
String modifiedFxml = disableUseSystemMenuBarProperty(fxmlText);
return modifiedFxml;
}

/**
* On MacOS, when loading a FXML with a menu bar where useSystemMenuBarProperty()
* is enabled, the menu in the FXML will hide the menu of Scene Builder.
* In this case, Scene Builder becomes unusable.
*
* Setting the property here to false has the advantage, that the FXML to be saved
* will still contain the defined property BUT the Scene Builder menu bar will remain
* visible.
*
* The modification of properties which are not desired to be active while
* editing must happen before loading the FXML using the FXMLLoader.
*
* Here a disconnect between the FXOM and FXML is created as the state of the
* useSystemMenuBarProperty is now different in both models.
*
* @param fxmlText FXML source to be modified
* @return FXML source with all properties disabled (=false) where WYSIWYG editing is not suitable.
* @throws NullPointerException in case of fxmlText is null
*/
private String disableUseSystemMenuBarProperty(String fxmlText) {
Objects.requireNonNull(fxmlText, "fxmlText must not be null");
if (OS.MAC == os) {
/*
* Regex description:
* mandatory white space
* useSystemMenuBar
* optional white space
* =
* optional white space
* "true"
*/
String regex = "(\\s)useSystemMenuBar(\\s*)[=](\\s*)\"true\"";
return fxmlText.replaceAll(regex, " useSystemMenuBar=\"false\"");
}
return fxmlText;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019 Gluon and/or its affiliates.
* Copyright (c) 2017, 2022, Gluon and/or its affiliates.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
Expand Down Expand Up @@ -44,8 +44,10 @@
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform;

import javafx.beans.property.ReadOnlyIntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.scene.Node;
Expand Down Expand Up @@ -80,16 +82,37 @@ public class FXOMDocument {

private List<Class<?>> initialDeclaredClasses;

public FXOMDocument(String fxmlText, URL location, ClassLoader classLoader, ResourceBundle resources, boolean normalize) throws IOException {
/**
* Creates a new {@link FXOMDocument} from given FXML source. Depending on the
* use case, the {@link FXOMDocumentSwitch} items can be used to configure the
* document creation process according to specific needs. E.g. normalization is
* not enabled by default, thus if required the {@link FXOMDocumentSwitch}
* {@code NORMALIZED} should be added as constructor argument.
*
* @param fxmlText FXML source
* @param location {@link URL} describing the actual document location
* @param classLoader {@link ClassLoader} to be used
* @param resources {@link ResourceBundle} to be used
* @param switches {@link FXOMDocumentSwitch} configuration options to enable
* or disable certain steps in {@link FXOMDocument} creation
* (e.g. enforcing normalization)
* @throws IOException when the fxmlText cannot be loaded
*/
public FXOMDocument(String fxmlText, URL location, ClassLoader classLoader, ResourceBundle resources, FXOMDocumentSwitch... switches) throws IOException {
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
this.glue = new GlueDocument(fxmlText);
this.location = location;
this.classLoader = classLoader;
this.resources = resources;
initialDeclaredClasses = new ArrayList<>();
if (this.glue.getRootElement() != null) {
String fxmlTextToLoad = fxmlText;
if (!Set.of(switches).contains(FXOMDocumentSwitch.FOR_PREVIEW)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extract Set.of(switches) to a variable, so you don't create the set twice?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is now on set used for both places where it is required.

final FXMLPropertiesDisabler fxmlPropertiesDisabler = new FXMLPropertiesDisabler();
fxmlTextToLoad = fxmlPropertiesDisabler.disableProperties(fxmlText);
}
final FXOMLoader loader = new FXOMLoader(this);
loader.load(fxmlText);
if (normalize) {
loader.load(fxmlTextToLoad);
if (Set.of(switches).contains(FXOMDocumentSwitch.NORMALIZED)) {
final FXOMNormalizer normalizer = new FXOMNormalizer(this);
normalizer.normalize();
}
Expand All @@ -102,13 +125,7 @@ public FXOMDocument(String fxmlText, URL location, ClassLoader classLoader, Reso

hasGluonControls = fxmlText.contains(EditorPlatform.GLUON_PACKAGE);
}


public FXOMDocument(String fxmlText, URL location, ClassLoader classLoader, ResourceBundle resources) throws IOException {
this(fxmlText, location, classLoader, resources, true /* normalize */);
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
}



public FXOMDocument() {
this.glue = new GlueDocument();
}
Expand Down Expand Up @@ -443,4 +460,25 @@ public static interface SceneGraphHolder {
public void fxomDocumentWillRefreshSceneGraph(FXOMDocument fxomDocument);
public void fxomDocumentDidRefreshSceneGraph(FXOMDocument fxomDocument);
}

/**
* Depending on where the {@link FXOMDocument} shall be used,
* it is necessary to configure the {@link FXOMDocument} creation process.
* The switches here can be used to configure the creation process in the desired way.
*/
public enum FXOMDocumentSwitch {
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
/**
* When this flag is present, the {@link FXOMDocument} will be normalized (see {@link FXOMNormalizer}).
*/
NORMALIZED,

/**
* When this flag is present during {@link FXOMDocument} creation, the
* {@link FXMLPropertiesDisabler} will be used to modify the FXML source in such
* a way that the included settings will not interfere Scene Builder's
* configuration. One possible example here is the option to use the MacOS
* system menu bar.
*/
FOR_PREVIEW;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates.
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
Expand Down Expand Up @@ -57,7 +57,8 @@ public enum Type {
private Object sourceSceneGraphObject;


FXOMIntrinsic(FXOMDocument document, GlueElement glueElement, Object targetSceneGraphObject, List<FXOMProperty> properties) {
FXOMIntrinsic(FXOMDocument document, GlueElement glueElement, Object targetSceneGraphObject,
Oliver-Loeffler marked this conversation as resolved.
Show resolved Hide resolved
List<FXOMProperty> properties) {
super(document, glueElement, null);
this.sourceSceneGraphObject = targetSceneGraphObject;
for (FXOMProperty p : properties) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2014, Oracle and/or its affiliates.
* Copyright (c) 2012, 2022, Oracle and/or its affiliates.
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
* All rights reserved. Use is subject to license terms.
*
* This file is available and licensed under the following license:
Expand Down Expand Up @@ -720,7 +720,7 @@ private static FXOMDocument makeFxomDocumentFromImageURL(
fitWidth = 0;
fitHeight = 0;
} else {
final double widthScale = fitSize / imageSize;
final double widthScale = fitSize / imageSize;
Oliver-Loeffler marked this conversation as resolved.
Show resolved Hide resolved
final double heightScale = fitSize / imageHeight;
final double scale = Math.min(widthScale, heightScale);
fitWidth = Math.floor(imageWidth * scale);
Expand Down Expand Up @@ -784,7 +784,7 @@ private static FXOMDocument makeFxomDocumentFromMedia(
fitWidth = 0;
fitHeight = 0;
} else {
final double widthScale = fitSize / mediaSize;
final double widthScale = fitSize / mediaSize;
final double heightScale = fitSize / mediaHeight;
final double scale = Math.min(widthScale, heightScale);
fitWidth = Math.floor(mediaWidth * scale);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,12 @@ public void moveBeforeSibling(FXOMObject sibling) {

public Scene getScene() {
final Scene result;

jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
if (sceneGraphObject instanceof Node) {
final Node sceneGraphNode = (Node) sceneGraphObject;
result = sceneGraphNode.getScene();
} else {
} else {
result = null;
}

}
return result;
}

Expand Down Expand Up @@ -688,13 +686,11 @@ protected void changeFxomDocument(FXOMDocument destination) {
assert destination != null;
assert destination != getFxomDocument();
assert destination.getGlue() == glueElement.getDocument();
assert (parentProperty == null) || (destination == parentProperty.getFxomDocument());
assert (parentProperty == null) || (destination == parentProperty.getFxomDocument());
assert (parentCollection == null) || (destination == parentCollection.getFxomDocument());

super.changeFxomDocument(destination);
}


/*
* Object
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Gluon and/or its affiliates.
* Copyright (c) 2019, 2022, Gluon and/or its affiliates.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
Expand Down Expand Up @@ -64,8 +64,7 @@ public void refresh(FXOMDocument document) {
= new FXOMDocument(fxmlText,
document.getLocation(),
document.getClassLoader(),
document.getResources(),
false /* normalized */);
document.getResources());
final TransientStateBackup backup = new TransientStateBackup(document);
// if the refresh should not take place (e.g. due to an error), remove a property from intrinsic
if (newDocument.getSceneGraphRoot() == null && newDocument.getFxomRoot() == null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2017 Gluon and/or its affiliates.
* Copyright (c) 2016, 2022, Gluon and/or its affiliates.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
Expand Down Expand Up @@ -1260,6 +1260,8 @@ public boolean isPropertyTrimmingNeeded(PropertyName name) {
new PropertyName("unitIncrement");
private final PropertyName upperBoundName =
new PropertyName("upperBound");
private final PropertyName useSystemMenuBarName =
new PropertyName("useSystemMenuBar");
private final PropertyName userAgentStylesheetName =
new PropertyName("userAgentStylesheet");
private final PropertyName valignmentName =
Expand Down Expand Up @@ -4470,7 +4472,12 @@ public boolean isPropertyTrimmingNeeded(PropertyName name) {
com.oracle.javafx.scenebuilder.kit.metadata.property.value.DoublePropertyMetadata.DoubleKind.COORDINATE,
true, /* readWrite */
100.0, /* defaultValue */
new InspectorPath("Properties", "Specific", 98));
new InspectorPath("Properties", "Specific", 10));
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
private final ValuePropertyMetadata useSystemMenuBarNamePropertyMetadata =
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved
new BooleanPropertyMetadata(useSystemMenuBarName,
true, /* readWrite */
false,
new InspectorPath("Properties", "Specific", 70));
Oliver-Loeffler marked this conversation as resolved.
Show resolved Hide resolved
private final ValuePropertyMetadata userAgentStylesheetPropertyMetadata =
new StringPropertyMetadata(
userAgentStylesheetName,
Expand Down Expand Up @@ -5412,6 +5419,7 @@ private Metadata() {
MenuBarMetadata.getProperties().add(accessibleRole_MENU_BAR_PropertyMetadata);
MenuBarMetadata.getProperties().add(menusPropertyMetadata);
MenuBarMetadata.getProperties().add(styleClass_c18_PropertyMetadata);
MenuBarMetadata.getProperties().add(useSystemMenuBarNamePropertyMetadata);
jperedadnr marked this conversation as resolved.
Show resolved Hide resolved

MenuButtonMetadata.getProperties().add(accessibleRole_MENU_BUTTON_PropertyMetadata);
MenuButtonMetadata.getProperties().add(focusTraversable_true_PropertyMetadata);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2019, Gluon and/or its affiliates.
* Copyright (c) 2016, 2022, Gluon and/or its affiliates.
* Copyright (c) 2012, 2014, Oracle and/or its affiliates.
* All rights reserved. Use is subject to license terms.
*
Expand Down Expand Up @@ -38,6 +38,7 @@
import com.oracle.javafx.scenebuilder.kit.editor.EditorPlatform.Theme;
import com.oracle.javafx.scenebuilder.kit.editor.panel.util.AbstractWindowController;
import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.FXOMDocumentSwitch;
import com.oracle.javafx.scenebuilder.kit.i18n.I18N;
import com.oracle.javafx.scenebuilder.kit.util.MathUtils;

Expand Down Expand Up @@ -214,7 +215,8 @@ public void openDialog() {
clone = new FXOMDocument(fxomDocument.getFxmlText(false),
fxomDocument.getLocation(),
fxomDocument.getClassLoader(),
fxomDocument.getResources());
fxomDocument.getResources(),
FXOMDocumentSwitch.FOR_PREVIEW, FXOMDocumentSwitch.NORMALIZED);
clone.setSampleDataEnabled(fxomDocument.isSampleDataEnabled());
} catch (IOException ex) {
throw new RuntimeException("Bug in PreviewWindowController::openDialog", ex); //NOI18N
Expand Down Expand Up @@ -280,7 +282,8 @@ public void run() {
clone = new FXOMDocument(fxomDocument.getFxmlText(false),
fxomDocument.getLocation(),
fxomDocument.getClassLoader(),
fxomDocument.getResources());
fxomDocument.getResources(),
FXOMDocumentSwitch.FOR_PREVIEW);
clone.setSampleDataEnabled(fxomDocument.isSampleDataEnabled());
} catch (IOException ex) {
throw new RuntimeException("Bug in PreviewWindowController::requestUpdate", ex); //NOI18N
Expand Down
Loading