VA Smalltalk/IBM Smalltalk users: welcome to the border between Smalltalk and host resources. Traditionally in these latter two environments, if you use an object that allocates host resources of any kind, you must explicitly release those objects when you are done with them. If you don’t, the Smalltalk garbage collector will collect them when they are no longer referenced, but the resources will not be freed. The result is that your limited resources under your host windowing system will slowly degrade.One way to do deal with the problem is simply to send the message release to each GO when it is no longer referenced and will be garbage-collected, typically before you close your window or when you delete a GO.We implement a default finalize in GFGraphicObject that says:We can therefore be sure that every nodeGO will receive the message finalize, resulting in the release of host window system resources, when it is no longer held onto by anybody.You can create group and composite GO’s using the graphicObjects: method, supplying a collection of any GO’s as an argument. The following script illustrates the process. Also, refer to Creating a GO in the Network Editor as an example of a simple GFGroupGO.Locators are required when you use dependent GO’s. Dependent line type GO’s we supply include GFDependentLineGO and GFDependentOrthogonalPathGO. You may use locators if you specialize handle behavior, too. See the discussions in GFLocator and Specializing Handles in the Network Editor . For another example of dependent line usage, see the PsiSolid class used in the 3-D Figures demo, discussed in Dependent Lines.When you send the locator the message evaluate or asPoint, it will return the result of sending the message center to the polyline, aGO. Any message understood by the polyline is acceptable, as long as it returns a Point.This last expression will locate the first point in the polyline. It would only be useful with polylines, because all GO’s do not understand point:. This particular locator would be used to specify the location of a handle at a particular point on a polyline.There is a set of common protocol in GFGraphicObject to return points at specific locations in GO’s. Specific GO’s extend or override the protocol, as in the point: method of GFPolylineGO. Common protocol that all GO’s understand includes:
on: aGO
at: #offCenter:
with: 5@5
change: #translateBy:.An more elaborate very useful approach is to use a sense selector to compute a point from the mouse movement delta, and pass that result as an argument to the change selector. The protocol is:To take some action when a handle is invoked, you can handle the event #handleInvoked, which is triggered by the GFDrawingInterface.Whenever a GO needs handles (i.e., whenever it is selected), it triggers the event #generateHandles. If you do not handle the event, you will get the default set of handles for the GO. The default handles will work fine for initial development of an application, but they are almost guaranteed to be inappropriate for your end application. To specify the handles that are appropriate for your application’s GO’s, write a method that returns a collection of handles:Often, the state of an application determines what handles are appropriate. Also, since handles have so much behavior themselves, you may need to decide in your application logic what events handles will be handling, and what kinds of actions they will invoke. The typical way to deal with the problem is to write a handlesFor: method in your application. Then, when you create the GO, simply tell it:A position handle is the handle that is created when a GO is to be moved. While position handles are primarily used to move a GO, you may find other uses for them in your application. For example, you may want to send some message to another object whenever you let go of a the GO you are positioning. In that case, you could create the GFPositionHandle in a positionHandleFor: method in your application, and specify the releaseAction for it when you create the handle:Events are central to GF/ST architecture, so you’ll be using them a lot whether you know it or not. Refer to The GF/ST Event Model for more information on the basics of events. If you want to know when or why an event is triggered, refer to Events Explained in the Class Hierarchy, Protocol and Events section. In this section, we’ll try to anticipate some of the questions you might have about events when you start developing an application using GF/ST.We’re all used to looking at senders and implementors to track how messages flow through Smalltalk. When you use events, an event may be triggered in a method whose name is different than the event name, and it may result in execution of a method that is different than the event name. Consider the case when you use the #getMenu event to be able to provide your own menu to your drawing.If you look for implementors of getMenu, you will find that nobody implements it. When you look for senders of getMenu, you will find the methods that trigger the event. These methods are not sending the message getMenu, they are sending the message triggerEvent:, with #getMenu as the argument. Fortunately, “senders” locates all methods that use the symbol #getMenu.If you look at senders of networkMenu , you’ll only find the method where you set up the dependency; i.e., the method that does the when:send:to:. Let’s take a look at the #getMenu event to see what’s really happening.Examining senders of getMenu, we see the only interesting case is the menu method in GFGraphicObject:Now, if you put a breakpoint in your networkMenu method and popup a menu in the GFNetworkEditor example, this is the stack you’ll see:
|   |