How to create a standalone app
Creating a standalone app based on Glamorous Toolkit is as simple as opening an application specific window and closing the existing GT window. This can be achieved in just a few steps.
BlSpace
is responsible for displaying a scene in a separate window. Users can customise window's title or extent. To spawn a window send BlSpace>>#show
to an instance of the space.
aSpace := BlSpace new addChild: GtCreateStandaloneAppHowToGuide new helloWorldScene; extent: 800@600; title: 'Hello World'. aSpace show
By default, a space offers the possibility to close the window, but if all windows are closed, the image will still be running. If you want to associate the closing of the window with stopping the image, you can listen to the BlSpaceClosedEvent
and exit when it happens:
aSpace when: BlSpaceClosedEvent do: [ Smalltalk snapshot: false andQuit: true ].
The Glamorous Toolkit comes with a GtWorld
opened by default. When creating a standalone app based on GT we should close that window, which can be done in two steps.
In order to shutdown the process when a window is closed, we add a BlSpaceShutdownOnCloseListener
as an event handler to a BlSpace
. It should be removed before we close such spaces.
GtWorld allInstances do: [ :eachWorld | eachWorld removeShutdownListener ]
To close an opened window, it is enough to just send BlSpace>>#close
to an intended space.
GtWorld allInstances do: [ :eachWorld | eachWorld close ]
By design, GT checks for closed GtWorld
instances. And if the snapshotted image doesn't have any opened windows, then GT will spawn the Morphic World by attaching a renderer and a window to it.
The class hierarhy diagram for those renderers is described below.
view := GtMondrian new. view nodes umlClassShapeWithName: [ :each | each name ]; with: AbstractWorldRenderer withAllSubclasses. view edges fromCenterBottom; toCenterTop; connectFrom: #superclass. view layout tree levelDistance: 100. view
The Image is calling the next method to decide which renderer it will use, it is performing a search based on a class priority
and an isApplicableFor:
properties. AbstractWorldRenderer>>#detectCorrectOneForWorld:
Thus, you need to create you own subclass to override these properties, and you need to make sure, what your's class priority is greater than in others.
Evaluate the next snippet to create you own minimal subclass of the GtNullWorldMorphicRenderer
GtNullWorldMorphicRenderer subclass: #MyWorldRenderer. MyWorldRenderer class compile: 'priority ^ 200'; compile: 'isApplicableFor: aWorld ^true'.
Once the intended application window is opened and there are no more GT windows we can save the image (without quitting):
Smalltalk snapshot: true andQuit: false.