Search in sources :

Example 6 with MenuHeader

use of edu.cmu.cs.hcii.cogtool.model.MenuHeader 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)

Example 7 with MenuHeader

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

the class DesignExportToHTML method buildWidgetHTML.

protected String buildWidgetHTML(IWidget widget, Set<SimpleWidgetGroup> visitedGroups, Frame frame) {
    //Function is called once for each widget...
    StringBuilder html = new StringBuilder();
    DoubleRectangle bounds = widget.getEltBounds();
    String name = widget.getName();
    //How does below boolean work?
    boolean isStandard = widget.isStandard();
    //MAYBE CREATE AN IF STATEMENT TO HANDLE BUTTONS/MENU BUTTON DIFFERENTLY
    // Put the html widget in the same place as the CogTool widget
    // (adjusting for the position of the html table)
    //WE ARE ADDING TEN HERE TO COMPENSATE FOR LOCATION WITHIN BROWSER
    //WE DO NOT WANT TO ADD THAT SINCE WE ARE SWITCHING TO AREA TAG AND DEALING WITHIN IMAGE ONLY
    //POSITION AS OF NOW IS RELATIVE TO IMAGE :)
    String properties = "onfocus=\"onFocus('" + name + "')\" onblur=\"onBlur()\"" + " id=\"" + name + "\" style=\"position: absolute; left: " + (bounds.x + 10) + "; top: " + (bounds.y + 33) + "; width: " + bounds.width + "; height: " + bounds.height + ";\"";
    WidgetType type = widget.getWidgetType();
    // don't pop up the "does not help..." message if there is no left click
    // transition defined from these widgets
    int ignoreButton = 0;
    boolean ignoreLeftClick = (WidgetType.Check.equals(type) || WidgetType.TextBox.equals(type) || WidgetType.Graffiti.equals(type) || WidgetType.Menu.equals(type));
    if (ignoreLeftClick) {
        ignoreButton = LEFT_MOUSE;
    } else if (WidgetType.ContextMenu.equals(type)) {
        ignoreButton = RIGHT_MOUSE;
    }
    String eventString = getEventString(widget, ignoreButton);
    if (!widget.isRendered() && "".equals(widget.getTitle()) && widget.getImage() == null && frame.getBackgroundImage() == null && !WidgetType.Noninteractive.equals(type)) {
        blindHotSpotWarning += "This CogTool model has a hidden widget on screen. " + "You will not be able to visibly identify the location of +" + widget.getName() + ".\n";
    }
    //Why did they not use a switch statement here ?
    if (isStandard) {
        if (WidgetType.Noninteractive.equals(type) || WidgetType.Text.equals(type)) {
            return getHotspotString(widget, properties, eventString);
        }
        if (WidgetType.Button.equals(type)) {
            if (!widget.isRendered()) {
                if (!"".equals(widget.getTitle())) {
                    html.append("<div align=\"middle\"" + properties + eventString + ">" + widget.getTitle() + "</div>\n");
                }
                //In the below 6 lines I create an area tag that will be placed within the map tags, within the html code,
                //in order to create HotSpots over the image of the frame
                mapHTML += "<area shape=\"rect\" name=value ";
                mapHTML += "value ='" + widget.getTitle() + "'";
                mapHTML += " onfocus=\"onFocus('" + name + "')\" onblur=\"onBlur()\"" + " id=\"" + name + "\"" + " coords=\"" + bounds.x + "," + bounds.y + "," + (bounds.x + bounds.width) + "," + (bounds.y + bounds.height) + "\"";
                mapHTML += eventString + "/>\n";
            } else {
                html.append("<input type=button name=value value='");
                html.append(widget.getTitle());
                html.append("' " + properties + eventString + ">\n");
            }
        } else if (WidgetType.Check.equals(type)) {
            String checked = "";
            Object isSel = widget.getAttribute(WidgetAttributes.IS_SELECTED_ATTR);
            if (NullSafe.equals(WidgetAttributes.IS_SELECTED, isSel)) {
                checked = " checked";
            }
            // for checkboxes, width and height don't matter, so only deal with
            // the x and y
            String styleString = properties.substring(0, properties.indexOf("width")) + "\"";
            html.append("<input type=checkbox " + styleString + eventString);
            html.append(checked + ">\n");
            String textStyle = "style=\"position: absolute; left: " + (bounds.x + 30) + "; top: " + (bounds.y + 33) + ";\"";
            String textEvent = eventString;
            if (textSelect(widget)) {
                textEvent += " onclick=\"toggleCheckbox('";
                textEvent += widget.getName();
                textEvent += "')\"";
            }
            html.append("<a " + textStyle + textEvent + ">");
            html.append(widget.getTitle() + "</a>\n");
        } else if (WidgetType.Radio.equals(type)) {
            SimpleWidgetGroup group = widget.getParentGroup();
            if ((group != null) && !visitedGroups.contains(group)) {
                visitedGroups.add(group);
                String groupName = widget.getName();
                Iterator<IWidget> widgets = group.iterator();
                while (widgets.hasNext()) {
                    IWidget w = widgets.next();
                    DoublePoint origin = w.getShape().getOrigin();
                    String itemString = getEventString(w, LEFT_MOUSE);
                    String checked = "";
                    Object isSel = w.getAttribute(WidgetAttributes.IS_SELECTED_ATTR);
                    if (NullSafe.equals(WidgetAttributes.IS_SELECTED, isSel)) {
                        checked = " checked";
                    }
                    // for radio buttons, width and height don't matter, so only deal with
                    // the x and y
                    String styleString = "onfocus=\"onFocus('" + w.getName() + "')\" onblur=\"onBlur()\"" + "style=\"position: absolute; left: " + (origin.x + 10) + "; top: " + (origin.y + 33) + ";\"";
                    // TODO: if transitioned from, never deselects
                    html.append("<input type=radio name=\"" + groupName + "\"");
                    html.append(" id=\"");
                    html.append(w.getName());
                    html.append("\" " + styleString + itemString + checked + ">\n");
                    String textStyle = "style=\"position: absolute; left: " + (origin.x + 30) + "; top: " + (origin.y + 33) + ";\"";
                    String textEvent = itemString;
                    if (textSelect(w)) {
                        textEvent += " onclick=\"selectRadio('";
                        textEvent += w.getName();
                        textEvent += "')\"";
                    }
                    html.append("<a " + textStyle + textEvent + ">");
                    html.append(w.getTitle() + "</a>\n");
                }
            }
        } else if (WidgetType.TextBox.equals(type) || WidgetType.Graffiti.equals(type)) {
            html.append("<input type=text name=value value='");
            html.append(widget.getTitle());
            html.append("' " + properties + eventString + ">\n");
        } else if (widget instanceof ListItem) {
            SimpleWidgetGroup group = widget.getParentGroup();
            // this code will change
            if (!(visitedGroups.contains(group))) {
                visitedGroups.add(group);
                ListItem firstItem = (ListItem) group.get(0);
                DoubleRectangle itemBounds = firstItem.getEltBounds();
                // use properties of the first item in the list
                properties = "onfocus=\"onFocus('" + firstItem.getName() + "')\" onblur=\"onBlur()\"" + " id=\"" + firstItem.getName() + "\" style=\"position: absolute; left: " + (itemBounds.x + 10) + "; top: " + (itemBounds.y + 33) + "; width: " + itemBounds.width + ";\"";
                html.append("<select size=" + group.size() + " " + properties + ">\n");
                Iterator<IWidget> widgets = group.iterator();
                while (widgets.hasNext()) {
                    IWidget w = widgets.next();
                    String itemEvent = getEventString(w, 0);
                    html.append("<option" + itemEvent + " id=\"");
                    html.append(w.getName() + "\">");
                    html.append(w.getTitle() + "\n");
                }
                html.append("</select>\n");
            }
        } else if (widget instanceof MenuHeader) {
            // make hotspot associated w/ menu, use widget's
            // name for ID
            //            html.append("<input type=button name=value value='");
            //            html.append(widget.getTitle());
            //            html.append("' style=" + style + " id=\"");
            //            html.append(widget.getName());
            //            html.append("\">\n");
            // TODO: add background color?
            properties = properties.substring(0, properties.length() - 1);
            properties += " background: lightGray;\"";
            html.append("<div " + properties + eventString + ">");
            html.append(widget.getTitle());
            html.append("</div>\n");
        } else if (widget instanceof ContextMenu) {
            // TODO: add background color?
            //            style = style.substring(0, style.length() - 1);
            //            style += " background: lightGray;\"";
            html.append("<div " + properties + eventString + ">");
            html.append(widget.getTitle());
            html.append("</div>\n");
        } else if (widget instanceof PullDownHeader) {
            PullDownHeader pdh = (PullDownHeader) widget;
            //"select tag is used to create a select list" --> http://www.w3schools.com/TAGS/tag_Select.asp
            html.append("<select " + properties + ">\n");
            if (pdh.itemCount() > 0) {
                //html.append("<optgroup>\n"); //TODO: style
                Iterator<IWidget> children = pdh.getChildren().iterator();
                while (children.hasNext()) {
                    IWidget pdi = children.next();
                    String childEvent = getEventString(pdi, 0);
                    html.append("<option" + childEvent + " id=\"");
                    html.append(pdi.getName() + "\">" + pdi.getTitle() + "\n");
                }
            //html.append("</optgroup>\n");
            }
            html.append("</select>\n");
        } else if (WidgetType.Link.equals(type)) {
            properties = properties.substring(0, properties.length() - 1);
            html.append("<a " + properties + " color: blue;\"");
            html.append(eventString + "><u>");
            html.append(widget.getTitle());
            html.append("</u></a>\n");
        }
    } else {
        // unknown widget or custom version of an interactive widget
        return getHotspotString(widget, properties, eventString);
    }
    return html.toString();
}
Also used : SimpleWidgetGroup(edu.cmu.cs.hcii.cogtool.model.SimpleWidgetGroup) MenuHeader(edu.cmu.cs.hcii.cogtool.model.MenuHeader) ContextMenu(edu.cmu.cs.hcii.cogtool.model.ContextMenu) PullDownHeader(edu.cmu.cs.hcii.cogtool.model.PullDownHeader) DoubleRectangle(edu.cmu.cs.hcii.cogtool.model.DoubleRectangle) DoublePoint(edu.cmu.cs.hcii.cogtool.model.DoublePoint) DoublePoint(edu.cmu.cs.hcii.cogtool.model.DoublePoint) Iterator(java.util.Iterator) ListItem(edu.cmu.cs.hcii.cogtool.model.ListItem) WidgetType(edu.cmu.cs.hcii.cogtool.model.WidgetType) IWidget(edu.cmu.cs.hcii.cogtool.model.IWidget)

Example 8 with MenuHeader

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

the class FrameEditorController method insertDuplicateWidget.

/**
     * If group or parent is non-null, duplicate the widget within the given
     * group.  If they are both null, the widget was dragged to empty space, so
     * give it a new group.
     */
private boolean insertDuplicateWidget(IWidget widget, SimpleWidgetGroup group, int index, AParentWidget parent, double moveByX, double moveByY) {
    Map<IWidget, IWidget> widgetCopies = new LinkedHashMap<IWidget, IWidget>();
    double startPosX = 0.0;
    double startPosY = 0.0;
    DoubleSize newSize;
    if (parent != null) {
        newSize = getNewWidgetSize(parent);
        newSize.height *= getHeightFactor(widget, parent.getChildren());
    } else if ((group == null) || (group.size() == 0)) {
        newSize = widget.getShape().getSize();
    } else {
        DoublePoint startPos = group.get(0).getShape().getOrigin();
        startPosX = startPos.x;
        startPosY = startPos.y;
        newSize = group.get(0).getShape().getSize();
        if (widget instanceof ListItem) {
            newSize.height *= getHeightFactor(widget, group);
        }
    }
    widgetSituator.reset(widgetCopies, null);
    IWidget newWidget = null;
    if (parent != null) {
        if (widget instanceof ChildWidget) {
            newWidget = ((ChildWidget) widget).duplicate(parent, lookupFrameDuplicator, widgetSituator, index);
            newWidget.setWidgetSize(newSize.width, newSize.height);
            if (newWidget instanceof AParentWidget) {
                resizeChildren(newWidget);
                DesignEditorCmd.repositionChildren((AParentWidget) newWidget);
            }
            DesignEditorCmd.repositionChildren(parent);
        }
    } else if (group != null) {
        if (widget instanceof MenuHeader) {
            newWidget = ((MenuHeader) widget).duplicate(group, lookupFrameDuplicator, widgetSituator, index);
        } else if (widget instanceof ListItem) {
            newWidget = ((ListItem) widget).duplicate(group, lookupFrameDuplicator, index);
        }
        newWidget.setWidgetSize(newSize.width, newSize.height);
        resizeChildren(newWidget);
        widgetSituator.placeInContext(widget, newWidget);
        DesignEditorCmd.repositionChildren(group, startPosX, startPosY);
    } else {
        // Duplicating into space
        if ((widget instanceof MenuHeader) || (widget instanceof ListItem)) {
            SimpleWidgetGroup newGroup = null;
            if (widget instanceof MenuHeader) {
                newGroup = new SimpleWidgetGroup(SimpleWidgetGroup.HORIZONTAL);
                newWidget = ((MenuHeader) widget).duplicate(newGroup, lookupFrameDuplicator, widgetSituator);
            } else {
                // (widget instanceof ListItem)
                newGroup = new SimpleWidgetGroup(SimpleWidgetGroup.VERTICAL);
                newWidget = ((ListItem) widget).duplicate(newGroup, lookupFrameDuplicator);
            }
            group = newGroup;
            widgetSituator.placeInContext(widget, newWidget);
            newWidget.moveElement(moveByX, moveByY);
            group.setAttribute(WidgetAttributes.IS_RENDERED_ATTR, Boolean.valueOf(widget.isRendered()));
        }
    }
    widgetSituator.completeWork();
    Collection<IWidget> duplicateWidgets = widgetCopies.values();
    Iterator<IWidget> copies = duplicateWidgets.iterator();
    while (copies.hasNext()) {
        IWidget widgetCopy = copies.next();
        // Warning: it is important that each widget be added
        // to the frame *before* we make the next widget name
        // unique, or we can end up with non-unique names.
        makeWidgetNameUnique(widgetCopy);
        model.addWidget(widgetCopy);
    }
    SimpleWidgetGroup newGroup = (group != null) ? group : newWidget.getParentGroup();
    Object rendered = newGroup.getAttribute(WidgetAttributes.IS_RENDERED_ATTR);
    boolean groupRendered = ((Boolean) rendered).booleanValue();
    boolean widgetRendered = widget.isRendered();
    if (groupRendered != widgetRendered) {
        newWidget.setRendered(groupRendered);
    }
    insertDuplicateEdit(newWidget, new ReadOnlyList<IWidget>(new ArrayList<IWidget>(duplicateWidgets)), group, index, parent, startPosX, startPosY, undoMgr);
    return true;
}
Also used : SimpleWidgetGroup(edu.cmu.cs.hcii.cogtool.model.SimpleWidgetGroup) MenuHeader(edu.cmu.cs.hcii.cogtool.model.MenuHeader) ArrayList(java.util.ArrayList) AParentWidget(edu.cmu.cs.hcii.cogtool.model.AParentWidget) DoubleSize(edu.cmu.cs.hcii.cogtool.model.DoubleSize) LinkedHashMap(java.util.LinkedHashMap) DoublePoint(edu.cmu.cs.hcii.cogtool.model.DoublePoint) ListItem(edu.cmu.cs.hcii.cogtool.model.ListItem) ChildWidget(edu.cmu.cs.hcii.cogtool.model.ChildWidget) IWidget(edu.cmu.cs.hcii.cogtool.model.IWidget)

Example 9 with MenuHeader

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

the class FrameEditorController method resizeChildren.

private void resizeChildren(IWidget widget) {
    if (widget instanceof AParentWidget) {
        AParentWidget parent = (AParentWidget) widget;
        DoubleSize size = parent.getShape().getSize();
        if (parent instanceof MenuHeader) {
            size.width *= FrameEditorUI.MENU_ITEM_RATIO;
        }
        int numItems = parent.itemCount();
        for (int i = 0; i < numItems; i++) {
            ChildWidget child = parent.getItem(i);
            double h = size.height;
            Object isSep = child.getAttribute(WidgetAttributes.IS_SEPARATOR_ATTR);
            if (NullSafe.equals(WidgetAttributes.IS_SEPARATOR, isSep)) {
                h /= FrameEditorUI.SEPARATOR_RATIO;
            }
            child.setWidgetSize(size.width, h);
            resizeChildren(child);
        }
    }
}
Also used : MenuHeader(edu.cmu.cs.hcii.cogtool.model.MenuHeader) AParentWidget(edu.cmu.cs.hcii.cogtool.model.AParentWidget) ChildWidget(edu.cmu.cs.hcii.cogtool.model.ChildWidget) DoubleSize(edu.cmu.cs.hcii.cogtool.model.DoubleSize) DoublePoint(edu.cmu.cs.hcii.cogtool.model.DoublePoint)

Aggregations

MenuHeader (edu.cmu.cs.hcii.cogtool.model.MenuHeader)9 IWidget (edu.cmu.cs.hcii.cogtool.model.IWidget)7 AParentWidget (edu.cmu.cs.hcii.cogtool.model.AParentWidget)6 SimpleWidgetGroup (edu.cmu.cs.hcii.cogtool.model.SimpleWidgetGroup)6 ChildWidget (edu.cmu.cs.hcii.cogtool.model.ChildWidget)5 ContextMenu (edu.cmu.cs.hcii.cogtool.model.ContextMenu)5 DoublePoint (edu.cmu.cs.hcii.cogtool.model.DoublePoint)5 ListItem (edu.cmu.cs.hcii.cogtool.model.ListItem)5 PullDownHeader (edu.cmu.cs.hcii.cogtool.model.PullDownHeader)4 AMenuWidget (edu.cmu.cs.hcii.cogtool.model.AMenuWidget)3 DoubleRectangle (edu.cmu.cs.hcii.cogtool.model.DoubleRectangle)3 DoubleSize (edu.cmu.cs.hcii.cogtool.model.DoubleSize)3 TraversableWidget (edu.cmu.cs.hcii.cogtool.model.TraversableWidget)3 CheckBox (edu.cmu.cs.hcii.cogtool.model.CheckBox)2 GridButtonGroup (edu.cmu.cs.hcii.cogtool.model.GridButtonGroup)2 MenuItem (edu.cmu.cs.hcii.cogtool.model.MenuItem)2 PullDownItem (edu.cmu.cs.hcii.cogtool.model.PullDownItem)2 RadioButton (edu.cmu.cs.hcii.cogtool.model.RadioButton)2 Widget (edu.cmu.cs.hcii.cogtool.model.Widget)2 WidgetType (edu.cmu.cs.hcii.cogtool.model.WidgetType)2