nfeske / dope

The DOpE widget set for the Genode OS Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

                ========================================
                DOpE widgets for the Genode OS Framework
                ========================================


                             Norman Feske


DOpE stands for Desktop Operating Environment. It is a light-weight window
system originally created for real-time applications. In the original version,
DOpE represented a server process, to which multiple clients could connect.

Compared with commodity GUI tool kits, DOpE has the following distinctive
features:

* Widgets and their layouts are handled at the "server side" almost without
  intervention of the GUI application. The GUI application communicates a
  fairly high-level model of the widget composition to the server. After
  this initialization phase, client and server are loosely coupled.
  The server informs the client in the event of user input. The client
  pushes incremental model updates to the server.

* The communication protocol between client and server is based on a
  human-readable domain-specific language, inspired by Tcl/Tk. However,
  in contrast to Tcl/Tk, the language is not a fully-fledged programming
  language.

* The client interface is non-blocking and does not synchronously execute
  heavyweight operations on the server side. I.e., drawing operations are
  performed out of band of the client interface. This design principally allows
  any number of clients to interact with the server without impeding the
  quality of service for all clients.

* DOpE is self-sufficient and fairly free-standing. It does not need a C
  library.

More information about the rationale behind the design is provided by the
following document:

:[http://www.genode-labs.com/publications/secure-gui-2009.pdf]:
  "Securing Graphical User Interfaces"
  _Dissertation, TU Dresden, February 2009_

Given its research background, DOpE was not created as a product for real-world
usage. It lacks many features that are normally expected from modern GUI tool
kits. Still it can be useful in scenarios where a simple GUI with a low memory
and CPU footprint is desired.

The version provided herein uses the DOpE widget set as a mere library on top
of the Genode OS framework [http://genode.org]. Each application contains a
copy of the whole GUI server. At API level, the use of DOpE as a library
instead of a server is transparent. To enable multiple DOpE applications be be
present on a single screen, Genode's nitpicker GUI server is used.

DOpE was originally implemented in C. The Genode version is partially ported to
C++ to make it easier to cleanly integrate it with Genode. The code is still
structured in a object-oriented-C fashion and the move to C++ is not finished
by any means.

Limitations
-----------

* Only supports 32-bit platforms
* Only supports RGB565 color depth
* Fixed keyboard layout (edit 'keymap.cc' according to your needs)


A quick test drive
##################

Obtain the source code [1] and tool chain [2] of the Genode OS Framework.

[1] https://github.com/genodelabs/genode
[2] http://genode.org/download/tool-chain

Create a build directory for your Genode base platform of choice. Follow
the platform-specific documentation [3].

[3] http://genode.org/documentation/platforms/index

For example, on Linux, create a build directory via

! ./tool/create_builddir linux_x86 BUILD_DIR=build

Obtain the DOpE source tree [4].

[4] https://github.com/nfeske/dope

Add the path of the DOpE source tree to the 'REPOSITORIES' declaration
in your _<build-dir>/etc/build.conf_ file by adding the following line:

! REPOSITORIES += location/of/dope.git

Build and run a simple test program from within your build directory:

! make run/dope_widgets

After the build process is completed, you should be greeted with a simple
demo application that showcases a few widgets. The test program is located
at _src/test/dope_widgets_ within DOpE's source tree. The run script for the
corresponding Genode scenario can be found at _run/dope_widgets.run_.


Introduction to the basic concepts
##################################

Command interface
=================

DOpE provides a command interface to create and configure widgets and
their relationships. The text-command-based approach has the following advantages
over a conventional API:

* Interface extensions of DOpE are transparent to client applications. No
  recompilation of client applications is needed.
* The user interface can be described in very compact expressions.
* Multiple attribute changes can be expressed as one atomic unit using
  the tag-value notation.
* The native (program language level) API is very simple and can easily be
  ported to other communication schemes than IDL.
* Prototyping of graphical user interfaces can be done interactively using
  a simple terminal program.
* Text based communication can be monitored by a human reader for debugging
  purposes.


Creating widgets
~~~~~~~~~~~~~~~~

Widgets can be created and assigned to a variable with the 'new' command:
! <varname> = new <widget type>(<initial attibutes>)

After created, the new widget can be accessed via the assigned variable name.
A multiple assignment to the same variable makes the previously associated
widget inaccessible for the client application but does not destroy it
as long as there exists another reference to it - for example if it is
referenced as the child of another widget. A *Window* can be
created this way:
! w = new Window()

Initial attributes of the newly created widget can be defined at creation
time by specifying '-tag value' pairs within the parenthesis. For example:
! b = new Button(-text "Cancel")


Attribute and argument types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Widget attributes and method arguments can be of distinct types.

:Boolean: values are mostly used to enable or disable features. They are
  specified by using the values 'on' and 'off' (or 'yes' and 'no' alternatively).

:Integer: values are whole numbers and must be specified in decimal form.

:Float: values are fractional numbers specified in a very traditional way: #12.345#

:Strings: are used to specify text. Generally, strings must be quoted. If a
  string contains only characters that are valid for identifiers, the quoting
  is not needed (but still recommended). For example:
  ! "This is a valid string"
  ! quotes_are_not_needed_here

:Sets of values: are used to express non-boolean feature settings such as
  'north', 'south', 'east' and 'west'. The valid elements of such a set depend
  on each case. In fact, sets of values are implemented as strings that contain
  only valid identifier characters.


Setting attributes
~~~~~~~~~~~~~~~~~~

Attributes can be modified by using the 'set' method that is available for all
widgets. Each attribute is addressed via its tag followed by the
desired value. Multiple attributes can be configured as one atomic
action by chaining multiple tag-value pairs. The following example
enables both scrollbars of a *Frame* 'f' and sets the widget #a# as
its content:

! f.set(-scrollx yes -scrolly yes -content a)


Requesting attributes
~~~~~~~~~~~~~~~~~~~~~

Attributes can be requested via the DOpE command:
! <varname>.<attribute name>


Invoking methods
~~~~~~~~~~~~~~~~

Methods of widgets can be invoked via the DOpE command:
! <varname>.<method name>(<mandatory args><optional args>)

For example the following command sets the width of the row 5 of a *Grid*
widget 'g'. The first argument (the row number) is mandatory. All following
arguments are optional and therefore are expressed via the tag-value notation:
! g.rowconfig(5, -size 100)


DOpElib
#######

For the implementation of DOpE client applications, DOpElib provides a
simple-to-use interface to communicate to the DOpE window server and
handle events.


Initializing the library
========================

Before using DOpElib, it must be initialized by calling 'dope_init'.
! long dope_init(void);
This function returns #0# on success.

At the exit of DOpE clients, 'dope_deinit' should be called to release
all used resources.
! void dope_deinit(void);


(Un-)Register a new DOpE client application
===========================================

The 'dope_init_app' function starts a new client session and creates a fresh
variable namespace for this session. The return value of this function is an
identifier for later reference to the session. When registering a client
session an application name must be specified. This name will be the default
window title for all windows of this session.
! long dope_init_app(char *appname);

Note that distinct variable name spaces can be established by creating multiple
client sessions within one application.

A client session can be closed via 'dope_deinit_app' taking the desired session
identifier as argument. When called, DOpE destroys the associated variable name
space and closes all windows of the session.
! long dope_deinit_app(long app_id);


Executing DOpE commands
=======================

Once a client session is started via 'dope_init_app', a client application
can send commands referring to such a session via the 'dope_cmd' function.
It takes a session identifier and a textual command string as arguments. On
success 0 is returned. With 'dope_cmdf' there exists a simple way to use
format strings as DOpE commands as well.
! int dope_cmd(long app_id,char *cmd);
! int dope_cmdf(long app_id, char *cmdf, ...);


Requesting results of DOpE commands
===================================

While 'dope_cmd' and 'dope_cmdf' allow the execution of DOpE commands
the result of these commands is not returned (mostly the result is of no
interest - therefore we can skip the transfer of the result in common case).
When the result of a DOpE command is of importance, #dope_req# and #dope_reqf#
must be utilized to request the result.
! int dope_req(long app_id, char *dst, int dst_size, char *cmd);
! int dope_reqf(long app_id, char *dst, int dst_size, char *cmdf, ...);
This pair of functions takes the
destination buffer 'dst' and its size for storing the result as argument.
For example, to request the width of a window as an integer one can do:
! char req_buf[16];
! int width;
! dope_req(app_id, req_buf, 16, "win.w");
! width = atoi(req_buf);


Binding events to callback functions
====================================

! void dope_bind(long app_id, char *var,
!                char *event_type,
!                void (*callback)(dope_event *,void *),
!                void *arg);

! void dope_bindf(long app_id, char *var,
!                 char *event_type,
!                 void (*callback)(dope_event *,void *),
!                 void *arg,
!                 ...);

The two functions 'dope_bind' and 'dope_bindf' can be used to bind events
to widgets. Their common arguments are:

:'app_id':
  DOpE application id

:'var':
  Name of the DOpE widget to which the event should be attached.

:'event_type':
  A DOpE event identifier. There are common identifiers for
  all widget types. Furthermore some widgets provide custom bindings.

:'callback':
  Function that should be called when an event of the specified
  type occurs.

:'arg':
  Argument that is passed to the registered callback function.

The only difference between 'dope_bind' and 'dope_bindf' is that 'dope_bindf'
takes the widget name as format string. The format string arguments are passed
via _varargs_ as the very last parameters of the function.


Start event processing
======================

! void dope_eventloop(long app_id);


Widget set
##########

This section is an introduction into the widget layout concept of DOpE.
Furthermore, it describes the properties, attributes and methods of the widget
types implemented in DOpE.


Widget layout concept
=====================

DOpE provides two kinds of widgets, _leaf widgets_ representing data and
_layout widgets_, which contain other widgets. Whereas the application specifies
the information that should be represented on screen and the relationships of
widgets, DOpE decides how to represent the information in the form of pixels.
For example, an application requests that a number should be represented
on screen in the form of a Scale widget. It does not define the exact dimensions,
the color, and the used font. This way, the user who finally uses the application
can choose his/her favorite way of representation by configuring DOpE.

_Note: at the current stage, the configuration options of DOpE are very limited._
_But this approach enables us to be very flexible in the future._

Every leaf widget actually knows its way of representing its information and
tells its parent layout widget about its minimal and maximal size on screen.
The layout widget in turn, takes the min/max constraints of all children into
account to define their actual position and size within the layout widget. The
min/max constrains of the layout widget, again, depend on its children. For
example, a window cannot get bigger than the maximum size of its content. Each
time, a min/max constrain of a widget changes (for example, a Label is asked to
displays another text) the widget reports the change to its parent. This way,
the parent can update its layout by considering the new constraints.

To summarize, there are two rules:
* A child widget report its current constraints to its parent.
* A parent widget defines the actual size of its children while considering
  their min/max constraints.


Generic widget attributes
=========================

  Attribute | Type      | Access | Default
 ------------------------------------------------------------------------------
  x,y       | <integer> | r/w    | 0
 ------------------------------------------------------------------------------
  w,h       | <integer> | r/w    | 64
 ------------------------------------------------------------------------------
  type      | <string>  | r      | type identifier string
 ------------------------------------------------------------------------------
  grabfocus | <boolean> | r/w    | no

[table widget_attributes] generic widget attributes overview


Table [widget_attributes] displays common attributes of widgets. The 'x' and
'y' attributes define the position of a widget relative to its parent widget.
The values refer to the top-left corner of the widget relative to the top-left
corner of the parent widget. The current size of a widget can be accessed via
the 'w' and 'h' attributes. Normaly, the position and size of widgets are
assigned by their parents so that these attributes should not be modified
manually.

The 'type' attribute of a widget is the name of its widget type as a string.

By default, the keyboard focus can be switched among widgets by using the tab
key. However, there are widgets that need to keep the keyboard focus once
they receive it, for example a text edit field. For such widgets, the
boolean attribute 'grabfocus' can be enabled to prevent the focus switching
and thus, let the application handle all key strokes referring the widget by
itself.


Generic widget methods
======================

  Method | Arguments
 ------------------------------------------------------------------------------
  bind   | <string> type,
         | <string> message
 ------------------------------------------------------------------------------
  unbind | <string> type
 ------------------------------------------------------------------------------
  focus  |

[table widget_methods] generic widget methods overview

Normally, the user defines the keyboard focus by clicking on the corresponding
widget with the mouse, or moving the focus among the widgets via the keyboard.
In some cases though, applications need to define the focus manually to provide
a more convenient workflow to the user. For this, the widget method 'focus'
can be used to set the currently active keyboard focus to the widget. If the
application owns the currently active window, the window holding the widget,
is activated, too.


Built-in base widget set
########################


Background
==========

  Attribute  | Type       | Access | Default
 ------------------------------------------------------------------------------
  content    | <widget>   | w      | none

[table background_attributes] Background attributes overview


Button
======

  Attribute  | Type       | Access | Default
 ------------------------------------------------------------------------------
  text       | <string>   | r/w    | ""
 ------------------------------------------------------------------------------
  padx       | <int>      | r/w    | 2
 ------------------------------------------------------------------------------
  pady       | <int>      | r/w    | 2

[table button_attributes] Button attributes overview


The 'padx' and 'pady' attributes of a Button widget specify the vertical
and horizontal distances between the widget border and the visible button.


  Event binding | Short description
 ------------------------------------------------------------------------------
  commit        | commit the action that is associated with the button
 ------------------------------------------------------------------------------
  click         | user clicks on the button
 ------------------------------------------------------------------------------
  clack         | user releases the mouse button

[table button_bindings] Button event bindings


Beside the generic bindings 'press' and 'release', button widgets support the
higher-level bindings for receiving user input events as displayed in
table [button_bindings]. Normally, the 'commit' binding should be used for
all buttons that trigger an action in the application. If the application
needs to specifically react on the mouse press and release, the bindings 'click'
and 'clack' can be used. In contrast to 'press' and 'release', these bindings
make DOpE manage the visible behaviour of the button when clicked.
It is recommended to use the 'clack' binding for all critical actions that
are not easily reversible. For such actions, we want to grant the user some
more time to decide whether it applies the action (by releasing the mouse
on the button) or cancel the action (by moving the mouse away from the button
and then releasing the mouse).


Entry
=====

  Attribute  | Type       | Access | Default
 ------------------------------------------------------------------------------
  text       | <string>   | r/w    | ""
 ------------------------------------------------------------------------------
  blind      | <boolean>  | r/w    | no

[table entry_attributes] Entry attributes overview


The entry widget is a single-line text edit field. DOpE handles all editing
functions such as cursor movement, insertion and deletion of characters. The
'text' attribute contains the current text.

When the entry widget is used to insert passwords, it can be switched to a
blind mode. When the 'blind' attribute is set, each character is printed as an
unreadable placeholder.


Frame
=====

  Attribute  | Type       | Access | Default
 ------------------------------------------------------------------------------
  content    | <widget>   | w      | none
 ------------------------------------------------------------------------------
  background | <boolean>  | r/w    | off
 ------------------------------------------------------------------------------
  scrollx    | <boolean>  | r/w    | off
 ------------------------------------------------------------------------------
  scrolly    | <boolean>  | r/w    | off
 ------------------------------------------------------------------------------
  xview      | <integer>  | r/w    | 0
 ------------------------------------------------------------------------------
  yview      | <integer>  | r/w    | 0

[table frame_attributes] Frame attributes overview


Grid
====

  Method       | Arguments
 ------------------------------------------------------------------------------
  columnconfig | <integer> index,
               | -weight <float>
               | -size <integer>
 ------------------------------------------------------------------------------
  rowconfig    | <integer> index,
               | -weight <float>
               | -size <integer>
 ------------------------------------------------------------------------------
  place        | <widget> child,
               | -column <integer>
               | -row <integer>
               | -padx <integer>
               | -pady <integer>
               | -align <string>
 ------------------------------------------------------------------------------
  remove       | <widget> child

[table grid_methods] grid methods overview


The grid layout widget manages the layout of child-widgets in rows and columns.
A child widget 'c' can be placed into a grid 'g' by using the 'place' method:

! g.place(c, -column 1 -row 1)

Rows and columns are created on demand when a child-widget is placed. Additionally,
the 'place' method can take an alignment as argument. An alignment specifier
consists of the characters 'n' (north), 's' (south), 'e' (east) and 'w' (west).
For example, the option '-align ew' can be used to stretch the child widget
horizontally (from east to west) but center it vertically.


Label
=====

  Attribute  | Type       | Access | Default
 ------------------------------------------------------------------------------
  text       | <string>   | r/w    | ""
 ------------------------------------------------------------------------------
  variable   | <variable> | r/w    | <undefined>

[table label_attributes] Label attributes overview


LoadDisplay
===========

  Attribute  | Type       | Access | Default
 ------------------------------------------------------------------------------
  from       | <float>    | r/w    | 0.0
 ------------------------------------------------------------------------------
  to         | <float>    | r/w    | 100.0
 ------------------------------------------------------------------------------
  orient     | <string>   | r/w    | horizontal

[table loaddisplay_attributes] LoadDisplay attributes overview


The load display represents fractions of a defined range of values
in the shape of bars. It can be used to implement progress bars or load
bars. Multiple bars per load display are supported. The range of values
can be freely defined via the 'from' and 'to' attributes. Ranges
including negative values are supported.


  Method       | Arguments
 ------------------------------------------------------------------------------
  barconfig    | <string> bar_identifier,
               | -value <float>

[table loaddisplay_methods] LoadDisplay methods overview


A bar can be placed into the load display by calling the 'barconfig'
method. For example:
! ld = new LoadDisplay()
! ld.barconfig(load, -value 33.3)

Each bar can be referenced by a dedicated string identifier
that can freely be assigned via the 'barconfig' method. Bars
are created on demand - if a bar identifier is not yet known to
the load display, a new bar is created.

The orientation of a load display can be defined via the
'orient' attribute that can hold the values 'horizontal' or 'vertical'.

Per default (if 'from' < 'to') bars grow from left to right (or from
top to bottom respectively). Reversed ranges ('from' > 'to') reverse
the direction of bars.


Scale
=====

  Attribute  | Type       | Access | Default
 ------------------------------------------------------------------------------
  variable   | <variable> | w      |
 ------------------------------------------------------------------------------
  value      | <float>    | r/w    | 50.0
 ------------------------------------------------------------------------------
  from       | <float>    | r/w    | 0.0
 ------------------------------------------------------------------------------
  to         | <float>    | r/w    | 100.0
 ------------------------------------------------------------------------------
  orient     | <set>      | r/w    | horizontal

[table scale_attributes] Scale attributes overview


Scrollbar
=========

  Attribute  | Type       | Access | Default
 ------------------------------------------------------------------------------
  realsize   | <integer>  | r/w    | 500
 ------------------------------------------------------------------------------
  viewsize   | <integer>  | r/w    | 128
 ------------------------------------------------------------------------------
  offset     | <integer>  | r/w    | 0
 ------------------------------------------------------------------------------
  orient     | <set>      | r/w    | horizontal

[table scrollbar_attributes] Scrollbar attributes overview


The Scrollbar widget type represents a view port on an object (for example a
text) that is larger than its actual representation on screen (for example the
text editor). Table [scrollbar_attributes] displays the attributes of a scrollbar.
The 'realsize' attribute defines the real size of the object while the viewport
on the object is defined by its 'viewsize' and the 'offset'.
The 'orient' attribute defines whether the scrollbar widget appears 'vertical' or
'horizontal'.


  Event binding | Short description
 ------------------------------------------------------------------------------
  change        | the view offset changed

[table scrollbar_bindings] Scrollbar event bindings

Applications can receive events on the change of the view port offset via the
'change' binding.


Variable
========

  Attribute  | Type      | Access | Default
 ------------------------------------------------------------------------------
  value      | <string>  | r/w    | "<undefined>"

[table variable_attributes] Variable attributes overview


VScreen
=======

  Attribute      | Type      | Access |  Default
 ------------------------------------------------------------------------------
  mousex, mousey | <integer> | r/w    | 0
 ------------------------------------------------------------------------------
  grabmouse      | <boolean> | r/w    | off

[table vscreen_attributes] VScreen attributes overview

VScreen is a virtual screen buffer that contains raw pixel data. It is
allocated by DOpE and mapped to the client's address space via shared
memory. Thus, it provides a way to display pixel-based data with a very low
copying overhead.
Table [vscreen_attributes] contains the VScreen specific attributes.

After a VScreen is created, a video mode can be probed via the 'probemode'
method. VScreen supports the pixel formats 'RGB16' and 'YUV420'.
If 'probemode' returns '1', the specified videomode is supported by DOpE
and can be set via the 'setmode' method.

The virtual screen buffer can be exported to the client application
via the 'map' method that returns an identifier for the corresponding shared
memory block. The client application can use this identifier to map the shared
memory block into its local address space.


Mouse grabbing
~~~~~~~~~~~~~~

For applications, which handle a custom mouse cursor, a VScreen widget can
be configured to grab the mouse cursor via the 'grabmouse' attribute.
When this attribute is enabled, the mouse gets trapped within the widget
area as soon as the user clicks on the VScreen. The user can free the
mouse at any time by pressing the _pause_ key. When the mouse is grabbed,
its position within the VScreen widget can be requested and defined via
the 'mousex' and 'mousey' attributes.

  Method       | Arguments
 ------------------------------------------------------------------------------
  probemode    | <long> width,
               | <long> height,
               | <string> mode
 ------------------------------------------------------------------------------
  setmode      | <long> width,
               | <long> height,
               | <string> mode
------------------------------------------------------------------------------
  refresh      | -x <integer>
               | -y <integer>
               | -w <integer>
               | -h <integer>
 ------------------------------------------------------------------------------
  share        | <widget> from

[table vscreen_methods] VScreen methods overview


VTextScreen
===========

The VTextScreen is the counterpart of VScreen for textual data that can be
represented by monospaced text. This is the case for Terminal-like applications.
VTextScreen provides a virtual VGA text console featuring a character buffer
(ASCII code) and a corresponding attribute buffer that contains foreground and
background color information for each character.


  Method       | Arguments
 ------------------------------------------------------------------------------
  probemode    | <long> width,
               | <long> height,
               | <string> mode
 ------------------------------------------------------------------------------
  setmode      | <long> width,
               | <long> height,
               | <string> mode
 ------------------------------------------------------------------------------
  map          | -thread <string>
 ------------------------------------------------------------------------------
  refresh      | -x <integer>
               | -y <integer>
               | -w <integer>
               | -h <integer>

[table vtextscreen_methods] VTextScreen methods overview


As displayed in table [vtextscreen_methods], VTextScreen behaves very similar
to VScreen. A virtual text mode can be probed and set via the 'probemode' and
'setmode' methods. The currently supported mode is 'C8A8PLN'. This term describes a
mode with 8 bit characters, 8 bit attributes, planar --- both buffers are stored
in succession. The 'width' and 'height' arguments must be specified as number of
character. The lower bits 0..2 of an attribute value describe the background color
index and the bits 3..5 describe the foreground color index of the corresponding
character. Table [vtextscreen_colors] displays the available colors.
Bits 6..7 define the brightness level. There are 3 brightness levels available.


  Color index | Color
 -------------------------
       0      | black
       1      | red
       2      | green
       3      | yellow
       4      | blue
       5      | purple
       6      | cyan
       7      | white

[table vtextscreen_colors] Definitions of color indices


After a successful initialization of a virtual text screen mode, the text and
attribute buffer can be mapped to the client applications in the same way as
for VScreen widgets. Each time, the client application modifies a portion
of the shared buffer, the 'refresh' method must be called to inform DOpE to
update the corresponding text area on screen.

  Attribute        | Type      | Access | Default
 ------------------------------------------------------------------------------
  cursorx, cursory | <integer> | w      | 0

[table vtextscreen_attributes] VTextScreen attributes overview


Window
======

  Attribute    | Type      | Access  |  Default
 ------------------------------------------------------------------------------
  workx, worky | <integer> | r/w     | position of the work area
 ------------------------------------------------------------------------------
  workw, workh | <integer> | r/w     | size of the work area
 ------------------------------------------------------------------------------
  title        | <string>  | r/w     | window title text

[table window_attributes] Window attributes overview


Window widgets feature additional attributes as presented in
table [window_attributes]. Since the position and size of widgets
always refers to the bounding box of widgets, the widget attributes
'x', 'y', 'w' and 'h' of windows refer to the outer boundary of the
window containing the window elements and window border. For application
programmers the actual working area of the window is of more interest.
Thus, the position and size of the actual working area are accessible
via the window-specific attributes 'workx', 'wworky', 'workw' and 'workh'.


  Method       | Arguments
 ------------------------------------------------------------------------------
  open         |
 ------------------------------------------------------------------------------
  close        |
 ------------------------------------------------------------------------------
  top          |

[table window_methods] Window methods overview


Frequently Asked Questions
##########################

How to insert a placeholder with a fixed size?
==============================================

For defining placeholders between child widgets of a Grid, you can define empty
rows and columns using the #rowconfig# and #columnconfig# methods of the Grid
layout widget with a specified #-size# parameter.


How to avoid shrinking the size of a frame when its content shrinks?
====================================================================

Generally, a Frame cannot get larger than its content. But when using a grid
as content you can easily configure the grid of expand infinitely by inserting
a row/column with a #-weight# that is far larger than the weight of the other
rows/columns. For example, you want to place a button within a frame but want
the frame to expand such that the empty space beyond the bottom of the button
gets visible:
! f = new Frame()
! g = new Grid()
! f.set(-content g)
! b = new Button()
! g.place(b, -column 1 -row 1)
! g.rowconfig(9999, -weight 1)


How to set a widget to a fixed size?
====================================

If an application needs to define the actual size of a certain widget in pixels
(which is not recommended in general), it must use a layout widget as parent of
this widget, which enforces this fixed size. For example, rows and columns of a
Grid can be configured to have a fixed size. Still, the defined size cannot
exceed the constraints of the widget.

About

The DOpE widget set for the Genode OS Framework

License:GNU General Public License v2.0


Languages

Language:C 59.8%Language:C++ 34.2%Language:Objective-C 6.0%