home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / programming / vista_1 / !Manual_manual_wins < prev    next >
Encoding:
Text File  |  1996-01-09  |  17.0 KB  |  483 lines

  1. <html>
  2. <title>Derived Windows</title>
  3. <h1>Derived Windows</h1>
  4.  
  5. The Window class provides facilities for the manipulation of basic windows.  In 
  6. order to provide more functional windows, it is necessary to define new
  7. classes based on the Window class.  The Window class has a set of virtual
  8. member functions which may be replaced by a derived class in order to
  9. enhance the functionality.
  10. <p>
  11. Vista includes a set of useful functional windows which may be used
  12. by the program.  Again, if the functionality of the windows defined i
  13. not sufficient, it is a simple matter of deriving a new class from
  14. them.
  15. <p>
  16. The derived windows supplied with Vista are:
  17. <p>
  18. <ul>
  19. <li><a href="file:wins#dbox">DialogueBox:</a> - An input/output device
  20. <li><a href="file:wins#grid">IconGrid:</a> - A window like a Filer
  21. <li><a href="file:wins#save">SaveBox:</a> - The standard Save box
  22. <li><a href="file:wins#prog">ProgramInfo:</a> - The standard Program Info box
  23. </ul>
  24.  
  25. <p>
  26. <hr>
  27. <p>
  28. <a name="dbox"></a>
  29. <h2>DialogueBox</h2>
  30.  
  31. The DialogueBox class implements a generic data input/output mechanism.
  32. It consists of a window which contains a set of <a href="file:wins#attr">attributes.</a>
  33. An attribute
  34. is a piece of data that may be modified by the user.  It appears as
  35. an icon in the window.
  36. <p>
  37. The Dialogue Box class is defined as:
  38. <hr>
  39. <pre>
  40.  
  41.    class DialogueBox : public Window, public Thread
  42.       {
  43.       public:
  44.          DialogueBox (Task *t, char *tname, int cancel = -1, int ok = -1, char *menu = 0) ;
  45.          virtual ~DialogueBox() ;
  46.          void click (int mx, int my, int buttons, int icon) ;
  47.          void key(int icon, int x, int y, int height, int index, int code) ;
  48.          virtual void show() ;
  49.          virtual void hide() ;
  50.          void run() ;
  51.          void close() ;
  52.          Icon *find_icon (int icon) { return NULL ; }
  53.          virtual void cancel(int button) ;
  54.          virtual void ok(int button) ;
  55.          void add_attribute (Attribute *attr) ;
  56.          void create_attribute (int iconnum, char *str) ;
  57.          void create_attribute (int iconnum, int &num) ;
  58.          void create_attribute (int iconnum, bool &value) ;
  59.          void create_attribute (int num_values, bool *values, ...) ;
  60.          void create_attribute (Icon *icon, char *str) ;
  61.          void create_attribute (Icon *icon, int &num) ;
  62.          void create_attribute (Icon *icon, bool &num) ;
  63.          void next_attribute (int icon) ;
  64.          void prev_attribute (int icon) ;
  65.       protected:
  66.          Attribute *attributes ;
  67.          Attribute *last_attribute ;
  68.          Icon *cancel_icon ;
  69.          Icon *ok_icon ;
  70.          ThreadSemaphore *waiting ;
  71.          int from_menu ;
  72.       public:
  73.          int cancelled ;
  74.       } ;
  75.  
  76. </pre>
  77. <hr>
  78. <p>
  79. It is derived from both the Window and Thread classes.  This means that it
  80. behaves like both classes.  It appears as a window on the screen, but also
  81. runs as a thread.
  82. <p>
  83. The normal operation for a dialogue box is for the user to display it on the
  84. screen, fill in some of the fields and click on either the OK or Cancel button.
  85. If the OK button is clicked, the attributes are committed, otherwise the values
  86. entered by the user are discarded.  It is normally necessary for the program
  87. to wait for the user to enter the data before it can continue.
  88. <p>
  89. The DialogueBox is created by use of the constructor.  This is supplied with the
  90. following parameters:
  91. <p>
  92. <ol>
  93. <li>The task
  94. <li>The name of the window template
  95. <li>The icon number for the 'Cancel' icon (-1 = none)
  96. <li>The icon number for the 'OK' icon (-1 = none)
  97. <li>The name of a menu (0 = none)
  98. </ol>
  99. <p>
  100. The dialogue box does not appear on the screen.  To do this, the 'show()'
  101. function must be called.  This causes the window to appear on the screen
  102. and the thread started.  The thread terminates when the user has closed the
  103. dialogue box by clicking on OK or Cancel (or by otherwise causing the
  104. window to close).  Usually the function which opened the dialogue box will
  105. be waiting the the user to fill it in.
  106.  
  107. <p>
  108. <a name="attr"></a>
  109. <h3>Attributes</h3>
  110.  
  111. When defining a dialogue box, a new class should be derived from the 
  112. DialogueBox base class.  This new class should contain all the attributes
  113. to be filled in by the user.  An attribute consists of 2 parts:
  114. <p>
  115. <ol>
  116. <li>A piece of data which will contain the value of the attribute
  117. <li>A user interface allowing the user to modify the value.
  118. </ol>
  119. <p>
  120. In order to tie these 2 parts together, you need to tell the DialogueBox
  121. class what they are.  The functions 'create_attribute' allow the dialogue
  122. box to be told of all the attributes it contains.
  123. <p>
  124. For example, consider the following dialogue box:
  125. <pre>
  126.  
  127. class PersonDetails : public DialogueBox
  128.    {
  129.    public:
  130.       PersonDetails(Task *t) : DialogueBox (t, "details", 1, 2)
  131.           {
  132.           strcpy (name, "") ;
  133.           age = 21 ;
  134.           create_attribute (3, name) ;
  135.           create_attribute (4, age) ;
  136.           }
  137.       ~PersonDetails() {}
  138.  
  139. // attributes
  140.  
  141.       char name[32] ;
  142.       int age ;
  143.    } ;
  144.  
  145. </pre>
  146. This dialogue box is created from a template called "details" and
  147. has an OK and a Cancel button.  The OK button has icon number 2 and the
  148. Cancel button is icon 1.
  149. <p>
  150. There are 2 attributes:
  151. <p>
  152. <ol>
  153. <li><b>name</b> - a string (icon number 3)
  154. <li><b>age</b> - an integral number (icon number 4)
  155. </ol>
  156. <p>
  157. The constructor initialises the values for the attributes and tells the
  158. DialogueBox class the icon number and data address of each.  The icons
  159. representing the attributes should be writeable icons so that the user
  160. may fill them in.
  161. <p>
  162. When the user clicks on the OK button, the values he has types in to the
  163. icons are copied into the attributes value.  If he clicks on Cancel, the
  164. values types in are ignored.  Also, clicking on Cancel sets a variable
  165. called 'cancelled' inside the DialogueBox and this can be interrogated
  166. by the caller.
  167. <p>
  168. Attributes may also be created manually by creating an object of a type
  169. derived from the type 'Attribute'.  This is an abstract class which has
  170. a number of specific attribute types derived from it.  The attribute
  171. types are:
  172. <p>
  173. <ol>
  174. <li><b>StringAttribute</b>    - the value is a string
  175. <li><b>BoolAttribute</b>      - the value is a boolean
  176. <li><b>IntegerAttribute</b>   - the value is an integer
  177. <li><b>SetAttribute</b>       - the value is a set of boolean values (array of words)
  178. </ol>
  179. <p>
  180. Once the attribute has been created it is automatically added to the dialogue box
  181. and deleted when the dialogue box is deleted.
  182. <p>
  183. <h3>Displaying a Dialogue Box</h3>
  184.  
  185. In order to cause a dialogue box to appear on the screen, the function
  186. 'show()' is called.  This opens the window and starts the thread running.
  187. The function that called 'show()' may then wait for the user to fill in
  188. and close the dialogue box by use of the 'sleep()' function.
  189. <p>
  190.  
  191. For example, if we wanted to open the PersonDetails dialogue box and
  192. wait for the user to fill in the name and age, we would write the following
  193. code:
  194. <pre>
  195.  
  196. void fill_in_details(Task *task)
  197.    {
  198.    PersonDetails details (task) ;     // create the DialogueBox
  199.    details.show() ;                   // show it on the screen
  200.    task->sleep (&details) ;           // sleep until it is closed
  201.    if (!details.cancelled)            // check if input was cancelled
  202.       {
  203.       // use the attribute values from details.
  204.       }
  205.    }
  206.  
  207. </pre>
  208. The destructor for the PersonDetails dialogue box will be called
  209. at the end of the function when the variable 'details' goes out
  210. of scope.
  211. <p>
  212. If the dialogue box is attached to a menu selection it will behave
  213. differently.  When Vista informs the task or window that the
  214. appropriate menu selection has been made, the menu handler function
  215. simply opens the DialogueBox.  If the user then moves the mouse
  216. back over the menu, or clicks outside the dialogue box, it will
  217. be closed.
  218. <p>
  219. The code for opening a dialogue box off a menu selection would be:
  220. <pre>
  221.  
  222. void MyWin::menu (MenuItem items[])
  223.    {
  224.    switch (items[0])
  225.       {
  226.       case DETAILS:
  227.          {
  228.          PersonDetails details (task) ;
  229.          details.show() ;
  230.          task->sleep (&details) ;
  231.          if (!details.cancelled)
  232.             {
  233.             }
  234.          break ;
  235.          }
  236.       case OTHERSELECTION:
  237.         ...
  238.       }
  239.    }
  240.  
  241. </pre>
  242.  
  243. The task will awaken when the dialogue box thread has terminated.  This
  244. will occur when the box closes for any reason.
  245. <p>
  246. <ul>
  247. <li><em>NOTE: the braces round the case limb for DETAILS are necessary.  This is
  248. because there is a variable created ('details') if the appropriate
  249. menu selection is made, but the destructor for this variable will
  250. be called when the variable goes out of scope.  This is fine if the
  251. menu selection was correct, but if another menu selection is made, the
  252. destructor will be called for a variable that hasn't been constructed.
  253. You could always get round this by using the 'new' and 'delete' operators
  254. to create the dialogue box, but this will have a performance hit as
  255. it will allocate the memory from the heap.</em>
  256. </ul>
  257.  
  258.  
  259.  
  260. <p>
  261. <hr>
  262. <p>
  263. <a name="grid"></a>
  264. <h2>IconGrid</h2>
  265.  
  266. This class behaves like a Filer window.  It holds and displays a set of
  267. icons in a grid formation.  It is derived directly from the <a href="file:window">Window</a>
  268. class and is defined as:
  269. <pre>
  270.  
  271.    class IconGrid : public Window
  272.       {
  273.       public:
  274.          enum flags
  275.             {
  276.             NONE,
  277.             NOSELECT = 0x01,        // click doesn't select icons
  278.             NODESELECT = 0x02,      // double-click doesn't deselect
  279.             SORTED = 0x04,          // keep icons sorted
  280.             } ;
  281.          IconGrid (Task *t, char *tname, int ticon, char *menu = 0) ;
  282.          IconGrid (Window *w, char *tname, int ticon, char *menu = 0) ;
  283.          virtual ~IconGrid() ;
  284.          Icon *insert_icon(char *text, void *ref = 0) ;
  285.          Icon *insert_icon(char *text, char *sprite, void *ref = 0) ;
  286.          void delete_icon (Icon *) ;
  287.          void delete_icon (void *ref) ;       // delete icon with ref
  288.          void open (int x0, int y0, int x1, int y1, int scx, int scy, int behind) ;
  289.          void click (int mx, int my, int buttons, int icon) ;
  290.          virtual void double_click (int mx, int my, int buttons, Icon *icon) ;
  291.          virtual void drag_icon (int mx, int my, int buttons, Icon *icon) ;
  292.          virtual void drag_selection (int mx, int my, int buttons, int x0, int y0, int x1, int y1) ;
  293.          Icon *find_icon (int icon) ;
  294.          virtual void select_all () ;       // select all icons
  295.          virtual void clear_selection() ;   // clear selection
  296.          void drag (int x0, int y0, int x1, int y1, int id) ;
  297.          void set_flag (flags flag) ;
  298.          void clear_flag (flags flag) ;
  299.          virtual void sort() ;               // sort the icons
  300.    
  301.       protected:
  302.          Icon *template_icon ;   // icon to copy
  303.          int num_icons ;         // number of icons in the window
  304.          int num_columns ;       // number of columns
  305.          int num_rows ;          // number of rows
  306.          int icon_width ;        // width of icons
  307.          int icon_height ;       // height of icons
  308.          int current_column ;    // current column number
  309.          int current_row ;       // current row number
  310.          Icon::buttontype template_button_type;
  311.          flags flag_set ;
  312.          int min_height ;        // minimum height of window in OS units
  313.    
  314.          void rearrange() ;      // rearrange the icons in the window
  315.          void init (int ticon) ;      // initialise
  316.       } ;
  317.  
  318. </pre>
  319. The IconGrid handles the rearrangement of the icons during resizing operations.
  320. It will keep the icons in a grid which is wide enough to fit in the
  321. window.  It can keep the icons sorted or unsorted depending on the
  322. value of a flag.
  323. <p>
  324. The window works by having a 'template icon' available at all times.  Every
  325. time a new icon is <a href="file:wins#insert">inserted,</a> the template icon is copied.  
  326. Usually the
  327. template icon will be of type 'Text and Sprite'.  The template
  328. icon is never visible.
  329. <p>
  330. When creating the IconGrid object, the template icon's number is
  331. supplied to the constructor.  This can be positioned anywhere in
  332. the window as it will be moved out of the way at startup.
  333. <p>
  334. If the icon grid is not resizeable and consists of one column, then 
  335. it behaves like a 'Scrolling List'.  
  336. <p>
  337. The user may select icons in the grid in exactly the same way
  338. as a in filer windows.  The icons can also be dragged out
  339. of the window.
  340. <p>
  341. Because the IconGrid is derived from the Windoe class, it inherits
  342. all the member functions and facilities provided by the Window
  343. class.
  344.  
  345. <p>
  346. <a name="insert"></a>
  347. <h3>Inserting and deleting icons</h3>
  348.  
  349. In order to insert a new icon into an IconGrid, the function 'insert_icon'
  350. is called.  This function has 2 versions available depending on whether the
  351. icon is to have the same sprite as the template icon or not.  A new icon
  352. is created by taking a copy of the template icon and moving the new
  353. icon to the appropriate position.  The icon created is returned to the
  354. caller, so the program may write to the icon text (using the Icon::print()
  355. function) or change the sprite (using the Icon::change_sprite() function)
  356. <p>
  357. An icon is deleted by using the 'delete_icon' function.  You can either
  358. delete an icon given a pointer to it (returned from 'insert_icon')
  359. or you may delete it using its user reference.  If it is deleted
  360. using the user reference, the first icon found whose user reference
  361. matches that passed will be deleted.
  362.  
  363. <p>
  364. <hr>
  365. <p>
  366. <a name="save"></a>
  367. <h2>SaveBox</h2>
  368.  
  369. A SaveBox class is a DialogueBox that allows the user to save
  370. something by dragging an icon to a filer window or another application.
  371. It displays a window containing a sprite that may be dragged and
  372. a writeable icon.
  373. <p>
  374. The SaveBox is defined as:
  375. <pre>
  376.  
  377.    class SaveBox : public DialogueBox
  378.       {
  379.       public:
  380.          SaveBox (Task *t, char *tname, char *path, char *leafname, DataSave *saver) ;
  381.          ~SaveBox() ;
  382.          void drag (int x0, int y0, int x1, int y1, int id) ;   // end of drag operation
  383.          void ok(int button) ;
  384.       protected:
  385.          DataSave *saver ;
  386.          char path[256] ;
  387.          Icon *file_icon ;
  388.          Attribute *name ;
  389.       } ;
  390.  
  391. </pre>
  392. As can be seen, it is derived from the DialogueBox class and therefore
  393. inherits all the facilities of it.
  394. <p>
  395. The SaveBox is created using the constructor.  This takes the following
  396. parameters:
  397. <p>
  398. <ol>
  399. <li>The <em>task</em>
  400. <li>The name of the <em>template</em> to use
  401. <li>The <em>full path</em> to save to if it exists.  If there is no path, this should
  402.       be an empty string (not a NULL pointer, but "")
  403. <li>The name of the <em>leaf</em> to use if there is no path supplied.
  404. <li>A pointer to an <em>object</em> to actually do the saving.
  405. </ol>
  406. <p>
  407. The SaveBox will invoke functions in the object called the 'saver' and
  408. passed at the last parameter to the constructor.  This object is
  409. specific to the data being saved and is derived from the DataSave
  410. class.  The user can invoke a save operation in 2 ways:
  411. <p>
  412. <ol>
  413. <li>He can drag the sprite to a filer window
  414. <li>He can click on the 'Save' button in the SaveBox.
  415. </ol>
  416. <p>
  417. Both these operations result in a call to the saver.  The DataSave class is defined:
  418. <pre>
  419.  
  420.    class DataSave : public Channel
  421.       {
  422.       public:
  423.          struct saveackdata
  424.             {
  425.             int window ;
  426.             int icon ;
  427.             int x ;
  428.             int y ;
  429.             int est_size ;
  430.             int filetype ;
  431.             char pathname[1] ;
  432.             } ;
  433.          DataSave(Task *task) ;
  434.          virtual ~DataSave() ;
  435.          virtual void receive (int action, int task, int my_ref, 
  436.                                int your_ref, int data_length, void *data) = 0 ;
  437.          int accept (int your_ref) ;   // accept a message?
  438.          virtual void save (int window, int icon, int x, int y, char *leaf) ;
  439.          virtual void save (char *path) ;
  440.          void datasave (int window, int icon, int x, int y, int est_size, int filetype, char *leaf) ;
  441.          void datasaveack (int my_ref, saveackdata *data, char *path) ;
  442.          void dataload (int task, int my_ref, int your_ref, int data_length, void *data) ;
  443.          void dataloadack (int task, int my_ref, int your_ref, int data_length, void *data) ;
  444.       protected:
  445.          int my_ref ;
  446.       } ;
  447.  
  448. </pre>
  449. The important functions are the 2 'save' functions.  The first save function
  450. is called when the user drags the icon to a filer window (or another
  451. application).  The second function is called when the user has clicked on
  452. the 'Save' button and a full path is available.
  453. <p>
  454. For further information see the section on <a href="file:channel">Communications</a>.
  455.  
  456. <p>
  457. <hr>
  458. <p>
  459. <a name="prog"></a>
  460. <h2>ProgramInfo</h2>
  461.  
  462. This is a simple dialogue box which displays information about the program being
  463. run.  When the dialogue box is created, you pass a version string to it and
  464. tell it what the icon number for the version icon is.  The template for the
  465. window should have the other information already contained in it.
  466. <p>
  467. The class is simply defined as:
  468. <pre>
  469.  
  470. class ProgramInfo : public DialogueBox
  471.    {
  472.    public:
  473.       ProgramInfo (Task *t, int version_icon, char *version) ;
  474.       ~ProgramInfo() ;
  475.    private:
  476.       Icon *version ;
  477.    } ;
  478.    
  479. </pre>
  480. If other fields are required in the dialogue box, other classes may be derived
  481. from this one.
  482.  
  483.