Thursday, 17 May 2012

New mg-desktop binaries: This time with 100% more framework and 100% less coding

Does this look familiar to you?

It looks a lot like this doesn't it?

That's because with the latest binary drop of mg-desktop we now have a full-blown framework (hereby known as the AppLayout Engine) which means you do not have to write a single line of code* to have a functional mapping application.

Introducing the AppLayout Engine

The AppLayout Engine was an idea that came about after my last mg-desktop related post.

I had begun experimenting with the componentization of the existing map functionality (Buffer, Measure, etc), such that you could drag and drop these components from the Visual Studio toolbox into your Form Designer and tie them into the (also dragged-and-dropped) map viewer control by only needing to set the appropriate properties in the VS property grid and not having to write a single line of code to do all this. You still needed to write some code to bootstrap the platform and load in the map, but everything else was done design-time in Visual Studio.

This worked so well that I then started doing the same thing for every map related piece of functionality (Zoom, Pan, etc), and through the magic of WinForms Control Extenders, we can tie menu items and toolbar buttons to components and be able to:
  • Invoke the associated component when clicked
  • Inherit label/tooltip/icons settings from the component
  • Automatically enable/disable itself based on certain component conditions (eg. A zoom button disables itself if there is no map loaded)
All this componentization has meant the Visual Studio toolbox for mg-desktop has become quite hefty:

So through this componentization work, it was now possible to assemble a map viewer in a completely declarative fashion by dragging and dropping the components you're interested in and tying them all together by setting the appropriate properties via the Visual Studio property grid. Building an mg-desktop application in this manner is probably a topic for another post.

It was at this point when I noticed that my components were functionally and conceptually similar to what you already know as Commands in the AJAX Viewer and Widgets in Fusion.

Given that the only code we had to write at this point is to initialize the mg-desktop platform and load the main application window, I figured what the hell? Let's go ahead and make this thing 100% declarative without writing a single line of code and thus the AppLayout Engine was born.

The AppLayout Engine consists of a skeleton Shell window (which serves as your application's main window), that you initialize with an AppLayout document.

The AppLayout document

If you understand WebLayout documents for the AJAX viewer or ApplicationDefinition documents for Fusion, then understanding AppLayout documents is very straightforward, because AppLayout documents are structurally and syntactically similar to both.
  • You declare a series of Component Definitions (ie. Your commands/widgets)
  • You specify the structure of your menus and toolbars and the declared components that they link to
  • You specify a Map Definition that is loaded by the viewer.
  • Customize various aspects of the viewer user interface.
A Component Definition looks like this in its simplest form:

For Components that expose properties, you can set them as well:

Notice the syntatical similarity to an AJAX Viewer command or Fusion widget. It wasn't intentional, I guess the stars aligned or something because the design naturally converged to something very similar to what we already have with the AJAX Viewer and Fusion.

So once you have authored up the AppLayout document, you feed the document to MgAppLayout.exe to have your own custom mapping application. You can take a look at the Sheboygan.AppLayout sample document that's included with this release as a comprehensive example of what an AppLayout document should look like.


MgAppLayout.exe is the front-end to the AppLayout Engine. It takes your AppLayout document, and does the following:
  • Parses and registers all the component definitions defined inside the document (and loads the relevant assemblies if these are external components)
  • Constructs the menus and toolbars based on the layouts specified
  • Loads the specified Map Definition and optionally invokes a registered component on startup
The MgAppLayout executable, in conjunction with an AppLayout document, gives you the final mapping application, just like your AJAX and Fusion viewer with their respective WebLayout and ApplicationDefinition documents.

Loading your AppLayout is simply a case of calling MgAppLayout.exe with the path to the AppLayout document you want to load. For example:

MgAppLayout.exe Sheboygan.AppLayout

If you do decide to run the sample Sheboygan.AppLayout, you will need to have the Sheboygan sample data set loaded. The sample AppLayout includes a Load Package component available under the File menu for this very purpose.

The default component set

For this release, this is the list of components that are available to you out of the box for assembling your AppLayout:

  • Buffer
  • Select Radius
  • Clear Selection
  • Copy Map image to clipboard
  • Generic Invoke+
  • Initial View
  • Load Map
  • Load Package
  • Measure
  • Pan
  • Select Polygon
  • Print Map
  • Generic Query
  • Quit
  • Refresh Map
  • Select
  • Theme
  • Tooltip Toggle
  • Viewer Options
  • Zoom In
  • Zoom Out
  • Zoom to Selection

+ The Generic Invoke component is basically our version of the InvokeURL command/widget and is actually used for the Visual Studio drag-and-drop scenario for a way to have your own custom code get called. It's not really usable within the AppLayout framework, but is listed above for completeness.

*Adding your own functionality

If you require custom functionality, you can create your own subclasses of MgComponent (or MgViewerComponent if you need to display a user interface in the Task Pane). This is once again conceptually similar to creating your own InvokeScript and InvokeURL commands in the AJAX and Fusion viewers.

Adding these components to your AppLayout just requires an extra Assembly element in the Component Definition.

The Assembly element is a relative path (from the path of MgAppLayout.exe) to the assembly containing that particular component implementation. This release contains a SampleExtension.dll which contains some external components (used by the sample Sheboygan.AppLayout). The SampleExtension source can be found here

So there you have it. Web Layouts have arrived for mg-desktop, allowing for desktop mapping applications with minimal to zero code required!

Download mg-desktop

No comments: