Demystifying the Workspace - GlimmerLabs/MathOverImages GitHub Wiki
MIST's GUI (the workspace) is made up of many parts and uses over 25 javascript files to function. Here we'll try and break that down and look at how the GUI functions.
Shapes, Groups, Layers, and Stages
The GUI is written in KineticJS. This JavaScript library make it easier to interact with the HTML5 canvas element. You can draw rectangles, circles, text, etc.; group these elements together; and even drag them around or have them animate. Please read KineticJS's wiki page. They give a good description of how their framework is set up and the hierarchy of nodes.
Global Variables and Functions
One of the most important files to the system is the global variables file, mist-gui-globalVariables.js
. This file contains the width and height of objects, fonts, font sizes, colors, names of values and functions, booleans, and finally all of the layers in the stage. The width of the stage is stored in a separate file, mist-gui-width-var.js
. (We treat this separately so that it's easier to change that for different layouts.) (Sam thinks that you should use objects to store the "globals" and that would make it more adaptable.)
mist-gui-predicates.js
contains (you guessed it) all of the predicate functions for the system.
mist-gui-utilityFunctions.js
contains various utility functions.
mist-gui-constructors.js
contains the functions that create or add to the workspace functions, values, outlets, lines, editable text, and menu tweens.
Layers
Layers are each tied to their own canvas element and can contain nodes, such as groups, text, or shapes.
Here are the different layers in the GUI:
- The line layer holds connecting lines between nodes in the work area.
- The menu layer holds the buttons that users can click on to drag a new node into the work area.
- The menuButton layer holds the super buttons that are used to expand the menus.
- The menuArrowLayer holds the arrows for the scrolling menus.
- The menuControlLayer contains the buttons to save/open/reset the workspace
- The toolboxLayer holds the draggable toolbox
- The work layer holds all active nodes that are either connected or available to be connected.
- The border layer stores static elements of the page such as dividing lines.
- The funBar layer contains the elements of the funBar at the bottom of the screen.
- The drag layer holds nodes while they are being moved about the workspace.
- The text layer hold the editable text boxes for constant values and function text.
- The labelLayer contains informative labels that appear on mouseover
- The screenLayer contains pop-up windows for meta events
- The renderLayer contains the large rendered canvas when saving an image.
(Zoe should say something about the relative placement of the layers. What has to be on top of what?)
Initialize stage
To begin working, we need to initialize our stage. This function is written in mist-gui-initializeStage.js
. It grabs our canvas elements, adds all of the layers to the stage (in a particular order), and sets up an event listener (we'll discuss these later).
Make _______
The next step is to create the basic elements that are always in the workspace: the menu, the function bar, and the tool box.
Make Menu
In mist-gui-makeMenu.js
the borders, menu buttons, and menu items (functions and values) are created and added to the stage in the appropriate layer.
For example, the "valuesButton" ('add a value') is a group that contains an outer rectangle, a representation of a value, and text. Later on, we'll set up an event listener that performs a series of actions whenever the group 'valuesButton' is clicked on.
Values/Functions
The nodes for values and functions are created with the functions makeValueGroup
and makeFunctionGroup
which are found in mist-gui-constructors.js
. These functions take a name, and x and y coordinates. In addition to styling, the constructor adds additional parameters to the group.
Values contain fields for their:
- renderFunction (what the renderer uses to produce an image)
- rep (representation, the text that appears on the node)
- lineOut[] (an array of the lines going out of this value)
- renderLayer (this node's layer for rendering the thumbnail of it's image)
Functions contain fields for their:
- numInputs (current number of inputs to the function)
- maxInputs (maximum number of inputs the function can hold)
- lineOut[] (an array of the lines going out of this node)
- rep (representation, the text that appears on the node)
- prefix (ask Earnest)
- separator (ask Earnest)
- renderFunction (the expression given to the renderer to produce the image. initialized at null)
- renderLayer (this node's layer for rendering the thumbnail of it's image)
Make Toolbox
In mist-gui-makeToolbox.js
the draggable toolbox is created and added to the toolboxLayer. The toolbox allows the user to switch between the work tool, line tool, and delete tool, as well as undo and redo actions.
Make Function Bar
At the bottom of the workspace is the function bar. Here the user can see (at least a portion of) the expression of the image they've created and can also save their image. In mist-gui-makeFunctionBar.js
the function bar is created and added to the funBarLayer.
Make Labels
Whenever a user hover over a menu or toolbox item in the workspace, and tags are turned on, a label describing that item appears. Functions to create these labels are in mist-gui-makeLabels.js
.
Once our infrastructure is created, we are ready to start interacting with the workspace.
Interactions
Here come the fun (but more complicated) part: Event listeners! An event is a function that occurs when an action is performed by the user. Events can be connected to individual shapes, groups, layers, or the whole stage. For example, on a 'click' of the 'add a value' button, we shift the function button and its underlying nodes to the right, and expand the values. On a second 'click' the values collapse, and the functions move back to the left. There are also 'mouseover', 'mouseout', 'mousedown', 'mouseup', 'dragstart', 'dragmove', 'draw', and other actions you can use to create an event listener. (Zoe should add sample code to help a novice understand.)
In these next sections, we'll explore more deeply how users interact with the workspace.
Interacting with the Menu
Tweens (animation)
We went over briefly how values expand in the menu, but there's a little bit more to the story. The value/function buttons and nodes move across the menu using something called a Tween. Tweens allow for animation, and can be used to change the scale, color, or position of an object. Tweens animate using an easing, so that the change of state is looks smoother.
The Tweens for the menu are located in mist-gui-menuTweens.js
.
[to be continued]
Dragging From the Menu
Making Connections
Previewing Images
Undo/Redo
Things Zoe should think about
- Add links to sections of the KineticJS Wiki
- Snippets of code in here to clarify (with notes as to what file they appear in so that readers can see more depth)