X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Felements%2FTextNode.java;h=f948bc053c901b7a1e92201e5c4904fb61be6f6a;hp=6fb0611f1efb34a99474bda00fcfd0f15bee3941;hb=b809a171b6dfb81ed9ef9e84870dcbcbc5912f0e;hpb=0e8cf1e1708870e179330c2f9af2d03589d553ab diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java index 6fb0611f1..f948bc053 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/elements/TextNode.java @@ -129,11 +129,6 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L */ protected String text = null; - /** - * Tells if this node is still pending for real results or not. - */ - protected boolean pending = false; - /** * The font used to render the {@link #text}. */ @@ -180,12 +175,25 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L */ protected byte verticalAlignment = 3; - protected boolean hover = false; - boolean editable = false; - boolean showSelection = true; - - - boolean wrapText = true; + /** + * Tells if this node is still pending for real results or not. + */ + protected static final int STATE_PENDING = (1 << 0); + protected static final int STATE_HOVER = (1 << 1); + protected static final int STATE_EDITABLE = (1 << 2); + protected static final int STATE_SHOW_SELECTION = (1 << 3); + protected static final int STATE_WRAP_TEXT = (1 << 4); + protected transient static final int STATE_EDITING = (1 << 5); + protected transient static final int STATE_VALID = (1 << 6); + protected transient static final int STATE_X_OFFSET_IS_DIRTY = (1 << 7); + protected static final int STATE_ALWAYS_ADD_LISTENERS = (1 << 8); + protected static final int STATE_LISTENERS_ADDED = (1 << 9); + + /** + * A combination of all the STATE_ constants defined in this class, + * e.g. {@link #STATE_PENDING}. + */ + protected int state = STATE_SHOW_SELECTION | STATE_WRAP_TEXT | STATE_VALID | STATE_X_OFFSET_IS_DIRTY; protected RVI dataRVI = null; @@ -201,11 +209,6 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L ITextListener textListener; ITextContentFilter editContentFilter; - transient boolean editing = false; - transient boolean valid = true; - - private transient boolean xOffsetIsDirty = true; - /** * The renderable line structures parsed from {@link #text} by * {@link #parseLines(String)}, laid out by @@ -248,12 +251,55 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L super.cleanup(); } + protected boolean hasState(int flags) { + return (state & flags) == flags; + } + + protected void setState(int flags) { + this.state |= flags; + } + + protected void setState(int flags, boolean set) { + if (set) + this.state |= flags; + else + this.state &= ~flags; + } + + protected void clearState(int flags) { + this.state &= ~flags; + } + + protected void setListeners(boolean add) { + if (add) + addListeners(); + else + removeListeners(); + } + protected void addListeners() { - addEventHandler(this); + if (!hasState(STATE_LISTENERS_ADDED)) { + addEventHandler(this); + setState(STATE_LISTENERS_ADDED); + } } protected void removeListeners() { - removeEventHandler(this); + if (hasState(STATE_LISTENERS_ADDED)) { + removeEventHandler(this); + clearState(STATE_LISTENERS_ADDED); + } + } + + /** + * Set to true to always enable event listening in this TextNode to allow the text node to keep track of hovering, etc. and to allow DnD even when + * @param force + */ + public void setForceEventListening(boolean force) { + setState(STATE_ALWAYS_ADD_LISTENERS, force); + if (force && !hasState(STATE_EDITABLE)) { + setListeners(force); + } } /** @@ -277,11 +323,11 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L * @return null if no change to edit state was made */ protected Boolean setEditMode(boolean edit, boolean notify) { - if (edit && !editable) + if (edit && !hasState(STATE_EDITABLE)) return null; - if (editing == edit) + if (hasState(STATE_EDITING) == edit) return null; - this.editing = edit; + setState(STATE_EDITING); if (edit) { caret = text != null ? text.length() : 0; selectionTail = 0; @@ -298,29 +344,26 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @SyncField({"editable"}) public void setEditable(boolean editable) { - boolean changed = this.editable != editable; - this.editable = editable; - if (editing && !editable) + boolean changed = hasState(STATE_EDITABLE) != editable; + setState(STATE_EDITABLE, editable); + if (hasState(STATE_EDITING) && !editable) setEditMode(false); - if (changed) { - if (editable) - addListeners(); - else - removeListeners(); + if (changed && !hasState(STATE_ALWAYS_ADD_LISTENERS)) { + setListeners(editable); } } public boolean isEditable() { - return editable; + return hasState(STATE_EDITABLE); } public boolean isEditMode() { - return editing; + return hasState(STATE_EDITING); } @SyncField({"wrapText"}) public void setWrapText(boolean wrapText) { - this.wrapText = wrapText; + setState(STATE_WRAP_TEXT, wrapText); } /** @@ -328,16 +371,16 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L * the width of the box is fixed */ public boolean isWrapText() { - return this.wrapText; + return hasState(STATE_WRAP_TEXT); } @SyncField({"showSelection"}) public void setShowSelection(boolean showSelection) { - this.showSelection = showSelection; + setState(STATE_SHOW_SELECTION, showSelection); } public boolean showsSelection() { - return showSelection; + return hasState(STATE_SHOW_SELECTION); } /** @@ -353,7 +396,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L // no value => value if(this.text == null && text != null) NodeUtil.decreasePending(this); - if (editing) + if (hasState(STATE_EDITING)) return; this.text = new String(text != null ? text : ""); @@ -399,7 +442,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @SyncField({"text","caret","selectionTail"}) public void setText(String text) { //System.out.println("TextNode.setText('" + text + "', " + editing + ")"); - if (editing) + if (hasState(STATE_EDITING)) return; // value => no value @@ -416,9 +459,11 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @SyncField({"pending"}) public void setPending(boolean pending) { - if(!this.pending && pending) NodeUtil.increasePending(this); - if(this.pending && !pending) NodeUtil.decreasePending(this); - this.pending = pending; + boolean p = hasState(STATE_PENDING); + if(!p && pending) NodeUtil.increasePending(this); + if(p && !pending) NodeUtil.decreasePending(this); + if(p != pending) + setState(STATE_PENDING, pending); } @SyncField({"fixedWidth"}) @@ -448,16 +493,16 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L } public final void synchronizeWrapText(boolean wrap) { - wrapText = wrap; + setState(STATE_WRAP_TEXT, wrap); } public boolean isHovering() { - return hover; + return hasState(STATE_HOVER); } @SyncField({"hover"}) public void setHover(boolean hover) { - this.hover = hover; + setState(STATE_HOVER, hover); repaint(); } @@ -564,6 +609,8 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L Color color = this.color; boolean isSelected = NodeUtil.isSelected(this, 1); + boolean hover = hasState(STATE_HOVER); + boolean editing = hasState(STATE_EDITING); if (!isSelected && hover) { color = add(color, 120, 120, 120); @@ -634,7 +681,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L fieldName.equals("created_by") ); } - Color backgroundColor = valid ? this.backgroundColor : Color.red; + Color backgroundColor = hasState(STATE_VALID) ? this.backgroundColor : Color.red; // RENDER if ( !isPdfField ) { @@ -887,7 +934,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L if(validator != null) { String error = validator.apply(text); - valid = (error == null); + setState(STATE_VALID, (error == null)); } resetCaches(); @@ -908,7 +955,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @ServerSide protected void fireTextEditingCancelled() { - valid = true; + setState(STATE_VALID); if (deactivateEdit()) { if (textListener != null) @@ -925,9 +972,9 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @ServerSide public void fireTextEditingEnded() { - if (!valid) { + if (!hasState(STATE_VALID)) { fireTextEditingCancelled(); - valid = true; + setState(STATE_VALID); return; } @@ -957,13 +1004,13 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L } private void invalidateXOffset() { - xOffsetIsDirty = true; + setState(STATE_X_OFFSET_IS_DIRTY); } private void computeEditingXOffset() { if(lines == null) return; - if(!xOffsetIsDirty) return; + if(!hasState(STATE_X_OFFSET_IS_DIRTY)) return; if(fixedWidth > 0f) { // TODO: implement @@ -979,7 +1026,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L } - xOffsetIsDirty = false; + clearState(STATE_X_OFFSET_IS_DIRTY); } @@ -1259,7 +1306,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L // Parse & layout (unaligned) Line[] lines = null; - if(wrapText) { + if(hasState(STATE_WRAP_TEXT)) { float width = fixedWidth; if(width <= 0 && targetBounds != null) width = (float) (((targetBounds.getWidth() - 2*paddingX)) * scaleRecip); @@ -1545,7 +1592,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @Override protected boolean handleCommand(CommandEvent e) { - if (!editing) + if (!hasState(STATE_EDITING)) return false; if (Commands.SELECT_ALL.equals(e.command)) { @@ -1557,7 +1604,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @Override protected boolean keyPressed(KeyPressedEvent event) { - if (!editing) + if (!hasState(STATE_EDITING)) return false; char c = event.character; @@ -1658,7 +1705,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L case KeyEvent.VK_ESCAPE: text = textBeforeEdit; resetCaches(); - editing = false; + clearState(STATE_EDITING); fireTextEditingCancelled(); return true; @@ -1725,7 +1772,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L if (event.button != MouseClickEvent.LEFT_BUTTON) return false; - if (hover) { + if (hasState(STATE_HOVER)) { hoverClick++; if (hoverClick < 2) return false; @@ -1734,7 +1781,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L if (ctx == null) return false; IElement e = DiagramNodeUtil.getElement(ctx, this); - if (!editing) { + if (!hasState(STATE_EDITING)) { if (Boolean.TRUE.equals(setEditMode(true))) { editActivation = activateEdit(0, e, ctx); repaint(); @@ -1742,7 +1789,7 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L } } else { hoverClick = 0; - if (editing) { + if (hasState(STATE_EDITING)) { fireTextEditingEnded(); } } @@ -1772,13 +1819,13 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @Override protected boolean mouseButtonPressed(MouseButtonPressedEvent event) { - if (!editing) + if (!hasState(STATE_EDITING)) return false; Point2D local = controlToLocal( event.controlPosition ); // FIXME: once the event coordinate systems are cleared up, remove this workaround local = parentToLocal(local); - if (hover && this.containsLocal(local)) { + if (hasState(STATE_HOVER) && this.containsLocal(local)) { setCaret(local, event.isShiftDown()); } return false; @@ -1787,8 +1834,8 @@ public class TextNode extends G2DNode implements IDynamicSelectionPainterNode, L @Override protected boolean mouseMoved(MouseMovedEvent event) { boolean hit = hitTest(event, 3.0); - if (hit != hover) { - hover = hit; + if (hit != hasState(STATE_HOVER)) { + setState(STATE_HOVER, hit); repaint(); } return false;