{"id":0,"registry":{"0":{"submorphs":[],"scripts":[],"id":"CC145AE8-B342-432B-A49C-75958117383A","shape":{"__isSmartRef__":true,"id":1},"droppingEnabled":true,"halosEnabled":true,"_ClipMode":"auto","eventHandler":{"__isSmartRef__":true,"id":2},"itemList":["Example","Readme","Action 1","Action 2","Action 3"],"selectOnMove":false,"showsHalos":false,"name":"PullDownMenu","partsBinMetaInfo":{"__isSmartRef__":true,"id":3},"derivationIds":[6545,"9CE40D45-F249-461A-9C31-2DDA97BCFCC6","85902790-A508-4E9B-A66C-627AAD9FADDC","620FEF7D-3401-4E6F-8027-0AC7C79843E6","F339E9CE-B044-4123-B43D-B7DC107D37C1","F57B43AF-61CC-45C5-AD8E-2B43B0361819","49286E69-1813-40F2-A62B-70147132FC13","9EAE49DA-FF79-4D36-A42C-FD24209C2CC2","0DB347B1-0435-4125-8EA6-565E9D7EC6AC","975CAB2D-9DFC-472B-9793-DA41F9D412E7"],"selectedLineNo":-1,"_ToolTip":"Choose the mode: editing, edit master, present, or play","changeTriggered":true,"attributeConnections":[{"__isSmartRef__":true,"id":6}],"doNotSerialize":["$$selection"],"doNotCopyProperties":["$$selection"],"actionStruct":{"__isSmartRef__":true,"id":8},"title":"Example","actions":{"__isSmartRef__":true,"id":9},"__serializedExpressions__":["_Position","distanceToDragEvent"],"_Rotation":0,"_Scale":1,"__serializedLivelyClosures__":{"__isSmartRef__":true,"id":10},"__LivelyClassName__":"lively.morphic.DropDownList","__SourceModuleName__":"Global.lively.morphic.Lists","_Position":"lively.pt(0.0,0.0)","distanceToDragEvent":"lively.pt(77.0,-5.0)"},"1":{"_BorderWidth":0,"__serializedExpressions__":["_Position","_Extent","_BorderColor","_Fill","_Padding"],"__LivelyClassName__":"lively.morphic.Shapes.Rectangle","__SourceModuleName__":"Global.lively.morphic.Shapes","_Position":"lively.pt(0.0,0.0)","_Extent":"lively.pt(107.0,25.0)","_BorderColor":"Color.rgb(0,0,0)","_Fill":"Color.rgb(243,243,243)","_Padding":"lively.rect(0,0,0,0)"},"2":{"morph":{"__isSmartRef__":true,"id":0},"__LivelyClassName__":"lively.morphic.EventHandler","__SourceModuleName__":"Global.lively.morphic.Events"},"3":{"requiredModules":[],"migrationLevel":9,"partsSpaceName":"PartsBin/Inputs/","comment":"A dropdownlist which essentially exports only one call: init(anActionStruct). Documented by this.readMe(); see this.showExample() to generate the\nexample menu.  The general idea is that after calling init(anActionStruct), all the connections and actions follow\n","partName":"PullDownMenu","changes":[{"__isSmartRef__":true,"id":4},{"__isSmartRef__":true,"id":5}],"__serializedExpressions__":["lastModifiedDate"],"__LivelyClassName__":"lively.PartsBin.PartsBinMetaInfo","__SourceModuleName__":"Global.lively.PartsBin","lastModifiedDate":"new Date(\"Wed Dec 03 2014 08:57:43 GMT-0800 (PST)\")"},"4":{"author":"rick","message":"no comment","id":"AE0615B4-13AF-48E7-ABEE-D4F7456580E9","__serializedExpressions__":["date"],"date":"new Date(\"Wed Dec 03 2014 08:57:42 GMT-0800 (PST)\")"},"5":{"__serializedExpressions__":["date"],"author":"rick","message":"no comment","id":"C2C76BC5-4EAA-4BBE-8AE9-6793C2245809","date":"new Date(\"Thu Dec 18 2014 18:34:54 GMT-0800 (PST)\")"},"6":{"sourceObj":{"__isSmartRef__":true,"id":0},"sourceAttrName":"selection","targetObj":{"__isSmartRef__":true,"id":0},"targetMethodName":"doAction","varMapping":{"__isSmartRef__":true,"id":7},"__LivelyClassName__":"AttributeConnection","__SourceModuleName__":"Global.lively.bindings.Core"},"7":{"source":{"__isSmartRef__":true,"id":0},"target":{"__isSmartRef__":true,"id":0}},"8":{},"9":{},"10":{"init":{"__isSmartRef__":true,"id":11},"readMe":{"__isSmartRef__":true,"id":14},"doAction":{"__isSmartRef__":true,"id":17},"showExample":{"__isSmartRef__":true,"id":20}},"11":{"varMapping":{"__isSmartRef__":true,"id":12},"source":"function init(anActionStruct) {\n    // the idea behind a pulldown Menu is that it's self-contained:\n    // the only connection is to itself, and all the information to fill\n    // the list and perform the actions is in the action struct\n    // an ActionStruct is of the form\n    // {title: aString,\n    //  actions: {S1: F1,\n    //            S2: F2...\n    //             }\n    // menuOrder: [S1, S2,]\n    // }\n    // the list is populated with aString, S1, S2,...\n    // Fi is called as the action when Si is selected\n    // optArg: menuOrder: a list with some of the keys specified.  These will\n    // appear first in the list after the title, in order.  Other keys added\n    // as Object.keys(anActionStruct.actions) fills them\n    this.clearSelections()\n    this.setList([])\n    var keys = Object.keys(anActionStruct.actions)\n    var itemList = [anActionStruct.title]\n    anActionStruct.menuOrder.forEach(function(aString) {\n        if (aString == anActionStruct.title) {\n            alert(\"Error: \" + aString + \" can't be both a title and an action\")\n        } else if (itemList.indexOf(aString) != -1) {\n            alert('Error: ' + aString + ' appears twice')\n        } else if (keys.indexOf(aString) == -1) {\n            alert(\"Error: \" + aString + \" appears in menuOrder but has no action\")\n        } else {\n            itemList.push(aString)\n        }\n    })\n    keys.forEach(function (aString) {\n        if (itemList.indexOf(aString) != -1) return;\n        if (aString == anActionStruct.title) {\n            alert(\"Error: \" + aString + \" can't be both a title and an action\")\n            return\n        } \n        itemList.push(aString)\n    })\n    this.setList(itemList)\n    this.actions = anActionStruct.actions\n    this.title = anActionStruct.title\n    \n    \n    \n}","funcProperties":{"__isSmartRef__":true,"id":13},"__LivelyClassName__":"lively.Closure"},"12":{"this":{"__isSmartRef__":true,"id":0}},"13":{"__serializedExpressions__":["timestamp"],"user":"rick","timestamp":"new Date(\"Wed Dec 03 2014 08:55:21 GMT-0800 (PST)\")"},"14":{"varMapping":{"__isSmartRef__":true,"id":15},"source":"function readMe() {\n    return \"The idea behind a pulldown Menu is that it's self-contained: \"+\n  \" the only connection is to itself, and all the information to fill\" +\n   \" the list and perform the actions is in the action struct\" +\n   \" an ActionStruct is of the form\" +\n   \" {title: aString,\" +\n   \"  actions: {S1: F1,\" +\n   \"            S2: F2...\" +\n   \"             }\" +\n   \" menuOrder: [S1, S2,]\" +\n   \" }\" +\n   \" the list is populated with aString, S1, S2,...\" +\n   \" Fi is called as the action when Si is selected\" +\n   \" optArg: menuOrder: a list with some of the keys specified.  These will\" +\n   \" appear first in the list after the title, in order.  Other keys added\" +\n   \" as Object.keys(anActionStruct.actions) fills them\";\n   \n}","funcProperties":{"__isSmartRef__":true,"id":16},"__LivelyClassName__":"lively.Closure"},"15":{"this":{"__isSmartRef__":true,"id":0}},"16":{"__serializedExpressions__":["timestamp"],"user":"rick","timestamp":"new Date(\"Thu Dec 18 2014 18:34:11 GMT-0800 (PST)\")"},"17":{"varMapping":{"__isSmartRef__":true,"id":18},"source":"function doAction(anItemFromList) {\n    // catch bogus events on load, etc\n    if (!anItemFromList) return;\n    // generic action called on selection.  This should only be called\n    // in response to a selection change, and then it just does \n    // this.actions[anItemFromList].action() and resets to the title\n    if (anItemFromList == this.title) {\n        // just resetting to the title, do nothing\n        return;\n    }\n    // shouldn't happen, but suspenders & belt\n    if (this.itemList.indexOf(anItemFromList) == -1) {\n        alert(\"Error: \" +  anItemFromList + \" doesn't appear in the menu!\")\n    }\n    // OK, just do the action and return.  This is guaranteed to be there\n    this.actions[anItemFromList]()\n    this.setSelection(this.title)\n    \n}","funcProperties":{"__isSmartRef__":true,"id":19},"__LivelyClassName__":"lively.Closure"},"18":{"this":{"__isSmartRef__":true,"id":0}},"19":{"__serializedExpressions__":["timestamp"],"user":"rick","timestamp":"new Date(\"Thu Dec 18 2014 18:34:45 GMT-0800 (PST)\")"},"20":{"varMapping":{"__isSmartRef__":true,"id":21},"source":"function showExample() {\n    // call this to generate an example menu\n    var menu = this; // lexical scope to pass this object properly \n    this.init({title:\"Example\",\n            actions:  {\n                \"Action 1\": function() {alert(\"Action 1\")},\n                \"Action 2\": function() {alert(\"Action 2\")},\n                \"Action 3\": function() {alert(\"Action 3\")},\n                \"Readme\": function() {show(menu.readMe())}\n            },\n            menuOrder: [\"Readme\", \"Action 1\"]\n            })\n    \n}","funcProperties":{"__isSmartRef__":true,"id":22},"__LivelyClassName__":"lively.Closure"},"21":{"this":{"__isSmartRef__":true,"id":0}},"22":{"__serializedExpressions__":["timestamp"],"user":"rick","timestamp":"new Date(\"Wed Dec 03 2014 08:51:17 GMT-0800 (PST)\")"},"isSimplifiedRegistry":true}}