Published: 04-07-2016
Here the functionality of the full blown design app is discussed. It now includes javascript panels and the makeit-processor library.
Overview
The new look design app is the full version that these blogs have been incrementally moving towards. The app now has javascript panels for writing CAD and CAM and code. This code is sent to an Iframe where it is executed with the makeit-processor library. The result is render-able geometry and G-code. The new layout looks like:
New look design app layout
Embedding iframe
Embedding the Iframe is straightforward. An iframe element is palced in the HTML template:

<iframe id="processor" src="http://localhost:3002">
</iframe>

Messages can then be sent to the iframe using postMessage():

var domain = 'http://localhost:3002';
var iframe = document.getElementById('processor').contentWindow;
var message = { 
	type: 'code',
	code: this.cad + "\n" + this.cam 
}
iframe.postMessage(message, domain);

An event listener can be set up in the iframe page to receive the message:

window.addEventListener('message', function(event) {
	
	if (event.origin !== 'http://localhost:3001') return;
	// Do something with message
	
}, false);

Sizing the page dynamically
Making the best use of space requires the editors to span near enough the entire length of the page. They must also line up with the panels inside the iframe. The iframe's height must also be set. Using CSS and and a percentage based layout does not work well with the editors which must be set in pixels. The heights must therefore be calculated and set using javascript.
Creating panels
It would be impossible to display all the renderings and data the user might generate using the makeit-processor library. Having a fixed layout would also limit usability. To get around these problems generic panels are set up for the user to manipulate (panel_top and panel_bottom). Both panels are half the height of the iframe. Users can call methods like panel_top.addTab(something_renderer) to display different renders or code snippets. The panels can be used to add multiple tabs allowing for highly flexible viewing of geometry or G-code.
Refactoring to typescript namespaces
Initially the makeit-processor used typescript 'modules' just like all the previously written code. This created a problem when using eval() on user CAD and CAM code. Typescript creates namespaced variables for modules when converting to raw javascript. These are different from the original class names and so code written by the user would not execute properly (using eval()). The problem was solved by switching to typescript 'namespaces'. Here the files are referenced rather than explicitly imported or exported (internally, I believe it just uses iffys to namespace segments). The switch required a separate gulp process for the makeit-processor directory. All the files are compiled into one large 'makeit.js' file and manually linked in the head of the HTML page. As an added side effect, it makes it easy to swap in and out different 'makeit-processor' versions on the fly. It also decouples it from the main app.js file that 'runs' the iframe.
During the refactoring more modular layouts of the CAD and CAM operations were created:
Makeit modular layout
The modular layout aimed to improve the usability for the user while making it easier to manage for future testing. All the complicated converters are hidden and exposed through grouped interfaces. For example, instead of having to explicitly call the profile G-code converter and add the result to Gcode(), one can now call Gcode().addProfile(). The Gcode() class effectively aliases the conversion calls. This should make it more intuitive for users.
Adding a side menu
A side menu with nice big icons seemed like an elegant way of providing functionality to the user. The main buttons consist of 'update', 'save', 'new' and 'plugins'.
Update - sends the code to the iframe, effectively triggering a reset and reprocessing of all the code.
Save - will eventually save a version of the code, corresponding to a 'commit'. Unsaved code will be kept in memory on the redis server.
New - will be used to create a new part or project
Plugins - will be used to load plugins/macros making it easier to build more complex parts.
Full-screen panels
One of the aims was to make multi-tab/multi-window editing possible. Here, multiple windows of the same part can be opened on different screens or even different computers. Each quadrant can then optionally be made full-screen to aid in productivity. It requires editor data to be kept in sync and the ability to dynamically change the layout. To change the layout individual full-screen buttons are placed over each quadrant. When clicked the size and display mode of each panel is calculated. Angular variables are changed and the bindings take care of updating the page.
Unfortunately it's not quite that straight forward. We can do all of that with the host page but not the iframe. To modify the iframe we have to send a message and eval() code in the same way the user does. Essentially a special method on the Panel class, setHeight() is called. This method changes the height of the panels. When the close button is pressed all the panel and editor values are reset to their normal values.
Full-screen buttons
Multi-window/tab functionality
It order to offer multi-window functionality the CAD and CAM code must be kept in sync across browser windows/tabs. Websockets are used to accomplish this. When a value changes on window 1, the new value is sent via websockets to the server. The server then broadcasts this value to all the other connections, who update their on page value as required. This rather crude implementation works for the simplified app being developed at this point in time. Eventually redis pubsub will be used so that CAD CAM code can be synced across multiple servers and separated by channels.
Multi-window/tab functionality