Search in sources :

Example 76 with IWidget

use of edu.cmu.cs.hcii.cogtool.model.IWidget in project cogtool by cogtool.

the class DesignEditorCmd method repositionChildren.

/**
     * TODO: If we ever allow children above or left of a parent,
     * we need to pass in childrenLocation here in addition to the group.
     */
public static void repositionChildren(SimpleWidgetGroup group, double x, double y) {
    int orientation = group.getOrientation();
    if (orientation == SimpleWidgetGroup.FREEFORM) {
        return;
    }
    Iterator<IWidget> groupIter = group.iterator();
    while (groupIter.hasNext()) {
        IWidget widget = groupIter.next();
        widget.setWidgetOrigin(x, y);
        if (orientation == SimpleWidgetGroup.HORIZONTAL) {
            x += widget.getEltBounds().width;
        } else if (orientation == SimpleWidgetGroup.VERTICAL) {
            y += widget.getEltBounds().height;
        }
        if (widget instanceof AParentWidget) {
            repositionChildren((AParentWidget) widget);
        }
    }
}
Also used : AParentWidget(edu.cmu.cs.hcii.cogtool.model.AParentWidget) DoublePoint(edu.cmu.cs.hcii.cogtool.model.DoublePoint) IWidget(edu.cmu.cs.hcii.cogtool.model.IWidget)

Example 77 with IWidget

use of edu.cmu.cs.hcii.cogtool.model.IWidget in project cogtool by cogtool.

the class DesignEditorCmd method pasteElements.

// pasteFrameElementGroup
public static int pasteElements(Design design, final Frame frame, Collection<Object> objects, DemoStateManager mgr, IUndoableEditSequence editSequence) {
    // If given objects contain widgets, insert into the given frame
    if ((objects != null) && (objects.size() > 0)) {
        Iterator<Object> objIt = objects.iterator();
        Set<SimpleWidgetGroup> addedGroups = new HashSet<SimpleWidgetGroup>();
        final Set<IWidget> addedRemoteLabels = new HashSet<IWidget>();
        final Set<FrameElementGroup> addedEltGroups = new HashSet<FrameElementGroup>();
        int numPasted = 0;
        // May need to add a device
        int currentDeviceTypes = DeviceType.buildDeviceSet(design.getDeviceTypes());
        // create them.
        while (objIt.hasNext()) {
            Object o = objIt.next();
            if (o instanceof IWidget) {
                IWidget widget = (IWidget) o;
                numPasted += pasteWidget(widget, design, currentDeviceTypes, frame, mgr, editSequence, addedEltGroups, addedRemoteLabels);
                SimpleWidgetGroup group = widget.getParentGroup();
                if (group != null) {
                    addedGroups.add(group);
                }
            } else if (o instanceof FrameElementGroup) {
                numPasted += pasteFrameElementGroup((FrameElementGroup) o, design, currentDeviceTypes, frame, mgr, editSequence, addedEltGroups, addedRemoteLabels);
            }
        }
        Iterator<SimpleWidgetGroup> groupsIter = addedGroups.iterator();
        while (groupsIter.hasNext()) {
            SimpleWidgetGroup group = groupsIter.next();
            repositionChildren(group);
            if (group instanceof GridButtonGroup) {
                ((GridButtonGroup) group).recalculateOffsets();
            }
            addedEltGroups.addAll(group.getEltGroups());
        }
        Iterator<FrameElementGroup> eltGroups = addedEltGroups.iterator();
        while (eltGroups.hasNext()) {
            frame.addEltGroup(eltGroups.next());
        }
        Iterator<IWidget> remoteLabels = addedRemoteLabels.iterator();
        while (remoteLabels.hasNext()) {
            IWidget remoteLabel = remoteLabels.next();
            if (!frame.containsWidget(remoteLabel)) {
                String uniqueName = NamedObjectUtil.makeNameUnique(remoteLabel.getName(), frame.getWidgets());
                remoteLabel.setName(uniqueName);
                frame.addWidget(remoteLabel);
            }
        }
        IUndoableEdit edit = new AUndoableEdit(CogToolLID.Paste) {

            @Override
            public String getPresentationName() {
                return PASTE;
            }

            @Override
            public void redo() {
                super.redo();
                Iterator<FrameElementGroup> eltGroups = addedEltGroups.iterator();
                while (eltGroups.hasNext()) {
                    frame.addEltGroup(eltGroups.next());
                }
                Iterator<IWidget> remoteLabels = addedRemoteLabels.iterator();
                while (remoteLabels.hasNext()) {
                    IWidget remoteLabel = remoteLabels.next();
                    if (!frame.containsWidget(remoteLabel)) {
                        frame.addWidget(remoteLabel);
                    }
                }
            }

            @Override
            public void undo() {
                super.undo();
                Iterator<FrameElementGroup> eltGroups = addedEltGroups.iterator();
                while (eltGroups.hasNext()) {
                    frame.removeEltGroup(eltGroups.next());
                }
                Iterator<IWidget> remoteLabels = addedRemoteLabels.iterator();
                while (remoteLabels.hasNext()) {
                    IWidget remoteLabel = remoteLabels.next();
                    if (frame.containsWidget(remoteLabel)) {
                        frame.removeWidget(remoteLabel);
                    }
                }
            }
        };
        editSequence.addEdit(edit);
        return numPasted;
    }
    return 0;
}
Also used : SimpleWidgetGroup(edu.cmu.cs.hcii.cogtool.model.SimpleWidgetGroup) FrameElementGroup(edu.cmu.cs.hcii.cogtool.model.FrameElementGroup) DoublePoint(edu.cmu.cs.hcii.cogtool.model.DoublePoint) AUndoableEdit(edu.cmu.cs.hcii.cogtool.util.AUndoableEdit) IUndoableEdit(edu.cmu.cs.hcii.cogtool.util.IUndoableEdit) IWidget(edu.cmu.cs.hcii.cogtool.model.IWidget) HashSet(java.util.HashSet) GridButtonGroup(edu.cmu.cs.hcii.cogtool.model.GridButtonGroup)

Example 78 with IWidget

use of edu.cmu.cs.hcii.cogtool.model.IWidget in project cogtool by cogtool.

the class DemoScriptCmd method exportScriptToCSV.

public static boolean exportScriptToCSV(Script script, Project project, Interaction interaction, IUndoableEditSequence editSeq) {
    Demonstration demo = script.getDemonstration();
    TaskApplication ta = demo.getTaskApplication();
    Design design = ta.getDesign();
    AUndertaking task = ta.getTask();
    String name = project.getName();
    name += "_" + design.getName();
    name += "_" + task.getName();
    File dest = null;
    if (interaction != null) {
        dest = interaction.selectCSVFileDest(name);
    } else {
        dest = new File(CogTool.exportCSVKludgeDir, name + ".txt");
    }
    if (dest == null) {
        return false;
    }
    FileWriter fw = null;
    BufferedWriter buffer = null;
    try {
        fw = new FileWriter(dest);
        buffer = new BufferedWriter(fw);
        CSVSupport.writeCell("Format version:", buffer);
        CSVSupport.addSeparator(buffer);
        CSVSupport.writeCell(FORMAT_VERSION, buffer);
        CSVSupport.addLineEnding(buffer);
        Date now = new Date();
        String date = DateFormat.getDateTimeInstance().format(now);
        CSVSupport.writeCell("Date and Time:", buffer);
        CSVSupport.addSeparator(buffer);
        CSVSupport.writeCell(date, buffer);
        CSVSupport.addLineEnding(buffer);
        CSVSupport.writeCell("Project Name:", buffer);
        CSVSupport.addSeparator(buffer);
        CSVSupport.writeCell(project.getName(), buffer);
        CSVSupport.addLineEnding(buffer);
        CSVSupport.writeCell("Design Name:", buffer);
        CSVSupport.addSeparator(buffer);
        CSVSupport.writeCell(design.getName(), buffer);
        CSVSupport.addLineEnding(buffer);
        CSVSupport.writeCell("Task Hierarchy:", buffer);
        String taskName = task.getFullName();
        String[] cells = taskName.split(":");
        for (String cell : cells) {
            CSVSupport.addSeparator(buffer);
            CSVSupport.writeCell(cell, buffer);
        }
        CSVSupport.addLineEnding(buffer);
        CSVSupport.addSeparator(buffer);
        CSVSupport.addLineEnding(buffer);
        buffer.write("\"Frame\",\"Action\",\"Widget-Name\"," + "\"Displayed-Label\",\"Widget-Type\"");
        CSVSupport.addLineEnding(buffer);
        IWidget lastMovedToWidget = null;
        Iterator<DefaultModelGeneratorState> stepStates = script.getStepStates().iterator();
        while (stepStates.hasNext()) {
            DefaultModelGeneratorState stepState = stepStates.next();
            AScriptStep step = stepState.getScriptStep();
            TransitionSource stepFocus = step.getStepFocus();
            String frameName = step.getCurrentFrame().getName();
            String actionName = KeyDisplayUtil.convertActionToMenuText(step.getLocalizedString());
            if ((!(step instanceof LookAtScriptStep)) && (!(step instanceof ThinkScriptStep)) && (!(step instanceof TextActionSegment))) {
                actionName = step.getLocalizedActionString(actionName, lastMovedToWidget);
            }
            lastMovedToWidget = stepState.getLastMovedToWidget();
            String widgetName = "";
            String widgetType = "";
            String widgetTitle = "";
            if (stepFocus != null) {
                widgetName = stepFocus.getName();
                if (stepFocus instanceof IWidget) {
                    IWidget w = (IWidget) stepFocus;
                    widgetType = w.getWidgetType().toString();
                    String s = w.getTitle();
                    if (s != null) {
                        widgetTitle = s;
                    }
                }
            }
            CSVSupport.writeCell(frameName, buffer);
            CSVSupport.addSeparator(buffer);
            CSVSupport.writeCell(actionName, buffer);
            CSVSupport.addSeparator(buffer);
            CSVSupport.writeCell(widgetName, buffer);
            CSVSupport.addSeparator(buffer);
            CSVSupport.writeCell(widgetTitle, buffer);
            CSVSupport.addSeparator(buffer);
            CSVSupport.writeCell(widgetType, buffer);
            CSVSupport.addLineEnding(buffer);
        }
        Frame resultFrame = demo.getResultFrame();
        if (resultFrame != null) {
            CSVSupport.writeCell(resultFrame.getName(), buffer);
        }
        if (interaction != null) {
            interaction.setStatusMessage(L10N.get("DSO.ExportCompletedPre", "Export completed to ") + dest + L10N.get("DSO.ExportCompletePost", "."));
        }
    } catch (IOException e) {
        if (interaction != null) {
            interaction.reportProblem("File I/O Error", e.getMessage());
        } else {
            e.printStackTrace();
        }
        return false;
    } finally {
        try {
            if (buffer != null) {
                buffer.close();
            }
            if (fw != null) {
                fw.close();
            }
        } catch (IOException e) {
            if (interaction != null) {
                interaction.reportProblem("File I/O Error on Close", e.getMessage());
            } else {
                e.printStackTrace();
            }
            return false;
        }
    }
    return true;
}
Also used : Frame(edu.cmu.cs.hcii.cogtool.model.Frame) FileWriter(java.io.FileWriter) IOException(java.io.IOException) AScriptStep(edu.cmu.cs.hcii.cogtool.model.AScriptStep) Date(java.util.Date) BufferedWriter(java.io.BufferedWriter) ThinkScriptStep(edu.cmu.cs.hcii.cogtool.model.ThinkScriptStep) Design(edu.cmu.cs.hcii.cogtool.model.Design) TransitionSource(edu.cmu.cs.hcii.cogtool.model.TransitionSource) TextActionSegment(edu.cmu.cs.hcii.cogtool.model.TextActionSegment) AUndertaking(edu.cmu.cs.hcii.cogtool.model.AUndertaking) LookAtScriptStep(edu.cmu.cs.hcii.cogtool.model.LookAtScriptStep) TaskApplication(edu.cmu.cs.hcii.cogtool.model.TaskApplication) Demonstration(edu.cmu.cs.hcii.cogtool.model.Demonstration) File(java.io.File) IWidget(edu.cmu.cs.hcii.cogtool.model.IWidget) DefaultModelGeneratorState(edu.cmu.cs.hcii.cogtool.model.DefaultModelGeneratorState)

Example 79 with IWidget

use of edu.cmu.cs.hcii.cogtool.model.IWidget in project cogtool by cogtool.

the class BalsamiqButtonAPIConverter method parseBMMLWidget.

/** Helper function used by parseFrame
	 * This method is used to parse the tags of each control tag in Balsamiq XML. A control tag
	 * represents a Balsamiq Widget.
     * 
     * @param  node a node of the tree that represents a Balsamiq widget
     * @frame  frame that the widget is being added to
     * @group  parent group
     * @groupX x coordinate of parent group
     * @groupY y coordinate of parent group
     * @return      the newly created widget
     */
protected Widget parseBMMLWidget(Node node, Frame frame, SimpleWidgetGroup group, double groupX, double groupY) throws IOException {
    System.out.println("parseBMMLWidget " + group + " x: " + groupX + "y: " + groupY);
    NodeList children = node.getChildNodes();
    Widget widget = null;
    WidgetType widgetType = null;
    String balsamiqControlType = getAttributeValue(node, CONTROL_TYPE_ATTR);
    String widgetTypeString = (balsamiqControlType == null) ? null : getBMMLWidgetType(balsamiqControlType);
    String widgetName = getAttributeValue(node, CONTROL_ID_ATTR);
    if (widgetName == null) {
    //TODO: make a random widget name and move on. report to the user. need to be unique within the frame. Frame.java has a method for this
    }
    System.out.println("462- wN " + widgetName + "widT " + widgetTypeString);
    if (widgetTypeString == null) {
    //TODO: report to the user
    } else {
        widgetType = getWidgetType(widgetTypeString);
        //Parse the widget name, location and size from the attributes of the XML tag
        //TODO: Error check all of the getAttributeValues()
        double x = Double.parseDouble(getAttributeValue(node, X_ATTR));
        double y = Double.parseDouble(getAttributeValue(node, Y_ATTR));
        //TODO: difference between w and measuredW, same for height
        double width = Integer.parseInt(getAttributeValue(node, BWIDTH_ATTR));
        double height = Integer.parseInt(getAttributeValue(node, BHEIGHT_ATTR));
        double measWidth = Integer.parseInt(getAttributeValue(node, MEASURED_WIDTH_ATTR));
        double measHeight = Integer.parseInt(getAttributeValue(node, MEASURED_HEIGHT_ATTR));
        if (//TODO: make sure the dimensions are positive
        width == -1 && height == -1) {
            System.out.println("493- changing widget dimensions");
            width = measWidth;
            height = measHeight;
        }
        /*bounds is the size and location of the widget*/
        if (group != null) {
            System.out.println("488-Group is not null");
            DoubleRectangle rect = group.getGroupBounds();
            if (rect != null) {
                System.out.println("500-rect is not null");
            //x += groupX;
            //y += groupY;
            }
        }
        x += groupX;
        y += groupY;
        System.out.println("new widget has dimens:" + x + " " + y);
        DoubleRectangle bounds = new DoubleRectangle(x, y, width, height);
        if (widgetType == WidgetType.Check) {
            System.out.println("505-The widget is a check so now make a group for it");
            if (group == null) {
                group = new GridButtonGroup();
                //give it a random widget name										
                group.setName("newName");
                groupRegistry.put("newName", group);
            }
            //if(group instanceof GridButtonGroup)
            //{
            int eltCount = group.elementCount();
            System.out.println("513-group is gridbuttongroup " + group.getName() + " " + eltCount);
            if (eltCount > 0) {
                //TODO: check if the widgets align best horizontally or vertically
                //align the widgets to average coord, first, left or rightmost
                IWidget wid = group.getElement(group.elementCount() - 1);
                DoubleRectangle bounds2 = wid.getEltBounds();
                System.out.println("530 " + bounds2.getX() + " " + bounds2.getWidth() + " " + bounds2.getY() + " " + bounds2.getHeight());
                double diffX = Math.abs(x - bounds2.getX());
                double diffY = Math.abs(y - bounds2.getY());
                System.out.println("diffX " + diffX + " " + diffY);
                DoubleRectangle bounds3 = new DoubleRectangle(bounds2.getX() + bounds2.getWidth(), bounds2.getY(), width, height);
                if (diffX < diffY) {
                    bounds3 = new DoubleRectangle(bounds2.getX(), bounds2.getY() + bounds2.getHeight(), width, height);
                }
                widget = new CheckBox((GridButtonGroup) group, bounds3, widgetName);
            } else {
                widget = new CheckBox((GridButtonGroup) group, bounds, widgetName);
            }
            widget.setWidgetType(widgetType);
        /*}
				else
				{
					System.out.println("517-group2 is gridbuttongroup");
					GridButtonGroup group2 = new GridButtonGroup();
					group2.setName("newNameCheck");										
					groupRegistry.put("newNameCheck", group2);
					widget = new CheckBox(group2, bounds, widgetName);
					//group.addElement((IWidget) group2);

				}*/
        } else {
            widget = new Widget(bounds, widgetType);
        }
        widget.setName(widgetName);
        for (int i = 0; i < children.getLength(); i++) {
            Node child = children.item(i);
            String nodeName = child.getNodeName();
            /*Whitespace in the DOM tree is represented as #text. Ignore these nodes. Anywhere between the open and closed tag*/
            if (!nodeName.equals("#text")) {
                if (nodeName.equalsIgnoreCase(CONTROL_PROP_ELT)) {
                    NodeList controlTags = child.getChildNodes();
                    for (int j = 0; j < controlTags.getLength(); j++) {
                        Node controlTag = controlTags.item(j);
                        String propertyTag = controlTag.getNodeName();
                        //CogTool widget Display Label
                        if (propertyTag.equalsIgnoreCase(BALSAMIQ_TEXT_ELT)) {
                            /*Must decode the title. For instance the title in
							    Balsamiq, "First%20Frame" is "First Frame" in CogTool*/
                            String title = getElementText(controlTag);
                            title = URLDecoder.decode(title, "UTF-8");
                            widget.setTitle(title);
                        } else //CogTool transition on the present widget
                        if (propertyTag.equalsIgnoreCase(HREF_ELT)) {
                            String destinationFileName = getElementText(controlTag);
                            File destinationFile = new File(designPathName, destinationFileName);
                            //Make sure the file exists before attempting to parse the file
                            if (destinationFile.exists()) {
                                parseBalsamiqFile(destinationFile);
                                parseTransition(destinationFileName, widget);
                            }
                        } else if (propertyTag.equalsIgnoreCase(STATE_ELT)) {
                            //TODO: work on states
                            //A Balsamiq Button can be normal, selected, or disabled
                            String state = getElementText(controlTag);
                            if (state.equals("selected")) {
                                widget.setAttribute(WidgetAttributes.IS_SELECTED_ATTR, Boolean.TRUE);
                            } else {
                            //TODO: Other Balsamiq states like "disabled", "disabled and selected"
                            }
                        }
                    // END OF STATE OF BUTTON
                    }
                // END OF PROPERTY TAG
                }
            // END OF CONTROL PROPERTIES TAG
            }
        }
    }
    widget.setRendered(true);
    return widget;
}
Also used : CheckBox(edu.cmu.cs.hcii.cogtool.model.CheckBox) NodeList(org.w3c.dom.NodeList) Node(org.w3c.dom.Node) IWidget(edu.cmu.cs.hcii.cogtool.model.IWidget) Widget(edu.cmu.cs.hcii.cogtool.model.Widget) WidgetType(edu.cmu.cs.hcii.cogtool.model.WidgetType) DoubleRectangle(edu.cmu.cs.hcii.cogtool.model.DoubleRectangle) File(java.io.File) IWidget(edu.cmu.cs.hcii.cogtool.model.IWidget) GridButtonGroup(edu.cmu.cs.hcii.cogtool.model.GridButtonGroup)

Example 80 with IWidget

use of edu.cmu.cs.hcii.cogtool.model.IWidget in project cogtool by cogtool.

the class DesignExportToHTML method buildFrameHTML.

/**
	 * Build the HTML around a single frame.
	 * This really just involves building an image map over the
	 * areas specified by the widgets, as well as the GraphicalDevices
	 * Since the graphical Devices don't really have a "Name"
	 * Also, since the Graphical devices and the frame name are not in the
	 * Normal frame... (and we are using a frame not a design)
	 * Need to add graphical devices using normal HTML.
	 *
	 * Requires the name of the frame image to be passed in.
	 *
	 * A copy of overlib.js needs to be copied to the output directory as well.
	 * InputStream stream =
	 *     ClassLoader.getSystemResourceAsStream
	 *          ("edu/cmu/cs/hcii/cogtool/resources/overlib.js");
	 *
	 * @param frame
	 * @param frameImageName
	 * @return
	 */
protected String buildFrameHTML(Frame frame) {
    String notHelpString = NOT_HELP_DEFAULT;
    StringBuilder html = new StringBuilder();
    html.append("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n");
    html.append("<html>\n");
    html.append("<title>");
    html.append(frame.getName());
    html.append("</title>\n");
    //html.append("<style type='text/css'> body { margin:0; padding:0; } </style>\n");
    html.append("<link rel='stylesheet' type='text/css' href='build/fonts-min.css' />\n");
    html.append("<link rel='stylesheet' type='text/css' href='build/menu.css' />\n");
    html.append("<script type='text/javascript' src='build/yahoo-dom-event.js'></script>\n");
    html.append("<script type='text/javascript' src='build/container_core.js'></script>\n");
    html.append("<script type='text/javascript' src='build/menu.js'></script>\n");
    // Add javascript load for overlay code.
    html.append("<script type='text/javascript' ");
    html.append(" src='build/overlib.js' ");
    html.append(" language='JavaScript'></script>\n");
    html.append("<style type='text/css'> div.yuimenu { position: absolute; visibility: hidden; } </style>\n");
    html.append("<body style=\"cursor:default;\" class=' yui-skin-sam' onload=\"onLoad()\" onkeydown=\"checkKey(event)\">\n");
    // Create the table with the frame name.
    html.append("<table border=1>\n");
    html.append("<tr>\n");
    // -------------------------
    // Add the frame title
    // -------------------------
    html.append("<td align='center'>\n");
    html.append(frame.getName());
    html.append("</td>\n");
    html.append("</tr>\n");
    // -------------------------
    // Add the device interfaces.
    // -------------------------
    html.append("<tr>\n");
    html.append("<td>\n");
    html.append("<img align=center src='");
    html.append(getFrameURL(frame, ".jpg"));
    //Overlib is a javascript biult-in function that shows a nice pop-up box. DEMONSTRATE!
    //I have added a map for this image so that this image will follow a map in the case of "HotSpots"
    html.append("' onclick=\"" + NOT_ACCOMPLISH_GOAL + "\" usemap=\"#Button_Map\" />\n");
    html.append("</td>\n</tr>\n</table>\n");
    // save any menus encountered to create them in javascript later
    List<AMenuWidget> menus = new ArrayList<AMenuWidget>();
    // only build a group of radio buttons or list box items once
    Set<SimpleWidgetGroup> visitedGroups = new HashSet<SimpleWidgetGroup>();
    // loop over all widgets
    Iterator<IWidget> widgetIterator = frame.getWidgets().iterator();
    //NoticS: while function to go over all widgets
    while (widgetIterator.hasNext()) {
        IWidget widget = widgetIterator.next();
        //html.append(buildWidgetHTML(widget, visitedGroups));
        widgetHTML += buildWidgetHTML(widget, visitedGroups, frame);
        if ((widget instanceof MenuHeader) || (widget instanceof ContextMenu)) {
            menus.add((AMenuWidget) widget);
        }
    }
    mapHTML += "</map>\n";
    html.append(mapHTML);
    html.append(widgetHTML);
    mapHTML = "<map name=\"Button_map\">\n";
    widgetHTML = "";
    //javascript functions
    html.append("<script type='text/javascript'>\n");
    html.append("var isIE = navigator.appName.indexOf(\"Microsoft\")!=-1;\n");
    html.append("var isWin = navigator.appVersion.indexOf(\"Win\")!=-1;\n");
    html.append("var notAccomplishGoal = \"" + notHelpString + "\";\n");
    html.append("var keyboardString = \"\";\n");
    html.append("var hoverElt = null;\n");
    html.append("var keyTransitionMap = new Object();\n");
    html.append("var clickMap = null;\n");
    html.append("var curEvt = null;\n");
    html.append("var numClicks = 0;\n");
    html.append("var focusString = \"\";\n");
    html.append("var focusTransitionMaps = new Object();\n");
    html.append("var curFocusMap = null;\n");
    int devTypes = DeviceType.buildDeviceSet(frame.getDesign().getDeviceTypes());
    if (DeviceType.Keyboard.isMember(devTypes) || DeviceType.Touchscreen.isMember(devTypes)) {
        html.append(buildKeyTransitionMap(frame.getInputDevices(), frame.getWidgets()));
    }
    // Function to account for IE versus Firefox differences in
    // mouse events - they use a different set of mouse button constants
    html.append("\nfunction getMouseButton(button)\n{\n");
    html.append("  if (button == " + LEFT_MOUSE + ") {\n");
    html.append("    return isIE ? 1 : 0;\n  }\n");
    html.append("  if (button == " + MIDDLE_MOUSE + ") {\n");
    html.append("    return isIE ? 4 : 1;\n  }\n");
    html.append("  if (button == " + RIGHT_MOUSE + ") {\n");
    html.append("    return isIE ? 2 : 2;\n  }\n}\n\n");
    html.append("function onLoad()\n{\n");
    html.append("  var str = document.location.search;\n");
    html.append("  if (str != null) {\n");
    html.append("    str = str.substr(1);\n");
    html.append("    var search = str.split(\"&\");\n");
    html.append("    var searchCount = search.length;\n");
    html.append("    for (i = 0; i < searchCount; i++) {\n");
    html.append("      var check = search[0].split(\"=\");\n");
    html.append("      if ((check.length == 2) && (check[0] == \"focusID\")) {\n");
    html.append("        var elt = document.getElementById(decodeURIComponent(check[1]));\n");
    html.append("        if (elt != null) {\n");
    html.append("          elt.focus();\n");
    html.append("          if (elt.type == 'radio') {\n");
    html.append("            elt.checked = true;\n        }\n");
    html.append("          else if (elt.type == 'checkbox') {\n");
    html.append("            elt.checked = ! elt.checked;\n");
    html.append("          }\n");
    html.append("        }\n");
    html.append("        break;\n");
    html.append("      }\n    }\n  }\n} // onLoad\n\n");
    // The following two methods are only used for Yahoo menu events.
    // newframe is a string representing the html file of the frame to be
    // transitioned to; button is the mouse button that causes that
    // transition, and e is the actual event that is checked against
    html.append("function checkMenuTransitions(newFrame, button, e)\n{\n");
    html.append("  return (newFrame && (button == e.button));\n}\n\n");
    // The Yahoo menus use this function, so it requires three parameters.
    // The first we don't use, the second stores the event, and the third
    // is an array of strings representing html files. The function above
    // takes this information plus a mapping from the index in that array
    // to the mouse button that effects the corresponding transition, and
    // determines whether a transition should occur.  If so, it changes
    // the location of the document.
    html.append("function menuTransition(ignore, p_aArgs, p_oValue)\n{\n");
    html.append("  var transitionIndex = -1;\n  for (i = 0; i < p_oValue.length; i++) {\n");
    html.append("    if (checkMenuTransitions(p_oValue[i], getMouseButton(i+1), p_aArgs[0])) {\n");
    html.append("      if ((p_oValue[i] == " + IGNORE_LEFT_CLICK + ")) {\n");
    html.append("        return;\n      }\n");
    html.append("      transitionIndex = i;\n    }\n  }\n");
    html.append("  if (transitionIndex >= 0) {\n");
    html.append("    document.location.href = p_oValue[transitionIndex];\n  }\n");
    html.append("  else {\n    " + NOT_ACCOMPLISH_GOAL + "\n  }\n}\n\n");
    // Return an integer representing the modifier state of the current
    // event object (NOTE: event has "metaKey" but no fnKey or cmdKey)
    html.append("function getModifiers(e)\n{\n");
    html.append("  var result = 0;\n  if (e.shiftKey) {\n");
    html.append("    result += " + AAction.SHIFT + ";\n  }\n");
    html.append("  if (e.ctrlKey) {\n    result += " + AAction.CTRL + ";\n  }\n");
    html.append("  if (e.altKey) {\n    result += " + AAction.ALT + ";\n  }\n\n");
    html.append("  return result;\n}\n\n");
    // The following two functions are used for transitions from regular
    // HTML elements.  This one takes the current event object, the set
    // of values to be considered, and the number of clicks that have
    // occurred and determines whether a transition should be followed.
    html.append("function checkTransitions(clicks, params, event)\n{\n");
    html.append("  if (clicks != params[1]) {\n    return false;\n  }\n\n");
    html.append("  var modifiers = getModifiers(event);\n");
    html.append("  var button = event.button;\n");
    html.append("  if ((params[0] == " + RIGHT_MOUSE + ") &&");
    html.append(" (modifiers & " + AAction.CTRL + ") && (! isWin)) {\n");
    html.append("    button = getMouseButton(" + RIGHT_MOUSE + ");\n");
    html.append("    modifiers -= " + AAction.CTRL + ";\n  }\n\n");
    html.append("  if (getMouseButton(params[0]) != button) {\n");
    html.append("    return false;\n  }\n  if (modifiers != params[2]) {\n");
    html.append("    return false;\n  }\n\n  return true;\n}\n\n");
    // clicks is the number of clicks performed on the widget (1, 2, or 3),
    // and event is the HTML event object.  transitionMap is an array of
    // arrays.  The sub-arrays have four elements that together define a
    // mouse transition: which button, how many clicks, the keyboard
    // modifier state, and the destination frame, in that order.
    html.append("function followTransition(clicks, event, transitionMap)\n{\n");
    html.append("  var frame = null;\n");
    html.append("  for (i = 0; i < transitionMap.length; i++) {\n");
    html.append("    var params = transitionMap[i];\n");
    html.append("    if (checkTransitions(clicks, params, event)) {\n");
    html.append("      frame = params[3];\n");
    html.append("      if ((frame == " + IGNORE_LEFT_CLICK + ") && (clicks == 1)) return;\n    }\n  }\n\n");
    html.append("  if (frame != null) {\n");
    html.append("    document.location.href = frame;\n");
    html.append("    return true;\n  }\n");
    html.append("  " + NOT_ACCOMPLISH_GOAL + "\n  return false;\n}\n\n");
    // Used for context menus to put the menu where the mouse was clicked
    html.append("function displayContextMenu(event, menu)\n{\n");
    html.append("  menu.cfg.setProperty(\"x\", event.clientX);\n");
    html.append("  menu.cfg.setProperty(\"y\", event.clientY);\n");
    html.append("  menu.show();\n}\n\n");
    // This function allows clicking on the label of a checkbox to toggle
    // it instead of only being able to click on the box itself.  CogTool
    // checkbox widgets work this way.
    html.append("function toggleCheckbox(eltId)\n{\n");
    html.append("  var elt = document.getElementById(eltId);\n");
    html.append("  if (typeof(elt) != 'undefined') {\n");
    html.append("    if (elt.type == 'checkbox') {\n");
    html.append("      elt.checked = ! elt.checked;\n    }\n  }\n}\n");
    // Similar to toggleCheckbox, but for radio buttons
    html.append("function selectRadio(eltId)\n{\n");
    html.append("  var elt = document.getElementById(eltId);\n");
    html.append("  if (typeof(elt) != 'undefined') {\n");
    html.append("    if (elt.type == 'radio') {\n");
    html.append("      elt.checked = true;\n    }\n  }\n}\n\n");
    // There is no notion of "hover" in html, only mouse over.  So if
    // there is a hover transition, it needs to save the frame to be
    // transitioned to in a global variable and start a timer to see
    // if the cursor remains hovered over the element.
    html.append("function timeHover(frame)\n{\n  hoverElt = frame;\n");
    html.append("  window.setTimeout(\"checkHover()\", 1000);\n}\n\n");
    // When the timer is up, if the cursor is still there, it does the
    // transition.
    html.append("function checkHover()\n{\n  if (hoverElt) {\n");
    html.append("    document.location.href = hoverElt;\n  }\n");
    html.append(/*else {\n" + NOT_ACCOMPLISH_GOAL + "\n}\n*/
    "}\n\n");
    // If there is a mouse out event on any widget, it discards the hover
    // information.
    html.append("function cancelHover()\n{\n  hoverElt = null;\n}\n\n");
    // Used for keyboard transitions.  Taking into account regexp special
    // characters, it uses a regular expression to test whether the string
    // str (the string that collects keyboard input) ends with the string
    // s (the string that causes a transition)
    html.append("function endsWith(str, s)\n{\n");
    html.append("  s = s.replace(/\\\\|\\(|\\)|\\*|\\^|\\$|\\+|\\?|\\.|\\||\\{|\\}|\\[|\\]/g, escaper);\n");
    html.append("  var reg = new RegExp(s + \"$\");\n");
    html.append("  return reg.test(str);\n}\n\n");
    // Called when a key is pressed; adds the new key to the keyboard
    // string and, if applicable, the string for the widget that has the
    // focus (first), and checks whether it should do a transition
    // TODO NOTE: Widgets for which key transitions don't work:
    // radio buttons, links, menu items, pull-down items, list box items
    html.append("function checkKey(e)\n{\n  if (curFocusMap) {\n");
    html.append("    focusString += String.fromCharCode(e.keyCode);\n");
    html.append("    var result = checkStrings(focusString, curFocusMap);\n");
    html.append("    if (result) {\n      document.location.href = result;\n");
    html.append("      return;\n    }\n  }\n");
    html.append("  keyboardString += String.fromCharCode(e.keyCode);\n");
    html.append("  var result = checkStrings(keyboardString, keyTransitionMap);\n");
    html.append("  if (result) {\n      document.location.href = result;\n  }\n}\n\n");
    // Returns the longest string that matches the currently collected
    // input, or null
    html.append("function checkStrings(collector, map)\n{\n");
    html.append("  var longest = null;\n");
    html.append("  for (var i in map) {\n");
    html.append("    if (endsWith(collector.toLowerCase(), i)) {\n");
    html.append("      if (! longest) {\n        longest = i;\n      }\n");
    html.append("      if (i.length > longest.length) {\n        longest = i;\n");
    html.append("      }\n    }\n  }\n");
    html.append("  if (longest) {\n    return map[longest];\n  }\n");
    html.append("  return null;\n}\n\n");
    // adds escape characters to special keys so the regexp doesn't
    // get confused
    html.append("function escaper(c)\n{\n  return \'\\\\\' + c;\n}\n\n");
    // html detects left double-clicks but not middle or right double clicks,
    // so the next two functions handle that.  This one is called on mouse
    // up (onclick doesn't detect right clicks, see buildWidgetHTML()).
    // transitionMap is an array of arrays (see the comments above
    // followTransition).  It starts a timer after it is called; if
    // it is called again before the timer runs out (as determined by the
    // state of the global numClicks variable), it starts another timer,
    // otherwise it checks a single click transition.  If the second timer
    // runs out, it checks a double click transition, but if this function
    // is called a third time, it checks a triple click transition.
    // TODO: NOTE: Even with onmouseup, html seems to fail to detect middle
    // clicks in Firefox, so this solution works only with right clicks.
    html.append("function checkClicks(transitionMap, e)\n{\n");
    html.append("  curEvt = e;\n  numClicks++;\n\n");
    html.append("  if (numClicks == 3) {\n");
    html.append("    if (followTransition(3, e, transitionMap)) {\n");
    html.append("      window.clearTimeout();\n    }\n\n");
    html.append("    numClicks = 0;\n  }\n  else {\n");
    html.append("    clickMap = transitionMap;\n");
    html.append("    if (numClicks == 1) {\n");
    html.append("      window.setTimeout(\"doClick1()\", 500);\n    }\n");
    html.append("    else if (numClicks == 2) {\n");
    html.append("      window.clearTimeout();\n");
    html.append("      window.setTimeout(\"doClick2()\", 300);\n    }\n  }\n}\n\n");
    // If there was only a single click, it uses the saved
    // map to try to perform a transition with one click, and clears the state.
    html.append("function doClick1()\n{\n");
    html.append("  if ((clickMap != null) && (numClicks == 1)) {\n");
    html.append("    followTransition(1, curEvt, clickMap);\n");
    html.append("    clickMap = null;\n    numClicks = 0;\n  }\n}\n\n");
    // If there was a double click, it uses the saved
    // map to try to perform a transition with two clicks, and clears the state.
    html.append("function doClick2()\n{\n");
    html.append("  if ((clickMap != null) && (numClicks == 2)) {\n");
    html.append("    followTransition(2, curEvt, clickMap);\n");
    html.append("    clickMap = null;\n    numClicks = 0;\n  }\n}\n\n");
    // Called when any widget gets the focus (html's onfocus).  Uses the
    // widgets ID to index into the map of widgets' keyboard transitions.
    html.append("function onFocus(eltID)\n{\n");
    html.append("  keyboardString = \"\";\n");
    html.append("  var map = focusTransitionMaps[eltID];\n");
    html.append("  if (typeof(map) != 'undefined') {\n");
    html.append("    curFocusMap = focusTransitionMaps[eltID];\n  }\n}\n\n");
    // Clears the current focus map so it knows that no widget has the focus
    html.append("function onBlur()\n{\n  curFocusMap = null;\n}\n\n");
    html.append("YAHOO.util.Event.onDOMReady(function () {\n");
    // use yahoo javascript library to build up menus
    if (menus.size() > 0) {
        for (int i = 0; i < menus.size(); i++) {
            AMenuWidget menu = menus.get(i);
            String menuVar = "oMenu" + i;
            String context = "";
            if (menu instanceof MenuHeader) {
                // associate it with the corresponding menu header
                context = ", { context: [\"" + menu.getName() + "\", \"tl\", \"bl\"]}";
            }
            // else, if it is a context menu, have it appear wherever the
            // mouse is clicked (in a javascript method)
            // create the javascript menu object
            html.append("  var " + menuVar + " = new YAHOO.widget.Menu(\"menu" + i + "\"" + context + ");\n");
            html.append("  " + menuVar + ".addItems(" + buildItemsString(menu.getChildren().iterator()) + ");\n");
            html.append("  " + menuVar + ".showEvent.subscribe(function () { this.focus(); });\n");
            html.append("  " + menuVar + ".render(document.body);\n");
            if (menu instanceof MenuHeader) {
                html.append("  YAHOO.util.Event.addListener(\"" + menu.getName() + "\", \"click\", " + menuVar + ".show, null, " + menuVar + ");\n");
            } else if (menu instanceof ContextMenu) {
                html.append("  YAHOO.util.Event.addListener(\"" + menu.getName() + "\", \"contextmenu\", displayContextMenu, " + menuVar + ", " + menuVar + ");\n");
            }
        }
    }
    html.append("\n  document.body.oncontextmenu = function () {\n    return false;\n  }\n});\n\n");
    html.append("</script>\n");
    html.append("</body>\n");
    html.append("</html>\n");
    return html.toString();
}
Also used : SimpleWidgetGroup(edu.cmu.cs.hcii.cogtool.model.SimpleWidgetGroup) MenuHeader(edu.cmu.cs.hcii.cogtool.model.MenuHeader) ArrayList(java.util.ArrayList) AMenuWidget(edu.cmu.cs.hcii.cogtool.model.AMenuWidget) ContextMenu(edu.cmu.cs.hcii.cogtool.model.ContextMenu) DoublePoint(edu.cmu.cs.hcii.cogtool.model.DoublePoint) IWidget(edu.cmu.cs.hcii.cogtool.model.IWidget) HashSet(java.util.HashSet)

Aggregations

IWidget (edu.cmu.cs.hcii.cogtool.model.IWidget)93 SimpleWidgetGroup (edu.cmu.cs.hcii.cogtool.model.SimpleWidgetGroup)29 FrameElement (edu.cmu.cs.hcii.cogtool.model.FrameElement)20 DoublePoint (edu.cmu.cs.hcii.cogtool.model.DoublePoint)19 DoubleRectangle (edu.cmu.cs.hcii.cogtool.model.DoubleRectangle)15 FrameElementGroup (edu.cmu.cs.hcii.cogtool.model.FrameElementGroup)15 CompoundUndoableEdit (edu.cmu.cs.hcii.cogtool.util.CompoundUndoableEdit)12 AParentWidget (edu.cmu.cs.hcii.cogtool.model.AParentWidget)11 Point (org.eclipse.draw2d.geometry.Point)11 IListenerAction (edu.cmu.cs.hcii.cogtool.util.IListenerAction)10 ChildWidget (edu.cmu.cs.hcii.cogtool.model.ChildWidget)9 Frame (edu.cmu.cs.hcii.cogtool.model.Frame)9 GridButtonGroup (edu.cmu.cs.hcii.cogtool.model.GridButtonGroup)9 HashSet (java.util.HashSet)8 GridButton (edu.cmu.cs.hcii.cogtool.model.GridButton)7 InputDevice (edu.cmu.cs.hcii.cogtool.model.InputDevice)7 WidgetType (edu.cmu.cs.hcii.cogtool.model.WidgetType)7 FrameEditorUI (edu.cmu.cs.hcii.cogtool.ui.FrameEditorUI)7 Iterator (java.util.Iterator)7 EventObject (java.util.EventObject)6