Jan 2001, S.Geerken@ping.de
Last update: Dec 2004

========
DwWidget
========

The base object for all Dw widgets.
     

Structures
==========

DwRectangle
-----------
A replacement for GdkRectangle, the only difference is the use of 32
instead of 16 bit integers.


DwAllocation, DwRequisition
---------------------------
Similar to GtkAllocation and GtkRequisition. Instead of a height, you
have two members, ascent and descent.


DwExtremes
----------
A structure containing the minimal and maximal width of a widget. See
get_extremes below for details.


DwWidget
--------
Some members you may use:

   parent                The parent widget. NULL for toplevel widgets.

   flags                 See below.

   style                 The style attached to the widget, this must
                         always be defined, but is not created
                         automatically. Instead, this has to be done
                         immediately after creating the widget
                         (e.g., in a_Web_dispatch_by_type). This style
                         contains attributes and resources for general
                         drawing.  See DwStyle.txt for details.

These members should only be used within the "core" (GtkDw*, DwWidget
and DwEmbedGtk):

   viewport              The viewport containing the widget. Defined
                         for all widgets.

   allocation,
   requisition,
   extremes,
   user_requisition      These are used to optimize several wrappers,
                         see below.

   anchors_table         See notes on achors.

Flags
-----
Flags can be set and unset with DW_WIDGET_SET_FLAGS and
DW_WIDGET_UNSET_FLAGS. For reading flags use the macros DW_WIDGET_...

   DW_NEEDS_RESIZE
   DW_EXTREMES_CHANGED   Denotes that the widget must be resized. Used
                         only internally. See Dw.txt and the source
                         for more details.

   DW_NEEDS_ALLOCATE     Set to overide the optimation in
                         a_Dw_widget_size_allocate. Used only
                         internally.

   DW_REALIZED           Set when the widget is realized. Should be
                         used to prevent crashes in certain
                         situations.

Following flags describe characteristics of widgets and are typically
set in the init function:

   DW_USES_HINTS         A widget with this flag set has a complex way
                         to deal with sizes, and should

                            - implement the functions set_width,
                              set_ascent, set_descent, and
                              get_extremes, and
                            - deal completely with width and height
                              in widget->style.

                         Examples are DwPage and DwTable. Other
                         widgets, like DwImage and DwHRuler, are much
                         simpler and don't have to set this flag. For
                         these widgets, much of the size calculation
                         is done by the parent widget.

                         This flag is unset by default.

   DW_HAS_CONTENT        If this flag is set, more space is reserved
                         for the widget in some circumstances. E.g.,
                         if an image has a width of 100%, it makes
                         sense to use more space within a table cell,
                         as compared to a horizontal ruler, which does
                         not "have a content".

                         This flag is set by default.


Signal Prototypes
=================

  - void size_request (DwWidget *widget,
                       DwRequisition *requisition);
        
      Similar to Gtk.

   void get_extremes (DwWidget *widget,
                      DwExtremes *extremes);

      Return the maximal and minimal width of the widget, equivalent
      to the requisition width after calling set_width with zero and
      infinitive, respectively. This is important for fast table
      rendering. Simple widgets do not have to implement this; the
      default is the requisition width for both values.

  - void size_allocate (DwWidget *widget,
                        DwAllocation *allocation);

      Similar in Gtk. Note: allocation has world coordinates.

  - void set_width (DwWidget *widget,
                    guint32 width);

  - void set_height (DwWidget *widget,
                     guint32 height);

      These are hints by the caller, which *may* influence the size
      returned by size_request. The implementation should call
      Dw_widget_queue_resize if necessary. In most cases, these
      signals do not have to be implemented. Currently, only the
      DwPage widget uses this to determine the width for rewrapping
      text (note that the resulting width returned by
      Dw_page_size_request may be _bigger_) and relative sizes of the
      children.

  - void draw (DwWidget *widget,
               DwRectangle *area,
               GdkEventExpose *event);

      Draw the widget's content in the specified area. It may either
      be caused by an expose event, or by an internal drawing request
      (e.g., followed by resizing of widgets). In the first case, you
      get the *original* expose event as third argument. In the
      latter, event is NULL. The area argument has widget
      coordinates. A DwContainer is responsible for drawing its
      children.
        
      (Since DwWidget's are always windowless, there was no need for
      two signals, "draw" and "expose_event".)

  - void realize (DwWidget *widget);

      Create all necessary X resources. Called when either the
      viewport (top-level widgets) or, respectively, the parent Dw
      widget is realized, or an widget is added to an already
      realized Dw widget/viewport.

  - void unrealize (DwWidget *widget);

      Remove created X resources.

  - gint button_press_event (DwWidget *widget,
                             guint32 x,
                             guint32 y,
                             GdkEventButton *event);

      This signal is emitted when the user presses a mouse button in
      a DwWidget. x and y are the coordinates relative to the origin
      of the widget, event is the *original* event, which may, e.g.,
      be used to determine the number of the pressed button, the state
      of the shift keys, etc. The implementation of this signal
      should return TRUE, if the event has been processed, otherwise
      FALSE.

      A DwContainer is *not* responsible for delivering button press
      events to its children. Instead, Dw first emits the
      button_press_event signal for the most inner widgets and
      continues this for the parents, until TRUE is returned.

  - gint button_release_event (DwWidget *widget,
                                 guint32 x,
                               guint32 y,
                               GdkEventButton *event);

      Compare button_press_event.

  - gint motion_notify_event (DwWidget *widget,
                              guint32 x,
                              guint32 y,
                              GdkEventMotion *event);

      Compare button_press_event. event may be NULL when the call was
      caused by something different than a "real" motion notify event.
      E.g., either when widgets are moved (not yet implemented), or the
      viewport.

  - gint enter_notify_event (DwWidget *widget,
                             DwWidget *last_widget,
                             GdkEventMotion *event);

      These "events" are simulated based on motion nofify events.
      event is the *original* event (may also be NULL in some cases).
      last_widget is the widget in which the pointer was in before.

  - gint leave_notify_event (DwWidget *widget,
                             DwWidget *next_widget,
                             GdkEventMotion *event);

      Compare enter_notify_event. next_widget is the widget the
      pointer is now in.


Useful Internal Functions and Macros
====================================

  - gint Dw_widget_intersect (DwWidget *widget,
                              DwRectangle *area,
                              DwRectangle *intersection);

      Calculates the intersection of widget->allocation and area,
      returned in intersection (in widget coordinates!). Typically
      used by containers when drawing their children. Returns whether
      intersection is not empty.

  - gint32 Dw_widget_x_viewport_to_world (DwWidget *widget,
                                          gint16 viewport_x);

  - gint32 Dw_widget_y_viewport_to_world (DwWidget *widget,
                                          gint16 viewport_y);

  - gint16 Dw_widget_x_world_to_viewport (DwWidget *widget,
                                          gint32 world_x);

  - gint16 Dw_widget_y_world_to_viewport (DwWidget *widget,
                                          gint32 world_y);

      These functions convert between world and viewport coordinates.

  - void Dw_widget_queue_draw (DwWidget *widget);

  - void Dw_widget_queue_draw_area (DwWidget *widget,
                                    gint32 x,
                                    gint32 y,
                                    guint32 width,
                                    guint32 height);

  - void Dw_widget_queue_clear (DwWidget *widget);

  - void Dw_widget_queue_clear_area (DwWidget *widget,
                                     gint32 x,
                                     gint32 y,
                                     guint32 width,
                                     guint32 height);

      Equivalents to the Gtk+ functions. They (currently) result in a
      call of gtk_widget_xxx_area with the viewport as first
      argument. x and y are widget coordinates.

  - void Dw_widget_queue_resize (DwWidget *widget,
                                 gint ref,
                                 gboolean extremes_changed);

      Similar to gtk_widget_queue_resize. Call this function when the
      widget has changed its size. The next call to
      Dw_xxx_size_request should then return the new size.

      See Dw.txt for explanation on how to use the ref argument,
      extremes_changed specifies whether the extremes have changed
      (the latter is often not the case for an implementations of
      set_{width|ascent|descent}).

  - void Dw_widget_set_anchor (DwWidget *widget,
                               gchar *name,
                               int pos);

      Add an anchor to a widget. The name will not be copied, it has
      to be stored elsewhere (DwPage e.g. stores it in the DwPageWord
      structure).

  - void a_Dw_widget_set_cursor (DwWidget *widget,
                                 GdkCursor *cursor)

      Set the cursor for a DwWidget. cursor has to be stored
      elsewhere, it is not copied (and not destroyed). If cursor is
      NULL, the cursor of the parent widget is used.

      (This will probably be changed in the future and replaced by a
      common style mechanism.)

   - DW_WIDGET_WINDOW (widget)

      Returns the window a widget should draw into.


External Functions
==================

  - void a_Dw_widget_set_usize (DwWidget *widget,
                                guint32 width,
                                guint32 ascent,
                                guint32 descent);

      Override the "desired" size of a widget. Further calls of
      a_Dw_widget_request_size will return these values, except those
      specified as -1. A possible use shows Html_add_widget in
      html.c.

      (This will probably be removed. Instead DwStyle should be used.)


  - void a_Dw_widget_set_bg_color (DwWidget *widget,
                                   gint32 color);

      Set the background color of a widget. This works currently only
      for the top-level widget. In this case, the background color of
      the GtkDwViewport is changed. In future, background colors for
      all widgets will be needed, e.g., for table cells (will be
      DwPage's), this will (probably) be based on filled rectangles.

  - void a_Dw_widget_scroll_to (DwWidget *widget,
                                int pos)

      Scroll viewport to pos (vertical widget coordinate).

There are furthermore wrappers for the signals, in some cases they
are optimized and/or provide further functionality. In (almost) no
case should you emit the signals directly. See dw_widget.c for more
details.
