use of edu.cmu.cs.hcii.cogtool.model.DoubleRectangle in project cogtool by cogtool.
the class FrameEditorController method createSetRemoteLabelTextAction.
// createUngroupElementsAction
private IListenerAction createSetRemoteLabelTextAction() {
return new IListenerAction() {
public Class<?> getParameterClass() {
return FrameEditorUI.SetRemoteLabelTextParms.class;
}
public boolean performAction(Object prms) {
FrameEditorUI.SetRemoteLabelTextParms p = (FrameEditorUI.SetRemoteLabelTextParms) prms;
// Check p.selectedElement; must be an FrameElementGroup
// or an IWidget of WidgetType Button, PullDownList, Graffiti,
// or TextBox (whether IS_STANDARD or IS_CUSTOM) or an IWidget
// of WidgetType Radio, Check, or ListBoxItem if IS_STANDARD
// (in which case, the label belongs to the parent SimpleWidgetGroup)
FrameElement owningElt = p.selectedElement.getRemoteLabelOwner();
if (owningElt == null) {
interaction.protestUnsupportedLabelOwnerType();
return false;
}
IWidget remoteLabel = (IWidget) owningElt.getAttribute(WidgetAttributes.REMOTE_LABEL_ATTR);
// Already has a label; simply update
if (remoteLabel != null) {
changeTitleProperty(FrameEditorLID.SetRemoteLabelText, SET_REMOTE_LABEL, remoteLabel, p.newText, // not a separator!
false, undoMgr);
} else if ((p.newText != null) && !p.newText.equals("")) {
CompoundUndoableEdit editSequence = new CompoundUndoableEdit(SET_REMOTE_LABEL, FrameEditorLID.SetRemoteLabelText);
final double INITIAL_WIDTH = 100.0;
final double INITIAL_HEIGHT = 16.0;
final double MIN_MARGIN = 5.0;
final double EXTRA_MARGIN = 10.0;
DoubleRectangle eltBds = owningElt.getEltBounds();
double maxY = eltBds.y - INITIAL_HEIGHT - MIN_MARGIN;
DoubleRectangle labelBds;
if (0.0 <= maxY) {
labelBds = new DoubleRectangle(eltBds.x, Math.max(0.0, maxY - EXTRA_MARGIN), INITIAL_WIDTH, INITIAL_HEIGHT);
} else {
double maxX = Math.max(0.0, eltBds.x - INITIAL_WIDTH - MIN_MARGIN);
labelBds = new DoubleRectangle(Math.max(0.0, maxX - EXTRA_MARGIN), eltBds.y, INITIAL_WIDTH, INITIAL_HEIGHT);
}
remoteLabel = new Widget(labelBds, WidgetType.Text);
DefaultCmd.setAttribute(owningElt, demoStateMgr, WidgetAttributes.REMOTE_LABEL_ATTR, remoteLabel, interaction, editSequence);
remoteLabel.setAttribute(WidgetAttributes.IS_STANDARD_ATTR, WidgetAttributes.IS_CUSTOM);
remoteLabel.setAttribute(WidgetAttributes.REMOTE_LABEL_OWNER_ATTR, owningElt);
remoteLabel.setName(generateUniqueWidgetName());
remoteLabel.setTitle(p.newText);
// Add the new widget to the undo system and to the model
editSequence.addEdit(addWidget(remoteLabel));
// Commit the edit
editSequence.end();
// Only add this edit if it is significant
if (editSequence.isSignificant()) {
undoMgr.addEdit(editSequence);
}
}
return true;
}
};
}
use of edu.cmu.cs.hcii.cogtool.model.DoubleRectangle in project cogtool by cogtool.
the class FrameEditorController method setAsSeparator.
// assignActions
private boolean setAsSeparator(final IWidget widget, final Object value, final ChildWidget oldSelectedItem, IUndoableEditSequence editSeq) {
final String IS_SEP_ATTR = WidgetAttributes.IS_SEPARATOR_ATTR;
final Object oldValue = widget.getAttribute(IS_SEP_ATTR);
final DoubleRectangle bounds = widget.getEltBounds();
final double oldHeight = bounds.height;
final double newHeight = WidgetAttributes.IS_SEPARATOR.equals(value) ? (oldHeight / FrameEditorUI.SEPARATOR_RATIO) : (oldHeight * FrameEditorUI.SEPARATOR_RATIO);
final boolean isAuto = widget.isStandard();
final SimpleWidgetGroup group = widget.getParentGroup();
final AParentWidget pullDown = (oldSelectedItem != null) ? oldSelectedItem.getParent() : null;
if (widget.equals(oldSelectedItem)) {
// the currently selected widget in the pull down
// has changed to a separator; deselect it
pullDown.setAttribute(WidgetAttributes.SELECTION_ATTR, WidgetAttributes.NONE_SELECTED);
}
widget.setAttribute(IS_SEP_ATTR, value);
if (isAuto) {
widget.setWidgetSize(bounds.width, newHeight);
DesignEditorCmd.repositionChildren(widget.getParentGroup());
}
if (editSeq != null) {
DemoStateManager.IDesignUndoableEdit edit = new DemoStateManager.InvalidatingEdit(CogToolLID.SetAttribute, demoStateMgr) {
@Override
public String getPresentationName() {
return DefaultCmd.SET_ATTRIBUTE;
}
@Override
public void redo() {
super.redo();
if (widget.equals(oldSelectedItem)) {
pullDown.setAttribute(WidgetAttributes.SELECTION_ATTR, WidgetAttributes.NONE_SELECTED);
}
widget.setAttribute(IS_SEP_ATTR, value);
if (isAuto) {
widget.setWidgetSize(bounds.width, newHeight);
DesignEditorCmd.repositionChildren(group);
}
stateMgr.noteWidgetEdit(widget, this);
}
@Override
public void undo() {
super.undo();
if (widget.equals(oldSelectedItem)) {
pullDown.setAttribute(WidgetAttributes.SELECTION_ATTR, oldSelectedItem);
}
widget.setAttribute(IS_SEP_ATTR, oldValue);
if (isAuto) {
widget.setWidgetSize(bounds.width, oldHeight);
DesignEditorCmd.repositionChildren(group);
}
stateMgr.noteWidgetEdit(widget, this);
}
};
demoStateMgr.noteWidgetEdit(widget, edit);
editSeq.addEdit(edit);
}
return true;
}
use of edu.cmu.cs.hcii.cogtool.model.DoubleRectangle in project cogtool by cogtool.
the class FrameEditorController method deleteWidget.
/**
* This deletes a widget from the model and adds the action to the undo list.
*
* @param w is the widget to delete.
* @param moveSiblings is a flag - if it is true, the other widgets in the
* group will be moved to close up the space left by the deleted widget.
* @param editSequence is the compound edit to add this delete operation to.
*/
private void deleteWidget(IWidget w, boolean moveSiblings, FrameElementGroup fromGroup, IUndoableEditSequence editSequence) {
// If this is a remote label, delete the attribute indicating so
// from the point of view of its owner.
FrameElement remoteLabelOwner = (FrameElement) w.getAttribute(WidgetAttributes.REMOTE_LABEL_OWNER_ATTR);
if (remoteLabelOwner != null) {
DefaultCmd.unsetAttribute(remoteLabelOwner, demoStateMgr, WidgetAttributes.REMOTE_LABEL_ATTR, interaction, editSequence);
} else {
// Check if this widget is a remote label owner; if so, delete
// the remote label as well
deleteRemoteLabel(w, editSequence);
}
SimpleWidgetGroup parentGroup = w.getParentGroup();
int atIndex = (parentGroup != null) ? parentGroup.indexOf(w) : -1;
double deltaX = 0;
double deltaY = 0;
// since we know every item in them will be deleted.
if (w instanceof AParentWidget) {
AParentWidget pw = (AParentWidget) w;
while (pw.itemCount() > 0) {
deleteWidget(pw.getItem(0), false, fromGroup, editSequence);
}
}
// If the widget is the last object of the its root element,
// then the root element must be removed from any containing groups
// and, if the root element is the second to last member of any
// group, then the group should be removed as well.
// This must be done before the removeWidget call.
FrameElement rootElt = w.getRootElement();
// containing associations
if (rootElt == w) {
removeRootElement(DELETE_WIDGET, rootElt, fromGroup, editSequence);
} else if (rootElt instanceof SimpleWidgetGroup) {
// Otherwise, need to do the same only if the root element
// is a widget group that will become empty.
SimpleWidgetGroup rootGroup = (SimpleWidgetGroup) rootElt;
// remove it from containing associations
if (rootGroup.size() == 1) {
removeRootElement(DELETE_WIDGET, rootElt, fromGroup, editSequence);
}
}
model.removeWidget(w);
if (parentGroup != null) {
// Check if this parent group is a remote label owner; if so, delete
// the remote label as well
deleteRemoteLabel(parentGroup, editSequence);
if (moveSiblings) {
int myGroupNum = parentGroup.size();
if (parentGroup.getOrientation() == SimpleWidgetGroup.HORIZONTAL) {
deltaX = -w.getEltBounds().width;
} else if (parentGroup.getOrientation() == SimpleWidgetGroup.VERTICAL) {
deltaY = -w.getEltBounds().height;
}
// This loop will be ineffective for grid buttons
for (int i = atIndex + 1; i < myGroupNum; i++) {
IWidget curWidget = parentGroup.get(i);
curWidget.moveElement(deltaX, deltaY);
}
}
// Otherwise, remove it from its parent group.
if (w instanceof ChildWidget) {
ChildWidget child = (ChildWidget) w;
AParentWidget itemParent = child.getParent();
itemParent.removeItem(child);
} else {
parentGroup.remove(w);
}
if (parentGroup instanceof GridButtonGroup) {
GridButtonGroup gbg = (GridButtonGroup) parentGroup;
GridButton gb = (GridButton) w;
DoubleRectangle b = w.getEltBounds();
double x = b.x + b.width;
double y = b.y + b.height;
double newHoriz = gb.getHorizSpace();
double newVert = gb.getVertSpace();
ReadOnlyList<GridButton> movedButtons = null;
GridButton top = null;
double dx = 0.0;
double dy = 0.0;
if (gbg.getColumn(gb).size() == 0) {
// w was the only widget in the column; need to move next
// column over
movedButtons = gbg.getMovedButtons(false, x, b.y);
if (movedButtons.size() > 0) {
top = movedButtons.get(0);
DoublePoint p = top.getShape().getOrigin();
dx = b.x - p.x;
}
} else {
// need to move lower widgets up to fill the hole
movedButtons = gbg.getMovedButtons(true, b.x, y);
if (movedButtons.size() > 0) {
top = movedButtons.get(0);
DoublePoint p = top.getShape().getOrigin();
dy = b.y - p.y;
}
}
if (top != null) {
moveGridButton(FrameEditorLID.Delete, DELETE_WIDGET, top, dx, dy, newHoriz, newVert, editSequence);
}
}
}
DemoStateManager.IDesignUndoableEdit edit;
// Add the deletion to the undoable history
if (w instanceof ChildWidget) {
ChildWidget child = (ChildWidget) w;
final AParentWidget itemParent = child.getParent();
edit = new DeleteWidgetUndoableEdit(w, parentGroup, atIndex, deltaX, deltaY) {
@Override
public void redoHelper() {
itemParent.removeItem((ChildWidget) widget);
}
@Override
public void undoHelper() {
itemParent.addItem(atIndex, (ChildWidget) widget);
}
};
} else {
edit = new DeleteWidgetUndoableEdit(w, parentGroup, atIndex, deltaX, deltaY) {
@Override
public void redoHelper() {
parentGroup.remove(widget);
}
@Override
public void undoHelper() {
parentGroup.add(atIndex, widget);
}
};
}
demoStateMgr.noteWidgetEdit(w, edit);
editSequence.addEdit(edit);
}
use of edu.cmu.cs.hcii.cogtool.model.DoubleRectangle in project cogtool by cogtool.
the class FrameEditorController method resizeWidget.
/**
* Implementation on a per widget bases for resize.
* Calculates the new size be the difference between the fixed point and the
* released point.
*
* @param widget The widget to resize
* @param mouseReleased The point where the mouse was let up
* @param fixedPoint The point which will not move after resize
* @param edit The Compound undoable edit
*/
private void resizeWidget(final IWidget widget, double oldResizeX, double oldResizeY, double newResizeX, double newResizeY, final double ratioX, final double ratioY, final boolean childrenToo, IUndoableEditSequence editSequence) {
// Get the old shape bounds for the undo
DoubleRectangle oldBounds = widget.getEltBounds();
final double oldWidgetX = oldBounds.x;
final double oldWidgetY = oldBounds.y;
final double oldWidth = oldBounds.width;
final double oldHeight = oldBounds.height;
final double newWidgetX = ratioX * (oldBounds.x - oldResizeX) + newResizeX;
final double newWidgetY = ratioY * (oldBounds.y - oldResizeY) + newResizeY;
final double newWidth = Math.max(ratioX * oldBounds.width, 1.0);
final double newHeight = Math.max(ratioY * oldBounds.height, 1.0);
final double oldHoriz = (widget instanceof GridButton) ? ((GridButton) widget).getHorizSpace() : 0.0;
final double oldVert = (widget instanceof GridButton) ? ((GridButton) widget).getVertSpace() : 0.0;
// Actually make the changes to the model.
widget.setWidgetOrigin(newWidgetX, newWidgetY);
widget.setWidgetSize(newWidth, newHeight);
if (widget instanceof GridButton) {
GridButton gb = (GridButton) widget;
gb.setHorizSpace(oldHoriz * ratioX);
gb.setVertSpace(oldVert * ratioY);
} else if (widget instanceof AParentWidget) {
if (childrenToo) {
resizeChildren(widget);
}
DesignEditorCmd.repositionChildren((AParentWidget) widget);
}
// Add the undo support
DemoStateManager.ObsoletingEdit edit = new DemoStateManager.ObsoletingEdit(FrameEditorLID.ResizeWidgets, demoStateMgr) {
@Override
public String getPresentationName() {
return RESIZE_WIDGET;
}
@Override
public void redo() {
super.redo();
widget.setWidgetOrigin(newWidgetX, newWidgetY);
widget.setWidgetSize(newWidth, newHeight);
if (widget instanceof GridButton) {
GridButton gb = (GridButton) widget;
gb.setHorizSpace(oldHoriz * ratioX);
gb.setVertSpace(oldVert * ratioY);
} else if (widget instanceof AParentWidget) {
if (childrenToo) {
resizeChildren(widget);
}
DesignEditorCmd.repositionChildren((AParentWidget) widget);
}
noteEditCheckRegenerate(widget, this);
}
@Override
public void undo() {
super.undo();
widget.setWidgetOrigin(oldWidgetX, oldWidgetY);
widget.setWidgetSize(oldWidth, oldHeight);
if (widget instanceof GridButton) {
GridButton gb = (GridButton) widget;
gb.setHorizSpace(oldHoriz);
gb.setVertSpace(oldVert);
} else if (widget instanceof AParentWidget) {
if (childrenToo) {
// technically, this won't restore the sizes if they were changed manuallythes
resizeChildren(widget);
}
DesignEditorCmd.repositionChildren((AParentWidget) widget);
}
noteEditCheckRegenerate(widget, this);
}
};
noteEditCheckRegenerate(widget, edit);
editSequence.addEdit(edit);
}
use of edu.cmu.cs.hcii.cogtool.model.DoubleRectangle in project cogtool by cogtool.
the class DesignEditorController method spaceFramesEqually.
/**
* Spaces the selected frames equally along a certain axis
* @param vertical true for vertical axis; false for horizontal
*/
protected boolean spaceFramesEqually(Map<Frame, DoubleRectangle> frameMap, final boolean vertical) {
final String undoRedoLabel = vertical ? SPACE_VERTICALLY : SPACE_HORIZONTALLY;
CogToolLID lid = vertical ? DesignEditorLID.SpaceVertically : DesignEditorLID.SpaceHorizontally;
CompoundUndoableEdit editSequence = new CompoundUndoableEdit(undoRedoLabel, lid);
// Order the widgets according to location
// (either from the left or from the top)
Comparator<Map.Entry<Frame, DoubleRectangle>> c = vertical ? frameVerticalComparator : frameHorizontalComparator;
@SuppressWarnings("unchecked") Map.Entry<Frame, DoubleRectangle>[] entries = new Map.Entry[frameMap.size()];
frameMap.entrySet().toArray(entries);
Arrays.sort(entries, c);
// Calculate the spacing between widgets
double sum = 0;
double min = Double.MAX_VALUE;
double max = Double.MIN_VALUE;
// this can then be used to do spacing.
for (Entry<Frame, DoubleRectangle> entrie : entries) {
DoubleRectangle bounds = entrie.getValue();
double size = vertical ? bounds.height : bounds.width;
double position = vertical ? bounds.y : bounds.x;
sum += size;
min = Math.min(min, position);
max = Math.max(max, size + position);
}
// Get the spacing to use between each item.
double spacing = ((max - min) - sum) / (entries.length - 1);
// Adjust the spacings to the correct values
for (Entry<Frame, DoubleRectangle> entrie : entries) {
// go through each frame and set the frame's origin
final Frame f = entrie.getKey();
final DoubleRectangle bounds = entrie.getValue();
// TODO (dfm) this is probably the place to walk over the design pre-flighting
// problems we want to warn the user about, and give the opportunity
// to skip the export if desired
// Determine the old point...
final double p_old = vertical ? bounds.y : bounds.x;
final double p_new = min;
// Set the new location
f.setFrameOrigin(vertical ? bounds.x : p_new, vertical ? p_new : bounds.y);
// Advance the pointer to the next location
min += spacing + (vertical ? bounds.height : bounds.width);
IUndoableEdit edit = new AUndoableEdit(lid) {
@Override
public String getPresentationName() {
return undoRedoLabel;
}
@Override
public void redo() {
super.redo();
f.setFrameOrigin(vertical ? bounds.x : p_new, vertical ? p_new : bounds.y);
}
@Override
public void undo() {
super.undo();
f.setFrameOrigin(vertical ? bounds.x : p_old, vertical ? p_old : bounds.y);
}
};
editSequence.addEdit(edit);
}
editSequence.end();
// Only add this edit if it is significant
if (editSequence.isSignificant()) {
undoMgr.addEdit(editSequence);
}
return true;
}
Aggregations