package org.archstudio.bna.logics.editing; import static org.archstudio.sysutils.SystemUtils.firstOrNull; import org.archstudio.bna.BNAModelEvent; import org.archstudio.bna.IBNAModelListener; import org.archstudio.bna.IBNAView; import org.archstudio.bna.IBNAWorld; import org.archstudio.bna.ICoordinate; import org.archstudio.bna.constants.StickyMode; import org.archstudio.bna.facets.IHasIndicatorPoint; import org.archstudio.bna.facets.IHasMutableAngle; import org.archstudio.bna.facets.IHasMutableReferencePoint; import org.archstudio.bna.facets.IHasStickyShape; import org.archstudio.bna.facets.IHasText; import org.archstudio.bna.facets.IHasToolTip; import org.archstudio.bna.keys.IThingKey; import org.archstudio.bna.keys.IThingRefKey; import org.archstudio.bna.keys.ThingKey; import org.archstudio.bna.keys.ThingRefKey; import org.archstudio.bna.logics.AbstractThingLogic; import org.archstudio.bna.logics.coordinating.DynamicStickPointLogic; import org.archstudio.bna.logics.coordinating.MirrorValueLogic; import org.archstudio.bna.logics.tracking.ThingValueTrackingLogic; import org.archstudio.bna.things.labels.AnchoredLabelThing; import org.archstudio.bna.ui.IBNAMenuListener2; import org.archstudio.bna.utils.Assemblies; import org.archstudio.bna.utils.BNAAction; import org.archstudio.bna.utils.BNAUtils; import org.archstudio.bna.utils.BNAUtils2.ThingsAtLocation; import org.archstudio.bna.utils.UserEditableUtils; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IMenuManager; import org.eclipse.swt.graphics.RGB; import com.google.common.collect.Lists; public class ShowHideTagsLogic extends AbstractThingLogic implements IBNAMenuListener2, IBNAModelListener { public static final String USER_MAY_SHOW_HIDE_TAG = "userMayShowHideTag"; public static final IThingKey<Boolean> SHOW_TAG_KEY = ThingKey.create("showTag"); public static final IThingRefKey<AnchoredLabelThing> TAG_KEY = ThingRefKey.create("assembly-tag"); protected final ThingValueTrackingLogic valueLogic; protected final DynamicStickPointLogic stickLogic; protected final MirrorValueLogic mirrorLogic; public ShowHideTagsLogic(IBNAWorld world) { super(world); valueLogic = logics.addThingLogic(ThingValueTrackingLogic.class); stickLogic = logics.addThingLogic(DynamicStickPointLogic.class); mirrorLogic = logics.addThingLogic(MirrorValueLogic.class); for (IHasStickyShape forThing : valueLogic.getThings(SHOW_TAG_KEY, true, IHasStickyShape.class)) { showTag(forThing); } } @Override public void fillMenu(IBNAView view, ICoordinate location, ThingsAtLocation thingsAtLocation, IMenuManager menu) { BNAUtils.checkLock(); if (thingsAtLocation.getThingAtLocation() != null) { final IHasStickyShape st = Assemblies.getEditableThing(model, thingsAtLocation.getThing(), IHasStickyShape.class, USER_MAY_SHOW_HIDE_TAG); if (st != null) { final AnchoredLabelThing tt = getTag(st); // lookup tags for thing IAction tagAction = new BNAAction("Show Tag") { @Override public void runWithLock() { if (tt == null) { BNAOperations.set("Tag", model, st, SHOW_TAG_KEY, true); } else { BNAOperations.set("Tag", model, st, SHOW_TAG_KEY, false); } } }; tagAction.setChecked(tt != null); menu.add(tagAction); } } } @Override public void bnaModelChanged(BNAModelEvent evt) { BNAUtils.checkLock(); switch (evt.getEventType()) { case THING_CHANGED: if (!evt.getThingEvent().getPropertyName().equals(SHOW_TAG_KEY)) { break; } // fall through case THING_ADDED: if (evt.getTargetThing() instanceof IHasStickyShape) { if (evt.getTargetThing().has(SHOW_TAG_KEY, true)) { showTag((IHasStickyShape) evt.getTargetThing()); } else { hideTag((IHasStickyShape) evt.getTargetThing()); } } break; case THING_REMOVED: if (evt.getTargetThing() instanceof IHasStickyShape) { hideTag((IHasStickyShape) evt.getTargetThing()); } break; default: // do nothing } } protected AnchoredLabelThing getTag(IHasStickyShape forThing) { return firstOrNull(valueLogic.getThings(stickLogic.getStickyThingKey(IHasIndicatorPoint.INDICATOR_POINT_KEY), forThing.getID(), AnchoredLabelThing.class)); } protected AnchoredLabelThing showTag(IHasStickyShape forThing) { AnchoredLabelThing t = getTag(forThing); if (t == null) { t = model.addThing(new AnchoredLabelThing(Lists.newArrayList(forThing.getID(), "tag")), forThing); t.setAnchorPoint(BNAUtils.getCentralPoint(forThing)); t.setEdgeColor(new RGB(0, 0, 0)); UserEditableUtils.addEditableQualities(t, IHasMutableReferencePoint.USER_MAY_MOVE, IHasMutableAngle.USER_MAY_CHANGE_ANGLE); t.set(stickLogic.getStickyModeKey(IHasIndicatorPoint.INDICATOR_POINT_KEY), StickyMode.EDGE_FROM_CENTER); stickLogic.getStickyThingKey(IHasIndicatorPoint.INDICATOR_POINT_KEY).set(t, forThing); if (forThing instanceof IHasText) { mirrorLogic.mirrorValue(forThing, IHasText.TEXT_KEY, t); } else { mirrorLogic.mirrorValue(forThing, IHasToolTip.TOOL_TIP_KEY, t, IHasText.TEXT_KEY); } Assemblies.markPart(Assemblies.getRoot(model, forThing), TAG_KEY, t); } return t; } protected void hideTag(IHasStickyShape forThing) { AnchoredLabelThing t = getTag(forThing); if (t != null) { t.remove(stickLogic.getStickyThingKey(IHasIndicatorPoint.INDICATOR_POINT_KEY)); mirrorLogic.unmirror(t, IHasText.TEXT_KEY); Assemblies.unmarkPart(model, t); model.removeThing(t); } } }