Skip to content

Commit

Permalink
Bug 493084 - Rework status decoration system
Browse files Browse the repository at this point in the history
  • Loading branch information
tomsontom committed May 5, 2016
1 parent 1abda2b commit f9f426b
Show file tree
Hide file tree
Showing 23 changed files with 340 additions and 116 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Export-Package: org.eclipse.fx.ui.controls;version="2.4.0",
Bundle-ActivationPolicy: lazy
Service-Component: OSGI-INF/services/org.eclipse.fx.ui.controls.styledtext.UnderlineStrategyFactory.xml,
OSGI-INF/services/org.eclipse.fx.ui.controls.image.fontawesome.FontAwesomeIconFontProvider.xml,
OSGI-INF/services/org.eclipse.fx.ui.controls.form.SimpleStatusDecorator.xml
OSGI-INF/services/org.eclipse.fx.ui.controls.form.GraphicDecorator.xml
Bundle-Vendor: Eclipse.org
Import-Package: com.google.common.collect;version="15.0.0",
org.eclipse.fx.core;version="2.4.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.fx.ui.controls.form.GraphicDecorator">
<service>
<provide interface="org.eclipse.fx.ui.controls.form.NodeDecorator"/>
</service>
<implementation class="org.eclipse.fx.ui.controls.form.GraphicDecorator"/>
</scr:component>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.eclipse.fx.ui.controls.form;

import org.eclipse.fx.core.Status;

import javafx.beans.property.ObjectProperty;

public interface DecoratedNode {
public ObjectProperty<Status> statusProperty();
public void setStatus(Status status);
public Status getStatus();
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package org.eclipse.fx.ui.controls.form;

import org.eclipse.fx.core.Status;
import org.eclipse.fx.core.Status.State;
import org.osgi.service.component.annotations.Component;

import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.css.PseudoClass;
import javafx.scene.Node;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.control.SkinBase;

@Component
public class GraphicDecorator implements NodeDecorator {
static final String BASE_STYLESHEET = GraphicDecorator.class.getResource("graphic-status-decorator.css").toExternalForm(); //$NON-NLS-1$

public enum Location {
TOP_LEFT,
TOP_RIGHT,
BOTTOM_LEFT,
BOTTOM_RIGHT
}

// public interface LocationProvider extends Predicate<Control> {
// public Location getLocation(Control node);
// }

private Location location;

public GraphicDecorator() {
this(Location.TOP_LEFT);
}

public GraphicDecorator(Location location) {
this.location = location;
}

@Override
public DecoratedNode decorate(Node node) {
if( node instanceof Control ) {
return new GraphicDecoratedControl((Control) node, this.location);
}
throw new IllegalArgumentException("Unable to decorate '"+node+"'"); //$NON-NLS-1$//$NON-NLS-2$
}

static class GraphicDecoratedControl implements DecoratedNode {
private final Label icon;
private final ObjectProperty<Status> statusProperty = new SimpleObjectProperty<Status>(this, "status", Status.ok()); //$NON-NLS-1$

private static PseudoClass error = PseudoClass.getPseudoClass("error");
private static PseudoClass warning = PseudoClass.getPseudoClass("warning");
private static PseudoClass ok = PseudoClass.getPseudoClass("ok");
private static PseudoClass cancel = PseudoClass.getPseudoClass("cancel");

public GraphicDecoratedControl(Control c, Location location) {
this.icon = new Label() {
@Override
public String getUserAgentStylesheet() {
return BASE_STYLESHEET;
}
};
this.icon.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
this.icon.getStyleClass().add("status-decorator-icon"); //$NON-NLS-1$
this.icon.setManaged(false);

if( c.getSkin() != null ) {
((SkinBase<?>)c.getSkin()).getChildren().add(this.icon);
}

c.skinProperty().addListener( ( ob, ol, ne ) -> {
if( ol != null ) {
((SkinBase<?>)ol).getChildren().remove(this.icon);
}

if( ne != null ) {
((SkinBase<?>)ne).getChildren().add(this.icon);
}
});

if( location == Location.TOP_LEFT ) {
this.icon.translateXProperty().bind(this.icon.widthProperty().divide(-2));
this.icon.translateYProperty().bind(this.icon.heightProperty().divide(-2));
} else if( location == Location.TOP_RIGHT ) {
this.icon.translateXProperty().bind(Bindings.createDoubleBinding(() -> {
return Double.valueOf(c.getWidth() - this.icon.widthProperty().get() / 2);
},this.icon.widthProperty(), c.widthProperty()));
this.icon.translateYProperty().bind(this.icon.heightProperty().divide(-2));
} else if( location == Location.BOTTOM_LEFT ) {
this.icon.translateXProperty().bind(this.icon.widthProperty().divide(-2));
this.icon.translateYProperty().bind(Bindings.createDoubleBinding(() -> {
return Double.valueOf(c.getHeight() - this.icon.heightProperty().get() / 2);
}, this.icon.heightProperty(), c.heightProperty()));
} else if( location == Location.BOTTOM_RIGHT ) {
this.icon.translateXProperty().bind(Bindings.createDoubleBinding(() -> {
return Double.valueOf(c.getWidth() - this.icon.widthProperty().get() / 2);
},this.icon.widthProperty(), c.widthProperty()));
this.icon.translateYProperty().bind(Bindings.createDoubleBinding(() -> {
return Double.valueOf(c.getHeight() - this.icon.heightProperty().get() / 2);
}, this.icon.heightProperty(), c.heightProperty()));
}

updatePseudoState(this.icon, this.statusProperty.getValue());
this.statusProperty.addListener( (o, ol, ne) -> {
updatePseudoState(this.icon, ne);
});

this.icon.translateXProperty().addListener( o -> {
System.err.println(this.icon.translateXProperty().get());
});
}

private static void updatePseudoState(Node statusIcon, Status status) {
statusIcon.pseudoClassStateChanged(error, status.getState() == State.ERROR);
statusIcon.pseudoClassStateChanged(warning, status.getState() == State.WARNING);
statusIcon.pseudoClassStateChanged(ok, status.getState() == State.OK);
statusIcon.pseudoClassStateChanged(cancel, status.getState() == State.CANCEL);
statusIcon.autosize();
}

@Override
public ObjectProperty<Status> statusProperty() {
return this.statusProperty;
}

@Override
public void setStatus(Status status) {
statusProperty().set(status);
}

@Override
public Status getStatus() {
return statusProperty().get();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.eclipse.fx.ui.controls.form;

import org.eclipse.fx.core.Util;
import org.eclipse.fx.core.property.ValidationStatusPropertyOwner;

import javafx.scene.Node;

public interface NodeDecorator {
public DecoratedNode decorate(Node node);

public static DecoratedNode apply(NodeDecorator decorator, Node control) {
return decorator.decorate(control);
}

public static DecoratedNode apply(Node control) {
return Util.getService(NodeDecorator.class).orElseGet(() -> new GraphicDecorator()).decorate(control);
}

public static void apply(Node control, ValidationStatusPropertyOwner statusOwner) {
apply(control).statusProperty().bind(statusOwner.statusProperty());
}

public static void apply(NodeDecorator decorator, Node control, ValidationStatusPropertyOwner statusOwner) {
apply(decorator, control).statusProperty().bind(statusOwner.statusProperty());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.eclipse.fx.ui.controls.form;

import org.eclipse.fx.core.Status;
import org.eclipse.fx.core.property.ValidationStatusPropertyOwner;

import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Node;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;

public class SimpleDecoratedNode extends HBox implements DecoratedNode {
private ObjectProperty<Status> statusProperty = new SimpleObjectProperty<Status>(this, "status", Status.ok()); //$NON-NLS-1$

public SimpleDecoratedNode(Node node) {
HBox.setHgrow(node, Priority.ALWAYS);
getStyleClass().add("status-decoration-container"); //$NON-NLS-1$
getChildren().addAll(new StatusNode(this.statusProperty),node);
}

@Override
public ObjectProperty<Status> statusProperty() {
return this.statusProperty;
}

@Override
public void setStatus(Status status) {
statusProperty().set(status);
}

@Override
public Status getStatus() {
return statusProperty().get();
}

public static SimpleDecoratedNode create(Node node, ValidationStatusPropertyOwner validationStatusOwner) {
SimpleDecoratedNode c = new SimpleDecoratedNode(node);
c.statusProperty().bind(validationStatusOwner.statusProperty());
return c;
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class StatusNode extends Region {
private static PseudoClass ok = PseudoClass.getPseudoClass("ok");
private static PseudoClass cancel = PseudoClass.getPseudoClass("cancel");

static final String BASE_STYLESHEET = SimpleStatusDecorator.class.getResource("status-icon.css").toExternalForm(); //$NON-NLS-1$
static final String BASE_STYLESHEET = SimpleDecoratedNode.class.getResource("status-icon.css").toExternalForm(); //$NON-NLS-1$

public StatusNode(ReadOnlyProperty<Status> statusProperty) {
Label statusIcon = new Label();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.status-decorator-icon {
-fx-pref-width: 8;
-fx-pref-height: 8;
}

.status-decorator-icon:error {
-fx-graphic: url("icons/dialog-error-8.png");
}

.status-decorator-icon:warning {
-fx-graphic: url("icons/dialog-warning-8.png");
}

.status-decorator-icon:cancel {

}

.status-decorator-icon:ok {
visibility: false;
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Loading

0 comments on commit f9f426b

Please sign in to comment.