Programming with Morphic - Intro
// Morphic composition / hierarchy interface
morph.addMorph(submorph) // add a submorph
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Programmatically create, inspect, and modify Morphs • Morphic composition • Visual appearance • Transformations and Layouting • Interface offered by specific types of Morphs, e.g. Lists, Buttons, ... • Customizing behavior
Lively UI conventions
Menus
Halos
Dragging and Grabbing
Tools – PartsBin
➡︎
➡︎
PartsBin Publish Dialog • Upload new or modified parts
PartsBin Browser • Browse and search • Load parts
Data exploration and visualization
// Morphic composition / hierarchy interface
morph.addMorph(submorph) // add a submorph
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Lively allows to • Process data interactively ◦ Code snippets in workspaces ◦ List interfaces for filter/map/reduce operations • Interface data sources or data processing / analyzation systems • Integrate visualization libraries such as d3
Introduction  
helper scripts
X

Menu
$world.submorphs.grep('MorphicPages')
.invoke('get', 'pageList').pluck('itemList').flatten().pluck('value')
.invoke("withAllSubmorphsSelect", function(ea) { return ea.isCodeEditor; })
.flatten().invoke("setAutocompletionEnabled", true)
ext = $world.submorphs.grep('MorphicPages')[0].getExtent()
ext = lively.pt(1155.0,725.0)
$world.submorphs.grep('MorphicPages').invoke('setExtent', ext)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
➡︎
• Owner and submorphs
lively.PartsBin.getPart('CoordinateSystem', 'PartsBin/Debugging')
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
this.get('morph3').show()
this.get('morph3').owner.show()
bounds() / getExtent() / setExtent(newExtent)
getPosition() / setPosition(value)
moveBy(point)
align(p1, p2)
getRotation() / setRotation(rotinRad)
rotateBy(rad)
getScale() / setScale(scale)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Morphic – Layouting
• How morphs react to geometry changes No behavior is the default but can be customized ◦ No behavior = no layouter, no layout attributes Layout attributes for simple customizations ◦ Resizing, moving, centering, scaling Layouters for more complex rules involving groups of objects lively.ide.browse(lively.morphic.Layout.uri())
Data bindings
// Morphic composition / hierarchy interface
morph.addMorph(submorph) // add a submorph
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Data bindings are a declarative form to define publish/subscribe relationships between two objects. • They have the form connect(source, sourceAttribute, target, targetAction) ◦ Semantics: when source[sourceAttribute] changes run target[targetAction] By default data bindings will connect attributes to methods but other data bindings are ◦ Virtual sourceAttributes ◦ Method-to-emthod connects ◦ Data bindings involving multiple subbindings, e.g. for global transform of a morph.
Networking
// Morphic composition / hierarchy interface
morph.addMorph(submorph) // add a submorph
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
HTTP • Lively offers a thin layer over standard browser HTTP / AJAX interfaces ◦ URL / WebResource objects ◦ You can also use jQuery Lively2Lively Lively's own messaging protocol to allow peer-to-peer messaging • Connect's Lively worlds, servers or other non-Lively JavaScript environments Server networking • Via subservers Lively can implement new HTTP / Websocket interfaces ◦ or implement arbitrary networking, e.g. non-HTTP
Lively Server and Subservers
// Morphic composition / hierarchy interface
morph.addMorph(submorph) // add a submorph
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
• node.js based server installation instructions ◦ server just implements serving modules / files and WebDAV and plugin mechanism • plugin mechanism "subservers" ◦ subservers can implement arbitrary server logic, e.g. new HTTP handlers ◦ programmable from within Lively: Show subservers
Storage interfaces - SQLite
// Morphic composition / hierarchy interface
morph.addMorph(submorph) // add a submorph
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Lively comes with a database integration based on SQLite • The video shows how to build a morphic application backed by a database. The following slides show how to work with SQLite programatically.
Morphic – Events
// Morphic composition / hierarchy interface
morph.addMorph(submorph) // add a submorph
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
React to user input and other I/O • Mouse, keyboard, touch events • Browser events like resize, scroll, ... Morphic events Morphic events abstract from pure DOM events Event handlers are implemented by morphs, not DOM nodes Event dispatch • Dispatch is capturing: Outside in!
This world is made for learning and teaching about Lively. The "slides" below have information about various topics. You can click on the thumbnails at the bottom to page through the content.
Welcome to Lively-101!
Click here to dock the topic list to the bottom of your screen.
Morphic – methods you should now
X

Menu
Morphic methods you should now
lively.morphic.connect
/*animation*/
startStepping(stepTime, scriptName, argIfAny) // repeatedly execute a method `scriptName`
stopStepping() // stop repeated method execution
moveByAnimated(delta, time, callback) // smooth transition
withCSSTransitionDo(morphModifyFunc, duration, whenDone)
/*buildpsec*/
buildSpec() // generate buildSpec from morph
/*css*/
addStyleClassName(classNameOrNames) // add css class
setStyleClassNames(classNames) // set css class(es)
getStyleClassNames()
getStyleSheet()
setStyleSheet(styleSheet) // set css def
/*debugging*/
show() // highlight a morph
/*DOM access*/
jQuery() // returns jQuery object for the morph/shape's DOM node
renderContext().morphNode // the DOM node of the morph
renderContext().shapeNode // the DOM node of the morph's shape
/*events*/
focus() // set keyboard focus to morph
lively.morphic.Morph.focusedMorph() // retrieve Morph which currently has kbd focus
getScroll() // scroll of clipped morphs
setScroll(horiz, vert)
ignoreEvents() // disable processing all events in morph
onKeyDown(evt)
onMouseDown(evt)
onMouseMove(evt)
onMouseUp(evt)
onScroll(evt)
/*halos*/
disableHalos()
enableHalos()
/*layout*/
applyLayout()
getLayouter()
/*menus*/
this.morphMenuItems() // should return menu item lists that define what's in the menu
/*partsbin*/
copyToPartsBin(optPartsSpaceNamed) // publish into partsbin
copyToPartsBinWithUserRequest()
/*positioning / transformations / visuals*/
align(p1, p2) // change position of morph so that its position p1 is aligned with the position p2
bounds() // get the bounding box (in owner coordinates of the morph)
copy() // returns a copy of the morph
getExtent() // morph extent
getFill() // background color
getPosition()
getPositionInWorld() // global position = transform local position with transforms of all owners
getRotation()
getScale()
getTransform()
innerBounds() // local bounding box
localize(point)
moveBy(point)
setExtent(newExtent)
setFill(value)
setPosition(value)
setVisible(bool) // hide/show morph
/*direct styling*/
applyStyle(spec)
/*halos*/
that.showHalos()
that.removeHalos()
/*scripting*/
addScript(namedFunction) // attach function as new method to morph object
get(name) // lookup morph with name, returns only one match
/*windows*/
getWindow() // get the window of the current morph or null if morph not inside a window
openInWindow(); // open morph in window (morph becomes window.targetMorph)
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3 + 4
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Run it!
Storage interfaces - SQLite
Lively Server and Subservers
Networking
Data exploration and visualization
Data bindings
Morphic – Layouting
Morphic – Events
Programming with Morphic - Intro
Tools – PartsBin
Lively UI conventions
Introduction