summaryrefslogtreecommitdiff
path: root/doc/Dw.txt
diff options
context:
space:
mode:
authorjcid <devnull@localhost>2007-10-07 00:36:34 +0200
committerjcid <devnull@localhost>2007-10-07 00:36:34 +0200
commit93715c46a99c96d6c866968312691ec9ab0f6a03 (patch)
tree573f19ec6aa740844f53a7c0eb7114f04096bf64 /doc/Dw.txt
Initial revision
Diffstat (limited to 'doc/Dw.txt')
-rw-r--r--doc/Dw.txt383
1 files changed, 383 insertions, 0 deletions
diff --git a/doc/Dw.txt b/doc/Dw.txt
new file mode 100644
index 00000000..6ffd55d0
--- /dev/null
+++ b/doc/Dw.txt
@@ -0,0 +1,383 @@
+Jan 2001, S.Geerken@ping.de
+Last update: Dec 2004
+
+================
+Dw: Dillo Widget
+================
+
+NOTE (Aug 2004): The rendering has changed quite much, and many other
+documents are out of date, in ways described in DwRendering.txt. They
+will be updated some day.
+
+Dw is mainly the module for rendering HTML. It provides a framework
+for widgets, based on the Gtk+ object framework, and is very similar
+to Gtk+, so that experiences in using and extending Gtk+ help very
+much in understanding Dw. There is some documentation at www.gtk.org
+(and probably on your local harddisk, somewhere in /usr/doc/*gtk*),
+you should especially have read the chapter "Writing Your Own
+Widgets" in the tutorial.
+
+
+Why Not Gtk+?
+=============
+
+There are two reasons for designing a new model instead of simply
+using Gtk+ objects:
+
+ 1. Most important, Gtk+ widgets are limited in size, because X
+ windows are so.
+ 2. There are a few extensions which are due to the different needs
+ for HTML rendering compared to GUI's. (Of course, this could
+ have been solved by defining a new object derived from
+ GtkWidget.)
+
+
+Notes On Naming
+===============
+
+According to the naming standards, functions beginning with "a_Dw_"
+may be used outside of Dw, while, as an extention, functions used
+within Dw (e.g. p_Dw_widget_queue_resize) are prefixed with "p_Dw_".
+[todo: This could be included in NC_design.txt.]
+
+Non-static functions beginning with "Dw_" are only used between
+GtkDwViewport and DwWidget (e.g. Dw_gtk_viewport_remove_dw), they
+belong to the core of Dw. And, of course, functions only used within a
+sub-module (e.g. a specific widget) start with "Dw_" and are static
+(e.g. Dw_page_find_line_index).
+
+Dw widgets and some other structures have the prefix "Dw", while Gtk+
+widgets in Dw have the prefix "GtkDw", but functions of them begin
+with "Dw_gtk_" or "a_Dw_gtk", respectively.
+
+
+Basic Overview
+==============
+
+Dw widgets are objects derived from DwWidget, which itself derives
+from GtkObject. DwWidget is quite similar to GtkWidget, the main
+difference is that Dw widgets are always windowless and that they are
+presented in a viewport, so there is no need to limit the size. Much
+of the functionality normally provided by the X server is simulated
+by Dw.
+
+The interface between Gtk+ and Dw is the Gtk+ widget GtkDwViewport,
+which contains (at most) one top-level Dw widget.
+
+A Few Definitions:
+
+ - world coordinates: coordinates relative to the upper left corner
+ of the whole scrolled area ("the world")
+ - viewport coordinates: coordinates relative to the upper left
+ corner of the visible area
+ - widget coordinates: coordinates relative to the upper left corner
+ of the widget
+
+Dw widgets draw into the viewport window, and must adhere to
+*viewport coordinates*: the "world" is only an abstract term, there
+is no window for it. When GtkDwViewport processes expose events, they
+are automatically delivered to the Dw widgets. Redrawing requests due
+to scrolling of the viewport is done by the base object GtkLayout,
+you will not find any code for this in Dw.
+
+Mouse events also contain viewport coordinates. Dw will try to find
+the right Dw widget to deliver the event to.
+
+Resizing the GtkDwViewport will not resize the top-level Dw widget,
+but the latter will get some hints, so that, e.g., the page widget
+rewraps the lines at the appropriate width.
+
+See DwWidget.txt for more details.
+
+
+Embedding Gtk+ Widgets In Dw
+----------------------------
+Dw Widgets may embed Gtk+ widgets, this is done by the Dw widget
+DwEmbedGtk. For Gtk+, these embedded Gtk+ widgets are themselves
+children of the GtkDwViewport, since Gtk+ does not care about Dw.
+
+Of course, embedded Gtk+ widgets are again limited in size, but but
+in position: GtkDwViewport is derived from GtkLayout which is exactly
+designed for positioning widgets in an infinite scrolled area.
+
+
+How To Get The Top-Level Dw Widget From A BrowserWindow
+-------------------------------------------------------
+The member "docwin" of BrowserWindow points on a GtkDwScrolledWindow,
+which contains a GtkDwScrolledFrame, which contains a GtkDwViewport.
+The member "child" of the latter points on the top-level Dw widget,
+or may be NULL. The top-level Dw is (currently) a DwPage (HTML and
+plain text documents) or a DwImage (images).
+
+There is a function a_Dw_gtk_scrolled_window_get_dw for this.
+
+
+Sizes
+-----
+A feature adapted from the old Dw are baselines. As well DwAllocation
+as DwRequisition do not have a height member, but instead ascent and
+descent, both positive or zero. (Originally I removed this, but there
+will be a few widgets in future depending on this, e.g., math
+formulas.)
+
+Unlike in Gtk, sizes of zero are allowed. The upper limit for the
+size of a widget is 2^31 (this will be enough to show the contents of
+a small library in a web page).
+
+
+Resizing
+========
+
+From outside: When writing a new widget, you should implement the
+signal "size_request". When the widget changes its size, it should
+call p_Dw_widget_queue_resize, as in a_Dw_image_size. See "Incremental
+Resizing" below for a way to increase the speed.
+
+Even if the implementation of "size_request" gets quite expensive,
+you do not have to check whether the size has changed, this is done
+by a_Dw_widget_size_request.
+
+Inside: q_Dw_widget_queue_resize will set the DW_NEEDS_RESIZE flag, a
+further call of a_Dw_widget_size_request will only then emit the
+"size_request" signal. Furthermore, mark_size_change and
+mark_extremes_change are called (see below). After that, the resizing
+is done in an idle loop, this prevents too many size requests. The
+algorithm is quite simple: any widget with a child which needs
+resizing, needs resizing, thus all parents up to top-level widget are
+marked.
+
+Incremental Resizing
+---------------------
+A widget may calculate its size based on size calculations already
+done before. In this case, a widget must exactly know the reasons, why
+a call of size_request is necessary. To make use of this, a widget
+must implement the following:
+
+ 1. There is a member in DwWidget, called parent_ref, which is
+ totally under control of the parent widget (and so sometimes not
+ used at all). It is necessary to define how parent_ref is used
+ by a specific parent widget, and it has to be set to the correct
+ value whenever necessary.
+
+ 2. The widget must implement mark_size_change and
+ mark_extremes_change, these methods are called in two cases:
+
+ a) directly after q_Dw_widget_queue_resize, with the argument
+ ref was passed to q_Dw_widget_queue_resize, and
+ b) if a child widget has called q_Dw_widget_queue_resize,
+ with the value of the parent_ref member of this child.
+
+This way, a widget can exactly keep track on size changes, and so
+implement resizing in a faster way. A good example on how to use this
+is the DwPage widget, see DwPage.txt for details.
+
+
+Anchors and Scrolling
+=====================
+
+Anchors
+-------
+todo: This section is out of sync with the actual code.
+
+To set the anchor a page is viewed at, you can use one of the
+following functions:
+
+ - void a_Dw_gtk_viewport_set_anchor (GtkDwViewport *viewport,
+ gchar *anchor)
+
+ Scroll directly to an anchor. The anchor does not need to exist
+ already, see below.
+
+ - void a_Dw_gtk_viewport_queue_anchor (GtkDwViewport *viewport,
+ gchar *anchor)
+
+ Set the anchor for the next top-level DwWidget (the next call
+ of a_Dw_gtk_viewport_add_dw).
+
+There are wrappers, a_Dw_gtk_scrolled_window_queue_anchor and
+a_Dw_gtk_scrolled_window_set_anchor.
+
+After a_Dw_gtk_viewport_set_anchor has been called (indirectly by
+Nav_open_url, or by a_Dw_gtk_viewport_add_dw), changes of anchor
+positions (e.g., if widgets change there size or the anchor was not
+known before) will correct the viewport adjustment (in function
+p_Dw_gtk_viewport_update_anchor), but only as long as the user did not
+change it directly. Look at Dw_gtk_scrolled_window_init for details
+about the latter.
+
+Use p_Dw_widget_set_anchor to add anchors to a widget, see
+DwWidget.txt.
+
+Scrolling
+---------
+Here is an overview on more functions for scrolling:
+
+ - To scroll to a given position, there are two possibilities:
+ a_Dw_gtk_viewport_set_scrolling_position simply scrolls to this
+ position, while Dw_gtk_viewport_scroll_to has more facilities:
+ you specify a rectangle you want to see, and the way how it is
+ seen (at the border, centered, or just scroll as much as
+ necessary, that it is seen). If you have a widget, you can also
+ use Dw_widget_scroll_to. There is also a wrapper for
+ GtkDwScrolledWindow,
+ a_Dw_gtk_scrolled_window_set_scrolling_position, and two
+ functions for getting the position,
+ a_Dw_gtk_scrolled_window_get_scrolling_position_x, and
+ a_Dw_gtk_scrolled_window_get_scrolling_position_y.
+
+ - If you have a region, and want to display it, use
+ a_Dw_iterator_scroll_to. For example, the findtext module makes
+ use of it. There are equivalents for DwExtIterator and
+ DwWordIterator. See comments on and in the function for more
+ informations.
+
+ - If you just want to determine where some content is allocated,
+ represented by an iterator, you can use
+ a_Dw_iterator_get_allocation. There are equivalents for
+ DwExtIterator and DwWordIterator.
+
+
+The Objects
+===========
+
+This is the hierarchy of all objects of Dw:
+
+ (GtkObject)
+ +-DwWidget
+ | +----DwBullet
+ | +----DwContainer
+ | | `----DwPage
+ | +----DwEmbedGtk
+ | +----DwHruler
+ | `----DwImage
+ `----(GtkWidget)
+ `----(GtkContainer)
+ +----(GtkBin)
+ | +----(GtkScrolledWindow)
+ | | `----GtkDwScrolledWindow
+ | `----GtkDwScrolledFrame
+ `----(GtkLayout)
+ `----GtkDwViewport
+
+Objects in parentheses are part of Gtk+, not of Dw.
+
+
+DwBullet
+--------
+Simple widget used for unnumbered list (<ul>).
+
+
+DwContainer
+-----------
+The base object for Dw widgets which contain other Dw widgets. As in
+Gtk+, containers are responsible for storing the children, there is
+no common data structure. There are a few signals:
+
+ - void add (DwContainer *container,
+ DwWidget *child);
+
+ Currently not used, but may be in future.
+
+ - void remove (DwContainer *container,
+ DwWidget *widget);
+
+ *Recognize* that a widget is destroyed, i.e., an implementation
+ should remove *the pointer* from the list or so, but not
+ destroy the child widget. It is called by Dw_widget_shutdown.
+
+ - void forall (DwContainer *container,
+ DwCallback callback,
+ gpointer callback_data);
+
+ Process callback for all children, in the form
+ (*callback)(child, callback_data).
+
+ The include_internals of the Gtk+ equivalent was not adapted,
+ since it is used for more sophisticated purposes not needed in
+ Dw.
+
+
+DwEmbedGtk
+----------
+This Dw widget is used to embed Gtk+ widgets into Dw container
+widgets. The Gtk+ widget is set by a_Dw_embed_gtk_add_gtk, and can
+simply be removed by destroying it.
+
+If the DwEmbedGtk contains no Gtk+ widget, it always returns 0x0x0 as
+size, so, for speed reasons, first add the Gtk+ widget into the
+DwEmbedGtk, and then the DwEmbedGtk into the other Dw widget, as at
+the end of Html_tag_open_input.
+
+
+DwHruler
+--------
+Simple widget used for the <hr> tag.
+
+
+DwImage
+-------
+Widget for displaying image. See DwImage.txt for details.
+
+
+DwPage
+------
+A widget for displaying texts. See DwPage.txt for details.
+
+
+DwTable
+-------
+A container widget for rendering tables. See DwTable.txt for details.
+
+
+DwWidget
+--------
+The base object for all Dw widgets. See DwWidget.txt for details.
+
+
+GtkDwScrolledWindow
+-------------------
+Adds a few functionalities to GtkScrolledWindow: it creates the
+GtkDwScrolledFrame and the GtkDwViewport, connects some signals, and
+provides some wrappers for using the GtkDwViewport.
+
+
+GtkDwScrolledFrame
+------------------
+General purpose scrolled widget containing another scrolled widget,
+adding a border and a focus frame. Furthermore, it processes key
+presses and mouse drags (button 2, as in Gimp) to move the viewport.
+
+There are two signals (except "set_scroll_adjustments"),
+"user_hchanged" and "user_vchanged", which are emitted when the user
+changed the viewport adjustments horizontally/vertically by using the
+keys or button 2 dragging.
+
+
+GtkDwViewport
+-------------
+The interface between Gtk+ and Dw. It is responsible for displaying
+Dw Widgets and processing their events. It is derived from GtkLayout,
+to make embedding Gtk+ widgets into Dw widgets simpler, see the
+documentation of GtkLayout in the Gtk+ tutorial for details.
+
+GtkDwViewport contains at most one top-level Dw Widget, if it exists.
+The Gtk+ methods of GtkDwViewport are more or less mapped on the
+methods of the DwWidget. In detail:
+
+ - Dw_gtk_viewport_size_allocate will call a_Dw_widget_set_width,
+ a_Dw_widget_set_ascent (with allocation->height) and
+ a_Dw_widget_set_descent (with zero as argument), and then allocate
+ the Dw widget at the size returned by a_Dw_widget_size_request.
+
+ - Dw_gtk_viewport_draw and Dw_gtk_viewport_expose will call
+ a_Dw_widget_draw, which will emit the "draw" signal.
+
+ - Handling of mouse events is mostly done in Dw_widget_mouse_event,
+ see DwWidget.txt for details. Note that the functions return
+ FALSE, if the event was not processed, so that they are delivered
+ to the parent widget(s) of the GtkDwViewport, this scheme e.g.
+ prevents dragging of the viewport (done by GtkScrolledFrame) when
+ pressing mouse button 2 on a link.
+
+You may call gtk_container_set_border_width for a border around the
+scrolled area.