home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / dreamscape / docs / Dreamscape / Docs / Notes < prev    next >
Encoding:
Text File  |  1996-09-28  |  12.5 KB  |  312 lines

  1.                           Dreamscape: notes to users
  2.                          ============================
  3.  
  4. Contents
  5. --------
  6.  - Dreamscape pseudo exception handling
  7.  - Creating gadgets
  8.  - Using SaveAs windows
  9.  - Returning menus from pop up gadgets
  10.  - ColourDBox problems
  11.  - Showing and hidden handlers
  12.  - Multi-clicking/dragging
  13.  - Graphics renderers
  14.  - Errors during redrawing
  15.  - Pane handling
  16.  - Document and view classes
  17.  - Accessing low-level features
  18.  - Graphics and font handling
  19.  - The iconise() method
  20.  - Using Dreamscape from C
  21.  - Deferred delete templates
  22.  
  23.  
  24. Dreamscape pseudo exception handling
  25. ------------------------------------
  26. Since Acorn's CFront-based C++ compiler doesn't support exception handling,
  27. I've had to write a pseudo exception handler for Dreamscape. Note that this
  28. is by no means a proper exception handling system. It doesn't free up stack
  29. chunks that are no longer needed after an exception, and it doesn't call the
  30. destructors of objects in the stack. It also only handles RISC OS errors.
  31.  
  32. The main purpose of this exception handling system is to stop an error from
  33. causing the program to die with a postmortem message. It will also catch the
  34. 'illegal address' and 'illegal instruction' exceptions and allow the program
  35. to continue running. (Remember that these errors might be caused by the
  36. program corrupting its data, in which case carrying on might not be a good
  37. idea, although the user still has a choice and it may be safe to carry on
  38. anyway).
  39.  
  40. To use the exception handler, use a #include "x.h" line at the beginning of
  41. the file. To catch an error from a non-x-form SWI or from x_throw(), use a
  42. structure like this:
  43.  
  44.   x_try {
  45.     ... // errors occurring in this block will be caught
  46.   }
  47.   x_catch(error) {
  48.     ... // handling code here
  49.   }
  50.  
  51. The x_try block must always be followed by an x_catch block. To throw an
  52. exception, you use the x_throw() function. This comes in three forms:
  53.  
  54.   void x_throw(RISCOSError *error);
  55.   void x_throw(const char *message);
  56.   void x_throw();
  57.  
  58. The first version throws an exception from an actual RISC OS error block. The
  59. class RISCOSError is a RISC OS error block and can be cast from or to OSLib's
  60. os_error struct if necessary. The difference between the two is that
  61. RISCOSError is a C++ class and provides extra functions and constructors:
  62.  
  63.   class RISCOSError {
  64.   public:
  65.     RISCOSError();
  66.     RISCOSError(const char *m);
  67.     RISCOSError(const char *m, unsigned n);
  68.   
  69.     operator const char*() const;
  70.     operator char*();
  71.   
  72.     unsigned number;
  73.     char message[252];
  74.   };
  75.  
  76. The second version throws an error created from the given textual message,
  77. using an error number of 0. The last version of x_throw() throws the last
  78. error that occurred; useful for nested exception handlers.
  79.  
  80. Two functions in x.h provide standard error messages. x_msg_memory() returns
  81. a string with the message "Not enough memory". x_msg_internal() is passed a
  82. string and returns it converted into the form "Internal error (...)".
  83.  
  84. Lastly, if you create an error block without using new, and the block's scope
  85. is only in the function that created it, use x_buffer_error to copy it into
  86. an internal block and use the block returned.
  87.  
  88.  
  89. Creating gadgets
  90. ----------------
  91. If you create a gadget by using Window's get_gadget method, you must be
  92. careful that a gadget of the type you want is created, and not an object of
  93. the base Gadget type. For example, you might use the following in a
  94. constructor to make a reference to an action button gadget:
  95.  
  96.   button(*(ActionButton *) window->get_gadget(0))
  97.  
  98. Then you might use the following to assign a handler that is executed when
  99. the button is clicked:
  100.  
  101.   button->click_handler = &my_command;
  102.  
  103. If the action button code does not get linked with your program, an object
  104. the type ActionButton will not be created, but the program will quite happily
  105. cast the object to that type, and then assign the handler to somewhere
  106. outside the object, possibly corrupting something important.
  107.  
  108. You've just got to make sure that the action button code *does* get linked.
  109. If you call an action button method that isn't inlined, you'll be okay.
  110. Otherwise, you need to add "Dreamscape:gadgets.o.actionbutton" into the list
  111. of files to link.
  112.  
  113. The same also goes for Toolbox objects, although you will get an error if you
  114. try to create an object from a Toolbox class that is not recognised.
  115.  
  116.  
  117. Using SaveAs windows
  118. --------------------
  119. The SaveAs code in Dreamscape will happily support RAM transfers, so you can
  120. enable "Supports RAM transfers" in the objects in the Resource file. You
  121. should always select "Client participates".
  122.  
  123. However, if the handler you attach to the SaveAs object is a FileSaver not
  124. just a Saver, "Supports RAM transfers" should not be selected. FileSavers are
  125. there so you can save directories (as MakeApp does) or, for example, so you
  126. can call an external program to do the saving. Most of the time you should
  127. use a Saver object to do the saving.
  128.  
  129. Dreamscape also has a small patch that allows you to type spaces in the
  130. filename field of SaveAs windows. These spaces will be converted to hard
  131. spaces when you save the file - the patch is completely transparent.
  132.  
  133.  
  134. Returning menus from pop up gadgets
  135. -----------------------------------
  136. The get_menu() method in the PopUp class doesn't work - I think this might be
  137. a flaw in OSLib or the Window module, although I haven't had a chance to
  138. investigate this. A workaround is to create the menu manually and use
  139. set_menu() to assign it to the PopUp object.
  140.  
  141.  
  142. ColourDBox problems
  143. -------------------
  144. get_colour() doesn't appear to work (Toolbox bug I think). I doubt
  145. get_colour_model() works either. From what others have said on
  146. comp.sys.acorn.programmer, the ColourDBox module seems to be extremely buggy.
  147.  
  148.  
  149. Showing and hidden handlers
  150. ---------------------------
  151. The showing and hidden handlers are only called if the object is not already
  152. showing or hidden respectively. Unlike some handlers, you can only register
  153. one of each - this is for simplicity. If you want to register more, you can
  154. attach a MultiCommand object and add handlers to that.
  155.  
  156.  
  157. Multi-clicking/dragging
  158. -----------------------
  159. Dreamscape will handle triple-clicks and other numbers of clicks for you. It
  160. will also handle 'double-drag's, where the user clicks once and then drags on
  161. the second click (Zap and Edit use this to drag a selection of whole words).
  162.  
  163. You will have to set the click type of the button gadget or window work area
  164. appropriately for this to work. Some times you will not want triple clicks to
  165. be detected. Also, for double-dragging to work, the button type used must not
  166. have its own double-click handling, and so the double-pointer will not
  167. appear.
  168.  
  169. This list shows how some button types are handled:
  170.  
  171. 6   Click/drag          Multi-click and multi-drag handling
  172. 10  Double/click/drag   Multi-click handling
  173.  
  174.  
  175. Graphics renderers
  176. ------------------
  177. These will auto-load the relevant modules in the graphic class's constructor,
  178. so you don't need to bother loading them in the app's !Run file.
  179.  
  180. You can change the quality for graphic objects. This is how different
  181. graphics respond to quality settings:
  182.  
  183. DrawFile     This ignores the quality setting, as the DrawFile module only
  184.              displays draw files one way.
  185.  
  186. JPEGImage    Below 0x700000 (normal), no dithering is used. From 0x7000000
  187.              and below 0x9000000 (anti-aliased), fast inaccurate dithering
  188.              is used. From 0x9000000 upwards, slow accurate dithering is
  189.              used.
  190.  
  191. Graphics object files must be explicitly linked into programs before they
  192. will automatically recognise graphics files for you.
  193.  
  194.  
  195. Errors during redrawing
  196. -----------------------
  197. If an error occurs while a window is being redrawn, the redraw will stop and
  198. the error will be reported. If the error box disappearing causes another
  199. redraw request, the library will not attempt to redraw the window the second
  200. time.
  201.  
  202.  
  203. Pane handling
  204. -------------
  205. For Dreamscape-based pane handling to work (as opposed to Toolbox-based pane
  206. handling), the auto-open and auto-close options of the window must not be
  207. selected.
  208.  
  209. Dreamscape will open and close windows for you anyway if these are not set,
  210. but it would probably be slightly more efficient to leave them selected if
  211. you are not using panes, as the library's handler code would not have to be
  212. called.
  213.  
  214. Dreamscape also provides a transparent fix for the problem that multi-tasking
  215. stops when dragging windows with panes with Select. However, it will not fix
  216. this for panes that are handled by the Toolbox.
  217.  
  218.  
  219. Document and view classes
  220. -------------------------
  221. Note that these classes (in the document.h header) aren't tested at all - I
  222. haven't actually used them yet. They also aren't intended to be used for
  223. absolutely all cases of documents with multiple views, just for documents
  224. with multiple scalable views. You wouldn't use them for a plain text editor
  225. like Edit, for example.
  226.  
  227. Don't use the Document and Views classes yet, because they are going to have
  228. a complete redesign in a future version of Dreamscape.
  229.  
  230.  
  231. Accessing low-level features
  232. ----------------------------
  233. Dreamscape provides various hooks to allow the programmer to access things at
  234. a lower level. For example, you can find out the underlying Toolbox object of
  235. a window with get_toolbox_object(). This returns a ToolboxObject object which
  236. converts to OSLib's toolbox_o type.
  237.  
  238. You can also intercept Wimp messages and Wimp events that are already claimed
  239. by other classes. By registering a handler after the other class does so, you
  240. are guaranteed to receive the message first. You can use Dreamscape's
  241. low-level implementation of the data transfer protocol within other
  242. protocols.
  243.  
  244. Intercepting Toolbox events is harder as Dreamscape's handling system for
  245. these events is simplified to make it more efficient. If you need to patch
  246. something it is best to do it by modifying Dreamscape itself.
  247.  
  248. The Wimp event, Wimp message and Toolbox event handlers can now be used from
  249. C as well as C++. The Wimp event handler has been re-written to be more
  250. efficient, so it might be worthwhile using that in your programs even if you
  251. don't use any other features of Dreamscape! All the handlers have been
  252. written to be safe - the dispatchers can be called while they are threaded
  253. and handlers can be deregistered while the dispatcher is threaded.
  254.  
  255.  
  256. Graphics and font handling
  257. --------------------------
  258. Dreamscape does not yet provide any handling for graphics primitives such as
  259. line drawing with the Draw module or plot commands, nor does it provide any
  260. font plotting facilities. For now you will have to write code for this
  261. yourself by calling SWIs using OSLib.
  262.  
  263. Another thing about font rendering is that when I implement it I am
  264. definitely going to add support for other alphabets. If that means rewriting
  265. FontMenu and FontDBox to do it, then so be it!
  266.  
  267.  
  268. The iconise() method
  269. --------------------
  270. BaseWindow's iconise() method only half works at the moment. When it iconises
  271. a window, it doesn't give the icon the correct name. In the future, this
  272. will be fixed, and I will add methods that allow you to set a window's
  273. iconised title and icon.
  274.  
  275.  
  276. Using Dreamscape from C
  277. -----------------------
  278. Dreamscape's event handling routines and other routines can be used from C.
  279. However, some C 'features' complicate things. Unlike with C++, structures in
  280. C occupy their own namespace and types can't be re-typedef'd. This makes
  281. using OSLib structures without first #including the appropriate header a real
  282. pain - the OSLib headers are too large to #include them from Dreamscape
  283. unnecessarily.
  284.  
  285. If you want to access the contents of OSLib structures you must #include the
  286. relevant OSLib header yourself (in both C and C++). However, in C you must
  287. #include the OSLib headers *before* you #include the Dreamscape headers, or C
  288. will start giving nonsensical errors and will start getting confused about
  289. whether structure types match.
  290.  
  291.  
  292. Deferred delete templates
  293. -------------------------
  294. Sometimes you have to delete an object from within one of that object's
  295. member functions (usually a handler function). This can be done with "delete
  296. this", which is perfectly legal, although it can be dangerous - the object
  297. might be accessed after it has been deleted.
  298.  
  299. A safer way of doing this is to mark the object as deleted and delete it
  300. later. This is what the defdelete.h header does - it will delete objects on
  301. the next null Wimp event.
  302.  
  303. This header provides two template functions:
  304.  
  305. template<class Type> void deferred_delete(Type *object);
  306. template<class Type> void deferred_delete_a(Type *objects);
  307.  
  308. The first function will delete a single object (equivalent to "delete
  309. object"), whereas the second will delete an array of objects (equivalent to
  310. "delete [] objects"), although in practise the two do the same thing (the
  311. second type of delete is specified by C++).
  312.