diff options
Diffstat (limited to 'doc/dw-usage.doc')
-rw-r--r-- | doc/dw-usage.doc | 373 |
1 files changed, 373 insertions, 0 deletions
diff --git a/doc/dw-usage.doc b/doc/dw-usage.doc new file mode 100644 index 00000000..d0aa8d36 --- /dev/null +++ b/doc/dw-usage.doc @@ -0,0 +1,373 @@ +/** \page dw-usage Dillo Widget Usage + +This document describes the usage of Dw, without going too much into +detail. + + +<h2>Getting Started</h2> + +In this section, a small runnable example is described, based on the +FLTK implementation. + +As described in \ref dw-overview, the following objects are needed: + +<ul> +<li> dw::core::Layout, +<li> an implementation of dw::core::Platform (we will use + dw::fltk::FltkPlatform), +<li> at least one implementation of dw::core::View (dw::fltk::FltkViewport), + and +<li> some widgets (for this example, only a simple dw::Textblock). +</ul> + +First of all, the necessary #include's: + +\code +#include <fltk/Window.h> +#include <fltk/run.h> + +#include "dw/core.hh" +#include "dw/fltkcore.hh" +#include "dw/fltkviewport.hh" +#include "dw/textblock.hh" +\endcode + +Everything is put into one function: + +\code +int main(int argc, char **argv) +{ +\endcode + +As the first object, the platform is instanciated: + +\code + dw::fltk::FltkPlatform *platform = new dw::fltk::FltkPlatform (); +\endcode + +Then, the layout is created, with the platform attached: + +\code + dw::core::Layout *layout = new dw::core::Layout (platform); +\endcode + +For the view, we first need a FLTK window: + +\code + fltk::Window *window = new fltk::Window(200, 300, "Dw Example"); + window->begin(); +\endcode + +After this, we can create a viewport, and attach it to the layout: + +\code + dw::fltk::FltkViewport *viewport = + new dw::fltk::FltkViewport (0, 0, 200, 300); + layout->attachView (viewport); +\endcode + +Each widget needs a style (dw::core::style::Style, see dw::core::style), +so we construct it here. For this, we need to fill a +dw::core::style::StyleAttrs structure with values, and call +dw::core::style::Style::create (latter is done further below): + +\code + dw::core::style::StyleAttrs styleAttrs; + styleAttrs.initValues (); + styleAttrs.margin.setVal (5); +\endcode + +dw::core::style::StyleAttrs::initValues sets several default +values. The last line sets a margin of 5 pixels. Next, we need a +font. Fonts are created in a similar way, first, the attributes are +defined: + +\code + dw::core::style::FontAttrs fontAttrs; + fontAttrs.name = "Bitstream Charter"; + fontAttrs.size = 14; + fontAttrs.weight = 400; + fontAttrs.style = dw::core::style::FONT_STYLE_NORMAL; +\endcode + +Now, the font can be created: + +\code + styleAttrs.font = dw::core::style::Font::create (layout, &fontAttrs); +\endcode + +As the last attributes, the background and forground colors are +defined, here dw::core::style::Color::createSimple must be called: + +\code + styleAttrs.color = + dw::core::style::Color::createSimple (layout, 0x000000); + styleAttrs.backgroundColor = + dw::core::style::Color::createSimple (layout, 0xffffff); +\endcode + +Finally, the style for the widget is created: + +\code + dw::core::style::Style *widgetStyle = + dw::core::style::Style::create (layout, &styleAttrs); +\endcode + +Now, we create a widget, assign a style to it, and set it as the +toplevel widget of the layout: + +\code + dw::Textblock *textblock = new dw::Textblock (false); + textblock->setStyle (widgetStyle); + layout->setWidget (textblock); +\endcode + +The style is not needed anymore (a reference is added in +dw::core::Widget::setStyle), so it should be unreferred: + +\code + widgetStyle->unref(); +\endcode + +Now, some text should be added to the textblock. For this, we first +need another style. \em styleAttrs can still be used for this. We set +the margin to 0, and the background color to "transparent": + +\code + styleAttrs.margin.setVal (0); + styleAttrs.backgroundColor = NULL; + + dw::core::style::Style *wordStyle = + dw::core::style::Style::create (layout, &styleAttrs); +\endcode + +This loop adds some paragraphs: + +\code + for(int i = 1; i <= 10; i++) { + char buf[4]; + sprintf(buf, "%d.", i); + + char *words[] = { "This", "is", "the", buf, "paragraph.", + "Here", "comes", "some", "more", "text", + "to", "demonstrate", "word", "wrapping.", + NULL }; + + for(int j = 0; words[j]; j++) { + textblock->addText(strdup(words[j]), wordStyle); +\endcode + +Notice the \em strdup, dw::Textblock::addText will feel responsible +for the string, and free the text at the end. (This has been done to +avoid some overhead in the HTML parser.) + +The rest is simple, it also includes spaces (which also have styles): + +\code + textblock->addSpace(wordStyle); + } +\endcode + +Finally, a paragraph break is added, which is 10 pixels high: + +\code + textblock->addParbreak(10, wordStyle); + } +\endcode + +Again, this style should be unreferred: + +\code + wordStyle->unref(); +\endcode + +After adding text, this method should always be called (for faster +adding large text blocks): + +\code + textblock->flush (); +\endcode + +Some FLTK stuff to finally show the window: + +\code + window->resizable(viewport); + window->show(); + int errorCode = fltk::run(); +\endcode + +For cleaning up, it is sufficient to destroy the layout: + +\code + delete layout; +\endcode + +And the rest + +\code + return errorCode; +} +\endcode + +If you compile and start the program, you should see the following: + +\image html dw-example-screenshot.png + +Try to scroll, or to resize the window, you will see, that everything +is done automatically. + +Of course, creating new widgets, adding text to widgets etc. can also +be done while the program is running, i.e. after fltk::run has been +called, within timeouts, idles, I/O functions etc. Notice that Dw is +not thread safe, so that everything should be done within one thread. + +With the exception, that you have to call dw::Textblock::flush, +everything gets imediately visible, within reasonable times; Dw has +been optimized for frequent updates. + + +<h2>List of all Widgets</h2> + +These widgets are used within dillo: + +<ul> +<li>dw::core::ui::Embed +<li>dw::AlignedTextblock +<li>dw::Bullet +<li>dw::Ruler +<li>dw::Image +<li>dw::ListItem +<li>dw::Table +<li>dw::TableCell +<li>dw::Textblock +</ul> + +If you want to create a new widget, refer to \ref dw-layout-widgets. + + +<h2>List of Views</h2> + +There are three dw::core::View implementations for FLTK: + +<ul> +<li> dw::fltk::FltkViewport implements a viewport, which is used in the + example above. + +<li> dw::fltk::FltkPreview implements a preview window, together with + dw::fltk::FltkPreviewButton, it is possible to have a scaled down + overview of the whole canvas. + +<li> dw::fltk::FltkFlatView is a "flat" view, i.e. it does not support + scrolling. It is used for HTML buttons, see + dw::fltk::ui::FltkComplexButtonResource and especially + dw::fltk::ui::FltkComplexButtonResource::createNewWidget for details. +</ul> + +More informations about views in general can be found in \ref +dw-layout-views. + + +<h2>Iterators</h2> + +For examining generally the contents of widgets, there are iterators +(dw::core::Iterator), created by the method +dw::core::Widget::iterator (see there for more details). + +These simple iterators only iterate through one widget, and return +child widgets as dw::core::Content::WIDGET. The next call of +dw::core::Iterator::next will return the piece of contents \em after +(not within) this child widget. + +If you want to iterate through the whole widget trees, there are two +possibilities: + +<ol> +<li> Use a recursive function. Of course, with this approach, you are + limited by the program flow. + +<li> Maintain a stack of iterators, so you can freely pass this stack + around. This is already implemented, as dw::core::DeepIterator. +</ol> + +As an example, dw::core::SelectionState represents the selected region +as two instances of dw::core::DeepIterator. + + +<h2>Finding Text</h2> + +See dw::core::Layout::findtextState and dw::core::FindtextState +(details in the latter). There are delegation methods: + +<ul> +<li> dw::core::Layout::search and +<li> dw::core::Layout::resetSearch. +</ul> + + +<h2>Anchors and Scrolling</h2> + +In some cases, it is necessary to scroll to a given position, or to +an anchor, programmatically. + +<h3>Anchors</h3> + +Anchors are defined by widgets, e.g. dw::Textblock defines them, when +dw::Textblock::addAnchor is called. To jump to a specific anchor +within the current widget tree, use dw::core::Layout::setAnchor. + +This can be done immediately after assignig a toplevel widget, even +when the anchor has not yet been defined. The layout will remember the +anchor, and jump to the respective position, as soon as possible. Even +if the anchor position changes (e.g., when an anchor is moved +downwards, since some space is needed for an image in the text above), +the position is corrected. + +As soon as the user scrolls the viewport, this correction is not done +anymore. If in dillo, the user request a page with an anchor, which is +quite at the bottom of the page, he may be get interested in the text +at the beginning of the page, and so scrolling down. If then, after +the anchor has been read and added to the dw::Textblock, this anchor +would be jumped at, the user would become confused. + +The anchor is dismissed, too, when the toplevel widget is removed +again. + +\todo Currently, anchors only define vertical positions. + +<h3>Scrolling</h3> + +To scroll to a given position, use the method +dw::core::Layout::scrollTo. It expects several parameters: + +<ul> +<li>a horizontal adjustment parameter, defined by dw::core::HPosition, +<li>a vertical adjustment parameter, defined by dw::core::VPosition, and +<li>a rectangle (\em x, \em y, \em width and \em heigh) of the region + to be adjusted. +</ul> + +If you just want to move the canvas coordinate (\em x, \em y) into the +upper left corner of the viewport, you can call: + +\code +dw::core::Layout *layout; +// ... +layout->scrollTo(dw::core::HPOS_LEFT, dw::core::VPOS_TOP, 0, 0, 0, 0); +\endcode + +By using dw::core::HPOS_NO_CHANGE or dw::core::VPOS_NO_CHANGE, you can +change only one dimension. dw::core::HPOS_INTO_VIEW and +dw::core::VPOS_INTO_VIEW will cause the viewport to move as much as +necessary, that the region is visible in the viewport (this is +e.g. used for finding text). + + +<h2>Further Documentations</h2> + +<ul> +<li> dw::core::style +<li> dw::core::ui +<li> \ref dw-images-and-backgrounds +</ul> + +*/ |