📄 dw.txt
字号:
Jan 2001, S.Geerken@ping.deLast update: Nov 2001================Dw: Dillo Widget================Dw is mainly the module for rendering HTML. It provides a frameworkfor widgets, based on the Gtk+ object framework, and is very similarto Gtk+, so that experiences in using and extending Gtk+ help verymuch 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 OwnWidgets" in the tutorial.Why Not Gtk+?=============There are two reasons for designing a new model instead of simplyusing 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 usedwithin 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 betweenGtkDwViewport and DwWidget (e.g. Dw_gtk_viewport_remove_dw), theybelong to the core of Dw. And, of course, functions only used within asub-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 beginwith "Dw_gtk_" or "a_Dw_gtk", respectively.Basic Overview==============Dw widgets are objects derived from DwWidget, which itself derivesfrom GtkObject. DwWidget is quite similar to GtkWidget, the maindifference is that Dw widgets are always windowless and that they arepresented in a viewport, so there is no need to limit the size. Muchof the functionality normally provided by the X server is simulatedby 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 widgetDw widgets draw into the viewport window, and must adhere to*viewport coordinates*: the "world" is only an abstract term, thereis no window for it. When GtkDwViewport processes expose events, theyare automatically delivered to the Dw widgets. Redrawing requests dueto scrolling of the viewport is done by the base object GtkLayout,you will not find any code for this in Dw.Mouse event contain viewport coordinates, too. Dw will try to findthe 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 widgetrewraps 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 widgetDwEmbedGtk. For Gtk+, these embedded Gtk+ widgets are themselveschildren of the GtkDwViewport, since Gtk+ does not care about Dw.Of course, embedded Gtk+ widgets are again limited in size, but butin position: GtkDwViewport is derived from GtkLayout which is exactlydesigned 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 andplain 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 DwAllocationas DwRequisition do not have a height member, but instead ascent anddescent, both positive or zero. (Originally I removed this, but therewill be a few widgets in future depending on this, e.g. mathformulas.)Unlike in Gtk, sizes of zero are allowed. The upper limit for thesize of a widget is 2^31 (this will be enough to show the contents ofa small library in a web page).Resizing========From outside: When writing a new widget, you should implement thesignal "size_request". When the widget changes its size, it shouldcall p_Dw_widget_queue_resize, as in a_Dw_image_size. See "IncrementalResizing" 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 doneby a_Dw_widget_size_request.Inside: q_Dw_widget_queue_resize will set the DW_NEEDS_RESIZE flag, afurther call of a_Dw_widget_size_request will only then emit the"size_request" signal. Furthermore, mark_size_change andmark_extremes_change are called (see below). After that, the resizingis done in an idle loop, this prevents too many size requests. Thealgorithm is quite simple: any widget with a child which needsresizing, needs resizing, thus all parents up to top-level widget aremarked.Incremental Resizing---------------------A widget may calculate its size based on size calculations alreadydone before. In this case, a widget must exactly know the reasons, whya call of size_request is necessary. To make use of this, a widgetmust 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 soimplement resizing in a faster way. A good example on how to use thisis 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 thefollowing 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 anda_Dw_gtk_scrolled_window_set_anchor.After a_Dw_gtk_viewport_set_anchor has been called (by Nav_open_url(indirectly), or by a_Dw_gtk_viewport_add_dw), changes of anchorpositions (e.g. if widgets change there size, or the anchor was notknown before) will correct the viewport adjustment (in functionp_Dw_gtk_viewport_update_anchor), but only as long as the user did notchange it directly. Look at Dw_gtk_scrolled_window_init for detailsabout the latter.Use p_Dw_widget_set_anchor to add anchors to a widget, seeDwWidget.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. E.g, 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) `----GtkDwViewportObjects 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 inGtk+, containers are responsible for storing the children, there isno common data structure. There are a few signals: - void add (DwContainer *container, DwWidget *child); Currently not used, but may 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 containerwidgets. The Gtk+ widget is set by a_Dw_embed_gtk_add_gtk, and cansimply be removed by destroying it.If the DwEmbedGtk contains no Gtk+ widget, it always returns 0x0x0 assize, so, for speed reasons, first add the Gtk+ widget into theDwEmbedGtk, and then the DwEmbedGtk into the other Dw widget, as atthe 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 theGtkDwScrolledFrame and the GtkDwViewport, connects some signals, andprovides 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 keypresses 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 userchanged the viewport adjustments horizontally/vertically by using thekeys or button 2 dragging.GtkDwViewport-------------The interface between Gtk+ and Dw. It is responsible for displayingDw Widgets and processing their events. It is derived from GtkLayout,to make embedding Gtk+ widgets into Dw widgets simpler, see thedocumentation 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 themethods 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 thescrolled area.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -