Building A Super Cool Window Manager w/Knockout.js for the Schema App

I’ve been busy working on a “window manager” for the Encapsule Project Schema application based on the Knockout.js Model-View/View-Model (MVVM) Javascript library.

Firstly, I’ve had some good things to say about Knockout.js based on my first set of experiments and continue to be impressed. That said, writing complicated MVVM is not entirely trivial. There’s a metric shit ton of detail, lots of typing (even in Coffeescript) and ample opportunity to make little mistakes that take 5-10 minutes to debug (and I’ve taken hundred of these opportunities). Knockout.js does an admirable job encapsulating its job (binding observable data models to the DOM (and vice versa)). But there’s a lot of detail left over and no good way to manage it save slogging through the code.

My Knockout.js “Window Manager”

Schema is going to be an interactive editor and visualization application for modeling software systems in “Soft Circuit Description Language” (something I made up which is why you don’t know what it is – yet). It’s pretty complicated in detail. So complicated in fact that nobody understands what it is and I can’t really explain it. It has to be shown… SCDL itself is an object model where objects represent chunks of “virtual digital circuit schematic” that can be combined in various ways to build software specifications.

In order to build an intuitive editor requires that I provide a very fluid way of navigating, and a very clearly worked out way of segregating information and providing context as required by whatever operation the user is engaged in at the time. Without getting into further details on SCDL or the Schema editor right now, suffice it to say there’s a lot of information. Simple window layout schemes are just not sufficient for an application such as this.

Enter the new Window Manager:

Schema v0.81 Window Manager

Schema v0.81 Window Manager

Features:

Declarative Layout
The window manager constructor takes as input a parent DOM element and a Javascript object the declares the entire layout for the window manager.

The layout declaration comprises:

  • Global options
  • An array of “plane” descriptor objects.
  • Each “plane” object contains an ordered list of “splitter” descriptor objects.
  • Each “splitter” object contains one or two “window” descriptor objects.
  • Each “window” object can declare basic properties (e.g. color), and additionally includes an array of “mode” descriptor objects.
  • Each “mode” descriptor object describes a requested vertical or horizontal extent request (e.g. when the window is in “full” mode reserve a 400px horizontal extent).
  • Additionally, each “window” descriptor indicates the name of an external user-supplied observable class that will be bound into each window, along with an identifier for the HTML view template(s) that will be selected for each of a window’s declared modes.

It was a busy week but it’s basically working 🙂

I posted a development build snapshot you can check out here: http://www.chrisrussell.net/html5/schema-4/schema.html#/

^— Note that most of the “Schema” part of the app is actually offline in this build as I was testing only the window manager code.

What’s cool is that this was produced by feeding the following Javascript object to the window manager constructor:

###
 Dig this >:)-~
 ###
 Encapsule.code.app.viewLayout = {
 layout: {
#
 # Layout metadata
 #
 id: "idSchemaWindowManager"
 name: "#{appName} v#{appVersion} Window Manager"
#
 # Parent element attributes
 #
 pageBackgroundColor: undefined
#
 # Window manager glass plane attributes
 #
 glassOpacity: 0.6
 glassBackgroundColor: undefined
 glassMargin: 0 # document edge to glass edge
 glassBackgroundImage: "Aspen_trees_2.jpg"
 #glassBackgroundImage: "fire-on-the-mountain.jpg"
#
 # Window manager base plane attributes
 #
 windowManagerBackgroundColor: "white"
 windowManagerMargin: 10 # glass edge to window manager edge
 windowManagerOpacity: 0.5
 windowManagerFadeInTimeout: 1500
#
 # Managed window attributes
 #
 observableWindowHost: {
 backgroundColor: "white"
 border: "1px solid black"
 }
planes: [
 {
 id: "idSchemaPlaneDefault"
 name: "#{appName} v#{appVersion} Default View Plane"
 splitterStack: [
 {
 id: "idFrameStackSplitter"
 name: "Frame Stack Split"
 type: "vertical"
 Q1WindowDescriptor: undefined
 Q2WindowDescriptor: {
 id: "idFrameStack"
 name: "Frame Stack Window"
 initialMode: "min"
 initialEnable: true
 modes: { full: { reserve: 300 }, min: { reserve: 64 } }
 }
 },
 {
 id: "idToolbarSplitter"
 name: "Toolbar Split"
 type: "horizontal"
 Q1WindowDescriptor: {
 id: "idToolbar"
 name: "Toolbar Window"
 initialMode: "min"
 initialEnable: true
 modes: { full: { reserve: 128 }, min: { reserve: 64 } }
 }
 Q2WindowDescriptor: undefined
 },
 {
 id: "idSelect1Splitter"
 name: "Select 1 Split"
 type: "vertical"
 Q1WindowDescriptor: {
 id: "idSelect1"
 name: "Select 1 Window"
 initialMode: "min"
 initialEnable: true
 modes: { full: { reserve: 300 }, min: { reserve: 64 } }
 }
 Q2WindowDescriptor: undefined
 },
 {
 id: "idSelect2Splitter"
 name: "Select 2 Split"
 type: "vertical"
 Q1WindowDescriptor: {
 id: "idSelect2"
 name: "Select 1 Window"
 initialMode: "min"
 initialEnable: true
 modes: { full: { reserve: 300 }, min: { reserve: 64 } }
 }
 Q2WindowDescriptor: undefined
 },
 {
 id: "idSVGEditSplitter"
 name: "SVG/Edit Split"
 type: "horizontal"
 Q1WindowDescriptor: {
 id: "idSVGPlane"
 name: "SVG Plane"
 initialMode: "full"
 initialEnable: true
 modes: { full: { reserve: 0 }, min: { reserve: 0 } }
 }
 Q2WindowDescriptor: {
 id: "idEdit1"
 name: "Edit 1 Window"
 initialMode: "min"
 initialEnable: true
 modes: { full: { reserve: 0 }, min: { reserve: 64 } }
 }
 }
]
 },
 # end plane / new plane
 {
 id: "idSchemaSettingsPlane"
 name: "#{appName} Settings Plane"
 splitterStack: [
 {
 id: "idSetttingsPLaneSplitter0"
 name: "what ever some descriptive text"
 type: "horizontal"
 Q1WindowDescriptor: {
 id: "idSettings1"
 name: "Settings 1 Window"
 initialMode: "full"
 initialEnable: false
 modes: { full: { reserve: 0 }, min: { reserve: 0 } }
 }
 Q2WindowDescriptor: {
 id: "idSettings2"
 name: "Settings 2 Window"
 initialMode: "full"
 initialEnable: false
 modes: { full: { reserve: 0 }, min: { reserve: 0 } }
 }
 }
 ]
 }
 ] # end planes
 } # end layout
 } # end viewLayout
Advertisements

About Chris Russell

http://www.chrisrussell.net
This entry was posted in Internet, Open Source, Software and tagged , , , , , . Bookmark the permalink.

Comment on this article

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s