Vision4Mac Documentation
Contents
Guidelines
I'm trying to collect some information here on how (and why) we do some things in our implementation so we can be consistent for things we use in multiple places.
1) make vs initialize
What should be done where and why? Where should events be registered? -> make (for no reason)
Object creation
The way classes will be created is somewhat special in Eiffel Vision. Take a look at EV_ANY (, EV_ANY_I)
Here's a bit of it:
--|---------------------------------------------------------------- --| Creation sequence for all Vision2 objects is like this: --| --| - Default_create is defined once in EV_ANY. --| - create_implementation is defined in descendants, default_create calls them --| - After it is created, initialize is called on the implementation, this will --| do extra setup work but need not be redefined in every descendant. --| (Probably redefined in EV_WIDGET_IMP but not too many other places) --| Next default_create calls initialize on Current. --| --| `default_create' must be called during creation to satisfy the invariant. --| The normal pattern is that default_create will produce a properly --| initialized default object and any special convenience creation features --| will call default_create then do their extra work. --| --| The postcondition of `default_create' checks `is_in_default_state', this --| returns True by default but should be redefined by decendants to check for --| proper initial results from class queries. --|---------------------------------------------------------------- frozen default_create is -- Standard creation procedure. --| Must be called exactly once during creation. do check not_already_called: not default_create_called --| Calling default_create twice is not --| allowed. This means that reusing --| objects is not allowed unless a --| special purpose feature is provided. end check application_exists: application_exists end default_create_called := True create_implementation implementation.initialize initialize ensure then is_coupled: implementation /= Void is_initialized: is_initialized default_create_called_set: default_create_called is_in_default_state: is_in_default_state end
Event Handling
Due to some limitations of the wrapper generater we are using event handling is not quite trivial, but here's what you have to do if you want to add a new event:
In the creation procedure you need to have something like this:
id := app_implementation.get_id (current) target := get_event_control_target_external(control) app_implementation.install_event_handler (id, target, {carbonevents_anon_enums}.kEventClassControl, {carbonevents_anon_enums}.kEventMouseDown)
This code first gets an application-wide unique ID. The system needs this to find out which object triggered the event.
??What exactly does the target specify??
And the last line says that we would like to catch all events with the given id that are of a specific type. (here: MouseDown Events on a Control)
on_callback
-> The on_callback function is getting really ugly, here is my idea what we could do about that: we could create a on_callback* function in the WIDGET_IMP class and then only do the selection (which event type goes to which widget?) in the on_callback function of APPLICATION_IMP. The specifics could then be done in the widget's function.
EV_CARBON_DATABROWSER
This class is an abstraction for Carbon's powerful DataBrowser [1] which is used by Vision controls like EV_TREE, EV_LIST and EV_MULTI_COLUMN_LIST.
This is only an experimental idea so far, but it seems to work out quite okay. So the idea I currently have is the following: It would be nice to have a heavily platform specific class which supports all the neat OS X features and interacts directly with the wrapper. The Vision conrols could then transparently use that other widget. Now, if an experienced user (a Mac user :)) wants to write something OS X specific, he could also use that class directly.