You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2012/12/06 18:42:18 UTC
[44/52] [partial] ISIS-188: moving framework/ subdirs up to parent
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Shape.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Shape.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Shape.java
new file mode 100644
index 0000000..bf2196d
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Shape.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.drawing;
+
+public class Shape {
+ int count = 0;
+ int[] x = new int[6];
+ int[] y = new int[6];
+
+ public Shape() {
+ }
+
+ public Shape(final int xOrigin, final int yOrigin) {
+ this.x[0] = xOrigin;
+ this.y[0] = yOrigin;
+ count = 1;
+ }
+
+ public Shape(final Shape shape) {
+ count = shape.count;
+ this.x = new int[count];
+ this.y = new int[count];
+ for (int i = 0; i < count; i++) {
+ this.x[i] = shape.x[i];
+ this.y[i] = shape.y[i];
+ }
+ }
+
+ public void addVector(final int width, final int height) {
+ final int x = this.x[count - 1] + width;
+ final int y = this.y[count - 1] + height;
+ addPoint(x, y);
+ }
+
+ public void addPoint(final int x, final int y) {
+ if (this.x.length == count) {
+ final int[] newX = new int[count * 2];
+ final int[] newY = new int[count * 2];
+ System.arraycopy(this.x, 0, newX, 0, count);
+ System.arraycopy(this.y, 0, newY, 0, count);
+ this.x = newX;
+ this.y = newY;
+ }
+ this.x[count] = x;
+ this.y[count] = y;
+ count++;
+ }
+
+ public int count() {
+ return count;
+ }
+
+ public int[] getX() {
+ final int[] xx = new int[count];
+ System.arraycopy(x, 0, xx, 0, count);
+ return xx;
+ }
+
+ public int[] getY() {
+ final int[] yy = new int[count];
+ System.arraycopy(y, 0, yy, 0, count);
+ return yy;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuffer points = new StringBuffer();
+ for (int i = 0; i < count; i++) {
+ if (i > 0) {
+ points.append("; ");
+ }
+ points.append(this.x[i]);
+ points.append(",");
+ points.append(this.y[i]);
+ }
+ return "Shape {" + points + "}";
+ }
+
+ public void translate(final int x, final int y) {
+ for (int i = 0; i < count; i++) {
+ this.x[i] += x;
+ this.y[i] += y;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Size.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Size.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Size.java
new file mode 100644
index 0000000..f5dca68
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Size.java
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.drawing;
+
+public class Size {
+ public static final Size createMax() {
+ return new Size(10000, 10000);
+ }
+
+ int height;
+ int width;
+
+ public Size() {
+ width = 0;
+ height = 0;
+ }
+
+ public Size(final int width, final int height) {
+ this.width = width;
+ this.height = height;
+ }
+
+ public Size(final Size size) {
+ width = size.width;
+ height = size.height;
+ }
+
+ public void contract(final int width, final int height) {
+ this.width -= width;
+ this.height -= height;
+ }
+
+ public void contract(final Size size) {
+ this.width -= size.width;
+ this.height -= size.height;
+ }
+
+ public void contractHeight(final int height) {
+ this.height -= height;
+ }
+
+ public void contract(final Padding padding) {
+ height -= padding.top + padding.bottom;
+ width -= padding.left + padding.right;
+ }
+
+ public void contractWidth(final int width) {
+ this.width -= width;
+ }
+
+ public void ensureHeight(final int height) {
+ this.height = Math.max(this.height, height);
+ }
+
+ public void ensureWidth(final int width) {
+ this.width = Math.max(this.width, width);
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == this) {
+ return true;
+ }
+
+ if (obj instanceof Size) {
+ final Size object = (Size) obj;
+
+ return object.width == this.width && object.height == this.height;
+ }
+
+ return false;
+ }
+
+ public void extend(final int width, final int height) {
+ this.width += width;
+ this.height += height;
+ }
+
+ public void extend(final Padding padding) {
+ this.width += padding.getLeftRight();
+ this.height += padding.getTopBottom();
+ }
+
+ public void extend(final Size size) {
+ this.width += size.width;
+ this.height += size.height;
+ }
+
+ public void extendHeight(final int height) {
+ this.height += height;
+ }
+
+ public void extendWidth(final int width) {
+ this.width += width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ /**
+ * Limits the height of this Size so that if its height is greater than the
+ * specified maximum then the height is reduced to the maximum. If the
+ * height is less than maximum (or equal to it) then nothing is done.
+ */
+ public void limitHeight(final int maximum) {
+ height = Math.min(height, maximum);
+ }
+
+ /**
+ * Limits the width of this Size so that if its width is greater than the
+ * specified maximum then the width is reduced to the maximum. If the width
+ * is less than maximum (or equal to it) then nothing is done.
+ */
+ public void limitWidth(final int maximum) {
+ width = Math.min(width, maximum);
+ }
+
+ /**
+ * Limits the width and height of this Size so it is no larger than the
+ * specified maximum size.
+ *
+ * @see #limitWidth(int)
+ * @see #limitHeight(int)
+ */
+ public void limitSize(final Size maximum) {
+ limitWidth(maximum.width);
+ limitHeight(maximum.height);
+ }
+
+ public void setHeight(final int height) {
+ this.height = height;
+ }
+
+ public void setWidth(final int width) {
+ this.width = width;
+ }
+
+ @Override
+ public String toString() {
+ return width + "x" + height;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Text.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Text.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Text.java
new file mode 100644
index 0000000..68739e7
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/drawing/Text.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.drawing;
+
+public interface Text {
+
+ /**
+ * Returns the width, in pixels, of the specified character.
+ */
+ int charWidth(char c);
+
+ /**
+ * Returns the height, in pixels, of the distance from the baseline to top
+ * of the tallest character (including accents that are not common in
+ * english.
+ */
+ int getAscent();
+
+ /**
+ * Returns the height, in pixels, of the distance from bottom of the lowest
+ * descending character to the baseline.
+ */
+ int getDescent();
+
+ /**
+ * Returns the mid point, in pixels, between the baseline and the top of the
+ * characters.
+ */
+ int getMidPoint();
+
+ /**
+ * Return the name of this text style.
+ */
+ String getName();
+
+ /**
+ * Returns the height, in pixels, for a normal line of text - where there is
+ * some space between two lines of text.
+ */
+ int getTextHeight();
+
+ /**
+ * Returns the sum of the text height and line spacing.
+ *
+ * @see #getLineHeight()
+ * @see #getLineSpacing()
+ */
+ int getLineHeight();
+
+ /**
+ * Returns the number of blank vertical pixels to add between adjacent lines
+ * to give them additional spacing.
+ */
+ int getLineSpacing();
+
+ /**
+ * Returns the width of the specified in pixels.
+ */
+ int stringWidth(String text);
+
+ /**
+ * Returns the height in pixels when the specified text is wrapped at the
+ * specified width
+ */
+ int stringHeight(String text, int maxWidth);
+
+ int stringWidth(String message, int maxWidth);
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/AbstractField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/AbstractField.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/AbstractField.java
new file mode 100644
index 0000000..9980f16
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/AbstractField.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.commons.exceptions.NotYetImplementedException;
+import org.apache.isis.core.commons.lang.ToString;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Allow;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Image;
+import org.apache.isis.viewer.dnd.drawing.ImageFactory;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Padding;
+import org.apache.isis.viewer.dnd.view.BackgroundTask;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.InternalDrag;
+import org.apache.isis.viewer.dnd.view.KeyboardAction;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewAreaType;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.action.BackgroundWork;
+import org.apache.isis.viewer.dnd.view.base.AbstractView;
+
+public abstract class AbstractField extends AbstractView {
+ protected static final int TEXT_WIDTH = 20;
+ private boolean identified;
+
+ protected AbstractField(final Content content, final ViewSpecification design) {
+ super(content, design);
+ }
+
+ @Override
+ public boolean canFocus() {
+ return canChangeValue().isAllowed();
+ }
+
+ protected boolean provideClearCopyPaste() {
+ return false;
+ }
+
+ protected Consent canClear() {
+ return Allow.DEFAULT;
+ }
+
+ protected void clear() {
+ }
+
+ protected void copyToClipboard() {
+ }
+
+ protected void pasteFromClipboard() {
+ }
+
+ /**
+ * Indicates the drag started within this view's bounds is continuing. By
+ * default does nothing.
+ */
+ @Override
+ public void drag(final InternalDrag drag) {
+ }
+
+ /**
+ * Default implementation - does nothing
+ */
+ @Override
+ public void dragCancel(final InternalDrag drag) {
+ }
+
+ /**
+ * Indicates the start of a drag within this view's bounds. By default does
+ * nothing.
+ */
+ @Override
+ public View dragFrom(final Location location) {
+ return null;
+ }
+
+ /**
+ * Indicates the drag started within this view's bounds has been finished
+ * (although the location may now be outside of its bounds). By default does
+ * nothing.
+ */
+ @Override
+ public void dragTo(final InternalDrag drag) {
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ if (getState().isActive()) {
+ clearBackground(canvas, Toolkit.getColor(ColorsAndFonts.COLOR_IDENTIFIED));
+ }
+
+ if (getState().isOutOfSynch()) {
+ clearBackground(canvas, Toolkit.getColor(ColorsAndFonts.COLOR_OUT_OF_SYNC));
+ }
+
+ if (getState().isInvalid()) {
+ final Image image = ImageFactory.getInstance().loadIcon("invalid-entry", 12, null);
+ if (image != null) {
+ canvas.drawImage(image, getSize().getWidth() - 16, 2);
+ }
+
+ // canvas.clearBackground(this,
+ // Toolkit.getColor(ColorsAndFonts.COLOR_INVALID));
+ }
+
+ super.draw(canvas);
+ }
+
+ @Override
+ public void entered() {
+ super.entered();
+ identified = true;
+ final Consent changable = canChangeValue();
+ if (changable.isVetoed()) {
+ getFeedbackManager().setViewDetail(changable.getReason());
+ }
+ markDamaged();
+ }
+
+ @Override
+ public void exited() {
+ super.exited();
+ identified = false;
+ markDamaged();
+ }
+
+ public boolean getIdentified() {
+ return identified;
+ }
+
+ @Override
+ public Padding getPadding() {
+ return new Padding(0, 0, 0, 0);
+ }
+
+ public View getRoot() {
+ throw new NotYetImplementedException();
+ }
+
+ String getSelectedText() {
+ return "";
+ }
+
+ @Override
+ public boolean hasFocus() {
+ return getViewManager().hasFocus(getView());
+ }
+
+ public boolean isEmpty() {
+ return false;
+ }
+
+ public boolean indicatesForView(final Location mouseLocation) {
+ return false;
+ }
+
+ /**
+ * Called when the user presses any key on the keyboard while this view has
+ * the focus.
+ */
+ @Override
+ public void keyPressed(final KeyboardAction key) {
+ }
+
+ /**
+ * Called when the user releases any key on the keyboard while this view has
+ * the focus.
+ */
+ @Override
+ public void keyReleased(final KeyboardAction action) {
+ }
+
+ /**
+ * Called when the user presses a non-control key (i.e. data entry keys and
+ * not shift, up-arrow etc). Such a key press will result in a prior call to
+ * <code>keyPressed</code> and a subsequent call to <code>keyReleased</code>
+ * .
+ */
+ @Override
+ public void keyTyped(final KeyboardAction action) {
+ }
+
+ @Override
+ public void contentMenuOptions(final UserActionSet options) {
+ if (provideClearCopyPaste()) {
+ options.add(new CopyValueOption(this));
+ options.add(new PasteValueOption(this));
+ options.add(new ClearValueOption(this));
+ }
+
+ super.contentMenuOptions((options));
+ options.setColor(Toolkit.getColor(ColorsAndFonts.COLOR_MENU_VALUE));
+ }
+
+ protected final void initiateSave(final boolean moveToNextField) {
+ BackgroundWork.runTaskInBackground(this, new BackgroundTask() {
+ @Override
+ public void execute() {
+ save();
+ getParent().updateView();
+ invalidateLayout();
+ if (moveToNextField) {
+ getFocusManager().focusNextView();
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "Save field";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Saving " + getContent().windowTitle();
+ }
+
+ });
+ }
+
+ protected abstract void save();
+
+ @Override
+ public String toString() {
+ final ToString str = new ToString(this, getId());
+ str.append("location", getLocation());
+ final ObjectAdapter adapter = getContent().getAdapter();
+ str.append("object", adapter == null ? "" : adapter.getObject());
+ return str.toString();
+ }
+
+ @Override
+ public ViewAreaType viewAreaType(final Location mouseLocation) {
+ return ViewAreaType.INTERNAL;
+ }
+
+ @Override
+ public int getBaseline() {
+ return Toolkit.defaultBaseline();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/AbstractValueOption.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/AbstractValueOption.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/AbstractValueOption.java
new file mode 100644
index 0000000..03f071b
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/AbstractValueOption.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.content.TextParseableContent;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+public abstract class AbstractValueOption extends UserActionAbstract {
+ protected final AbstractField field;
+
+ AbstractValueOption(final AbstractField field, final String name) {
+ super(name);
+ this.field = field;
+ }
+
+ protected ObjectAdapter getValue(final View view) {
+ final TextParseableContent vc = (TextParseableContent) view.getContent();
+ final ObjectAdapter value = vc.getAdapter();
+ return value;
+ }
+
+ protected void updateParent(final View view) {
+ // have commented this out because it isn't needed; the transaction
+ // manager will do this
+ // for us on endTransaction. Still, if I'm wrong and it is needed,
+ // hopefully this
+ // comment will help...
+ // IsisContext.getObjectPersistor().objectChangedAllDirty();
+
+ view.markDamaged();
+ view.getParent().invalidateContent();
+ }
+
+ protected boolean isEmpty(final View view) {
+ return field.isEmpty();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/CheckboxField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/CheckboxField.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/CheckboxField.java
new file mode 100644
index 0000000..dd44730
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/CheckboxField.java
@@ -0,0 +1,158 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.progmodel.facets.value.booleans.BooleanValueFacet;
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Color;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Image;
+import org.apache.isis.viewer.dnd.drawing.ImageFactory;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Click;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.KeyboardAction;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewConstants;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.base.AbstractFieldSpecification;
+import org.apache.isis.viewer.dnd.view.content.TextParseableContent;
+
+/*
+ * TODO this class does not set the underlying business object via its boolean adapter. Need
+ * to create an content type for flags.
+ */
+public class CheckboxField extends AbstractField {
+ private static final int size = Toolkit.getText(ColorsAndFonts.TEXT_NORMAL).getTextHeight();
+
+ public static class Specification extends AbstractFieldSpecification {
+ @Override
+ public boolean canDisplay(final ViewRequirement requirement) {
+ return requirement.isTextParseable() && requirement.isForValueType(BooleanValueFacet.class);
+ }
+
+ @Override
+ public View createView(final Content content, final Axes axes, final int sequence) {
+ return new CheckboxField(content, this);
+ }
+
+ @Override
+ public String getName() {
+ return "Checkbox";
+ }
+ }
+
+ public CheckboxField(final Content content, final ViewSpecification specification) {
+ super(content, specification);
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ Color color;
+ color = getIdentified() ? Toolkit.getColor(ColorsAndFonts.COLOR_SECONDARY2) : null;
+ color = hasFocus() ? Toolkit.getColor(ColorsAndFonts.COLOR_IDENTIFIED) : color;
+
+ final int top = ViewConstants.VPADDING;
+ final int left = ViewConstants.HPADDING;
+ if (color != null) {
+ canvas.drawRectangle(left - 2, top - 2, size + 4, size + 4, color);
+ }
+
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_SECONDARY1);
+ canvas.drawRectangle(left, top, size, size, color);
+ if (isSet()) {
+ final Image image = ImageFactory.getInstance().loadImage("check-mark");
+ canvas.drawImage(image, 3, 3, size, size);
+ }
+ }
+
+ @Override
+ public void firstClick(final Click click) {
+ toggle();
+ }
+
+ @Override
+ public void secondClick(final Click click) {
+ // ignore
+ }
+
+ @Override
+ public void thirdClick(final Click click) {
+ // ignore
+ }
+
+ @Override
+ public void keyTyped(final KeyboardAction action) {
+ if (action.getKeyCode() == ' ') {
+ toggle();
+ } else {
+ super.keyTyped(action);
+ }
+ }
+
+ private void toggle() {
+ if (canChangeValue().isAllowed()) {
+ initiateSave(false);
+ }
+ }
+
+ @Override
+ public Consent canChangeValue() {
+ final TextParseableContent cont = (TextParseableContent) getContent();
+ return cont.isEditable();
+ }
+
+ @Override
+ public int getBaseline() {
+ return ViewConstants.VPADDING + Toolkit.getText(ColorsAndFonts.TEXT_NORMAL).getAscent();
+ }
+
+ @Override
+ public Size getRequiredSize(final Size availableSpace) {
+ return new Size(ViewConstants.HPADDING + size + ViewConstants.HPADDING, ViewConstants.VPADDING + size + ViewConstants.VPADDING);
+ }
+
+ private boolean isSet() {
+ final BooleanValueFacet booleanValueFacet = getContent().getSpecification().getFacet(BooleanValueFacet.class);
+ return booleanValueFacet.isSet(getContent().getAdapter());
+ }
+
+ @Override
+ protected void save() {
+ final BooleanValueFacet booleanValueFacet = getContent().getSpecification().getFacet(BooleanValueFacet.class);
+ final ObjectAdapter adapter = getContent().getAdapter();
+ if (adapter == null) {
+ ((TextParseableContent) getContent()).parseTextEntry("true");
+ } else {
+ booleanValueFacet.toggle(adapter);
+ }
+
+ // return parsed != null ? PersistorUtil.createAdapter(parsed) : null;
+
+ markDamaged();
+ ((TextParseableContent) getContent()).entryComplete();
+ getParent().invalidateContent();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ClearValueOption.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ClearValueOption.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ClearValueOption.java
new file mode 100644
index 0000000..3daa53f
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ClearValueOption.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.Veto;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+
+public class ClearValueOption extends AbstractValueOption {
+
+ public ClearValueOption(final AbstractField field) {
+ super(field, "Clear");
+ }
+
+ @Override
+ public String getDescription(final View view) {
+ return "Clear field";
+ }
+
+ @Override
+ public Consent disabled(final View view) {
+ final ObjectAdapter value = getValue(view);
+ final Consent consent = view.canChangeValue();
+ if (consent.isVetoed()) {
+ return consent;
+ }
+ final Consent canClear = field.canClear();
+ if (canClear.isVetoed()) {
+ // TODO: move logic into Facets.
+ return new Veto(String.format("Can't clear %s values", value.getSpecification().getShortIdentifier()));
+ }
+ if (value == null || isEmpty(view)) {
+ // TODO: move logic into Facets.
+ return new Veto("Field is already empty");
+ }
+ // TODO: move logic into Facets.
+ return consent.setDescription(String.format("Clear value ", value.titleString()));
+ }
+
+ @Override
+ public void execute(final Workspace frame, final View view, final Location at) {
+ field.clear();
+ }
+
+ @Override
+ public String toString() {
+ return "ClearValueOption";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ColorField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ColorField.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ColorField.java
new file mode 100644
index 0000000..986ef0f
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ColorField.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.commons.exceptions.NotYetImplementedException;
+import org.apache.isis.core.metamodel.facets.object.parseable.InvalidEntryException;
+import org.apache.isis.core.progmodel.facets.value.color.ColorValueFacet;
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Color;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewConstants;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.base.AbstractFieldSpecification;
+import org.apache.isis.viewer.dnd.view.content.TextParseableContent;
+import org.apache.isis.viewer.dnd.view.lookup.OpenDropDownBorder;
+import org.apache.isis.viewer.dnd.view.lookup.OptionContent;
+
+public class ColorField extends TextParseableFieldAbstract {
+ public static class Specification extends AbstractFieldSpecification {
+
+ @Override
+ public boolean canDisplay(final ViewRequirement requirement) {
+ return requirement.isTextParseable() && requirement.isForValueType(ColorValueFacet.class);
+ }
+
+ @Override
+ public View createView(final Content content, final Axes axes, final int sequence) {
+ final ColorField field = new ColorField(content, this);
+ return new OpenDropDownBorder(field) {
+ @Override
+ protected View createDropDownView() {
+ return new ColorFieldOverlay(field);
+ }
+
+ @Override
+ protected void setSelection(final OptionContent selectedContent) {
+ }
+ };
+ }
+
+ @Override
+ public String getName() {
+ return "Color";
+ }
+ }
+
+ private int color;
+
+ public ColorField(final Content content, final ViewSpecification specification) {
+ super(content, specification);
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ Color color;
+
+ if (hasFocus()) {
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_PRIMARY1);
+ } else if (getParent().getState().isObjectIdentified()) {
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_IDENTIFIED);
+ } else if (getParent().getState().isRootViewIdentified()) {
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_PRIMARY2);
+ } else {
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_SECONDARY1);
+ }
+
+ int top = 0;
+ int left = 0;
+
+ final Size size = getSize();
+ int w = size.getWidth() - 1;
+ int h = size.getHeight() - 1;
+ canvas.drawRectangle(left, top, w, h, color);
+ left++;
+ top++;
+ w -= 1;
+ h -= 1;
+ canvas.drawSolidRectangle(left, top, w, h, Toolkit.getColor(getColor()));
+ }
+
+ /*
+ * @Override public void firstClick(final Click click) { if
+ * (((TextParseableContent) getContent()).isEditable().isAllowed()) { final
+ * View overlay = new DisposeOverlay(new ColorFieldOverlay(this), new
+ * ValueDropDownAxis((TextParseableContent) getContent(), getView())); final
+ * Location location = this.getAbsoluteLocation(); // Location location =
+ * click.getLocationWithinViewer(); // TODO offset by constant amount //
+ * location.move(10, 10); overlay.setLocation(location); //
+ * overlay.setSize(overlay.getRequiredSize(new Size())); //
+ * overlay.markDamaged(); getViewManager().setOverlayView(overlay); } }
+ */
+ @Override
+ public int getBaseline() {
+ return ViewConstants.VPADDING + Toolkit.getText(ColorsAndFonts.TEXT_NORMAL).getAscent();
+ }
+
+ int getColor() {
+ final TextParseableContent content = ((TextParseableContent) getContent());
+ final ColorValueFacet col = content.getSpecification().getFacet(ColorValueFacet.class);
+ return col.colorValue(content.getAdapter());
+ }
+
+ @Override
+ public Size getRequiredSize(final Size availableSpace) {
+ return new Size(45, 15);
+ }
+
+ @Override
+ protected void save() {
+ try {
+ parseEntry("" + color);
+ } catch (final InvalidEntryException e) {
+ throw new NotYetImplementedException();
+ }
+ }
+
+ void setColor(final int color) {
+ this.color = color;
+ initiateSave(false);
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ColorFieldOverlay.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ColorFieldOverlay.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ColorFieldOverlay.java
new file mode 100644
index 0000000..ab27820
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ColorFieldOverlay.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Color;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.Click;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.base.AbstractView;
+
+class ColorFieldOverlay extends AbstractView {
+ private static final int colors[] = new int[] { 0xffffff, 0x0, 0x666666, 0xcccccc, // white,
+ // black,
+ // dark
+ // gray, light gray
+ 0x000099, 0x0066cc, 0x0033ff, 0x99ccff, // blues
+ 0x990000, 0xff0033, 0xcc0066, 0xff66ff, // reds
+ 0x003300, 0x00ff33, 0x669933, 0xccff66 // greens
+ };
+ private static final int COLUMNS = 4;
+ private static final int ROWS = 4;
+ private static final int ROW_HEIGHT = 18;
+ private static final int COLUMN_WIDTH = 23;
+
+ private final ColorField field;
+
+ public ColorFieldOverlay(final ColorField field) {
+ super(field.getContent());
+
+ this.field = field;
+ }
+
+ @Override
+ public Size getRequiredSize(final Size availableSpace) {
+ return new Size(COLUMNS * COLUMN_WIDTH, ROWS * ROW_HEIGHT);
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ canvas.drawSolidRectangle(0, 0, COLUMNS * COLUMN_WIDTH - 1, ROWS * ROW_HEIGHT - 1, Toolkit.getColor(ColorsAndFonts.COLOR_SECONDARY3));
+ for (int i = 0; i < colors.length; i++) {
+ final Color color = Toolkit.getColor(colors[i]);
+ final int y = i / COLUMNS * ROW_HEIGHT;
+ final int x = i % COLUMNS * COLUMN_WIDTH;
+ canvas.drawSolidRectangle(x, y, COLUMN_WIDTH - 1, ROW_HEIGHT - 1, color);
+ }
+ canvas.drawRectangle(0, 0, COLUMNS * COLUMN_WIDTH - 1, ROWS * ROW_HEIGHT - 1, Toolkit.getColor(ColorsAndFonts.COLOR_PRIMARY2));
+ }
+
+ @Override
+ public void firstClick(final Click click) {
+ final int x = click.getLocation().getX();
+ final int y = click.getLocation().getY();
+ final int color = colors[y / ROW_HEIGHT * COLUMNS + x / COLUMN_WIDTH];
+ field.setColor(color);
+ getViewManager().clearOverlayView();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/CopyValueOption.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/CopyValueOption.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/CopyValueOption.java
new file mode 100644
index 0000000..b9219af
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/CopyValueOption.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.metamodel.consent.Allow;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.Veto;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+
+public class CopyValueOption extends AbstractValueOption {
+
+ public CopyValueOption(final AbstractField field) {
+ super(field, "Copy");
+ }
+
+ @Override
+ public Consent disabled(final View view) {
+ if (isEmpty(view)) {
+ // TODO: move logic into Facets
+ return new Veto("Field is empty");
+ }
+ // TODO: move logic into Facets
+ return Allow.DEFAULT;
+ // return new Allow(String.format("Copy value '%s' to clipboard",
+ // field.getSelectedText()));
+ }
+
+ @Override
+ public void execute(final Workspace frame, final View view, final Location at) {
+ field.copyToClipboard();
+ }
+
+ @Override
+ public String toString() {
+ return "CopyValueOption";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DateFieldSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DateFieldSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DateFieldSpecification.java
new file mode 100644
index 0000000..5a8cc12
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DateFieldSpecification.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.progmodel.facets.value.date.DateValueFacet;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.base.AbstractFieldSpecification;
+import org.apache.isis.viewer.dnd.view.border.TextFieldResizeBorder;
+import org.apache.isis.viewer.dnd.view.content.TextParseableContent;
+import org.apache.isis.viewer.dnd.view.lookup.OpenDropDownBorder;
+import org.apache.isis.viewer.dnd.view.lookup.OptionContent;
+
+/**
+ * Creates a single line text field with the base line drawn.
+ */
+public class DateFieldSpecification extends AbstractFieldSpecification {
+ @Override
+ public boolean canDisplay(final ViewRequirement requirement) {
+ return requirement.isTextParseable() && requirement.isForValueType(DateValueFacet.class);
+ }
+
+ @Override
+ public View createView(final Content content, final Axes axes, final int sequence) {
+ final SingleLineTextField textField = new SingleLineTextField((TextParseableContent) content, this, true);
+ final View field = new TextFieldResizeBorder(textField);
+ return new OpenDropDownBorder(field) {
+ @Override
+ protected View createDropDownView() {
+ return DatePickerControl.getPicker(content);
+ }
+
+ @Override
+ protected void setSelection(final OptionContent selectedContent) {
+ }
+ };
+ }
+
+ @Override
+ public String getName() {
+ return "Date Field";
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DatePicker.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DatePicker.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DatePicker.java
new file mode 100644
index 0000000..2153fb5
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DatePicker.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Size;
+
+public interface DatePicker {
+
+ public abstract Size getRequiredSize(Size availableSpace);
+
+ public abstract void draw(final Canvas canvas);
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DatePickerControl.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DatePickerControl.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DatePickerControl.java
new file mode 100644
index 0000000..99f1675
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/DatePickerControl.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Look;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.look.LookFactory;
+import org.apache.isis.viewer.dnd.view.look.linux.LinuxDatePicker;
+import org.apache.isis.viewer.dnd.view.look.linux.LinuxLook;
+
+public class DatePickerControl {
+
+ private static final Look LINUX_LOOK = new LinuxLook();
+
+ public static View getPicker(final Content content) {
+ final Look look = LookFactory.getInstalledLook();
+ if (look.getClass().isInstance(LINUX_LOOK)) {
+ return new LinuxDatePicker(content);
+ }
+ return new SimpleDatePicker(content);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/EmptyField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/EmptyField.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/EmptyField.java
new file mode 100644
index 0000000..1f5449a
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/EmptyField.java
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.drawing.Text;
+import org.apache.isis.viewer.dnd.icon.IconSpecification;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.ContentDrag;
+import org.apache.isis.viewer.dnd.view.ObjectContent;
+import org.apache.isis.viewer.dnd.view.Placement;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewConstants;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.action.ObjectParameter;
+import org.apache.isis.viewer.dnd.view.base.AbstractView;
+import org.apache.isis.viewer.dnd.view.base.IconGraphic;
+import org.apache.isis.viewer.dnd.view.border.ObjectBorder;
+import org.apache.isis.viewer.dnd.view.field.OneToOneField;
+import org.apache.isis.viewer.dnd.view.lookup.OpenObjectDropDownBorder;
+import org.apache.isis.viewer.dnd.view.text.TitleText;
+
+public class EmptyField extends AbstractView {
+
+ public static class Specification implements ViewSpecification {
+ @Override
+ public boolean canDisplay(final ViewRequirement requirement) {
+ return requirement.isObject() && requirement.isOpen() && !requirement.isTextParseable() && !requirement.hasReference();
+ }
+
+ @Override
+ public View createView(final Content content, final Axes axes, final int sequence) {
+ final EmptyField emptyField = new EmptyField(content, this, Toolkit.getText(ColorsAndFonts.TEXT_NORMAL));
+ if ((content instanceof OneToOneField && ((OneToOneField) content).isEditable().isAllowed()) || content instanceof ObjectParameter) {
+ if (content.isOptionEnabled()) {
+ return new ObjectBorder(new OpenObjectDropDownBorder(emptyField, new IconSpecification()));
+ } else {
+ return new ObjectBorder(emptyField);
+ }
+ } else {
+ return emptyField;
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "empty field";
+ }
+
+ @Override
+ public boolean isAligned() {
+ return false;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return false;
+ }
+
+ @Override
+ public boolean isReplaceable() {
+ return true;
+ }
+
+ @Override
+ public boolean isResizeable() {
+ return false;
+ }
+
+ @Override
+ public boolean isSubView() {
+ return true;
+ }
+ }
+
+ private final IconGraphic icon;
+ private final TitleText text;
+
+ public EmptyField(final Content content, final ViewSpecification specification, final Text style) {
+ super(content, specification);
+ if (((ObjectContent) content).getObject() != null) {
+ throw new IllegalArgumentException("Content for EmptyField must be null: " + content);
+ }
+ final ObjectAdapter object = ((ObjectContent) getContent()).getObject();
+ if (object != null) {
+ throw new IllegalArgumentException("Content for EmptyField must be null: " + object);
+ }
+ icon = new IconGraphic(this, style);
+ text = new EmptyFieldTitleText(this, style);
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ super.draw(canvas);
+ int x = 0;
+ final int y = icon.getBaseline();
+ icon.draw(canvas, x, y);
+ x += icon.getSize().getWidth();
+ x += ViewConstants.HPADDING;
+
+ text.draw(canvas, x, y);
+ }
+
+ @Override
+ public int getBaseline() {
+ return icon.getBaseline();
+ }
+
+ @Override
+ public Size getRequiredSize(final Size availableSpace) {
+ final Size size = icon.getSize();
+ size.extendWidth(ViewConstants.HPADDING);
+ size.extendWidth(text.getSize().getWidth());
+ return size;
+ }
+
+ private Consent canDrop(final ObjectAdapter dragSource) {
+ final ObjectContent content = (ObjectContent) getContent();
+ return content.canSet(dragSource);
+ }
+
+ @Override
+ public void dragIn(final ContentDrag drag) {
+ final Content sourceContent = drag.getSourceContent();
+ if (sourceContent instanceof ObjectContent) {
+ final ObjectAdapter source = ((ObjectContent) sourceContent).getObject();
+ final Consent canDrop = canDrop(source);
+ if (canDrop.isAllowed()) {
+ getState().setCanDrop();
+ } else {
+ getState().setCantDrop();
+ }
+ final String actionText = canDrop.isVetoed() ? canDrop.getReason() : "Set to " + sourceContent.title();
+ getFeedbackManager().setAction(actionText);
+ } else {
+ getState().setCantDrop();
+ }
+
+ markDamaged();
+ }
+
+ @Override
+ public void dragOut(final ContentDrag drag) {
+ getState().clearObjectIdentified();
+ markDamaged();
+ }
+
+ @Override
+ public void drop(final ContentDrag drag) {
+ getState().clearViewIdentified();
+ markDamaged();
+ final ObjectAdapter target = ((ObjectContent) getParent().getContent()).getObject();
+ final Content sourceContent = drag.getSourceContent();
+ if (sourceContent instanceof ObjectContent) {
+ final ObjectAdapter source = ((ObjectContent) sourceContent).getObject();
+ setField(target, source);
+ }
+ }
+
+ /**
+ * Objects returned by menus are used to set this field before passing the
+ * call on to the parent.
+ */
+ @Override
+ public void objectActionResult(final ObjectAdapter result, final Placement placement) {
+ final ObjectAdapter target = ((ObjectContent) getParent().getContent()).getObject();
+ if (result instanceof ObjectAdapter) {
+ setField(target, result);
+ }
+ super.objectActionResult(result, placement);
+ }
+
+ private void setField(final ObjectAdapter parent, final ObjectAdapter object) {
+ if (canDrop(object).isAllowed()) {
+ ((ObjectContent) getContent()).setObject(object);
+ getParent().invalidateContent();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "EmptyField" + getId();
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/EmptyFieldTitleText.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/EmptyFieldTitleText.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/EmptyFieldTitleText.java
new file mode 100644
index 0000000..4cbc524
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/EmptyFieldTitleText.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Text;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.ObjectContent;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.text.TitleText;
+
+class EmptyFieldTitleText extends TitleText {
+ private final Content content;
+
+ public EmptyFieldTitleText(final View view, final Text style) {
+ super(view, style, Toolkit.getColor(ColorsAndFonts.COLOR_SECONDARY2));
+ content = view.getContent();
+ }
+
+ @Override
+ protected String title() {
+ return ((ObjectContent) content).getSpecification().getSingularName();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/FieldOfSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/FieldOfSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/FieldOfSpecification.java
new file mode 100644
index 0000000..362405f
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/FieldOfSpecification.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.dnd.drawing.Color;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.drawing.Text;
+import org.apache.isis.viewer.dnd.form.InternalFormSpecification;
+import org.apache.isis.viewer.dnd.list.SimpleListSpecification;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.border.IconBorder;
+import org.apache.isis.viewer.dnd.view.composite.CompositeView;
+import org.apache.isis.viewer.dnd.view.content.FieldContent;
+import org.apache.isis.viewer.dnd.view.text.TitleText;
+
+public class FieldOfSpecification implements ViewSpecification {
+
+ @Override
+ public boolean canDisplay(final ViewRequirement requirement) {
+ return requirement.isOpen() && !requirement.isSubview() && requirement.getContent() instanceof FieldContent;
+ }
+
+ @Override
+ public String getName() {
+ return "Field Of";
+ }
+
+ @Override
+ public boolean isAligned() {
+ return false;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return false;
+ }
+
+ @Override
+ public boolean isReplaceable() {
+ return false;
+ }
+
+ @Override
+ public boolean isResizeable() {
+ return false;
+ }
+
+ @Override
+ public boolean isSubView() {
+ return false;
+ }
+
+ @Override
+ public View createView(final Content content, final Axes axes, final int sequence) {
+ final FieldContent fieldContent = (FieldContent) content;
+ final ObjectAdapter parent = fieldContent.getParent();
+ final Content parentContent = Toolkit.getContentFactory().createRootContent(parent);
+ View view = new InternalFieldView(parentContent, fieldContent, axes, this);
+ view = addBorder(parentContent, fieldContent, view);
+ return view;
+ }
+
+ private View addBorder(final Content parentContent, final FieldContent fieldContent, View view) {
+ final Text textStyle = Toolkit.getText(ColorsAndFonts.TEXT_TITLE);
+ final Color colorStyle = Toolkit.getColor(ColorsAndFonts.COLOR_BLACK);
+ final TitleText titleText = new TitleText(view, textStyle, colorStyle) {
+ @Override
+ protected String title() {
+ return parentContent.title() + "/" + fieldContent.getFieldName();
+ }
+ };
+ view = new IconBorder(view, titleText, null, textStyle);
+ return view;
+ }
+
+}
+
+class InternalFieldView extends CompositeView {
+ // final View[] subviews = new View[1];
+
+ private final Content fieldContent;
+
+ public InternalFieldView(final Content content, final Content fieldContent, final Axes axes, final ViewSpecification specification) {
+ super(content, specification);
+ this.fieldContent = fieldContent;
+ }
+
+ /*
+ * public void draw(Canvas canvas) { subviews[0].draw(canvas); }
+ *
+ * public View[] getSubviews() { return subviews; }
+ */
+ @Override
+ public Size requiredSize(final Size availableSpace) {
+ return getSubviews()[0].getRequiredSize(availableSpace);
+ }
+
+ @Override
+ protected void doLayout(final Size maximumSize) {
+ final View view = getSubviews()[0];
+ view.setSize(view.getRequiredSize(maximumSize));
+ view.layout();
+ }
+
+ @Override
+ protected void buildView() {
+ ViewSpecification internalSpecification;
+ if (fieldContent.isCollection()) {
+ internalSpecification = new SimpleListSpecification();
+ } else {
+ internalSpecification = new InternalFormSpecification();
+ }
+ addView(internalSpecification.createView(fieldContent, new Axes(), 0));
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ImageField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ImageField.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ImageField.java
new file mode 100644
index 0000000..cfbce6c
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/ImageField.java
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.File;
+
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.progmodel.facets.value.image.ImageValueFacet;
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Color;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.KeyboardAction;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewConstants;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.base.AbstractFieldSpecification;
+import org.apache.isis.viewer.dnd.view.base.AwtImage;
+import org.apache.isis.viewer.dnd.view.content.FieldContent;
+import org.apache.isis.viewer.dnd.view.field.OneToOneField;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+public class ImageField extends AbstractField {
+ public static class Specification extends AbstractFieldSpecification {
+ @Override
+ public boolean canDisplay(final ViewRequirement requirement) {
+ return requirement.isForValueType(ImageValueFacet.class);
+ }
+
+ @Override
+ public View createView(final Content content, final Axes axes, final int sequence) {
+ return new ImageField(content, this);
+ }
+
+ @Override
+ public String getName() {
+ return "Image";
+ }
+ }
+
+ private static final Logger LOG = Logger.getLogger(ImageField.class);
+ private static final MediaTracker mt = new MediaTracker(new java.awt.Canvas());
+
+ public ImageField(final Content content, final ViewSpecification specification) {
+ super(content, specification);
+ }
+
+ @Override
+ public boolean canFocus() {
+ return true;
+ }
+
+ @Override
+ public void contentMenuOptions(final UserActionSet options) {
+ super.contentMenuOptions(options);
+
+ options.add(new UserActionAbstract("Load image from file...") {
+ @Override
+ public void execute(final Workspace workspace, final View view, final Location at) {
+ final String file = getViewManager().selectFilePath("Load image", ".");
+ if (new File(file).exists()) {
+ loadImageFromFile(file);
+ }
+ }
+ });
+ }
+
+ private void copy() {
+ }
+
+ @Override
+ public void draw(final Canvas canvas) {
+ Color color;
+
+ if (hasFocus()) {
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_PRIMARY1);
+ } else if (getParent().getState().isObjectIdentified()) {
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_IDENTIFIED);
+ } else if (getParent().getState().isRootViewIdentified()) {
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_PRIMARY2);
+ } else {
+ color = Toolkit.getColor(ColorsAndFonts.COLOR_SECONDARY1);
+ }
+
+ int top = 0;
+ int left = 0;
+
+ final Size size = getSize();
+ int w = size.getWidth() - 1;
+ int h = size.getHeight() - 1;
+ canvas.drawRectangle(left, top, w, h, color);
+ left++;
+ top++;
+ w -= 1;
+ h -= 1;
+
+ final ObjectAdapter value = getContent().getAdapter();
+ if (value != null) {
+ final ImageValueFacet facet = value.getSpecification().getFacet(ImageValueFacet.class);
+ final java.awt.Image image = facet.getImage(value);
+ if (image != null) {
+ final Size imageSize = new Size(facet.getWidth(value), facet.getHeight(value));
+ if (imageSize.getWidth() <= w && imageSize.getHeight() <= h) {
+ canvas.drawImage(new AwtImage(image), left, top);
+ } else {
+ canvas.drawImage(new AwtImage(image), left, top, w, h);
+ }
+ }
+ }
+ }
+
+ @Override
+ public int getBaseline() {
+ return ViewConstants.VPADDING + Toolkit.getText(ColorsAndFonts.TEXT_NORMAL).getAscent();
+ }
+
+ @Override
+ public Size getRequiredSize(final Size availableSpace) {
+ final ObjectAdapter value = getContent().getAdapter();
+ if (value == null) {
+ return super.getRequiredSize(availableSpace);
+ } else {
+ final ImageValueFacet facet = value.getSpecification().getFacet(ImageValueFacet.class);
+ final int width = Math.min(120, Math.max(32, facet.getWidth(value)));
+ final int height = Math.min(120, Math.max(32, facet.getHeight(value)));
+ return new Size(width, height);
+ }
+ }
+
+ @Override
+ public void keyPressed(final KeyboardAction key) {
+ if (canChangeValue().isVetoed()) {
+ return;
+ }
+
+ final int keyCode = key.getKeyCode();
+ if (keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_SHIFT || keyCode == KeyEvent.VK_ALT) {
+ return;
+ }
+
+ final int modifiers = key.getModifiers();
+ final boolean ctrl = (modifiers & InputEvent.CTRL_MASK) > 0;
+
+ switch (keyCode) {
+ case KeyEvent.VK_V:
+ if (ctrl) {
+ key.consume();
+ pasteFromClipboard();
+ }
+ break;
+ case KeyEvent.VK_C:
+ if (ctrl) {
+ key.consume();
+ copy();
+ }
+ break;
+ }
+ }
+
+ private void loadImage(final Image image) {
+ mt.addImage(image, 1);
+ try {
+ mt.waitForAll();
+ } catch (final InterruptedException e) {
+ throw new IsisException(e);
+ }
+
+ // final ObjectAdapter value = getContent().getAdapter();
+ final ImageValueFacet facet = ((FieldContent) getContent()).getSpecification().getFacet(ImageValueFacet.class);
+ final ObjectAdapter object = facet.createValue(image);
+ ((OneToOneField) getContent()).setObject(object);
+ // ((TextParseableField) getContent()).entryComplete();
+ invalidateLayout();
+ }
+
+ /*
+ * private void loadImageFromURL(final String filename) { try { final URL
+ * url = new URL("file://" + filename); final Image image =
+ * java.awt.Toolkit.getDefaultToolkit().getImage(url); loadImage(image); }
+ * catch (final MalformedURLException e) { throw new
+ * IsisException("Failed to load image from " + filename); } }
+ */
+ private void loadImageFromFile(final String filename) {
+ final Image image = java.awt.Toolkit.getDefaultToolkit().getImage(filename);
+ loadImage(image);
+ }
+
+ @Override
+ protected void pasteFromClipboard() {
+ final Clipboard cb = java.awt.Toolkit.getDefaultToolkit().getSystemClipboard();
+ final Transferable content = cb.getContents(this);
+
+ try {
+ if (content.isDataFlavorSupported(DataFlavor.stringFlavor)) {
+ // treat a string as a file
+ final String filename = (String) content.getTransferData(DataFlavor.stringFlavor);
+ LOG.debug("pasted image from " + filename);
+ loadImageFromFile("file://" + filename);
+
+ } else {
+ LOG.info("unsupported paste operation " + content);
+
+ // note java does not support transferring images from the
+ // clipboard
+ // although it has an image flavor for it !!?
+ /*
+ * DataFlavor[] transferDataFlavors =
+ * content.getTransferDataFlavors(); for (int i = 0; i <
+ * transferDataFlavors.length; i++) {
+ * LOG.debug("data transfer as " +
+ * transferDataFlavors[i].getMimeType()); }
+ *
+ * Image image = (Image)
+ * content.getTransferData(DataFlavor.imageFlavor);
+ * LOG.debug("pasted " + image);
+ */
+
+ }
+
+ } catch (final Throwable e) {
+ LOG.error("invalid paste operation " + e);
+ }
+
+ }
+
+ @Override
+ protected void save() {
+ }
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/PasswordField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/PasswordField.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/PasswordField.java
new file mode 100644
index 0000000..fefd02f
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/PasswordField.java
@@ -0,0 +1,188 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.Color;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.drawing.Text;
+import org.apache.isis.viewer.dnd.util.Properties;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.ViewConstants;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.content.TextParseableContent;
+import org.apache.isis.viewer.dnd.view.text.TextContent;
+
+public class PasswordField extends TextField {
+ protected static final Text style = Toolkit.getText(ColorsAndFonts.TEXT_NORMAL);
+ private int maxTextWidth;
+ private char echoCharacter;
+
+ public PasswordField(final Content content, final ViewSpecification design) {
+ super((TextParseableContent) content, design, true, TextContent.NO_WRAPPING);
+ setMaxTextWidth(TEXT_WIDTH);
+ final String echoCharacterSetting = IsisContext.getConfiguration().getString(Properties.PROPERTY_BASE + "echo");
+ if (echoCharacterSetting == null || echoCharacterSetting.equals(" ")) {
+ echoCharacter = '*';
+ } else {
+ echoCharacter = echoCharacterSetting.charAt(0);
+ }
+ }
+
+ @Override
+ public void contentMenuOptions(final UserActionSet options) {
+ options.add(new ClearValueOption(this));
+ options.setColor(Toolkit.getColor(ColorsAndFonts.COLOR_MENU_VALUE));
+ }
+
+ @Override
+ protected boolean provideClearCopyPaste() {
+ return false;
+ }
+
+ /**
+ * Only allow deletion of last character, ie don;t allow editing of the
+ * internals of the password.
+ */
+ @Override
+ public void delete() {
+ textContent.deleteLeft(cursor);
+ cursor.left();
+ selection.resetTo(cursor);
+ changeMade();
+ }
+
+ /**
+ * disable left key.
+ */
+ @Override
+ protected void left(final boolean alt, final boolean shift) {
+ }
+
+ /**
+ * disable right key.
+ */
+ @Override
+ protected void right(final boolean alt, final boolean shift) {
+ }
+
+ /**
+ * disable home key.
+ */
+ @Override
+ protected void home(final boolean alt, final boolean shift) {
+ }
+
+ /**
+ * disable end key.
+ */
+ @Override
+ protected void end(final boolean alt, final boolean shift) {
+ }
+
+ /**
+ * disable page down key.
+ */
+ @Override
+ protected void pageDown(final boolean shift, final boolean ctrl) {
+ }
+
+ /**
+ * disable page up key.
+ */
+ @Override
+ protected void pageUp(final boolean shift, final boolean ctrl) {
+ }
+
+ private String echoPassword(final String password) {
+ final int length = password.length();
+ String echoedPassword = "";
+ for (int i = 0; i < length; i++) {
+ echoedPassword += echoCharacter;
+ }
+ return echoedPassword;
+ }
+
+ @Override
+ public Size getRequiredSize(final Size availableSpace) {
+ final int width = ViewConstants.HPADDING + maxTextWidth + ViewConstants.HPADDING;
+ int height = style.getTextHeight() + ViewConstants.VPADDING;
+ height = Math.max(height, Toolkit.defaultFieldHeight());
+
+ return new Size(width, height);
+ }
+
+ /**
+ * Set the maximum width of the field, as a number of characters
+ */
+ private void setMaxTextWidth(final int noCharacters) {
+ maxTextWidth = style.charWidth('o') * noCharacters;
+ }
+
+ @Override
+ protected void align() {
+ }
+
+ @Override
+ protected void drawHighlight(final Canvas canvas, final int maxWidth) {
+ }
+
+ @Override
+ protected void drawLines(final Canvas canvas, final Color color, final int width) {
+ final int baseline = getBaseline();
+ canvas.drawLine(ViewConstants.HPADDING, baseline, ViewConstants.HPADDING + width, baseline, color);
+ }
+
+ @Override
+ protected void drawText(final Canvas canvas, final Color textColor, final int width) {
+
+ final String[] lines = textContent.getDisplayLines();
+ if (lines.length > 1) {
+ throw new IsisException("Password field should contain a string that contains no line breaks; contains " + lines.length);
+ }
+
+ final String chars = lines[0];
+ if (chars == null) {
+ throw new IsisException();
+ }
+ if (chars.endsWith("\n")) {
+ throw new IsisException();
+ }
+
+ final int baseline = getBaseline();
+ final String echoPassword = echoPassword(chars);
+
+ // draw cursor
+ if (hasFocus() && canChangeValue().isAllowed()) {
+ final int pos = style.stringWidth(echoPassword) - ViewConstants.HPADDING;
+ final Color color = Toolkit.getColor(ColorsAndFonts.COLOR_TEXT_CURSOR);
+ canvas.drawLine(pos, (baseline + style.getDescent()), pos, baseline - style.getAscent(), color);
+ }
+
+ // draw text
+ canvas.drawText(echoPassword, ViewConstants.HPADDING, baseline, textColor, style);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/PasswordFieldSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/PasswordFieldSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/PasswordFieldSpecification.java
new file mode 100644
index 0000000..a51dfeb
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/field/PasswordFieldSpecification.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.viewer.dnd.field;
+
+import org.apache.isis.core.progmodel.facets.value.password.PasswordValueFacet;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.base.AbstractFieldSpecification;
+
+public class PasswordFieldSpecification extends AbstractFieldSpecification {
+ @Override
+ public boolean canDisplay(final ViewRequirement requirement) {
+ return requirement.isTextParseable() && requirement.isForValueType(PasswordValueFacet.class);
+ }
+
+ @Override
+ public View createView(final Content content, final Axes axes, final int sequence) {
+ return new PasswordField(content, this);
+ }
+
+ @Override
+ public String getName() {
+ return "Password Field";
+ }
+
+ @Override
+ public boolean isAligned() {
+ return true;
+ }
+}