-
-POCO WebWidgets is a library combining HTML generation with Javascript usage. WebPages can be easily created either in C++ code or via XML configuration loading. Each GUI element offers events as known from the HTML standard and supports registration of client-side callbacks (i.e. Javascript function calls) and server-side callbacks (i.e. for each event a HTTPRequest is sent to the server). This documentation will present in detail the available GUI elements and their usage.
- --
--
-The root class for all GUI elements is Widget. A Widget supports via the methods preVisit and visit a two-step visitor pattern. A Widget can be searched for other Widgets via the find method. All Widgets offer events and are creatable by loading and parsing an XML file.
--
-Each Widget can be loaded via an XML configuration. A simple example for a text label would be:
-<label>Test Label</label> --
-
Furthermore, all widgets share a common set of attributes:
-Thus, a label with an id and a class will look like this:
-<label id="lbl1" class="label">Test Label</label> --
-
-
-A GUI is a tree of GUI elements. Suppose you have created a GUI which contains a child named c1 and you want to retrieve it:
-using Poco::WebWidgets::Widget; -using Poco::WebWidgets::XMLUtil; - -std::ifstream in("mygui.xml"); -if (!in) - throw Poco::FileNotFoundException("mygui.xml"); -Poco::AutoPtr<Widget> ptrRoot = XMLUtil::loadWidget(in); -Poco::AutoPtr<Widget> ptrChild = Widget::find(ptrRoot, "c1"); -poco_assert (ptrChild); - [...]; // continue using ptrChild, like registering delegates,... --
-
Note that finding a child is an expensive operation which in the worst case requires full tree traversal.
- --Widgets come with their own event flavor called JavaScriptEvent. A JavaScriptEvent can be seen as a sort of extended Poco::BasicEvent. Thus, all the methods known from BasicEvent work:
- -using Poco::WebWidgets::Widget; -Poco::AutoPtr<Widget> ptrWidget = [...]; -ptrWidget->ESingleClick += delegate(this, &MyClass::onSingleClickMethod); -[...] -ptrWidget->ESingleClick -= delegate(this, &MyClass::onSingleClickMethod); --
-
JavaScriptEvents were extended in two different ways:
-An example for JSDelegate would be:
-using Poco::WebWidgets::JSDelegate; -using Poco::WebWidgets::jsDelegate; -using Poco::WebWidgets::Widget; - -Poco::AutoPtr<Widget> ptrWidget = [...]; -ptrWidget->ESingleClick += JSDelegate("onSingleClick", "appinf.js"); -ptrWidget->ESingleClick += jsDelegate("onSingleClick2", "additional.js"); --
-
The HTML generator will generate the following code for that. Note that we assume that the widget has the id i2:
-<script src="additional.js"></script> -<script src="appinf.js"></script> -<script type="text/javascript"> - function multiEventHandleronclicki2(ev) { - if (!ev) { - ev = window.event; - } - onSingleClick(ev); - onSingleClick2(ev); - } -</script> --
-
Method signatures of JSDelegates must take as input a JavaScript event object.
-The Widget class offers for each different event type a JavaScriptEvent:
-JavaScriptEvent<MouseEventArgs> ESingleClick; -JavaScriptEvent<MouseEventArgs> EDoubleClick; -JavaScriptEvent<MouseEventArgs> EMouseDown; -JavaScriptEvent<MouseEventArgs> EMouseUp; -JavaScriptEvent<MouseMovementArgs> EMouseOver; -JavaScriptEvent<MouseMovementArgs> EMouseOut; -JavaScriptEvent<MouseMovementArgs> EMouseMove; -JavaScriptEvent<KeyboardFocusArgs> EFocusEnter; -JavaScriptEvent<KeyboardFocusArgs> EFocusLost; -JavaScriptEvent<KeyEventArgs> EKeyUp; -JavaScriptEvent<KeyEventArgs> EKeyDown; -JavaScriptEvent<KeyEventArgs> EKeyPressed; --
-
Note that not all events are meaningful for all widgets! Some will never fire, some might behave differently with different browsers. There is still a lot of work to do in that area!
--
-JSDelegates can be configured via the XML file. Simply add to the Widget node a child named events and create for each different event type a child element with the name of the event. Then add your jsDelegates via the keyword delegate. The mapping of JavaScriptEvent to XML element name is as given:
-Assume that we have a label where we want to find out whenever someone is moving the mouse over it:
-<label> - Test Label - <events> - <onmouseover> - <delegate function="printMessage" file="appinf.js"/> - </onmouseover> - </events> -</label> --
-
-An InputField extends Widget and is the abstract root class for all form members that can send data back to the server.
--In addition to the events inherited from Widget, an InputField has the following JavaScriptEvents:
-JavaScriptEvent<InputField*> EChange; -JavaScriptEvent<InputField*> ESelect; --
-
which maps to the following XML keywords:
-Additionally, an InputField comes with a BasicEvent which works without JavaScript being enabled:
-This event will be fired whenever the value of the input field is updated at the server. This typically happens when the client clicks on a submit Button.
- --A RootPanel is the root widget for each GUI. Each Web page MUST have a RootPanel as its root element. It allows to set header specific information (by adding a HTML widget to the header element) and it takes n Widgets as children. The HTML code generated by a RootPanel is always a complete web page.
--
-RootPanel(const std::string& name, - const std::vector<Poco::AutoPtr<Widget> >& children = std::vector<Poco::AutoPtr<Widget> >()); --
-
-
-rootPanel --
-
-
--
-<rootPanel name="Test Document"> -<header> - <html> - <![CDATA[ - [...] - ]]> - </html> -</header> -<children> - <!-- set of widgets --> -</children> --
</rootPanel>
--
-A standard click button, can be of type reset or submit.
--
-Button(const std::string& text, - Type t = TYPE_SUBMIT); // TYPE_RESET --
-
-
-button --
-
-
--
-<button text="Click" type="submit"/> --
-
-
-<input class="button" id="i8" type="submit" value="Click"/> --
-
-A CheckBox is an InputField, checkBoxes can be grouped together by assigning them identical names. Multiple selection inside a group is possible.
--
-CheckBox(const std::string& name, const std::string& text, bool checked = false); --
-
-
-checkBox --
-
-
--
-<checkBox id="c1" name="check" checked="true">Check This</checkBox> -<checkBox id="c2" name="check">Check That</checkBox> --
-
-
-<input checked="checked" class="checkbox" id="c1" name="check" type="checkbox" value="Check This"/>Check This<br> -<input class="checkbox" id="c2" name="check" type="checkbox" value="Check That"/>Check That --
Check This
- -
-A ComboBox offers a drop-down menu that can only contain labels. When created from an XML file, all children not equal to label are simply ignored. A ComboBox only allows to select one single element. If multi-selection is required, consider using a ListView. Note that a selection of -1 means nothing is selected, indices start with 0.
--
-ComboBox(const std::string& uniqueName, - const std::vector<Poco::AutoPtr<Label> >& children = std::vector<Poco::AutoPtr<Label> >(), - int selected = -1); --
-
-
-comboBox --
-
-
--The following example will pre-select the 3rd label (indizes start with 0!).
-<comboBox name="combo" select="2" id="c1"> - <label>1st</label> - <label>2nd</label> - <label>3rd</label> - <label>4th</label> -</comboBox> --
-
-
-<select class="combobox" id="c1" name="combo" size="1"> - <option>1st</option> - <option>2nd</option> - <option selected="selected">3rd</option> - <option>4th</option> -</select> --
-
-A FlowPanel stores widgets next to each other as long as the page is wide enough.
--
-FlowPanel(const std::vector<Poco::AutoPtr<Widget> >& children = std::vector<Poco::AutoPtr<Widget> >()); --
-
-
-flow --
-
-No attributes.
--
-<flow> - <label>Test Label</label> - <label>2nd Label</label> - <label>3rd Label</label> -</flow> --
-
-
-<a>Test Label</a><a>2nd Label</a><a>3rd Label</a> --
Test Label2nd Label3rd Label
- -
-A HTML form object contains multiple other widgets, mostly InputField objects. A Form contains two urls: one allows to specify the action that should be executed e.g. the url of a CGI script, and the 2nd optional URL is a redirect to a page that should be shown after processing has finished.
--
-Form(const Poco::URI& action, - const Poco::URI& redirect, - Method m = M_GET|, //M_POST - const std::vector<Poco::AutoPtr<Widget> >& children = std::vector<Poco::AutoPtr<Widget> >()); --
-
-
-form --
-
-
--
-<form id="f1" action="/test.xml" method="post"> - [...] -</form> --
- -
-A HidablePanel decorates a single widget with a text and a minimize button. If you want to add more than one Widget, use a StackPanel, a FlowPanel or a Table to organize these widgets, and add that single Widget. Minimizing/maximizing requires JavaScript to be enabled.
--
-HidablePanel(Poco::AutoPtr<Widget> ptr, - const Poco::URI& onImage, - const Poco::URI& offImage, - const std::string& text, - bool inlineMode = false); --
-
-
-hidablePanel --
-
-
--
-<hidablePanel id="h1" on="images/on.gif" off="images/off.gif" text="Extended Settings"> - <flow> - <label>First Name</label> - <textField id="t1" size="20" maxLength="40" name="first"/> - </flow> -</hidablePanel> --
-
-
-function onClickh1() { - var child = $("hpt1"); - var imgBut = $("hpi1"); - if (child.style.display == "none") { - child.style.display = "block"; - imgBut.src = "images/on.gif"; - } else { - child.style.display = "none"; - imgBut.src = "images/off.gif"; - } -} - -<input class="imagebutton" id="hpi1" onclick="onClickh1()" src="images/on.gif" type="image"/>Extended Settings<br/> -<input class="textfield" id="hpt1" maxlength="40" name="first" size="20" type="text"/> --
- Extended Settings
-
-Use this class to inject raw HTML into a GUI. When defined in an XML file, wrap CDATA around the HTML code.
--
-HTML(const std::string& txt); --
-
-
-html --
-
-No attributes.
--
-<html> -<![CDATA[ - <meta name="Date" content="2005-11-15T23:31:20+01:00"> - <meta name="Identifier" content="http://appinf.com/html/test.htm"> - <meta name="Language" content="de"> -]]> -</html> --
-
-The HyperLink object simplifies link insertion. It can contain either a label or an image as child.
--
-HyperLink(const Poco::URI& uri, Poco::AutoPtr<Widget> ptrWidget=Poco::AutoPtr<Widget>()); --
-
-
-hyperLink --
-
-
--
-<hyperLink ref="http://pocoproject.org"> - <image>...</image> -</hyperLink> -<hyperLink ref="http://pocoproject.org"> - <label>The POCO Project</label> -</hyperLink> --
-
-
-<a href="http://pocoproject.org" id="l1">The POCO Project</a> --
The POCO Project
-
-Used to embed an image into a web page.
--
-Image(const Poco::URI& uri, const std::string& text, Poco::UInt32 width = 0, Poco::UInt32 height = 0); --
-
-
-image --
-
-
--
-<image id="i1" alt="Micro Image" title="Micro sized Image" src="http://appinf.com/poco/images/PocoLayers.jpg" width="20" height="16"/> --
-
-
-<img alt="Micro Image" class="image" height="16" id="i1" src="http://appinf.com/poco/images/PocoLayers.jpg" title="Micro sized Image" width="20"/> --
-
-An Imagebutton is basically a standard Button displaying an image instead of a text.
- --
-ImageButton(const Poco::URI& img, const std::string& alternativeText, Poco::UInt32 width = 0, Poco::UInt32 height = 0); --
-
-
-imageButton --
-
-
--
-<imageButton id="i1" text="Micro Image" img="http://appinf.com/poco/images/PocoLayers.jpg" width="30" height="30"/> --
-
-
-<input alt="Micro Image" class="imagebutton" height="30" id="i1" src="http://appinf.com/poco/images/PocoLayers.jpg" type="image" width="30"/> --
- -
-Use this class to add text to your GUI.
--
-Label(const std::string& txt); --
-
-
-label --
-
-No attributes.
--
-<label>Hello</label> --
-
-
-Hello --
Hello
--A ListView offers a scrollable list of selectable targets. As targets only labels are valid, non-labels are ignored. Multi-selection is possible. Indices start with 0.
--
-ListView(const std::string& uniqueName, - int viewSize, - bool multiple, - const std::vector<Poco::AutoPtr<Label> >& children = std::vector<Poco::AutoPtr<Label> >()); --
-
-
-listView --
-
-
--
-<listView id="v1" name="list" size="3" multiple="true" select="0 2 4"> - <label>1st</label> - <label>2nd</label> - <label>3rd</label> - <label>4th</label> - <label>5th</label> - <label>6th</label> -</listView> --
-
-
-<select class="listview" id="v1" multiple="multiple" name="list" size="3"> - <option selected="selected">1st</option> - <option>2nd</option> - <option selected="selected">3rd</option> - <option>4th</option> - <option selected="selected">5th</option> - <option>6th</option> -</select> --
-
-
-A text field to read passwords.
- --
-PwdField(const std::string& uniqueName, Poco::UInt32 size, Poco::UInt32 maxLength); --
-
-
-pwdField --
-
-
--
-<pwdField id="i1" size="20" maxLength="40" name="pwdField"/> --
-
-
-<input class="password" id="i1" maxlength="40" name="pwdField" size="20" type="password"/> --
-
-
-A RadioButton is a member of a button group. Only one can be selected of a group.
--
-RadioButton(const std::string& group, const std::string& text, bool checked=false); --
-
-
-radioButton --
-
-
--
-<radioButton id="b1" name="radio" checked="false">Click me</radioButton> -<radioButton id="b2" name="radio" checked="true">No! Click Me!</radioButton> --
-
-
-<input class="radiobutton" id="b1" name="radio" type="radio" value="Click me"/>Click me<br> -<input checked="checked" class="radiobutton" id="b2" name="radio" type="radio" value="No! Click Me!"/>No! Click Me! --
- Click me
- -
-A StackPanel contains a list of Widgets which are rendered on top of each other
--
-StackPanel(const std::vector<Poco::AutoPtr<Widget> >& children = std::vector<Poco::AutoPtr<Widget> >()); --
-
-
-stack --
-
-No attributes.
--
-<stack> - <label>Test Label</label> - <label>2nd label</label> - <label>3rd label</label> -</stack> --
- -
-
-Test Label<br>2nd label<br>3rd label --
- Test Label
-
-A Table stores a matrix of Widgets. A Table must have a column size, can have a maximum row count, can have a header, a footer and a body. For each of the last three elements separate attributes can be set.
--
-Table(Poco::UInt32 numRows, - Poco::UInt32 numCols, - bool tableHasFooter, - bool tableHasHeader = true, - Poco::UInt32 borderStrength = 0, - Poco::UInt32 width = 0); --
-
-
-table --
-
-
--Note that a table consists of cells. Each cell can have a row and col index. Indices start with 0. If one of these values is not present, the last value will be taken and incremented if necessary.
- -<table id="i1" border="1" cols="3"> - <cell> - <stack> - <radioButton id="i2" name="radio">Click me</radioButton> - <radioButton id="i3" name="radio"><![CDATA[<b>No! Click Me!</b>]]></radioButton> - </stack> - </cell> - <cell> - <stack> - <checkBox id="i4" name="check">Check This</checkBox> - <checkBox id="i5" name="check">Check That</checkBox> - </stack> - </cell> - <!-- the third column has no value --> - <cell row="1"> - <stack> - <label>A Text Area</label> - <textArea id="i6" rows="10" cols="30" name="textArea"/> - </stack> - </cell> - <cell col="2"> - <flow> - <label>A Text Field:</label> - <textField id="i7" size="20" maxLength="40" name="textField"/> - </flow> - </cell> -</table> --
- -
-
-<table border="1" class="table" id="i1"> - <thead> - <tr> - <th> - <input class="radiobutton" id="i2" name="radio" type="radio" value="Click me"/>Click me<br> - <input class="radiobutton" id="i3" name="radio" type="radio" value="No! Click Me!"/>No! Click Me! - </th> - <th> - <input class="checkbox" id="i4" name="check" type="checkbox" value="Check This"/>Check This<br> - <input class="checkbox" id="i5" name="check" type="checkbox" value="Check That"/>Check That</th> - <th> - - </th> - </tr> - </thead> - <tbody> - <tr> - <td> - A Text Area<br> - <textarea class="textarea" cols="30" id="i6" name="textArea" rows="10"></textarea> - </td> - <td> - - </td> - <td> - <a>A Text Field:</a> - <a><input class="textfield" id="i7" maxlength="40" name="textField" size="20" type="text"/></a> - </td> - </tr> - </tbody> -</table> --
-
Click me No! Click Me! | Check This Check That | |
---|---|---|
A Text Area | A Text Field: |
-
-A TextArea is a multi-line text field. Note that any default text will show up in the TextArea as entered in the XML file, i.e. with line breaks and tabs.
- --
-TextArea(const std::string& uniqueName, - Poco::UInt32 rows, - Poco::UInt32 cols, - const std::string& defTxt = std::string()); --
-
-
-textArea --
-
-
--
-<textArea id="i6" rows="10" cols="30" name="textArea">default text</textArea> --
- -
-
-<textarea class="textarea" cols="30" id="i6" name="textArea" rows="10">default text</textarea> --
-
- -
-A TextField is a single-line text field.
- --
-TextField(const std::string& uniqueName, - Poco::UInt32 size, - Poco::UInt32 maxLength, - const std::string& defTxt = std::string()); --
-
-
-textField --
-
-
--
-<textField id="i7" size="20" maxLength="40" name="textField">default text</textField> --
- -
-
-<input class="textfield" id="i7" maxlength="40" name="textField" size="20" type="text" value="default text"/> --
-
-
-The WebWidgets project comes with a pre-defined HTTPRequestHandlerFactory named Poco::WebWidgets::WidgetHandlerFactory. To get a WebWidgets application up and running follow these steps:
-Example:
-unsigned short port = (unsigned short) config().getInt("HTTPFormServer.port", 9980); - -// set-up a server socket -ServerSocket svs(port); -// set-up a HTTPServer instance -Poco::URI root("/"); - -// create the WidgetHandlerFactory -WidgetHandlerFactory* pFac = new WidgetHandlerFactory(); - -// load/create your widgets -std::ifstream in("Order.xml"); -Poco::AutoPtr<Widget> ptrWidget = XMLUtil::loadWidget(in); - -// register for events if required -Poco::AutoPtr<Widget> ptrSubmitButton = ptrWidget->find("submit"); -poco_assert (ptrSubmitButton); -ptrSubmitButton->ESingleClick += delegate(this, &MyServerApp:onOrderClicked); - -// register the widgets at the WidgetHandlerFactory -pFac->addWidget(root, ptrWidget); -HTTPServer srv(pFac, svs, new HTTPServerParams); -// start the HTTPServer -srv.start(); -// wait for CTRL-C or kill -waitForTerminationRequest(); -// Stop the HTTPServer -srv.stop(); -return Application::EXIT_OK; --
-
Note that the WidgetHandlerFactory is still incomplete. At least a possibility to add ones own HTTPRequestHandler for a given URI is required!
- -