
















                         PICASSO _W_i_d_g_e_t _W_r_i_t_e_r'_s _G_u_i_d_e


                          (_V_e_r_s_i_o_n _1._0 _J_u_l_y _1_5, _1_9_9_0)
























                        Computer Science Division - EECS
                            University of California
                               Berkeley, CA 94720

























                         PICASSO _W_i_d_g_e_t _W_r_i_t_e_r'_s _G_u_i_d_e|-
                         (_V_e_r_s_i_o_n _1._0 _A_u_g_u_s_t _2_4, _1_9_9_0)

                        _S_t_e_v_e _S_e_i_t_z _a_n_d _P_a_t_r_i_c_i_a _S_c_h_a_n_k

                        Computer Science Division - EECS
                            University of California
                               Berkeley, CA 94720



                                    _A_b_s_t_r_a_c_t


          PICASSO  is  an  object-oriented  graphical  user  interface
          development  system.  This manual describes how to write new
          widgets that can be used in the system.






























          ____________________
             |- This research was supported  by  the  National  Science
          Foundation (Grants DCR-8507256 and MIP-8715557), 3M Corpora-
          tion, and Siemens Corporation.















                                       1
                                  INTRODUCTION

          ____________________________________________________________________________________________________________________________________________________________________________________

          Overview


                         When do you need to write a new widget?  Many
                         PICASSO  programmers will never need to write
                         a widget. In general, you need  to  design  a
                         widget  whenever you wish to create an inter-
                         face which can't be done well with a combina-
                         tion of predefined widgets.

                         The need to create  a  new  widget  generally
                         arises in two cases:

                         o+    you're designing  an  application  which
                              does   fancy   or  nonstandard  graphics
                              operations

                         o+    you wish to design a new type  of  look-
                              and-feel  that  predefined widgets don't
                              provide.

                         The task of implementing a widget belongs  to
                         the widget-writer.  This document is provided
                         for the widget-writer, and should be read  in
                         conjunction   with   the   PICASSO  REFERENCE
                         MANUAL.  Most aspects of application  writing
                         are covered in the PICASSO REFERENCE MANUAL.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Widgets
          and Gadg-
          ets




                         Almost  all  input  and  output  behavior  of
                         PICASSO  is implemented through two interface
                         abstractions:  gadgets and widgets.  A gadget
                         is  an abstraction for output behavior (e.g.,
                         text-gadget).  A widget  is  the  abstraction
                         for  input  behavior.  Many interface objects
                         in  PICASSO  need  both  output   and   input
                         behavior.   To accomplish this in PICASSO, we
                         factor the output code into a gadget and  the
                         input code into a widget, and combine the two
                         classes  into  an  interface   object   which
                         "inherits"  the  behavior  of both the gadget
                         and the widget.  More  specifically,  PICASSO
                         has  a  pre-defined  class named "gadget" and
                         another class  named  "widget".   Suppose  we
                         want  to  implement a text-editor widget.  We
                         could first implement a text-gadget to simply
                         draw  a specified text-string.  Then we could
                         write  a  text-widget  that  handles   input.











                                                          INTRODUCTION


                         Finally,  we could write a text-editor-widget
                         that  inherits  from  text-gadget  and  text-
                         widget as shown below:


                                       widget                gadget
                                           \                    /
                                             \                 /
                                         text-widget      text-gadget
                                                \              /
                                                  \           /
                                               text-editor-widget



                         This scheme works but  it  is  cumbersome  to
                         implement.   The problem involves duplication
                         and coordination of  code.   The  text-widget
                         and  text-gadget  abstractions  are not truly
                         independent - the programmer must  make  sure
                         that  attributes in text-widget have the same
                         names  and  definitions  as  those  in  text-
                         gadget.   Furthermore,  the text-widget class
                         is useless by itself.  A better  scheme  that
                         is  used  in most PICASSO widgets is to elim-
                         inate  the   text-widget   class   altogether
                         (without  eliminating  text-gadget,  which is
                         useful in itself), as shown in the  following
                         diagram:


                                     widget               gadget
                                         \                  /
                                          \           text-gadget
                                           \              /
                                            \            /
                                          text-editor-widget



                         (The actual PICASSO text-widget  is  designed
                         differently  from  what  is shown above.  See
                         the  PICASSO  REFERENCE   MANUAL   for   more
                         details.)

                         This example illustrates how widgets are usu-
                         ally  implemented.   In  some cases, particu-
                         larly if the widget is  very  simple,  inter-
                         mediate  classes  such  as text-gadget can be
                         eliminated. In that case, the widget inherits
                         directly  from the widget class.  The PICASSO
                         button widget  is  designed  this  way.   For



          PICASSO Widget-Writer's Guide                            1-3







                                                          INTRODUCTION


                         convenience, we use the term "widget" to mean
                         an interface object with both input and  out-
                         put  behavior.  This fits with the model sug-
                         gested in the diagram above.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Contents


                         The remainder of this guide is  organized  as
                         follows.    Chapter   2   describes  widgets.
                         Chapter 3 describes how to  write  a  widget.
                         It  includes  a  full  definition  of  sample
                         widget and a short discussion  of  the  func-
                         tions  that implement the widget abstraction.
                         Chapter 4 describes  the  predefined  methods
                         that  are  used  to write widgets.  Chapter 5
                         describes the attributes common to all  widg-
                         ets   (i.e.,   inherited   slots   in  widget
                         objects).  Chapter 6  describes  how  widgets
                         receive   and   process  events.   Chapter  7
                         describes the basic utilities available to do
                         graphic  output  with  widgets.   And lastly,
                         chapter 7 describes how to make complex widg-
                         ets (i.e., collection widgets).
































          PICASSO Widget-Writer's Guide                            1-4







                                                          INTRODUCTION


                                               2
                                        WHAT'S A WIDGET

          ____________________________________________________________________________________________________________________________________________________________________________________

          Overview


                         This chapter describes widgets and  how  they
                         are used in PICASSO.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Widgets


                         Widgets provide  the  interface  between  the
                         user  and the program. All interaction (input
                         and output) is performed through widgets.  To
                         make   the  job  easier  on  the  programmer,
                         PICASSO  provides  more  than  30  predefined
                         widgets  and  gadgets  for  a variety of pur-
                         poses.  Different types of widgets are needed
                         for different types of input/output behavior.
                         Usually, some combination of  these  existing
                         widgets  will  produce a reasonable interface
                         for any PICASSO application.

                         PICASSO's widget abstraction  is  extensible,
                         meaning  that any newly defined widget can be
                         completely incorporated into the system.  The
                         new widget can be used in place of any prede-
                         fined widget. Furthurmore, PICASSO  makes  no
                         internal distinction between widgets that are
                         "predefined" (distributed  with  the  system)
                         and those that are added on later.


                         PICASSO predefined widgets range from ex-
                         tremely  simple to relatively complex.  A
                         simple widget is one that allows only ru-
                         dimentary  input behavior (if any) and is
                         intuitive in function.  For instance, the
                         most  widely  used  widget  in PICASSO is
                         also the simplest:  the button.















          PICASSO Widget-Writer's Guide                            1-5







                                                       WHAT'S A WIDGET



                         In its simplest form, a  button  has  one
                         output  value (a string or image) and one
                         device for input (a  pointer  click).   A
                         complex  widget  is more intricate in its
                         input/output behavior  and  is  generally
                         less intuitive in function. Complex widg-
                         ets are typically tailored to a  particu-
                         lar  type  of  use  so  they  appear in a
                         smaller variety of applications  than  do
                         simple  widgets.  An example of a complex
                         widget is  a  table-field.   Table-fields
                         can  be used to display data in a tabular
                         format (rows and columns).


























                         Because each cell of a table can contain  any
                         type of widget, the input behavior of a table
                         is very complex.  Tables are extremely power-
                         ful  in this respect.  However, tables can be
                         extremely confusing, so proper care  must  be
                         taken  to  design  a  clean interface for the
                         user.

                         Naturally, widgets which are simple  or  com-
                         plex for the user are going to be correspond-
                         ingly simple or complex for  the  application
                         writer  and widget writer. While a button can



          PICASSO Widget-Writer's Guide                            2-6







                                                       WHAT'S A WIDGET


                         be fully specified in two attributes,  tables
                         need  between  2-20  attributes  to  be fully
                         described. The burden of specifying  all  the
                         attributes   of   a   widget   lies   on  the
                         application-writer.


















































          PICASSO Widget-Writer's Guide                            2-7







                                                       WHAT'S A WIDGET


                                               3
                                        A SAMPLE WIDGET

          ____________________________________________________________________________________________________________________________________________________________________________________

          Overview


                         This chapter gives an overview of the process
                         of  writing  a  widget, and briefly describes
                         each task involved.  Later  chapters  contain
                         complete descriptions of these steps.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Widget
          Definition



                         In this chapter we will go through  the  pro-
                         cess  of  creating a widget.  We will explain
                         each step and show the actual widget code.

                         The first step is to design  the  widget.  In
                         some  cases,  the  design  procedure  can  be
                         incremental  (e.g.,    incrementally   adding
                         functionality),  but  you  should always know
                         what a widget will do before sitting down  to
                         write  it.   If you are writing a gadget that
                         will be used by a widget through inheritance,
                         it is a good idea to decide ahead of time how
                         the interface between the gadget  and  widget
                         components  will work. This avoids the hassle
                         of  having  to  rewrite  the  gadget  to  fit
                         together with the widget.


























          PICASSO Widget-Writer's Guide                            2-8







                                                       A SAMPLE WIDGET



                         In  this  chapter,  we   will   write   a
                         "bitmap-editor".     The    design    and
                         representation  is   as   follows.    Our
                         bitmap-editor provides a graphical inter-
                         face for viewing and  editing  a  bitmap.
                         The bitmap is represented internally as a
                         two-dimensional array of bits.  A bit  is
                         either 0 or 1.  The bitmap is represented
                         on the screen as a  two-dimensional  grid
                         of  squares.  Each square can have one of
                         two colors.  All squares are of the  same
                         size, which can be dynamically changed by
                         the user -  when  the  user  resizes  the
                         bitmap-editor   window,  each  square  is
                         grown  or  shrunk  proportionately.   All
                         editing   is  done  through  simple  bit-
                         toggling (clicking on a "bit" inverts its
                         color).  There are many simple extensions
                         to our design (e.g., converting the edit-
                         ed  bitmap  into  CLX format) that can be
                         added easily, with only a few more  lines
                         of widget code.
































          PICASSO Widget-Writer's Guide                            3-9







                                                       A SAMPLE WIDGET


          ____________________________________________________________________________________________________________________________________________________________________________________

          Gadget
          Definition




                         Adhering to the policy described in the  pre-
                         vious  chapter, we will create a gadget along
                         the way which handles the internal  represen-
                         tation and viewing of the bitmap.  When we're
                         finished, the  class  inheritance  will  look
                         like this:


                                                 widget             gadget
                                                     \                  /
                                                      \          bitmap-gadget
                                                       \           /
                                                        \         /
                                                        bitmap-editor



                         The responsibilities of bitmap-gadget are:

                         o+    Initialize  the  bitmap  (get   internal
                              representation correct)

                         o+    Draw a graphical representation  of  the
                              bitmap

                         o+    Handle  simple  requests  (new   bitmap,
                              resize).   Bitmap-gadget will be used by
                              bitmap-editor, and should be designed to
                              allow  a  simple  interface  to editing.
                              This issue will resurface frequently.

                         To  begin  the  widget-writing  process,   we
                         define the new gadget class.


















          PICASSO Widget-Writer's Guide                           3-10







                                                       A SAMPLE WIDGET



                       (defclass bitmap-gadget (gadget) ;; inherits from gadget class
                         ((dimensions                   ;; (<bits-wide> <bits-high>)
                           :type list
                           :initform nil
                           :initarg :dimensions         ;; User-specifiable
                                                        ;;  in instantiation
                           :reader dimensions)          ;; Implicitly defines
                                                        ;;  reader method
                          (bit-size                     ;; Size of each square
                                                        ;;  on the screen
                           :type integer
                           :initform 1)
                          (gc-dotted                    ;; Graphic-context
                                                            for drawing grid
                           :type vector
                           :initform nil)
                          (gc-spec                      ;; Graphic-context specs
                           :initform '((gc-res "default")
                                       (gc-dotted (:paint "gray50"))))))



                         A gadget or widget is defined  using  a  CLOS
                         defclass.  No other registration is required.
                         Bitmap-gadget inherits all slots from  gadget
                         and,  in addition, defines the following four
                         slots: _d_i_m_e_n_s_i_o_n_s, _b_i_t-_s_i_z_e,  _g_c-_d_o_t_t_e_d,  and
                         _g_c-_s_p_e_c.    Of   these,  only  _d_i_m_e_n_s_i_o_n_s  is
                         intended  for  external  access.   The  other
                         three  slots  are  internal.   The _d_i_m_e_n_s_i_o_n_s
                         slot is used to store the dimensions  of  the
                         bitmap (in pixels).  Since we intend to allow
                         the application-writer access to  the  dimen-
                         sions  of  a  bitmap the :initarg and :reader
                         arguments are specified.  :initarg  specifies
                         that :dimensions can be used as an instantia-
                         tion argument to  initialize  the  _d_i_m_e_n_s_i_o_n_s
                         slot  (initialization  is  discussed  later).
                         :reader _i_m_p_l_i_c_i_t_l_y _c_r_e_a_t_e_s _a  _m_e_t_h_o_d  (_c_a_l_l_e_d
                         _d_i_m_e_n_s_i_o_n_s)  that  returns  the slot-value of
                         the _d_i_m_e_n_s_i_o_n_s slot.  _b_i_t-_s_i_z_e will  be  used
                         to cache the size of one square on the screen
                         to speed up redrawing.  The  last  two  slots
                         are  used for graphic-contexts (see chapter 7
                         for more information  on  graphics-contexts).
                         Specifying   :reader   dimensions  _i_m_p_l_i_c_i_t_l_y
                         _c_r_e_a_t_e_s  _a  _r_e_a_d_e_r-_a_c_c_e_s_s_o_r  _m_e_t_h_o_d  _f_o_r  _t_h_e
                         _d_i_m_e_n_s_i_o_n_s  _s_l_o_t.   _B_e_c_a_u_s_e  _t_h_e  _o_t_h_e_r _t_h_r_e_e
                         _s_l_o_t_s _a_r_e _i_n_t_e_r_n_a_l  (_n_o_t  _a_c_c_e_s_s_i_b_l_e  _t_o  _t_h_e
                         _a_p_p_l_i_c_a_t_i_o_n-_w_r_i_t_e_r),   _w_e   _d_o   _n_o_t   _d_e_f_i_n_e




          PICASSO Widget-Writer's Guide                           3-11







                                                       A SAMPLE WIDGET


                         _r_e_a_d_e_r-_m_e_t_h_o_d_s _f_o_r _t_h_e_m.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Accessor
          Methods



                         Accessor methods in CLOS  provide  access  to
                         slots  of  an  instance of a class.  A simple
                         accessor method can be  implicitly  generated
                         by   specifying   the  :reader,  :writer,  or
                         :accessor  argument  in  the  defclass   (see
                         above).   These  simple accessor methods only
                         provide an interface to the slots.   Specify-
                         ing :reader myslot is equivalent to:


                          (defmethod myslot ((self myclass))
                            (slot-value self 'myslot))



                         Specifying :writer myslot is equivalent to:


                          (defmethod (setf myslot) (val (self myclass))
                            (setf (slot-value self 'myslot) val))



                         Specifying :accessor myslot is  the  same  as
                         defining both of these methods.

                         Sometimes it is desirable to produce  certain
                         side-effects whenever a slot is accessed.  In
                         this case the  implicitly  defined  accessors
                         are  not sufficient, so we need to explicitly
                         define accessors.

                         For example, we want the  writer  method  for
                         the  dimensions  slot  to  create a new blank
                         bitmap  with  the  specified  dimensions,  in
                         addition to setting the value of the slot. It
                         is also important to do some error  checking.
                         We define the following writer method:













          PICASSO Widget-Writer's Guide                           3-12







                                                       A SAMPLE WIDGET



                       (defmethod (setf dimensions) (val (self bitmap-gadget))
                         (if (not (and (pos-intp (car val))
                                  (pos-intp (cadr val))))
                             (warn
                              "bitmap-gadget.setf.dimensions:  invalid dims:  ~S~%" val)
                             (setf (value self)
                                   (make-array val
                                               :initial-element 0
                                               :element-type 'bit))))



                         This definition relies on the fact that there
                         is a value writer method already defined. You
                         must always define a _s_e_t_f-_m_e_t_h_o_d before it is
                         referenced.   It  turns  out  that there is a
                         value _w_r_i_t_e_r-_m_e_t_h_o_d already defined in one of
                         our  superclasses,  so we don't have to worry
                         about it here.

                         We need special processing to  occur  when  a
                         bitmap-gadget's   value  is  changed.   Let's
                         examine what needs to be done  when  somebody
                         wants to set the value of a bitmap-gadget.

                         o+    Check the new value to  make  sure  that
                              it's valid.

                         o+    Set the slot-value of the "value" slot.

                         o+    Update the "dimensions" slot.

                         o+    Adjust the  internal  representation  of
                              the  bitmap  to  reflect  the changes in
                              dimension.

                         o+    Redraw the representation of the  bitmap
                              on the screen.

                         The following method does the trick.














          PICASSO Widget-Writer's Guide                           3-13







                                                       A SAMPLE WIDGET



                       (defmethod (setf value) (val (self bitmap-gadget))
                         (if (not (arrayp val))
                             (warn "bitmap-gadget.setf.value:  bad array:  ~S~%" val)
                             (progn
                              (setf (slot-value self 'value)
                                    val
                                    (slot-value self 'dimensions)
                                    (array-dimensions val))
                              (resize-window-handler self)
                              (repaint self))))



                         There are three important points to note from
                         this section.

                         First, accessor code should  be  concise  and
                         straightforward.  Instead of making the value
                         writer-method  to   explicitly   adjust   all
                         related   data-structures   and   redraw  the
                         screen, the code is factored out  into  func-
                         tions and methods (like resize-window-handler
                         and do-repaint).

                         Second, accessors can be interdependent.  The
                         dimensions   writer  method  uses  the  value
                         writer method to handle a lot of  the  neces-
                         sary  work.  This avoids duplication of code.
                         However, it is important  to  understand  the
                         nature  of the interdependencies.  In complex
                         cases, it may be difficult to  trace  exactly
                         what  happens  when  a slot is accessed.  The
                         widget writer should make  sure  that  inter-
                         dependent  slot accesses don't call functions
                         twice!

                         Third, the order of definition matters.  CLOS
                         requires all setf-methods (writer methods) to
                         be defined before they are  referenced.   For
                         instance,  the  value  writer must be defined
                         before  the  dimensions  writer  because  the
                         value  is  setf'd  from within the dimensions
                         method. Luckily in this case the value writer
                         was  inherited from a superclass. In general,
                         if two writer methods are mutually dependent,
                         one  must be defined implicitly in the class-
                         definition (use  :writer  or  :accessor)  and







          PICASSO Widget-Writer's Guide                           3-14







                                                       A SAMPLE WIDGET


                         redefined later.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Initiali-
          zation



                         To actually create a bitmap-gadget object, we
                         use  the  make-instance method in CLOS.  How-
                         ever, it is usually helpful to define a func-
                         tion to simplify this.


                          (defun make-bitmap-gadget (&rest keys)
                            (apply #'make-instance
                                   'bitmap-gadget
                                   :allow-other-keys t
                                   keys))



                         The  arguments  to   make-bitmap-gadget   are
                         keyword-value  pairs that correspond to slots
                         and initial values in the new instance.  Only
                         slots  defined with :initarg specified can be
                         initialized in this fashion. For example:


                          (make-bitmap-gadget :dimensions '(16 16)
                                              :background "green")



                         Specifying slots and initial-values  in  this
                         manner  is  equivalent  to  setting the slots
                         with writer methods.

                         It is often desirable to do some  extra  ini-
                         tialization  when  a  widget is instantiated,
                         such  as   argument-checking   and   creating
                         relevant   data-structures.  In  PICASSO  the
                         method called new-instance  exists  for  just
                         this  purpose.  In the case of bitmap-gadget,
                         we need to worry about the slots "dimensions"
                         and  "value".  The  superclasses handle other
                         slots.  Since we defined writer methods to do
                         error  checking  and  initialization,  we can
                         invoke those directly from  the  new-instance
                         method.









          PICASSO Widget-Writer's Guide                           3-15







                                                       A SAMPLE WIDGET



                          (defmethod new-instance ((self bitmap-gadget)
                                       &key
                                       value
                                       dimensions
                                       &allow-other-keys)
                            (call-next-method)
                            (if value
                                (setf (value self) value)
                                (if dimensions
                                (setf (dimensions self) dimensions)))
                            self)



                         The call-next-method is used to  let  superc-
                         lasses  initialize  inherited  slots.   It is
                         customary to invoke  call-next-method  before
                         anything  else  in  the  new-instance method.
                         This way the child  class  can  override  any
                         initialization done in the parent class.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Interface


                         At this point, we  have  methods  to  create,
                         initialize,   and   access   a  bitmap-gadget
                         instance from the level  of  the  application
                         writer.   However, the bitmap-gadget is still
                         just a bunch of data structures, so  we  need
                         to  provide  routines  to handle interactions
                         with the user.   At  the  gadget  level,  the
                         interaction  is  relatively simple.  A gadget
                         is basically an output-only device.  The only
                         type  of  user-level  input that a gadget may
                         choose to handle is resizing.   PICASSO  pro-
                         vides  two  methods  for  output  and one for
                         resizing.

                         To handle  the  output  behavior  of  bitmap-
                         gadget,  we  use  the  do-repaint method (see
                         chapter on methods).  The  do-repaint  method
                         is  invoked whenever a bitmap-gadget instance
                         needs to be drawn or redrawn.  Our do-repaint
                         method must draw every bit of the bitmap, and
                         a grid to visually  separate  all  the  bits.
                         The following definition is sufficient:









          PICASSO Widget-Writer's Guide                           3-16







                                                       A SAMPLE WIDGET



                          (defmethod do-repaint ((self bitmap-gadget)
                                                 &aux dims bit-size bit-array gc)
                            (setq dims (dimensions self)
                                  bit-size (slot-value self 'bit-size)
                                  bit-array (value self)
                                  gc (gc-res self))
                            (when bit-array
                              (dotimes (x (car dims))
                                (dotimes (y (cadr dims))
                                  (draw-bit self bit-array bit-size gc x y)))
                              (draw-grid self)))



                         Notice that there are no explicit XLIB  calls
                         in  the do-repaint method; the calls are fac-
                         tored out into  the  functions  draw-bit  and
                         draw-grid.   The code for these two functions
                         is at the end of this chapter.  This  factor-
                         ing  out  of  code  simplifies the writing of
                         bitmap-editor (the widget for bitmap-gadget).
                         Bitmap-editor  needs  draw-bit since clicking
                         on a bit  forces  it  to  be  redrawn  in  an
                         inverse  color.  By factoring common lines of
                         code into auxiliary functions or macros (like
                         draw-bit),  we can reduce duplication of code
                         and make the program more readable. It  turns
                         out  that  draw-grid  is only used by the do-
                         repaint method.  However, it  is  still  good
                         practice  to  factor  this code into separate
                         functions to make the code more readable  and
                         manageable.

                         You may be wondering how the "bit-size"  slot
                         is used. As we see above, bit-size is used by
                         draw-bit (and hence by do-repaint) to specify
                         the size of the square region that represents
                         a bit on the screen.  Bit-size is  calculated
                         by determining the maximum size of a bit that
                         will allow all bits to "fit" inside the space
                         allocated  to a bitmap-gadget instance.  When
                         should this calculation be performed?   Since
                         the size of a bitmap-gadget may change dynam-
                         ically, bit-size must be updated dynamically.
                         We  could  do  everything  in  the do-repaint
                         method.  However, this would entail  recalcu-
                         lating  bit-size every time the bitmap-gadget
                         is redrawn.  This is costly.  It is better to
                         recalculate  bit-size  only  when the size of
                         the bitmap-gadget changes and cache  the  new
                         value  in  the bit-size slot.  We can use the



          PICASSO Widget-Writer's Guide                           3-17







                                                       A SAMPLE WIDGET


                         PICASSO resize-window-handler method for just
                         this purpose.


                       (defmethod resize-window-handler ((self bitmap-gadget)
                                                         &aux dims)
                         (if (setq dims (dimensions self))
                             (setf (slot-value self 'bit-size)
                               (min (truncate (width self) (car dims))
                                (truncate (height self) (cadr dims))))))



                         This completes bitmap-gadget.

                         At this point, you can use  bitmap-gadget  in
                         any  PICASSO  application,  provided you load
                         into a PICASSO dump what we have  written  so
                         far  (defclass,  accessors, new-instance, do-
                         repaint, & resize-window-handler) and include
                         the  functions draw-bit & draw-grid, found at
                         the end of this chapter.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Widget


                         The bitmap-editor class inherits all slots of
                         both   the   widget   and  the  bitmap-gadget
                         classes. The  major  responsibility  for  the
                         bitmap-editor  widget  is event-handling.  We
                         can create the bitmap-editor widget using the
                         bitmap-gadget.  As with the bitmap-gadget, we
                         begin by defining the bitmap-editor class.


                          (defclass bitmap-editor (widget bitmap-gadget)
                            ((event-mask :initform '(:exposure :button-press))))



                         The event-mask slot  specifies  which  events
                         the  widget  is  interested in - exposure and
                         button-press events.  To actually process  an
                         event,  we  have  to define an event-handler.
                         This is done  via  the  defhandler  macro  in
                         PICASSO.  It  turns  out  that the "exposure"
                         event is  handled  automatically  by  widgets
                         because  handlers  are  inherited, so we only
                         need to worry about the "button-press"  event
                         in  our widget.  What does a bitmap-editor do
                         when the mouse is clicked inside the  bitmap-
                         editor  window?   It simply figures out which
                         bit was clicked on, updates the corresponding



          PICASSO Widget-Writer's Guide                           3-18







                                                       A SAMPLE WIDGET


                         bit  in  the  internal  representation of the
                         bitmap, and redraws the bit (in the  opposite
                         color)  on the screen.  All of these are done
                         in the following handler:


                       (defhandler toggle-bit ((self bitmap-editor)
                                               &key x y
                                               &allow-other-keys
                                               &aux bit-size bit-array dims
                                               &default :button-press)
                         (setq bit-array (value self)
                               bit-size (slot-value self 'bit-size)
                               dims (dimensions self))
                         (setq x (truncate x bit-size)
                               y (truncate y bit-size))
                         (when (and (<= x (car dims)) (<= y (cadr dims)))
                           (setf (aref bit-array x y)
                                 (- (lognot (- (aref bit-array x y)))))
                           (draw-bit self bit-array bit-size (gc-res self) x y)))



                         The defhandler macro automatically  registers
                         a   handler   function  named  bitmap-editor-
                         toggle-bit  which  is   called   whenever   a
                         button-press  event  occurs in an instance of
                         the bitmap-editor class.

                         Finally, we define a  function  called  make-
                         bitmap-editor,  analogous  in  to  the  make-
                         bitmap-gadget function we defined earlier.


                          (defun make-bitmap-editor (&rest args)
                            (apply #'make-instance
                                   'bitmap-editor
                                   :allow-other-keys t
                                   args))



                         Here is the code for draw-grid, draw-bit, and
                         pos-intp.











          PICASSO Widget-Writer's Guide                           3-19







                                                       A SAMPLE WIDGET



                          (defun pos-intp (val)
                            (and (integerp val) (plusp val)))

                          (defun draw-bit (self bit-array bit-size gc i j
                                           &aux w x y)
                            (setq x (1+ (* i bit-size))
                                  y (1+ (* j bit-size))
                                  w (- bit-size 1))
                            (if (zerop (aref bit-array i j))
                                (clear-region self x y w w)
                                (xlib:draw-rectangle (res self) gc x y w w t)))

                          (defun draw-grid (self
                                            &aux gc res dims bit-size rx ry w h)
                            (setq res (res self)
                                  rx (repaint-x self)
                                  ry (repaint-y self)
                                  gc (gc-dotted self)
                                  dims (dimensions self)
                                  bit-size (slot-value self 'bit-size))
                            (setq w (* bit-size (car dims))
                                  h (* bit-size (cadr dims)))
                            (do ((x (+ rx bit-size) (+ x bit-size)))
                                ((> x (+ rx w)))
                                (xlib:draw-line res gc rx 0 x h))
                            (do ((y (+ ry bit-size) (+ y bit-size)))
                                ((> y (+ ry h)))
                                (xlib:draw-line res gc 0 ry w y)))


























          PICASSO Widget-Writer's Guide                           3-20







                                                       A SAMPLE WIDGET


                                               4
                                       Standard Methods

          ____________________________________________________________________________________________________________________________________________________________________________________

          Overview


                         There are several standard  methods  used  by
                         PICASSO for defining a widget.  These methods
                         can  be  broken   down   into   three   basic
                         categories:   Initialization, event-handling,
                         and connections. A widget may have all, some,
                         or   none  of  these  methods  definied.  Any
                         methods which are not defined for a  particu-
                         lar  class of widget are implicitly inherited
                         from the widget's  super  class.  Inheritance
                         can  also  be  used explicitly with a call to
                         call-next-method.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Initiali-
          zation



                         Initialization routines are called only  once
                         in  the lifetime of a widget.  Initialization
                         routines have three  primary  uses:   setting
                         defaults,  checking  instantiation arguments,
                         and creating local data structures. There are
                         two initialization methods:  new-instance and
                         update-instance-for-different-class.

                     new-instance

                                                              [_M_e_t_h_o_d]
                         (_s_e_l_f _c_l_a_s_s-_n_a_m_e)
                         &rest_a_r_g_s

                         CONTEXT:
                              new-instance is called once when  a  new
                              widget  is  instantiated.   Self  is the
                              newly instantiated widget and args  con-
                              sists   of  all  the  keyword  arguments
                              passed to make-instance  (e.g.,  :width,
                              :height, :background, :font, etc.).

                         INHERITANCE:
                              All new-instance methods must contain  a
                              call  to call-next-method.  This insures
                              that  inherited   attributes   will   be
                              correctly  initialized.  Preferably, the
                              call-next-method occurs near the  begin-
                              ning   of  the  new-instance  method  to
                              ensure that later references  to  inher-
                              ited attributes are correct.

                     update-instance-for-different-class :after

                                                              [_M_e_t_h_o_d]
                         (_o_l_d _c_l_a_s_s-_n_a_m_e)



          PICASSO Widget-Writer's Guide                           3-21







                                                      Standard Methods


                         (_n_e_w _c_l_a_s_s-_n_a_m_e)

                         CONTEXT:
                              update-instance-for-different-class   is
                              called  after  a  change-class operation
                              occurs.  This method  can  specified  to
                              discriminate  on  either  or both of its
                              arguments.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Event-
          handling
          Methods




                         Event-handling methods are  generally  called
                         either automatically, in response to incoming
                         X events, or manually, by internal PICASSO or
                         widget  code.   Because  of  the  asyncronous
                         nature of X events,  calls of the former type
                         occur  asyncronously.   Therefore, all event-
                         handling methods should be designed and writ-
                         ten   to  execute  asnycronously.   In  other
                         words, an event-handler cannot assume that it
                         will  execute  at  a  particular time or in a
                         particular context.   An  exception  is  that
                         event-handlers may assume that the widget has
                         already been attached (has  a  representation
                         in   the  server).   Event-handling  methods,
                         unlike user-defined handlers,  enable  inher-
                         ited  event-handling  behavior  to take place
                         (via call-next-method).  For  instance,  sup-
                         pose  there  exists a class named text-gadget
                         which displays text.  The  do-repaint  method
                         for  text-gadget draws the text.  Now suppose
                         we define a  class  named  text-widget  which
                         inherits from text-gadget and allows input as
                         well as output.  Since drawing  the  text  is
                         already   handled  by  text-gadget,  the  do-
                         repaint method for text-widget need only con-
                         tain  a call-next-method and code to draw the
                         cursor  at  its  current  position.   If  the
                         text-widget  is implemented without a cursor,
                         we can eliminate the  do-repaint  method  for
                         text-widget  altogether since the method will
                         be implicitly inherited from text-gadget.

                         _____________________________________________

          Repainting



                         There are  two  types  of  repaint  routines:
                         do-repaint and do-repaint-region

                     do-repaint

                                                              [_M_e_t_h_o_d]
                         (_s_e_l_f _c_l_a_s_s-_n_a_m_e)



          PICASSO Widget-Writer's Guide                           4-22







                                                      Standard Methods


                         USE:
                              The do-repaint method is used to  redraw
                              the   widget  in  its  current  position
                              specified by repaint-x,  repaint-y,  and
                              size.

                         CONTEXT:
                              do-repaint is called as a result  of  an
                              expose  event in a window which does not
                              handle  expose-region.   Do-repaint   is
                              called by repaint.

                         INHERITANCE:
                              A  do-repaint  method  for  any   widget
                              inheriting  from  the  collection-gadget
                              class must include a call to  call-next-
                              method.

                     do-repaint-region

                                                              [_M_e_t_h_o_d]
                         (_s_e_l_f _c_l_a_s_s-_n_a_m_e)
                         _x
                         _y
                         _w_i_d_t_h
                         _h_e_i_g_h_t

                         USE/CONTEXT:
                              The do-repaint-region method is used and
                              called  similarly  as do-repaint, except
                              that  windows   handling   expose-region
                              events  will almost always receive calls
                              to do-repaint-region in place  of  calls
                              to  do-repaint.   The  x and y arguments
                              are in  respect  to  the  repaint-x  and
                              repaint-y positions of the window.

                         INHERITANCE:
                              A  do-repaint-region  method   for   any
                              widget  inheriting  from the collection-
                              gadget class  must  include  a  call  to
                              call-next-method.

                         NOTE:
                              Since widgets may need to  be  repainted
                              frequently,  it  is a good idea to do as
                              little computation as  possible  in  the
                              do-repaint     and     do-repaint-region
                              methods. Typically, these methods should
                              access  values  which  have been updated
                              and cached away by  other  means  (e.g.,
                              resize-window-handler   [sec  3.2.2]  is





          PICASSO Widget-Writer's Guide                           4-23







                                                      Standard Methods


                              often used purely to update caches).

                         _____________________________________________

          Exposing



                         All windows can  be  exposed  and  concealed.
                         PICASSO  provides  the method do-expose which
                         is executed whenever a  window  needs  to  be
                         exposed.

                     do-expose

                                                              [_M_e_t_h_o_d]
                         (_s_e_l_f _c_l_a_s_s-_n_a_m_e)

                         USE:
                              The do-expose method can be used  to  do
                              miscellaneous  processing which needs to
                              be done when the widget is exposed.

                         CONTEXT:
                              The do-expose method may be invoked from
                              a  call to expose.  Expose can be called
                              from any  level  in  PICASSO.   The  do-
                              expose method is rarely needed for widg-
                              ets because do-repaint is almost  always
                              sufficient.

                         INHERITANCE:
                              A do-expose should call call-next-method
                              unless  it  wishes to override the stan-
                              dard exposure behavior for windows  (not
                              very often).

                         _____________________________________________

          Resize
          handling




                         Whenever  the  size  of  a  window   changes,
                         resize-window-handler is called.

                     resize-window-handler

                                                              [_M_e_t_h_o_d]
                         (_s_e_l_f _c_l_a_s_s-_n_a_m_e)

                         USE: Typically,   the   resize-window-handler
                              method  is  used  to  update local data-
                              structures called  "caches"  which  need
                              updating when a widget is resized.

                         CONTEXT:
                              Configure can  be  called  from  any  of
                              three levels in PICASSO:
                              (1) from a geometry manager or a  widget



          PICASSO Widget-Writer's Guide                           4-24







                                                      Standard Methods


                              (system level)
                              (2) from an application
                              (3) from a window-manager (user level).
                              Therefore, resize-window-handler can  be
                              activated from any of these levels.

                         INHERITANCE:
                              A resize-window-handler  may  optionally
                              call  call-next-method.   Any collection
                              which doesn't call  call-next-method  in
                              its  resize-window-handler  will not get
                              repacked [sec 7].

                         NOTE:
                              resize-window-handler  need   not   call
                              repaint  or  repaint-region because this
                              will be  done  automatically  after  the
                              resize-window-handler   completes.   The
                              resize-window-handler method is provided
                              purely  for  notification  purposes, not
                              for  actually  resizing.   Therefore,  a
                              widget  should  never  attempt to resize
                              itself directly within a  resize-window-
                              handler   method.   In  fact,  all  self
                              resizing at the widget-level  should  be
                              done through resize-hints [sec 8.2].
          ____________________________________________________________________________________________________________________________________________________________________________________

          Connec-
          tions



                         PICASSO is designed to allow each  widget  to
                         be  independently  attached  or detached from
                         the  X-server.   However,   reliable   detach
                         methods  are  not  implemented in the current
                         version of PICASSO. When detach  methods  are
                         fully  implemented,  it  will  be possible to
                         create  a  Lisp  dump  with  an   application
                         already  loaded,  but  detached.   This would
                         reduce startup time by half.

                         _____________________________________________

          Attaching



                         PICASSO uses the term "attach" for connecting
                         a widget to the server.

                     do-attach

                                                              [_M_e_t_h_o_d]
                         (_s_e_l_f _c_l_a_s_s-_n_a_m_e)

                         USE: do-attach attaches a picasso object  and
                              all  its  children.  Every widget has to
                              be  attached,   either   explicitly   or



          PICASSO Widget-Writer's Guide                           4-25







                                                      Standard Methods


                              implicitly.

                         CONTEXT:
                              Do-attach is called from attach.

                         INHERITANCE:
                              A do-attach method must call  call-next-
                              method at the beginning of the method.

                         _____________________________________________

          Detaching



                         PICASSO uses the term  "detach"  for  discon-
                         necting a widget from the server.

                     do-detach

                                                              [_M_e_t_h_o_d]
                         (_s_e_l_f _c_l_a_s_s-_n_a_m_e)

                         USE:
                              do-detach is not implemented reliably in
                              the  current  version  of Picasso.  When
                              implemented,  do-detach  should  do  the
                              inverse of do-attach.

                         CONTEXT:
                              Do-detach is called from detach.

                         INHERITANCE:
                              A do-detach method must call  call-next-
                              method.

                         _____________________________________________

          Destroying



                     do-destroy

                                                              [_M_e_t_h_o_d]
                         (_s_e_l_f _c_l_a_s_s-_n_a_m_e)

                         USE:
                              do-destroy is not  implemented  reliably
                              in the current version of Picasso.  When
                              implemented, do-detach will destroy both
                              the   internal  representation  and  the
                              server representation of the object.

                         CONTEXT:
                              Do-destroy is called from destroy.

                         INHERITANCE:
                              A  do-destroy  method  must  call  call-
                              next-method.



          PICASSO Widget-Writer's Guide                           4-26







                                                      Standard Methods


                                               5
                                     Inherited Attributes

          ____________________________________________________________________________________________________________________________________________________________________________________

          Overview


                         Widget attributes  are  data  of  the  widget
                         stored in accessible slots.  Inherited attri-
                         butes  are  attributes  inherited  from   the
                         widget's  super  class.  PICASSO contains the
                         following class-inheritance subtree.


                                        window
                                         /    \
                                        /      \
                                   x-window   gadget
                                      /
                                     /
                                  widget


                         A widget inherits attributes from the  widget
                         class, the gadget class, and the widow class.
                         An attribute may be  readable,  settable,  or
                         readable and settable.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Resources


                         Every attached window is associated with  one
                         window  in  the  server.  A widget inheriting
                         from the widget class has its own server win-
                         dow. A gadget inherits the server window from
                         its parent.  Each server window is associated
                         with  a  particular  screen, which in turn is
                         associated with a particular display  in  the
                         server.

                         The  following  reader  methods  return   the
                         appropriate  resource  used  by  a  widget or
                         gadget.

                     res

                                                              [_R_e_a_d_e_r]
                         returns  the  X-window  associated  with  the
                         object (of type xlib:window), or nil.

                     screen

                                                              [_R_e_a_d_e_r]
                         returns the X screen of a PICASSO object  (of
                         type xlib:screen), or nil.

                     display

                                                              [_R_e_a_d_e_r]
                         returns the X display of a PICASSO object (of



          PICASSO Widget-Writer's Guide                           4-27







                                                  Inherited Attributes


                         type xlib:display), or nil.

                         The following predicates return  the  current
                         status of the PICASSO object.

                     attached-p

                                                               [_M_a_c_r_o]
                         returns if the object is connected to  the  X
                         server.

                     detached-p

                                                               [_M_a_c_r_o]
                         returns if the object is disconnected to  the
                         X server.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Region


                         Every window has attributes which specify its
                         location  and size on the screen.  A window's
                         location  is  specified   relative   to   the
                         window's parent.  repaint-x and repaint-y are
                         specified relative to window's server-window.
                         All specifications are in pixels.  All region
                         accessors  are  READABLE  AND  SETTABLE,  but
                         widgets   should   not  configure  themselves
                         dynamically (see next section).

                     x-offset

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the x-coordinate (in pixels) of window  rela-
                         tive  to  the top-left corner of the window's
                         parent.  Type:  integer Default:  0

                     y-offset

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the y-coordinate (in pixels) of window  rela-
                         tive  to  the top-left corner of the window's
                         parent.  Type:  integer Default:  0

                     location

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         a list consisting of  window's  x-offset  and
                         y-offset.   We will denote this: (x-offset y-
                         offset).  Type:  cons Default:  (0 0)

                     width

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the  width  of  window  in   pixels.    Type:
                         positive-integer.  Default:  1

                     height

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the  height  of  window  in  pixels.    Type:
                         positive-integer.  Default:  1

                     size

                                                         [_M_e_t_h_o_d/_S_e_t_f]






          PICASSO Widget-Writer's Guide                           5-28







                                                  Inherited Attributes


                         (width height).  Type:  cons Default:  (1 1)

                     region

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         (x-offset  y-offset  width  height).    Type:
                         cons Default:  (0 0 1 1)
          ____________________________________________________________________________________________________________________________________________________________________________________

          Geometry
          hints



                         Windows  should  not   configure   themselves
                         dynamically.   This rule exists to avoid con-
                         flicts with geometry managers.  To request  a
                         particular  size, a widget can send a message
                         to its geometry-manager which the manager can
                         choose to consider or ignore.  These messages
                         are propagated via geometry hints.  There are
                         two  types  of  geometry hints:  resize-hints
                         and geometry-specification.  Resize-hints are
                         typically  defined  at  the widget definition
                         level.  Resize hints should  be  defined  for
                         every  widget  to  be  of any use.  Geometry-
                         specification is typically instance specific.
                         All geometry hints are READABLE AND SETTABLE.

                         _____________________________________________

          Resize-
          hints




                     base-width

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the  smallest  desirable  width  for  window.
                         Type:  positive-integer Default:  1

                     base-height

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the smallest  desirable  height  for  window.
                         Type:  positive-integer Default:  1

                     width-increment

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the best amount by  which  to  increment  the
                         width  of  window.   Type:   positive-integer
                         Default:  1

                     width-increment

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the best amount by  which  to  increment  the
                         height  of  window.   Type:  positive-integer
                         Default:  1

                     width-height-ratio

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the best ratio for  width/height  of  window.








          PICASSO Widget-Writer's Guide                           5-29







                                                  Inherited Attributes


                         Type:  positive-number/nil Default:  nil

                         _____________________________________________

          geometry-
          specification




                     geom-spec

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         various instructions concerning the  geometry
                         of  window that the window's geometry-manager
                         should look at.  Type:  anything
          ____________________________________________________________________________________________________________________________________________________________________________________

          Graphics


                         All windows have some  predefined  attributes
                         that  are  used in graphics operations.  Some
                         of these attributes are associated with built
                         in   mechanisms  that  perform  the  graphics
                         operations.  Others attributes  handle  data-
                         structures  which  widgets can use explicitly
                         to  perform  graphics  operations.   All  are
                         readable  and  settable  except  colormap and
                         gc-res.

                         _____________________________________________

          Graphics
          attributes
          with
          internal
          output
          mechanisms








                     inverted

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         when a window is inverted, its background and
                         inverted-  background  are  swapped  and  its
                         foreground  and  inverted-   foreground   are
                         swapped.  Type:  t/nil Default:  nil

                     dimmed

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         when a window is dimmed, its  background  and
                         dimmed-  background are swapped and its fore-
                         ground and dimmed-  foreground  are  swapped.
                         Type:  t/nil Default:  nil

                     background

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the background paint (color or tile) of  win-
                         dow.   Type:   paint/nil Default:  "white" if
                         widget, nil if gadget

                     inverted-background

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the  background  to  use   when   window   is
                         inverted.  Type:  paint/nil Default:  "black"
                         if widget, nil if gadget

                     dimmed-background

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the background to use when window is  dimmed.
                         Type:    paint/nil   Default:    "gray50"  if



          PICASSO Widget-Writer's Guide                           5-30







                                                  Inherited Attributes


                         widget, nil if gadget

                     colormap

                                                              [_R_e_a_d_e_r]
                         all windows have  a  colormap  which  can  be
                         read.  A widget's colormap may be set.  Type:
                         colormap Default:  inherited from parent

                         _____________________________________________

          Graphics
          attributes
          for con-
          venience






                     foreground

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the foreground to use in graphic  operations.
                         Type:  paint/nil Default:  "black"

                     inverted-foreground

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the foreground to use in  graphic  operations
                         when   the   window   is   inverted.    Type:
                         paint/nil Default:  "white"

                     dimmed-foreground

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the foreground to use in  graphic  operations
                         when  the window is dimmed.  Type:  paint/nil
                         Default:  "gray50"

                     font

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         every window has a font which may be used  in
                         graphic    operations.     Type:    paint/nil
                         Default:  "8x13"

                     gc-spec

                                                              [_R_e_a_d_e_r]
                         PICASSO provides  a  built-in  mechanism  for
                         creating  graphic- contexts on a per-instance
                         basis [sec 4].  Type:  gc-spec-type  Default:
                         nil

                     gc-res

                                                              [_R_e_a_d_e_r]
                         gc-res (if specified in gc-spec)  contains  a
                         graphics-context   which  gets  automatically
                         updated whenever window's foreground or back-
                         ground  changes.   Type:  xlib:gcontext/t/nil
                         Default:  nil

                     shared-gc-table

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         PICASSO provides  a  built-in  mechanism  for
                         sharing  graphics-  contexts across a window.
                         If  shared-gc-table  is  initially  t,   this
                         mechanism   is   enabled   [sec   4].   Type:







          PICASSO Widget-Writer's Guide                           5-31







                                                  Inherited Attributes


                         t/nil/hash-table Default:  nil
          ____________________________________________________________________________________________________________________________________________________________________________________

          Borders


                         PICASSO  has  an   extensible   window-border
                         mechanism (see ref man).  Any window can have
                         a border.  Border attributes are READABLE AND
                         SETTABLE.

                     border-type

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the type of border to use  for  window.   The
                         predefined  border-types  include  (nil  :box
                         :frame :black-frame  :inset  :standout  :sha-
                         dow).   Type:   keyword/nil Default:  :box if
                         widget, nil if gadget

                     border-width

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the dimensions of the  border  to  be  drawn.
                         Some  border-types allow borders to have non-
                         uniform dimensions.  Therefore,  border-width
                         may be either a list with four elements or an
                         integer value (e.g. a shadow-border may  have
                         border-width    (0    0   10   10)).    Type:
                         integer/4-D-list
          ____________________________________________________________________________________________________________________________________________________________________________________

          Labels


                         PICASSO  has   an   extensible   window-label
                         mechanism  (see ref man).  Any label can have
                         a label.  Label attributes are  READABLE  AND
                         SETTABLE.

                     label-type

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the type of label to  use  for  window.   The
                         predefined  label-types  include  (nil :left-
                         label  :bottom-label  :frame-label).    Type:
                         keyword/nil Default:  :left

                     label

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the label to draw.  Type:  anything  Default:
                         nil

                     label-x

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the x-coordinate of the label relative to  an
                         origin.   The  origin  is  dependent  on  the
                         label-type of window. Type:  integer Default:
                         0

                     label-y

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the y-coordinate of the label relative to  an
                         origin.   The  origin  is  dependent  on  the
                         label-type of window. Type:  integer Default:



          PICASSO Widget-Writer's Guide                           5-32







                                                  Inherited Attributes


                         0

                     label-font

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the font to use in drawing the label.

                     label-attributes

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         a list of  attributes  concerning  the  label
                         (e.g., (:foreground "red" :font "8x13" :ital-
                         icized  t)  ).   Which  label-attributes   to
                         specify,  if  any, is dependent on the label-
                         type of window.  Type:  keyword-value-list
          ____________________________________________________________________________________________________________________________________________________________________________________

          Status


                         The status of a window indicates  how  it  is
                         currently  represented on in the server.  The
                         status of a window is one of :exposed,  :con-
                         cealed, or :pending.  If a window exposed, it
                         is viewable on the screen except if:  (1) the
                         window  is  fully occluded by another window,
                         or (2) the window is a  child  of  the  root-
                         window.   In the latter case, the only way to
                         determine if an exposed window is actually on
                         the screen is by use of the viewable-p macro.
                         If a window is concealed it  is  not  on  the
                         screen.   If a window is pending, it wants to
                         be exposed but cannot be for some reason.

                     status

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the  status   of   window.    Type:    member
                         (:exposed   :concealed   :pending)   Default:
                         :exposed

                     state

                                                              [_R_e_a_d_e_r]
                         the state of window:

                         0:   window is exposed or concealed.

                         1:   window wants to be exposed but parent is
                              not.

                         2:   window wants  to  be  exposed  geometry-
                              manager  says no for some reason.  Type:
                              member (0 1 2).  Default:  1.

                         The following predicates  concerning  window-
                         status exist

                     exposed-p

                                                               [_M_a_c_r_o]






          PICASSO Widget-Writer's Guide                           5-33







                                                  Inherited Attributes


                         is window exposed?

                     concealed-p

                                                               [_M_a_c_r_o]
                         is window concealed?

                     pending-p

                                                               [_M_a_c_r_o]
                         is window pending?

                     invisible-p

                                                               [_M_a_c_r_o]
                         is state of window 1?

                     pended-p

                                                               [_M_a_c_r_o]
                         is state of window 2?

                     viewable-p

                                                               [_M_a_c_r_o]
                         is  window  viewable  on   screen   (can   be
                         occluded)?

                         The  following  functions  are  provided   to
                         change the status of a window

                     expose

                                                            [_F_u_n_c_t_i_o_n]
                         attempt to  expose  window.   Expose  updates
                         window's   status   and  state  appropriately
                         depending  if  expose  succeeds   or   fails.
                         Return-type:  t/nil

                     conceal

                                                            [_F_u_n_c_t_i_o_n]
                         conceal  window  and   update   status/state.
                         Return-type:  t

                     make-invisible

                                                            [_F_u_n_c_t_i_o_n]
                         pend window, update status, set state  to  1.
                         Return-type:  t

                     pend

                                                            [_F_u_n_c_t_i_o_n]
                         pend window, update status, set state  to  2.
                         Return-type:  t
          ____________________________________________________________________________________________________________________________________________________________________________________

          Miscel-
          laneous




                     parent

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the   parent   window   of   window.    Type:
                         window/nil Default:  nil

                     var-superior

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         the  lexical   parent   of   window.    Type:
                         picasso-object Default:  nil

                     attach-when-possible

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         specifies whether  or  not  to  automatically



          PICASSO Widget-Writer's Guide                           5-34







                                                  Inherited Attributes


                         attach  the  window  when  its status is con-
                         cealed  and  its  parent  becomes   attached.
                         Type:  t/nil Default:  nil

                     repaint-flag

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         if set to t, window will not be automatically
                         drawn  as  a result of either internal events
                         or a call to repaint.  Type:  t/nil  Default:
                         t

                     mf-selectable-widget

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         specifies  whether  or  not  window  can   be
                         "selected" in a table.  Type:  t/nil Default:
                         nil

                     name

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         a slot used to associate a name with  window.
                         Used  primarily  for  debugging.  Type:  any-
                         thing

                     doc

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         a documentation string associated  with  win-
                         dow.  Type:  string
































          PICASSO Widget-Writer's Guide                           5-35







                                                  Inherited Attributes


                                               6
                                        EVENT HANDLING

          ____________________________________________________________________________________________________________________________________________________________________________________

          Overview


                         PICASSO is  an  _e_v_e_n_t-_d_r_i_v_e_n  application:  a
                         PICASSO  tool  creates a set of widgets, then
                         enters a loop that 1)  waits  for  X  events,
                         such  as typing a key or mousing in a window,
                         to come in from the X server; 2) figures  out
                         which  widget can interpret the event; and 3)
                         passes that event off  to  the  widget.  This
                         process  is called _d_i_s_p_a_t_c_h_i_n_g the event, and
                         the widget is said to _h_a_n_d_l_e the event.  This
                         chapter  describes the event-handling mechan-
                         ism as implemented in PICASSO.

                         This chapter is designed to  describe  event-
                         handling   only  as  it  relates  to  writing
                         PICASSO  widgets.   This   section   is   not
                         designed  to  be  an  introduction  to event-
                         handling in any other form.   For  a  general
                         understanding  of  event-handling, the reader
                         should consult the section on events  in  the
                         PICASSO  REFERENCE  MANUAL  and/or in the CLX
                         documentation.

                         Any PICASSO  widget  can  choose  to  receive
                         various  types  of  events.  Only events that
                         are "requested" by the widget will be  "sent"
                         to the widget.  Requested events arrive asyn-
                         chronously.  When an event occurs  that  con-
                         cerns  an instance of a widget, that instance
                         is notified and must handle the event immedi-
                         ately.   If  the widget is unable to "handle"
                         the event, it  is  "dropped  on  the  floor",
                         which  is  to  say  effectively ignored.  All
                         event  traffic  and  interaction   with   the
                         window-server   is   done   automatically  by
                         PICASSO, usually. Some special  widgets  have
                         to  do  fancy  event-handling  that  requires
                         interrupting or superceding the regular  pro-
                         cessing  of events.  Such special widgets use
                         functions  like  event-loop  (event-loop  and
                         related  functions  are described in the sec-
                         tion on special event-handling.  However,  in
                         the  general case, the only aspects of event-
                         handling that concern the  widget-writer  are






          PICASSO Widget-Writer's Guide                           5-36







                                                        EVENT HANDLING


                         requesting and handling of events.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Requesting
          Events



                         An  event  is  requested  by  inserting   the
                         request-name  of the event-type in the event-
                         mask slot of an instance (of the widget) that
                         wishes to request it.  The request-name of an
                         event is not always the same as the  name  of
                         the   corresponding   event   that  a  widget
                         receives (called the sent-name).   To  deter-
                         mine  possible  return-names  from a request-
                         name, consult the following table.

                         The particular types of events that a  widget
                         can request depend both on the version of the
                         window-server and  the  version  of  PICASSO.
                         Both CLX and PICASSO have an extensible event
                         mechanism, in the sense that new  event-types
                         can  be  added easily.  The events-types that
                         are supported in the the current  release  of
                         PICASSO are summarized below.


          __________________________________________________________________________________
           Event Type      Event Request        Event Sent
          ____________________________________________________________________________________________________________________________________________________________________
           Keyboard        :key-press           :key-press
                           :key-release         :key-release
           Pointer         :button-press        :button-press, :double-click, :triple-click
                           :button-release      :button-release
                           :enter-window        :enter-notify
                           :leave-window        :leave-notify
                           :pointer-motion      :motion-notify
                           :button-motion       :motion-notify
                           :button-1-motion     :motion-notify
                           :button-2-motion     :motion-notify
                           :button-3-motion     :motion-notify
                           :button-4-motion     :motion-notify
                           :button-5-motion     :motion-notify
           Exposure        :exposure            _S_P_E_C_I_A_L
                           :expose-region       _S_P_E_C_I_A_L
                           :visibility-change   :visibility-notify
           Input Focus     :focus-change        :focus-in, :focus-out
           Client Events   :client-message      :client-message
          __________________________________________________________________________________

         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |
         |



















                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |
                        |



















                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |
                                             |



















                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |
                                                                                           |























                         To simplify things, all event-names  (request
                         and  sent)  in  the  above  table  correspond
                         directly to  event-names  in  CLX,  with  the



          PICASSO Widget-Writer's Guide                           6-37







                                                        EVENT HANDLING


                         exception  of  ":double-click"  and ":triple-
                         click".  A PICASSO event consists of  a  list
                         of  fields.  The contents of these fields are
                         exactly the same as those for the correspond-
                         ing   events   in  CLX.   For  instance,  the
                         button-press event in PICASSO has the follow-
                         ing fields: window, event-window, code, x, y,
                         state, time, root, root-x, root-y, child, and
                         same-screen-p.   These  are  the  exact  same
                         fields that the  button-press  event  in  CLX
                         contains.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Handling
          Events



                         When an event is "sent"  to  a  widget,  what
                         actually  happens  is  that PICASSO looks for
                         and invokes a _h_a_n_d_l_e_r for the event.  PICASSO
                         always  invokes  the _h_a_n_d_l_e_r most-specific to
                         the widget and the event.  The two  important
                         concepts  involved  here are mapping and han-
                         dling.

                         _____________________________________________

          Mapping


                         Any event-handler can be mapped to  any  type
                         of event via an _e_v_e_n_t-_m_a_p_p_i_n_g. _e_v_e_n_t-_m_a_p_p_i_n_g_s
                         can either be fully  qualified  or  partially
                         qualified.    PICASSO   always   invokes  the
                         _h_a_n_d_l_e_r corresponding to  _e_v_e_n_t-_m_a_p_p_i_n_g  that
                         most  closely  matches  the event.  An _e_v_e_n_t-
                         _m_a_p_p_i_n_g consists of  a  handler-specification
                         and one or more event-specifications, as fol-
                         lows:

                         event-mapping:
                              (_h_a_n_d_l_e_r-_s_p_e_c _e_v_e_n_t_s-_s_p_e_c)

                         _h_a_n_d_l_e_r-_s_p_e_c  identifies  the   event-handler
                         that  is  to  be mapped. Since event-handlers
                         are defined on classes (just  like  methods),
                         it  is  sometimes  necessary  to  specify the
                         class of the widget as part of the specifica-
                         tion   of   the  event-handler.   Hence,  the
                         _h_a_n_d_l_e_r-_s_p_e_c is either a list of  (_c_l_a_s_s-_n_a_m_e
                         _h_a_n_d_l_e_r-_n_a_m_e)  or  just  _h_a_n_d_l_e_r-_n_a_m_e  if the
                         `context is obvious.

                         handler-spec:
                              (_c_l_a_s_s-_n_a_m_e  _h_a_n_d_l_e_r-_n_a_m_e)  OR  _h_a_n_d_l_e_r-
                              _n_a_m_e




          PICASSO Widget-Writer's Guide                           6-38







                                                        EVENT HANDLING


                         _e_v_e_n_t-_s_p_e_c identifies the type of event to be
                         mapped  to.   The  heart  of  the  mapping is
                         expressed by the  properties  of  the  _e_v_e_n_t-
                         _s_p_e_c.   An  event-mapping  can include one or
                         more _e_v_e_n_t-_s_p_e_c_s as follows:

                         events-spec:
                              _e_v_e_n_t-_s_p_e_c OR (_e_v_e_n_t-_s_p_e_c+)

                         An _e_v_e_n_t-_s_p_e_c consists of an  event-type  and
                         two   qualifiers:   state  and  detail.   Any
                         unspecified qualifier is considered to  be  a
                         "wild-card".  A  wild-card  maps to anything.
                         For instance an _e_v_e_n_t-_s_p_e_c in which only type
                         = :button-press is specified maps to any kind
                         of button-press event.  The  more  wild-cards
                         an  _e_v_e_n_t-_s_p_e_c contains, the less specific it
                         becomes.  There are generally three  ways  to
                         specify an _e_v_e_n_t-_s_p_e_c:

                         event-spec:
                              _e_v_e_n_t-_t_y_p_e  (_e_v_e_n_t-_t_y_p_e  _s_t_a_t_e   _d_e_t_a_i_l)
                              (_e_v_e_n_t-_t_y_p_e   {:state   _s_t_a_t_e}  {:detail
                              _d_e_t_a_i_l})

                         Any one of the preceding is a valid form  for
                         _e_v_e_n_t-_s_p_e_c.   The  qualifier fields depend on
                         the _e_v_e_n_t-_t_y_p_e.  _s_t_a_t_e concerns the state  of
                         the input devices when the event occurs.  For
                         instance, _s_t_a_t_e  is  usually  one  of  :meta,
                         :shift,  :control,  etc.   _d_e_t_a_i_l  is  a more
                         specific indication of what the  contents  of
                         the event are.  For instance, _d_e_t_a_i_l can be a
                         character (in the case of a key event)  or  a
                         button-keyword  like  :left-button,  :middle-
                         button, :right-button (in the case of a  but-
                         ton event).

                         Some examples of event-mappings follow:


                          (select-1 (:button-press :detail :left-button))

                          ((his-widget select) :button-press)

                          (save ((:key-press :meta # (:key-press :meta #S)))



                         Event-mappings  in  PICASSO  are  defined  at
                         three    different   levels:    widget-level,
                         system-level, and  user-level.   System-level



          PICASSO Widget-Writer's Guide                           6-39







                                                        EVENT HANDLING


                         and  user-level mapping capabilities are pro-
                         vided  to  allow  fully  customizable  event-
                         mappings.   For  instance,  a  user could use
                         user-level mappings to customize  text-widget
                         to  be  like the user's usual text-editor.  A
                         systems administrator could adopt  a  certain
                         PICASSO  default  mapping  using system-level
                         mappings.  Defining  system-level  and  user-
                         level event-mappings is discussed in the sec-
                         tion  on  events  in  the  PICASSO  REFERENCE
                         MANUAL.   Widget-level  mappings  are done in
                         the PICASSO widget  code.   PICASSO  provides
                         two  ways  to  define  event-mappings  at the
                         widget-level:   defevents   and   defhandler.
                         defevents  is  explained below and defhandler
                         is explained later.

                         The syntax of defevents is as follows:

                     defevents

                                                               [_M_a_c_r_o]
                         _c_l_a_s_s-_n_a_m_e
                         _e_v_e_n_t-_m_a_p_p_i_n_g
                         Here is an example usage of defevents:


                          (defevents my-widget
                            (select-1 (:button-press :detail :left-button))
                            ((his-widget select) :button-press)
                            (save ((:key-press :meta # (:key-press :meta #S))))



                         _____________________________________________

          Handling



                         A widget can process an instance of any  type
                         of  event  in  the  third column of the above
                         table.   Processing  an   event   is   called
                         "event-handling"   and   is  done  within  an
                         event-handler.  Event-handlers are defined in
                         PICASSO using the defhandler macro.  The syn-
                         tax of defhandler is as follows:

                     defhandler

                                                               [_M_a_c_r_o]
                         _n_a_m_e
                         _a_r_g_l_i_s_t
                         {_d_o_c-_s_t_r_i_n_g}
                         {_b_o_d_y-_f_o_r_m_s}*

                         The syntax of defhandler is like  that  of  a
                         function declaration with two exceptions:



          PICASSO Widget-Writer's Guide                           6-40







                                                        EVENT HANDLING


                         1:   The first argument of _a_r_g_l_i_s_t is of  the
                              form    (_l_o_c_a_l-_v_a_r   _c_l_a_s_s-_n_a_m_e)   where
                              _c_l_a_s_s-_n_a_m_e is the name of the  class  on
                              which the event-handler is being defined
                              (just  like   a   method   declaration).
                              _a_r_g_l_i_s_t  can  include one &default argu-
                              ment  which  defines  a  default  event-
                              mapping and consists of one _e_v_e_n_t_s-_s_p_e_c.

                         2:   return-from statements must specify  the
                              entire   handler-name;   _c_l_a_s_s_n_a_m_e-_n_a_m_e.
                              This  is  necessary  because  defhandler
                              declares  a  function  called _c_l_a_s_s_n_a_m_e-
                              _n_a_m_e to actually handle events.

                         The arguments to defhandler are keyword argu-
                         ments  corresponding  to  the  fields  in the
                         event being handled.  Hence,  all  defhandler
                         forms  must  include  either an &allow-other-
                         keys or a &rest argument.

                         Here are some example uses of defhandler:


                          (defhandler select ((self button) &rest args
                                              &default :button-press)
                            "Selects a button by inverting it"
                            (declare (ignore args))
                            (invert self)
                            (execute 'press-func self args))

                          (defhandler print-location ((self valuator)
                                            &key x y
                                            &allow-other-keys
                                            &default
                                             ((:button-press :detail :left-button)
                                              (:button-press :detail :right-button)))
                            "Prints out where the mouse was clicked"
                            (declare (ignore args))
                            (format "Mouse was clicked at X-coord:              ~S and Y-coord:  ~S~%" x y))



                         It  is  possible  to  call  an  event-handler
                         explicitly.   To  call a handler defined with
                         defhandler, just invoke the  handler  as  you
                         would  invoke  a  regular  function with name
                         _c_l_a_s_s_n_a_m_e-_h_a_n_d_l_e_r_n_a_m_e.  It is  also  possible
                         to  register  a certain types of functions as
                         event-handlers.  Any such function must  have
                         a  name of the form _c_l_a_s_s_n_a_m_e-_n_a_m_e and either




          PICASSO Widget-Writer's Guide                           6-41







                                                        EVENT HANDLING


                         an &allow-other-keys or a &rest argument.

                         _____________________________________________

          Debugging
          Event-
          Mappings




                         When debugging and  changing  event  mappings
                         for  widgets, it is often necessary to reload
                         and redefine event-handlers.  Whenever a  new
                         defhandler  is  loaded  or  an  existing  one
                         changed, the following  operation  should  be
                         invoked.

                     make-class-event-map

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n_d_o_w
                         recreate the class  level  event-mapping  for
                         the  specified  _w_i_n_d_o_w instance.  make-class-
                         event-map _n_e_e_d _b_e _c_a_l_l_e_d _o_n_l_y _o_n_c_e _p_e_r  _c_l_a_s_s
                         (_n_o_t  _p_e_r  _i_n_s_t_a_n_c_e)  _t_h_a_t  _h_a_v_e  _n_e_w/_a_l_t_e_r_e_d
                         _d_e_f_h_a_n_d_l_e_r_s _d_e_f_i_n_e_d.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Special
          Event Han-
          dling




                         All activity (eg. running tools)  in  PICASSO
                         occurs  inside an event-loop.  The event-loop
                         continually polls the window-server  for  new
                         events  and  dispatches  the  events to their
                         corresponding  widgets.   This  paradigm   is
                         mutually   exclusive;   a   widget  can  only
                         receives  events  concerning  itself  and  an
                         event can only go to one widget.

                         Sometimes, widgets need to "grab" the  event-
                         loop  in  the  sense  of  a keyboard or mouse
                         grab.  In other words  a  widget  may  obtain
                         exclusive access to the event-loop to "inter-
                         cept" all events coming in.  PICASSO provides
                         several  functions  for  doing special event-
                         processing.

                     dispatch-event

                                                            [_F_u_n_c_t_i_o_n]
                         &rest
                         _e_v_e_n_t
                         &key
                         _d_i_s_p_l_a_y
                         _e_v_e_n_t-_w_i_n_d_o_w
                         _e_v_e_n_t-_k_e_y
                         &allow-other-keys
                         Used to send an event to a  window  (widget).
                         dispatch-event  determines  and  invokes  the
                         event-handler corresponding to _e_v_e_n_t.   Expo-
                         sure  events  are  handled  specially and not
                         dispatched to the window.  _e_v_e_n_t is a list of



          PICASSO Widget-Writer's Guide                           6-42







                                                        EVENT HANDLING


                         keyword-value   pairs  corresponding  to  the
                         fields in the actual event.

                     event-loop

                                                            [_F_u_n_c_t_i_o_n]
                         &key
                         (:_d_i_s_p_l_a_y (_c_u_r_r_e_n_t-_d_i_s_p_l_a_y))
                         (:handler #'dispatch-event)
                         (:hang t)
                         Invokes :_h_a_n_d_l_e_r on each event on the  event-
                         queue until :_h_a_n_d_l_e_r returns a non-nil value.
                         Then the non-nil :_h_a_n_d_l_e_r value  is  returned
                         by  event-loop.   :_h_a_n_d_l_e_r must take as argu-
                         ments the keyword-value  pairs  corresponding
                         to  the  fields of the event being processed.
                         For further information on the :_h_a_n_d_l_e_r func-
                         tion,  see the section on handler-function in
                         the CLX documentation.  If :_h_a_n_g is  non-nil,
                         event-loop  will  wait  indefinitely  for new
                         events.    Otherwise,   _e_v_e_n_t-_l_o_o_p    returns
                         automatically  when  all  events on the queue
                         are processed.

                     event-sync

                                                            [_F_u_n_c_t_i_o_n]
                         (:_d_i_s_p_l_a_y (_c_u_r_r_e_n_t-_d_i_s_p_l_a_y))
                         (:handler #'dispatch-event-special)
                         (:windows t)
                         (:mask t)
                         (:count :all)
                         (:discard-after-process nil)
                         (:discard-p nil)
                         (:hang nil)
                         Invokes _h_a_n_d_l_e_r on  selected  events  on  the
                         event-queue,  specified  by  :_w_i_n_d_o_w_s, :_m_a_s_k,
                         and :_c_o_u_n_t.  :_h_a_n_d_l_e_r is called with  regular
                         arguments :_w_i_n_d_o_w_s, :_m_a_s_k, and :_d_i_s_c_a_r_d-_p and
                         keyword-arguments  the  keyword-value   pairs
                         corresponding  to  the  fields  of  the event
                         being processed.  event-sync returns  immedi-
                         ately if :_h_a_n_d_l_e_r returns :abort.  If _h_a_n_d_l_e_r
                         is  not  specified,   event-sync   will   use
                         dispatch-event-special to filter out particu-
                         lar events according to the following specif-
                         ications:

                         :windows
                              Process  only  events  specific  to  the
                              these  PICASSO windows (widgets).  If t,
                              can be any window.
                              Type:  t, x-window OR (x-window*)

                         :mask
                              Process only events of type(s) specified



          PICASSO Widget-Writer's Guide                           6-43







                                                        EVENT HANDLING


                              in  mask.   If  t,  can  be  any type of
                              event.
                              Type:  t OR (event-type-keyword).

                         :count
                              Process first :_c_o_u_n_t  events  on  queue.
                              If :all, limit is disabled.
                              Type:  :all OR pos-int

                         :_d_i_s_c_a_r_d-_a_f_t_e_r-_p_r_o_c_e_s_s if  non-nil  specifies
                         that  all selected events are to be discarded
                         after  they  are  processed.   :_d_i_s_c_a_r_d-_p  if
                         non-nil  specifies  that  all selected events
                         are to be discarded without being  processed.
                         If  :_h_a_n_g  is  non-nil,  event-sync will wait
                         indefinitely  for  new  events.    Otherwise,
                         _e_v_e_n_t-_s_y_n_c  returns  automatically  when  all
                         events on the queue are processed.

                         event-sync is less efficient than  event-loop
                         so it is advisable to use event-loop whenever
                         possible.

                     event-dispatch-current

                                                            [_F_u_n_c_t_i_o_n]
                         &key
                         (_d_i_s_p_l_a_y (current-display))
                         Dispatches the  first  event  on  the  event-
                         queue.

                     event-discard

                                                            [_F_u_n_c_t_i_o_n]
                         &key
                         (_d_i_s_p_l_a_y (current-display))
                         Discards all events on the event-queue.

                     event-count

                                                            [_F_u_n_c_t_i_o_n]
                         &key
                         (_d_i_s_p_l_a_y (current-display))
                         Returns the number of events  on  the  event-
                         queue.

                     flush-window-output

                                                            [_F_u_n_c_t_i_o_n]
                         &key
                         (_d_i_s_p_l_a_y (current-display))
                         Flushes any buffered output to the screen.

                     flush-display

                                                            [_F_u_n_c_t_i_o_n]
                         &key
                         (_d_i_s_p_l_a_y (current-display))
                         Flushes any buffered output to  the  display,
                         flushes   any   buffered   errors  to  error-
                         handlers, and makes  sure  all  known  events
                         have  reached the event-queue.  flush-display



          PICASSO Widget-Writer's Guide                           6-44







                                                        EVENT HANDLING


                         will not return until all  of  this  is  com-
                         pleted (usually quite fast).

                     grab-display

                                                            [_F_u_n_c_t_i_o_n]
                         &key
                         (_d_i_s_p_l_a_y (current-display))
                         Grabs the  entire  window-server  and  effec-
                         tively freezes event-processing.

                     ungrab-display

                                                            [_F_u_n_c_t_i_o_n]
                         &key
                         (_d_i_s_p_l_a_y (current-display))
                         Releases a grab on the display.

                     descriptor

                                                            [_F_u_n_c_t_i_o_n]
                         _e_v_e_n_t
                         returns the event-descriptor for  the  _e_v_e_n_t.
                         A  descriptor  consists  of a list of (_e_v_e_n_t-
                         _t_y_p_e _s_t_a_t_e _d_e_t_a_i_l).  _e_v_e_n_t _c_o_n_s_i_s_t_s _o_f _a _l_i_s_t
                         _o_f   _k_e_y_w_o_r_d-_v_a_l_u_e  _p_a_i_r_s  _t_h_a_t  _s_p_e_c_i_f_y  _t_h_e
                         _a_t_t_r_i_b_u_t_e_s (_f_i_e_l_d_s) _o_f  _t_h_e  _c_o_r_r_e_s_p_o_n_d_i_n_g  X
                         _e_v_e_n_t.

                     find-entry

                                                         [_M_e_t_h_o_d/_S_e_t_f]
                         _t_a_b_l_e
                         _d_e_s_c_r_i_p_t_o_r
                         access the event-handler  for  the  specified
                         event-descriptor,  _d_e_s_c_r_i_p_t_o_r,  in the speci-
                         fied event-mapping-table, _t_a_b_l_e.  When  find-
                         entry  _i_s  _c_a_l_l_e_d,  _a  _h_i_e_r_a_r_c_h_i_c_a_l _l_o_o_k_u_p _i_s
                         _p_e_r_f_o_r_m_e_d.   _f_i_n_d-_e_n_t_r_y  first  looks  for  a
                         fully-qualified  match  with  the descriptor.
                         If a match is not found, first the _s_t_a_t_e  and
                         then  the _d_e_t_a_i_l fields, and then both fields
                         are ignored to find a  less-qualified  match.
                         If   a  match  is  found,  the  corresponding
                         event-handler is returned.  Otherwise, nil is
                         returned.

                     lookup-event-mapping

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n_d_o_w
                         _d_e_s_c_r_i_p_t_o_r
                         lookup and return the event-handler (if  any)
                         for  the specified event-descriptor, _d_e_s_c_r_i_p_-
                         _t_o_r on the specified window, _w_i_n_d_o_w.  lookup-
                         event-mapping  _p_e_r_f_o_r_m_s _a _f_i_n_d-_e_n_t_r_y on first
                         the instance-event-table and then the  class-
                         event-table  to  find  a  match.  If  none is







          PICASSO Widget-Writer's Guide                           6-45







                                                        EVENT HANDLING


                         found, nil is returned.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Instance
          Event-
          Handling




                         In addition to specifying event mappings  and
                         handlers  on  a  widget  _c_l_a_s_s level, PICASSO
                         provides support for specifying mappings  and
                         handlers  on a per _i_n_s_t_a_n_c_e basis.  As a gen-
                         eral  rule,  _i_n_s_t_a_n_c_e  event-mappings  always
                         take  precedence  over  _c_l_a_s_s event-mappings.
                         The format for _i_n_s_t_a_n_c_e event-mappings is the
                         same  as  for  _c_l_a_s_s event-mappings. However,
                         the things are specified a bit differently.

                         The specify an _i_n_s_t_a_n_c_e event-map the follow-
                         ing function is used.

                     register-callback

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n_d_o_w
                         _f_u_n_c
                         _e_v_e_n_t-_t_y_p_e
                         &key
                         (_s_t_a_t_e _n_i_l)
                         (detail nil)
                         &allow-other-keys
                         _c_r_e_a_t_e _a_n _i_n_s_t_a_n_c_e _e_v_e_n_t-_m_a_p_p_i_n_g.  _w_i_n_d_o_w _i_s _t_h_e _i_n_s_t_a_n_c_e,
                         _f_u_n_c _i_s _t_h_e _e_v_e_n_t-_h_a_n_d_l_e_r, _a_n_d _e_v_e_n_t-_t_y_p_e, _s_t_a_t_e, _a_n_d
                         _d_e_t_a_i_l _c_o_n_s_t_i_t_u_t_e _t_h_e _e_v_e_n_t-_s_p_e_c (_s_e_e _a_b_o_v_e _d_e_s_c_r_i_p_t_i_o_n _o_f
                         _e_v_e_n_t-_s_p_e_c).


























          PICASSO Widget-Writer's Guide                           6-46







                                                        EVENT HANDLING


                                               7
                                           GRAPHICS

          ____________________________________________________________________________________________________________________________________________________________________________________

          Overview


                         PICASSO  is  written  on  top  of  CLX.    As
                         described  in  the  PICASSO REFERENCE MANUAL,
                         PICASSO represents resources as  CLOS  object
                         instances,  which can be attached or detached
                         from the X  server.   But  sometimes  PICASSO
                         objects make more direct use of CLX.

                         This  chapter  explains  how   to   use   CLX
                         resources  in  graphics  operations. CLX pro-
                         vides a special structure to group together a
                         set  of  resources  to  be  used for graphics
                         operations.   This  structure  is  called   a
                         _g_r_a_p_h_i_c_s-_c_o_n_t_e_x_t    (abbreviated    as   _g_c).
                         Because the _g_r_a_p_h_i_c_s-_c_o_n_t_e_x_t is so central to
                         graphics  operations,  PICASSO  has  provided
                         facilities  for  managing  _g_r_a_p_h_i_c_s-_c_o_n_t_e_x_t_s.
                         This  first  section  describes the aforemen-
                         tioned  mechanism  and  subsequent   sections
                         describe  special  graphics  operations  that
                         PICASSO provides.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Graphics
          Contexts



                         In the X window-system,  graphics  operations
                         are    performed   with   structures   called
                         _g_r_a_p_h_i_c_s-_c_o_n_t_e_x_t_s.  CLX represents _g_c_s  as  a
                         lisp  structure.  For efficiency reasons, _g_c_s
                         are manipulated in their CLX form in  PICASSO
                         (instead of defining a special CLOS class for
                         _g_c_s).  Each _g_c has the following  fields  and
                         default values.


















          PICASSO Widget-Writer's Guide                           6-47







                                                              GRAPHICS


                             ____________________________________
                              Field            Default
                             ________________________________________________________________________
                              arc-mode         :pie-slice
                              background       "white"
                              cap-style        :butt
                              clip-mask        :none
                              clip-ordering    unsorted
                              clip-x           0
                              clip-y           0
                              dash-offset      0
                              dashes           4
                              exposures        off
                              fill-rule        even-odd
                              fill-style       solid
                              font             undefined
                              foreground       "black"
                              function         2
                              join-style       :miter
                              line-style       :solid
                              line-width       0
                              _p_a_i_n_t            _s_e_e _b_e_l_o_w
                              plane-mask       mask of ones
                              stipple          undefined
                              subwindow-mode   :clip-by-children
                              tile             undefined
                              ts-x             0
                              ts-y             0
                             ____________________________________

                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |
                            |


























                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |
                                            |


























                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |
                                                                |





























                         For more information on CLX graphic-contexts,
                         see the relevant CLX documentation.

                         _____________________________________________

          gc-spec



                         Each widget/gadget has a special  slot  named
                         _g_c-_s_p_e_c.   _g_c-_s_p_e_c can be used to specify _g_c_s
                         to be  automatically  created  and  destroyed
                         when  the  widget  is  attached and detached,
                         respectively.  _g_c-_s_p_e_c consists of a list  of
                         descriptions of _g_c_s and slots in which to put
                         them.  _g_c-_s_p_e_c is typically specified  as  an
                         initform in a widget's class-definition.  The
                         format of a _g_c-_s_p_e_c specification is  one  of
                         the following:

                         gc-spec:
                              _s_l_o_t-_s_p_e_c OR (_s_l_o_t-_s_p_e_c*)




          PICASSO Widget-Writer's Guide                           7-48







                                                              GRAPHICS


                         _s_l_o_t-_s_p_e_c is as following:

                         slot-spec:
                              (_s_l_o_t-_n_a_m_e _n_a_m_e-_s_p_e_c)

                         _s_l_o_t-_n_a_m_e must be the  name  of  an  existing
                         slot,  defined on the widget, in which the _g_c
                         can be stored when it is created.   _n_a_m_e-_s_p_e_c
                         is as follows:

                         name-spec:
                              _d_e_f_a_u_l_t-_g_c   OR   ({_d_e_f_a_u_l_t-_g_c}   _f_i_e_l_d-
                              _v_a_l_u_e*)

                         _d_e_f_a_u_l_t-_g_c, when specified, is a string which
                         represents  the  name  of a default graphics-
                         context    specification.     Default     gc-
                         specifications  are  created with register-gc
                         (explained later) and  they  specify  default
                         values  for  fields  in  the  _g_c.  _d_e_f_a_u_l_t-_g_c
                         defaults to "default".  The _f_i_e_l_d-_v_a_l_u_e argu-
                         ments  are  keyword-value pairs corresponding
                         to the field-value pairs of the _g_c.

                         field-value:
                              :_f_i_e_l_d-_n_a_m_e _v_a_l_u_e

                         _f_i_e_l_d-_n_a_m_e is just the name of the  field  of
                         the  _g_c.   _v_a_l_u_e is the desired value for the
                         field.  The type _v_a_l_u_e must  match  the  type
                         that  CLX  enforces for each field in the _g_c,
                         except for the following fields:

                         paint, background, foreground
                              Type:  string, paint,  or  integer.   If
                              string,  it  must correspond to the name
                              of a paint.  If integer, it  corresponds
                              to  the  pixel  value  of a color in the
                              colormap of the window.

                         tile, stipple
                              Type:  string or image.  If  string,  it
                              must correspond to the name of an image.

                         font Type:  string or font.   If  string,  it
                              must correspond to the name of a font.

                         Possible _g_c-_s_p_e_cs:







          PICASSO Widget-Writer's Guide                           7-49







                                                              GRAPHICS



                          (gc-res (:foreground "green" :font "6x10"))

                          ((gc-res "default")
                           (graygc (:paint "gray50"))
                           (weavegc ("weave" :foreground "white" :background "red")))



                         The :_p_a_i_n_t specification in the second  exam-
                         ple  above  is  a  added  feature in PICASSO.
                         Specifying :_p_a_i_n_t as  a  field-specifier  has
                         the   semantics   of   choosing  the  correct
                         resource depending on the  type  of  display.
                         :_p_a_i_n_t "gray50" has the following semantics:
                         If the  display  is  color,  :paint  "gray50"
                         translates to


                          :foreground "gray50" :fill-style :solid



                         If the  display  is  black-and-white,  :paint
                         "gray50" translates to


                          :tile "gray50" :fill-style :tiled



                         _____________________________________________

          gc-res



                         In addition to the _g_c-_s_p_e_c slot, PICASSO pro-
                         vides  one  other  predefined _g_c related slot
                         called gc-res.  Any _g_c put in the _g_c-_r_e_s slot
                         (via _g_c-_s_p_e_c or other means) is automatically
                         updated when the foreground and background of
                         the  window  change.  To be precise, when the
                         foreground or background of the window is set
                         to  a  color,  the  _f_o_r_e_g_r_o_u_n_d  or _b_a_c_k_g_r_o_u_n_d
                         field, respectively, of the _g_c in  gc-res  is
                         set  to the pixel number of the color and the
                         _f_i_l_l-_s_t_y_l_e field is set  to  :solid.  If  the
                         foreground or background of the window is set
                         to an image or tile, the _f_o_r_e_g_r_o_u_n_d or  _b_a_c_k_-
                         _g_r_o_u_n_d  field  in  the  _g_c  is set to the CLX
                         resource of the tile and  the  _f_i_l_l-_s_t_y_l_e  is
                         set to :tiled.




          PICASSO Widget-Writer's Guide                           7-50







                                                              GRAPHICS


                         Because _g_c-_r_e_s is updated  automatically,  it
                         is  usually  desirable  to include the _g_c-_r_e_s
                         slot in a widget's gc-spec.

                         _____________________________________________

          Creating
          GC's




                         Some widgets need to be able  to  create  _g_c_s
                         dynamically.   The  _g_c-_s_p_e_c  specification is
                         not appropriate for dynamically creating _g_c_s.
                         PICASSO provides support for dynamic creation
                         of _g_c_s with the following functions:

                     make-gc

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n_d_o_w
                         _s_p_e_c
                         &optional
                         (_s_h_a_r_e_d _n_i_l)
                         Returns a _g_c specified by  _w_i_n_d_o_w  and  _s_p_e_c.
                         _w_i_n_d_o_w  is  a  widget and _s_p_e_c is a _n_a_m_e-_s_p_e_c
                         having  the  syntax  explained  earlier.   If
                         _s_h_a_r_e_d  is  non-nil, make-gc will look to see
                         if there already exists a _g_c having the  same
                         _w_i_n_d_o_w  and  an equivalent _s_p_e_c that was also
                         created  with  the  _s_h_a_r_e_d  option.   If  the
                         lookup  is  successful,  make-gc  returns the
                         existing _g_c.  Otherwise, a new _g_c is  created
                         and  registed  as  being  sharable for future
                         calls.  Making shared _g_c_s is  generally  more
                         efficient,  in both time and space, than mak-
                         ing regular _g_c_s.  However, changing an attri-
                         bute  of  a  shared _g_c has the side-effect of
                         changing the output of  all  operations  that
                         use  the  _g_c (not just operations relating to
                         the one that originally changed the _g_c).

                     make-shared-gc

                                                               [_M_a_c_r_o]
                         _w_i_n_d_o_w
                         _s_p_e_c
                         A short form for making shared _g_c_s.  Has  the
                         same  effect  of  calling  make-gc  with  the
                         _s_h_a_r_e_d argument non-nil.

                         CLX  allows  dynamic   alteration   of   _g_c_s.
                         PICASSO provides a function providing an easy
                         interface for changing fields of  a  _g_c  that
                         takes  advantage  of  PICASSO support for _g_c_s
                         (the  :_p_a_i_n_t  field,  specifying  colors   as






          PICASSO Widget-Writer's Guide                           7-51







                                                              GRAPHICS


                         strings, etc.).

                     alter-gc

                                                            [_F_u_n_c_t_i_o_n]
                         _g_c
                         _a_t_t_s
                         Changes the fields of _g_c specified  in  _a_t_t_s.
                         _a_t_t_s   consists  of  a  list  of  _f_i_e_l_d-_v_a_l_u_e
                         specifications (the syntax of _f_i_e_l_d-_v_a_l_u_e was
                         described earlier in this chapter).
          ____________________________________________________________________________________________________________________________________________________________________________________

          Graphics
          Operations



                         Most graphics operations in PICASSO are  per-
                         formed   either  in  the  _d_o-_r_e_p_a_i_n_t  or  _d_o-
                         _r_e_p_a_i_n_t-_r_e_g_i_o_n _m_e_t_h_o_d_s, in event-handlers, or
                         as a result of bindings (eg. binds, alerters,
                         etc).  The advantage of doing graphics opera-
                         tions  in  the  repaint  methods  and  event-
                         handlers is that it is safe  to  assume  that
                         the   widget   is  actually  on  the  screen,
                         exposed.  Otherwise, it is advisable to check
                         that  the  window  is  viewable  before doing
                         graphics operations or  the  output  will  be
                         lost.   This  checking is done with following
                         macro.

                     viewable-p

                                                               [_M_a_c_r_o]
                         _w_i_n_d_o_w
                         Returns t if the window is  currently  mapped
                         onto  the screen (can be occluded), otherwise
                         nil.

                         Again, this macro is  not  necessary  in  the
                         repaint methods and event-handlers.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Put Method


                         PICASSO  provides  support  for  some  common
                         types  of  graphics  operations  like drawing
                         text and images in a window.  The  most  gen-
                         erally  useful of these support operations is
                         the put method.  The put method is defined on
                         data  types  like  strings, images, and lists
                         and provides a uniform interface for  drawing
                         a  data  object in a window.  All _p_u_t methods
                         have the following format, though  some  have
                         extra  keyword-arguments  that  others  don't
                         have.

                     put

                                                              [_M_e_t_h_o_d]
                         _s_e_l_f
                         &key



          PICASSO Widget-Writer's Guide                           7-52







                                                              GRAPHICS


                         (_w_i_n_d_o_w         _n_i_l)
                         (_g_c     (_g_c-_r_e_s _s_e_l_f))
                         (_f_o_n_t           _n_i_l)
                         (_x              _0)
                         (_y              _0)
                         (_h_e_i_g_h_t         (_h_e_i_g_h_t _s_e_l_f))
                         (_w_i_d_t_h          (_w_i_d_t_h _s_e_l_f))
                         (_m_a_s_k           _n_i_l)
                         (_d_i_m_m_e_d         _n_i_l)
                         (_i_n_v_e_r_t_e_d       _n_i_l)
                         (_h_o_r_i_z-_j_u_s_t     :_c_e_n_t_e_r)
                         (_v_e_r_t-_j_u_s_t      :_c_e_n_t_e_r)
                         &allow-other-keys
                         Draws the data object specified  by  _s_e_l_f  in
                         the  window specified by _w_i_n_d_o_w.  The default
                         values may vary for different _p_u_t methods.

                         window:
                              window in which to draw object.

                         gc:  _g_c with which to draw object.

                         font:
                              font with which to draw object (used  as
                              a convenience--changes _g_c).

                         x, y, width, height:
                              area in which to draw object  (not  used
                              for  :top or :left justification).  _x, _y
                              coordinates relative to upper-left orgin
                              of window.

                         mask:
                              draw in masked (no background--glyph for
                              text) form.

                         dimmed:
                              dim the object by  xoring  a  gray  tile
                              with output.

                         inverted:
                              invert the _g_c.

                         horiz-just:
                              horizontal justification for the  object
                              in area.

                         vert-just:
                              vertical justification for the object in
                              area.





          PICASSO Widget-Writer's Guide                           7-53







                                                              GRAPHICS


                         As many of the widgets use the put method for
                         output,  it is possible to customize the out-
                         put of many  of  the  predefined  widgets  by
                         defining  a new class and a corresponding put
                         method defined on the class.

                         For instance, one could make buttons  display
                         vertical text by defining a CLOS class called
                         vertical-text and a put method  that  outputs
                         an  instance  of  vertical-text.   To use the
                         vertical-text in a button, just set the value
                         of the button to an instance of vertical-text
                         and the button  will  draw  it  automatically
                         (since  the  button  uses  the put method for
                         output).

                         _____________________________________________

          Synthetic
          Gadgets




                         As described in the section  on  collections,
                         widgets  can  be _c_o_m_p_o_s_e_d to create more com-
                         plex types of interfaces.  Because a  complex
                         widget  may contain several widgets, creating
                         complex widgets can become  expensive.   Some
                         of  this expense can be avoided by using _s_y_n_-
                         _t_h_e_t_i_c _g_a_d_g_e_t_s.  _S_y_n_t_h_e_t_i_c _g_a_d_g_e_t_s  (abbrevi-
                         ated _s_y_n_t_h_s), are much cheaper to create than
                         normal widgets/gadgets and can even be faster
                         (to output).  Moreover, _s_y_n_t_h_s aer extensible
                         just like  normal  widgets/gadgets  (one  can
                         define new types of _s_y_n_t_h_s).

                         How are  _s_y_n_t_h_s  used  and  implemented?    A
                         _s_y_n_t_h  is  simply  a  list  consisting of the
                         arguments to a put method (described  above).
                         To draw a _s_y_n_t_h on the screen, simply invoke:


                          (apply #'put _s_y_n_t_h)



                         Many of the widgets/gadgets in  PICASSO  that
                         were originally implemented using collections
                         have  since  been  rewritten  to  use  _s_y_n_t_h_s
                         instead.    The   result  is  a  considerable
                         decrease in load-up time and an  increase  in
                         speed.  In complicated widgets like tables or
                         menus, _s_y_n_t_h_s really make a dramatic  differ-
                         ence (try creating and using a table contain-
                         ing text-widgets as fields).



          PICASSO Widget-Writer's Guide                           7-54







                                                              GRAPHICS


                         In using _s_y_n_t_h_s, it is often useful to  share
                         _g_c_s,  especially when several _g_c_s are sharing
                         the same window.  Sharing _g_c_s further reduces
                         the  overhead  of  creating  these CLX struc-
                         tures.

                         _____________________________________________

          Gray and
          Dimmed
          Output





                         Much of  the  PICASSO  interface  depends  on
                         borders in conjunction with various shades of
                         gray to achieve a  sort  of  3-D  look.   The
                         functions used to draw "gray" things are pro-
                         vided here along with those used to draw  the
                         3-D borders.

                     draw-gray-text

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n
                         _g_c
                         _s_t_r
                         _x
                         _y
                         _w
                         _h
                         Draws the string _s_t_r in unmasked form in  the
                         region  specified  by _x, _y, _w, _h.  The output
                         is effectively XOR'ed with the tile specified
                         in _g_c.  To be effective, the _f_i_l_l-_s_t_y_l_e field
                         of _g_c must be :tiled and the _f_u_n_c_t_i_o_n must be
                         8.

                     draw-gray-text-mask

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n
                         _g_c
                         _s_t_r
                         _x
                         _y
                         _w
                         _h
                         Draws the string _s_t_r in masked  form  in  the
                         region  specified  by _x, _y, _w, _h.  The output
                         is effectively xored with the tile  specified
                         in _g_c.  To be effective, the _f_i_l_l-_s_t_y_l_e field
                         of _g_c must be :tiled and the _f_u_n_c_t_i_o_n must be
                         8.

                     draw-gray-image

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n
                         _g_c
                         _i_m
                         _x



          PICASSO Widget-Writer's Guide                           7-55







                                                              GRAPHICS


                         _y
                         _w
                         _h
                         Draws the image _i_m in the region specified by
                         _x,  _y, _w, _h.  The output is effectively xored
                         with the tile specified in _g_c.  To be  effec-
                         tive,  the  _f_i_l_l-_s_t_y_l_e  field  of  _g_c must be
                         :tiled and the _f_u_n_c_t_i_o_n must be 8.

                     draw-3D-border

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n
                         _b_l_a_c_k-_g_c
                         _w_h_i_t_e-_g_c
                         _x
                         _y
                         _w
                         _h
                         &key
                         _i_n_v_e_r_t
                         Draws a "3-D" border in window _w_i_n in  region
                         _x, _y, _w, _h. The 3-D border consists of a rec-
                         tangular box in two colors to achieve  a  3-D
                         effect that "stands out".















                         _b_l_a_c_k-_g_c and _w_h_i_t_e-_g_c are  two  _g_c_s  used  to
                         draw  the  border.   Usually,  _b_a_c_k-_g_c is has
                         color "black" and _w_h_i_t_e-_g_c has color "white",
                         although  this is not necessary.  _i_n_v_e_r_t will
                         switch the use of the two _g_c_s  to  create  an
                         inverse "indented" 3-D effect.

                     draw-gray-border

                                                            [_F_u_n_c_t_i_o_n]
                         _w_i_n
                         _b_l_a_c_k-_g_c
                         _w_h_i_t_e-_g_c
                         &key
                         _i_n_v_e_r_t
                         _x-_w_i_d_t_h



          PICASSO Widget-Writer's Guide                           7-56







                                                              GRAPHICS


                         _y-_w_i_d_t_h
                         Draws a "gray" border surrounding the  window
                         _w_i_n.   The "gray" border consists of two con-
                         centric 3-D borders, the inner  one  inverted
                         to  achieve a 3-D effect that looks something
                         like a picture-frame.
















                         _b_l_a_c_k-_g_c and _w_h_i_t_e-_g_c are  two  _g_c_s  used  to
                         draw  the  border.   Usually,  _b_a_c_k-_g_c is has
                         color "black" and _w_h_i_t_e-_g_c has color "white",
                         although  this is not necessary.  _i_n_v_e_r_t will
                         switch the use of the two _g_c_s  to  create  an
                         inverse  "indented"  3-D effect.  _x-_w_i_d_t_h and
                         _y-_w_i_d_t_h specify the horizontal  and  vertical
                         widths of the border, respectively.  If width
                         is less than 3, only  the  outer  3-D  border
                         will be drawn.























          PICASSO Widget-Writer's Guide                           7-57







                                                              GRAPHICS


                                               8
                                          COLLECTIONS

          ____________________________________________________________________________________________________________________________________________________________________________________

          Overview


                         Often, it is possible to  take  advantage  of
                         existing  widgets  when writing a new widget.
                         For instance, if we were writing scroll-bars,
                         it would be wise to take advantage of buttons
                         without having to reimplement them as a  part
                         of  scroll-bars.   Similarly,  it  would be a
                         riduculous  waste  of  effort  to   implement
                         matrix-fields and table-fields independently.
                         Many widgets do little more than  bind  other
                         widgets  together  to  produce a more complex
                         interface.

                         The   techniques   for   collecting   widgets
                         together  into  a new more complex widget are
                         similar to the techniques,  outlined  in  the
                         PICASSO   REFERENCE  MANUAL,  for  collecting
                         widgets together into collection widgets  and
                         gadgets.

                         To be a collection,  a  widget  must  inherit
                         (either  directly  or indirectly) from either
                         of  the  two  classes  _c_o_l_l_e_c_t_i_o_n-_w_i_d_g_e_t   or
                         _c_o_l_l_e_c_t_i_o_n-_g_a_d_g_e_t.   If  the  widget wants to
                         receive  events,  it  should   inherit   from
                         _c_o_l_l_e_c_t_i_o_n-_w_i_d_g_e_t,    otherwise   _c_o_l_l_e_c_t_i_o_n-
                         _g_a_d_g_e_t is sufficient.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Adding
          Children



                         A collection can  have  any  number  of  sub-
                         widgets,  called _c_h_i_l_d_r_e_n.  The collection is
                         then called the _p_a_r_e_n_t of the _c_h_i_l_d_r_e_n.   Any
                         widget  can  become a child of the collection
                         by setting its _p_a_r_e_n_t attribute.  To create a
                         widget  whose  parent  is the collection <my-
                         collection>,  create  the  widget  with   the
                         :parent argument specified.  For example:


                          (make-button
                            :parent (root-window)
                            :value "Press-me")


                         creates a button which  is  a  child  of  the
                         root-window.



          PICASSO Widget-Writer's Guide                           7-58







                                                           COLLECTIONS


                         Though widgets can be created and  reparented
                         at  any  time,  it  is  usually  advisable to
                         create and parent the children of  a  collec-
                         tion when the collection is created.  Because
                         widget creation and reparenting are expensive
                         operations,  it is not as suitable to perform
                         them at run-time,  as  opposed  to  creation-
                         time.  Hence, children are usually created in
                         the new-instance method.
          ____________________________________________________________________________________________________________________________________________________________________________________

          Other
          Details



                         All  other  details  concerning  collections,
                         like          geometry-management         and
                         attaching/detaching,  can  be  found  in  the
                         PICASSO REFERENCE MANUAL.







































          PICASSO Widget-Writer's Guide                           8-59










                               Table of Contents


          Chapter 1:  INTRODUCTION
                 Overview .......................................  1-2
                 Widgets and Gadgets ............................  1-2
                 Contents .......................................  1-4
          Chapter 2:  WHAT'S A WIDGET
                 Overview .......................................  2-5
                 Widgets ........................................  2-5
          Chapter 3:  A SAMPLE WIDGET
                 Overview .......................................  3-8
                 Widget Definition ..............................  3-8
                 Gadget Definition .............................. 3-10
                 Accessor Methods ............................... 3-12
                 Initialization ................................. 3-15
                 Interface ...................................... 3-16
                 Widget ......................................... 3-18
          Chapter 4:  Standard Methods
                 Overview ....................................... 4-21
                 Initialization ................................. 4-21
                 Event-handling Methods ......................... 4-22
                 Connections .................................... 4-25
          Chapter 5:  Inherited Attributes
                 Overview ....................................... 5-27
                 Resources ...................................... 5-27
                 Region ......................................... 5-28
                 Geometry hints ................................. 5-29
                 Graphics ....................................... 5-30
                 Borders ........................................ 5-32
                 Labels ......................................... 5-32
                 Status ......................................... 5-33
                 Miscellaneous .................................. 5-34
          Chapter 6:  EVENT HANDLING
                 Overview ....................................... 6-36
                 Requesting Events .............................. 6-37
                 Handling Events ................................ 6-38
                 Special Event Handling ......................... 6-42
                 Instance Event-Handling ........................ 6-46
          Chapter 7:  GRAPHICS
                 Overview ....................................... 7-47
                 Graphics Contexts .............................. 7-47
                 Graphics Operations ............................ 7-52
                 Put Method ..................................... 7-52
          Chapter 8:  COLLECTIONS
                 Overview ....................................... 8-58
                 Adding Children ................................ 8-58
                 Other Details .................................. 8-59







          WWG                                                        i



