Click here to Skip to main content
Click here to Skip to main content
Go to top

Programming the Roma Widget Set (C# X11) - a zero dependency GUI application framework - Part 1, Basics

, 15 Aug 2014
Rate this:
Please Sign up or sign in to vote.
How to get out the maximum from the Roma widget in C# efficiently without dependencies to GUI frameworks like GTK or KDE. Basics and description of concepts.

Download complete project older version 0.10, 0.20, 0.30, 0.40 32 bit (zip).

Download complete project older version 0.10, 0.20, 0.30, 0.40 64 bit (zip).

Download complete project current version 0.50 32 bit (zip)

Download complete project current version 0.50 64 bit (zip)

Introduction

This article deals with the practical use of the Roma Widget Set (Xrw), a C# GUI application framework, that is directly based on X11 library calls. The idea of the Roma widget set has been developed as consequence of the first article of this series, Programming Xlib with Mono Develop - Part 1: Low-level (proof of concept) and influenced by the experience made through writing the subsequent articles Programming Xlib with Mono Develop - Part 2: Athena widgets (proof of concept), Programming Xlib with Mono Develop - Part 3: Motif widgets (proof of concept) and Programming Xlib with Mono Develop - Part 4: FWF Xt widgets.

Because the whole Topic grows beyond 50 pages with , i decided to split it into multiple parts:

This article provides a sample application's complete project for 32 bit and 64 bit. All features, described later on, can be marked as:

  • available from version 0.1,
  • disabled with version 0.2,
  • available from version 0.2,
  • disabled with version 0.3,
  • available from version 0.3,
  • disabled with version 0.4,
  • available from version 0.4,
  • disabled with version 0.5 and
  • available from version 0.5.

First - the main disadvantages:

  • The complete framework is crafted - there is no big developer comunity in the background.
  • The framework uses the capabilities of C# and X11 (via P/Invoke) only - currently no additional libraries like Xt, Xpm, Xft, Cairo, Pango, ... are involved - i.e. drawing capabilities are limited (no gradient color, no antialiasing).
  • It is platform dependend - it runs on X11 only.
  • There is no GUI designer.
  • Only 24 bit color model (16 777 216 colors, 32 bits per pixel) is fully supported right from . The 16 bit color model (65536 colors, 16 bits per pixel) is supported since , but no color optimization or smoothing is provided for the reduced color space.

Second - the main advantages:

  • The framework is small, very well inline-documented and can be adopted/extended to a specific need easyly.
  • The framework comes with complete source code and is wirtten entirely in C# - all parts of the framework can be maintained from a single C# solution or project.
  • The framework has no dependencies except X11 and it has zero overhead. It is very lightweight and fast.
  • The framework starts to provide widgets, that are not available for Athena widget set, and some of them even not for Motif or GTK. The first of them is a basic ribbon, followed by a property grid.

It might be, any future version includes the option to use additional libraries or run on other platforms than X11.

This provokes the question - why another GUI application framework? The answer is the fun to deal with it, the individuality that applications can reach and the flexibility to design an uncommon GUI for a specific application.

Background

The Roma widget set has been designed to support programming of simple GUIs for small tools. It's focus is the efficiency in application, not the completeness of rarely used features. What are the alternatives?

All other widget sets - the Athena widget set and its descendants (e. g. neXtaw, XawM, Xaw-Xpm, XawPlus or Xaw3d), the Motif widget set (Open Motif or LessTif), GTK (GTK+ alreaty has the C# wrapper GTK#) and KDE (Qt already has the C# wrapper Qyoto) - are developed in C/C++ and are very hard to adopt/extend to a specific purpose within a C# project.

The Roma widget set GUI framework shall support all adoptions/extentions through native C# code.

This is not a new idea/requirement. The DotGNU Portable.NET project - gone with the shutdown of it's parent project DotGNU in December 2012 - contains the pnetlib, which was under active development until March 2007 by Rhys Weatherley, at that time director of Southern Storm Software, Pty Ltd, and others. The last version (0.8.0) of the pnetlib project contains Xsharp and System.Windows.Forms among other things. While Xsharp implements a basic framework to program X11 from C# (and might be worth to take a look at it), System.Windows.Forms is a re-implementation of Microsoft's not ECMA standardized namespace and has always been subject of discussions and warnings about whether Microsoft is probably planning to destroy such C# implementations through patent suits.

The Roma widget set framework will not try to re-implement (be API compatible to) any known GUI framework.

Using the code

The sample application was written with Mono Develop 2.4.1 for Mono 2.8.1 on OPEN SUSE 11.3 Linux 32 bit EN and GNOME desktop. Neither the port to any older nor to any newer version should be a problem. The sample application's solution consists of three projects (the complete sources are provided for download):

  • X11Wrapper defines the function prototypes, structures and types for Xlib/X11 calls to the libX11.so
  • Xrw contains the Roma witget set (Xrw)
  • X11 contains the sample application

The sample application is also tested with Mono Develop 3.0.6 for Mono 3.0.4 on OPEN SUSE 12.3 Linux 64 bit DE and GNOME desktop, IceWM, TWM und Xfce.

The only difference between the 32 bit and the 64 bit solution is the definition of some types, as already described in the first article of this series.

Advice: To use the class library documentation shortcut (F1) from MonoDevelop, the "mono-tools" package to be installed.

The image shows the sample application with XrwTheme.GeneralStyle.WinClassic.

The image shows the sample application with XrwTheme.GeneralStyle.Gtk2Clearlooks.

The sample application demonstates

  • a ribbon widget in sector A,
  • a top tabbed notebook widget in sector B with two tabs,
    • the first tab contains a horizontally paned widget with a tree widget to the left and a property grid to the right,
    • the second tab contains a horizontally paned widget with a list widget to the left and a property grid to the right,
  • a bottom tabbed notebook widget in sector C with four tabs,
    • the first tab contains a menu widget and a command widget,
    • the second tab contains three toggle button widgets,
    • the third tab contains three radio button widgets,
    • the fourth tab contains a text widget and
  • a label widget in sector D.

Theme support

Currently the framework has a generic theme support and these predefined themes:

  • XrwTheme.GeneralStyle.WinClassic (in and named XrwTheme.GeneralStyle.Win95),
  • XrwTheme.GeneralStyle.WinLuna (loocks similar to WinXP / MS Office 2007),
  • XrwTheme.GeneralStyle.WinRoyale (loocks similar to Vista/Win7 / MS Office 2010),
  • XrwTheme.GeneralStyle.WinMidori (loocks similar to Win8 / MS Office 2013) and
  • XrwTheme.GeneralStyle.Gtk2Clearlooks.

The theme support covers colors, geometries and images.

To design an uncommon GUI for a specific application, almost all widget properties, that are influenced by a theme, can also be overruled by individual values. Or a new, alternatively XrwTheme.GeneralStyle can be created and applied.

Look & feel of XrwTheme.GeneralStyle.WinClassic demonstrated with the "File selection" dialog.

Look & feel of XrwTheme.GeneralStyle.Gtk2Clearlooks demonstrated with the "File selection" dialog.

Colors

The XrwTheme class supports these theme colors:

Property Samples (WinClassic und Gtk2)
:
InteractiveSelectedBackgroundColorLight
InteractiveSelectedBackgroundColorMedium
InteractiveSelectedBackgroundColorDark
:
CollectionItemSelectedBackgroundColorLight
CollectionItemSelectedBackgroundColorMedium
CollectionItemSelectedBackgroundColorDark
:
InteractiveFocusedSelectedBackgroundColorLight
InteractiveFocusedSelectedBackgroundColorMedium
InteractiveFocusedSelectedBackgroundColorDark
:
CollectionItemFocusedSelectedBackgroundColorLight
CollectionItemFocusedSelectedBackgroundColorMedium
CollectionItemFocusedSelectedBackgroundColorDark
:
ScrollBackgroundColor
:
ScrollFocusedBackgroundColor
:
ScrollThumbBackgroundColorLight
ScrollThumbBackgroundColorMedium
ScrollThumbBackgroundColorDark
:
ScrollThumbFocusedBackgroundColorLight
ScrollThumbFocusedBackgroundColorMedium
ScrollThumbFocusedBackgroundColorDark
:
TextColor
InverseTextColor
Property Samples (WinLuna und Gtk2)
:
RibbonTabCaptionBackgroundColor
RibbonTabCaptionFocusedBackgroundColor
RibbonBackgroundColorLight
RibbonBackgroundColorMedium
RibbonBackgroundColorDark
:
RibbonCommandGadgetSelectedBackgroundColorLight
RibbonCommandGadgetSelectedBackgroundColorMedium
RibbonCommandGadgetSelectedBackgroundColorDark
RibbonCommandGadgetFocusedBackgroundColorLight
RibbonCommandGadgetFocusedBackgroundColorMedium
RibbonCommandGadgetFocusedBackgroundColorDark
:
ApplicationButtonBackgroundColorLight
ApplicationButtonBackgroundColorMedium
ApplicationButtonBackgroundColorDark
ApplicationButtonFocusedBackgroundColorLight
ApplicationButtonFocusedBackgroundColorMedium
ApplicationButtonFocusedBackgroundColorDark

Property Samples (WinClassic und Gtk2)
:
PanerBackgroundColorLight
PanerBackgroundColorMedium
PanerBackgroundColorDark
EditableAlternativeBackgroundColor

Geometries

The XrwTheme class supports these theme geometries:

Property Samples
DlgShellPrimaryChildSpacing
ViewportChildSpacing

Images

The X11Graphic class supports these theme stock images (and the XrwTheme class provides easy access):

Property Samples (WinClassic und Gtk2)
Computer (16, 24, 32 and 48 pixel)
Drive (16, 24, 32 and 48 pixel)
FolderClose (16, 24, 32 and 48 pixel)
FolderOpen (16, 24, 32 and 48 pixel)
MyFolder (16, 24, 32 and 48 pixel)
Computer (16, 24, 32 and 48 pixel)
Property Sample (generic)
Attention (16, 24, 32 and 48 pixel)
Cancel (16, 24, 32 and 48 pixel)
Error (16, 24, 32 and 48 pixel)
File (16, 24, 32 and 48 pixel)
Information (16, 24, 32 and 48 pixel)
OK (16, 24, 32 and 48 pixel)
Question (16, 24, 32 and 48 pixel)
RadioOff (16 pixel)
RadioOn (16 pixel)
ToggleOff (16 pixel)
ToggleOn (16 pixel)
ToggleUnset (16 pixel)
Warning (16, 24, 32 and 48 pixel)
TextSub (16 pixel)
TextSuper (16 pixel)
ApplicationButton (16 pixel)
 Pipette (16, 24, 32 and 48 pixel)
Property Sample (Win und Gtk2)
RibbonClose (16 and 32 pixel)
RibbonExit (16 and 32 pixel)
RibbonNew (16 and 32 pixel)
RibbonOpen (16 and 32 pixel)
RibbonOptions (16 and 32 pixel)
RibbonSave (16 and 32 pixel)
RibbonSaveAs (16 and 32 pixel)
TextAlignBottom (16 pixel)
TextAlignCenter (16 pixel)
TextAlignJustify (16 pixel)
TextAlignLeft (16 pixel)
TextAlignMiddle (16 pixel)
TextAlignRight (16 pixel)
TextAlignTop (16 pixel)
TextBold (16 pixel)
TextItalic (16 pixel)
TextUnderline (16 pixel)

To select a theme, the program's Main() method should set the desired theme to the XrwTheme.Style static property before the instantiation of XrwApplicationShell.

public static void Main ()
{
    // Set the desired theme.
    XXrwTheme.Style = XrwTheme.GeneralStyle.Gtk2Clearlooks;
 
    Point assignedPosition = new Point (0, 0);
    Size  assignedSize     = new Size  (350, 300);
 
    // Instantiate the program's instance of XrwApplicationShell.
    X11Window appWindow    = new X11Window(ref assignedPosition, ref assignedSize);
 
    appWindow.Run ();
} 

Font support

The default font of most Xfree86 installation is "-misc-fixed-medium-r-semicondensed--13-*-*-*-*-*-*". Hence the XrwTheme class predefines these default font specifications:

DefaultFontName        = "-misc-fixed-medium-r-semicondensed--13-*-*-*-*-*-*";
DefaultItalicFontName  = "-misc-fixed-medium-o-semicondensed--13-*-*-*-*-*-*";
DefaultBoldFontName    = "-misc-fixed-bold-r-semicondensed--13-*-*-*-*-*-*"; 

These fonts are almost guaranteed to be available at every X server but they are monospace bitmap fonts and do not look very smart.

The image shows a sample -misc-fixed- font output.

This version introduces convenience methods to change the predefined font specifications with user defined font specifications and ensures all widget's GC (graphics context) initialization with the DefaultFontName font specification.

  • TrySetDefaultFont set the DefaultFontName to the user defined font specification and returns true on success (font is available) or leaves the DefaultFontName unchanged and returns false otherwise.
  • TrySetDefaultItalicFont set the DefaultItalicFontName to the user defined font specification and returns true on success (font is available) or leaves the DefaultItalicFontName unchanged and returns false otherwise.
  • TrySetDefaultBoldFont set the DefaultBoldFontName to the user defined font specification and returns true on success (font is available) or leaves the DefaultBoldFontName unchanged and returns false otherwise.

It is recommended to set user defined font specifications after the creation of the application shell before the widget hierarchy is build up.

public static void Main ()
{
    XrwTheme.Style = XrwTheme.GeneralStyle.Gtk2Clearlooks;
    
    Point assignedPosition = new Point (0, 0);
    Size  assignedSize     = new Size  (353, 480);
    X11Window appWindow    = new X11Window(ref assignedPosition, ref assignedSize);
    
    // Set the preferred font before the widget hierarchy is build up,
    // but after application shell creation.
    XrwTheme.TrySetDefaultBoldFont (appWindow.Display, appWindow.GC,
        "-*-helvetica-bold-r-normal--12-*-*-*-*-*-*");
    XrwTheme.TrySetDefaultItalicFont (appWindow.Display, appWindow.GC,
        "-*-helvetica-medium-o-normal--12-*-*-*-*-*-*");
    XrwTheme.TrySetDefaultFont (appWindow.Display, appWindow.GC,
        "-*-helvetica-medium-r-normal--12-*-*-*-*-*-*");
    
    appWindow.Run ();
} 

The image shows a sample -*-helvetica- font output.

Support for 16 Bit color model

The general approach to support 16 bit color model is to use an individual visual and colormap for the application, that is based on a 24 bit color model, if X server runs in 16 bit color mode (but 24 color mode is supportedby hardware and X11 server). The necessary code, especially XrwCore.InitializeApplicationShellWindow(), XrwCore.InitializeTransientShellWindow() and XrwCore.InitializeOverrideShellWindow() has been prepared already by . The following changes have been implemented with to support 16 Bit color model finally:

  • Reduction of the stock icon's color depth to 15 bit (not necessarily needed, but recommended).
  • Reduction of the application's icon color depth to 15 bit (required).
  • Correction of XrwApplicationFramework.SetWmShellIcon() (see "Fixed with " No. 3).
  • Correction of X11Graphic.CreateIndependentGraphicPixmap() (see "Fixed with " No. 4).

The /etc/X11/xorg.conf.d/50-screen.conf on my OPEN SUSE 11.3 Linux 32 bit EN has been modiefied like that, to test 16 bit color model support:

Section "Screen"
  Identifier "Default Screen"
  Device "Default Device"

  ## Doesn't help for radeon/radeonhd drivers; use magic in
  ## 50-device.conf instead
  Monitor "Default Monitor"

  # DefaultDepth 32 Chrashing!
  # DefaultDepth 24 # Running!
  DefaultDepth 16 # Running!
  # DefaultDepth 15 Chrashing!
  # DefaultDepth 8 # Running, but ugly!

  #############################################################################
  # Use one of these GRUB start options to repair a crashing X11 session:
  # - vga=ask: This option allows you to select the mode for the video adaptor.
  # - init=/bin/sh: Run the program /bin/sh (the shell) instead of init.
  #############################################################################
EndSection 

The ("X -configure" generated) /etc/X11/xorg.conf on my OPEN SUSE 12.3 Linux 64 bit DE has been modiefied like that, to test 16 bit color model support:

Section "Screen"
  ...

  # DefaultDepth 32 Chrashing!
  # DefaultDepth 24 # Running!
  DefaultDepth 16 # Running!
  # DefaultDepth 15 Running with Xfce only!
  # DefaultDepth 8 # Running, but ugly!
EndSection 

Anatomy of an application or dialog window

Application windows are based on an XrwApplicationShell, dialog windows are based on an XrwDialogShell. Both are derived from abstract XrwWmShell, and XrwWmShell is derived from XrwComposite - the base class for containers, that manages an arbitary number of child widgets. XrwWmShell provides interaction with the windows manager (move, resize, close, ... of a window). Since XrwComposite has no integrated layout management, it is recommended to assign one XrwBox or XrwGridForm child to each XrwApplicationShell or XrwDialogShell instance, that manages the layout of the shell's grandchildren.

Since XrwWmShell derivatives set the XSetWindowAttributes attribute bit_gravity to NorthWestGravity and the window's background color to XrwTheme.GeneralBackgroundColor, the flickering effects during the redraw procedure (as concequence of ConfigureNotify events - to observe on window resize operations) of a shell's layout manager widget/gadget are already minimized.

(The flickering effects, discussed here, come from the black (undrawn) shell background and the time delay between shell background cleaning and manager widget/gadget redrawing. There are more reasons for flickering effects - see Chapter Specific aspects of event processing.

The sample code shows how to use a XrwBox as manager gadget of a dialog shell.

public class XrwBitmapAndVectorFontSelectionDialog : XrwDialogShell
{
    // Define constants and member attributes.
    ...
 
    // Implement the constructor.
    public XrwBitmapAndVectorFontSelectionDialog (XrwApplicationShell parent,
                                                  ref Point assignedPosition,
                                                  ref Size assignedSize, string title)
        : base (parent, ref assignedPosition, ref assignedSize)
    {
        // Initialize member attributes.
        ...
 
        // Create shell's primary layout manager.
        XrwBox vboxMain = XrwBox.NewVBoxGadget (this);
        vboxMain.BorderWidth = XrwTheme.DlgShellPrimaryChildBorderWidth;
        vboxMain.BorderColor = _backgroundColorPixel;
        vboxMain.VertSpacing = XrwTheme.DlgShellPrimaryChildSpacing;
        AddChild (vboxMain);
 
        // Create shell's grandchildren.
        ...
    }
 
    // Implement the destructor, properties and methods.
    ...   
} 

Usage of popup menus

Popup menus can be created very easily. These are the steps:

  • Create a popup menu shell XrwSimpleMenuShell.
  • Add the menu entries with XrwSme to the menu shell and register the callbacks to the menu entries.
  • Force shell's geometry management.
  • Create a menu button XrmMenuButton and add it to the parent composite.
  • Register the menu shell to the menu button.

There is no additional code to process pop up, pop down or selection required.

The image shows a simple XrwMenuButton with left and right (transparent multicolor) bitmap - including it's poped up menu, based on a XrwDialogShell containing two XrwSme with left and right (transparent multicolor) bitmap.

The sample code shows how to create the simple pop up menu, illustrated by the previous image.

XrwSimpleMenu _fileMenuShell = null;

...

// ---- Create popup menu.

Point origin   = new Point (20, 20);
Size  initSize = new Size  (-1, -1);
_fileMenuShell = new XrwSimpleMenu (this, ref origin, ref initSize);

// ---- Add menu entries.

X11Graphic menuEntryGraphicA = XrwTheme.GetGraphic ( _display,_screenNumber,
    X11Graphic.StockIcon.Information16);
X11Graphic menuEntryGraphicB = XrwTheme.GetGraphic ( _display,_screenNumber,
    X11Graphic.StockIcon.Question16);
XrwSme menuEntry1 = XrwSme.NewSmeGadget (_fileMenuShell, "File menu entry 1",
    menuEntryGraphicA, true, menuEntryGraphicB, true);
menuEntry1.ButtonRelease += HandleMenuEntry1ButtonRelease;
_fileMenuShell.AddChild (menuEntry1);
XrwSme menuEntry2 = XrwSme.NewSmeGadget (_fileMenuShell, "File menu entry 2",
    menuEntryGraphicA, true, menuEntryGraphicB, true);
menuEntry2.ButtonRelease += HandleMenuEntry2ButtonRelease;
_fileMenuShell.AddChild (menuEntry2);

// ---- Beautify popup menu.

_fileMenuShell.CalculateChildLayout ();
_fileMenuShell.SetFixedWidth  (_fileMenuShell.AssignedSize.Width);
_fileMenuShell.SetFixedHeight (_fileMenuShell.AssignedSize.Height);

// ---- Create menu button.

X11Graphic cbw0GraphicA = XrwTheme.GetGraphic ( _display,_screenNumber,
    X11Graphic.StockIcon.FileGeneric16);
X11Graphic cbw0GraphicB = XrwTheme.GetGraphic ( _display,_screenNumber,
    X11Graphic.StockIcon.FolderClose16);
XrwMenuButton commandFileMenu = XrwMenuButton.NewMenuButtonWidget
    (hboxFileRibbon, "File", cbw0GraphicA, true, cbw0GraphicB, true);
commandFileMenu.FrameType = XrwTheme.StaticFrameType;
commandFileMenu.FrameWidth = XrwTheme.StaticFrameWidth;
commandFileMenu.ExpandToAvailableHeight = true;

// ---- Register menu to menu button and insert menu button into parent widget.

commandFileMenu.Menu = _fileMenuShell;
hboxFileRibbon.AddChild (commandFileMenu); 

To clean up the popup menu shell, an additional shell's close delegate must be registered:

    // Register close event.
    this.WmShellClose += HandleShellClose;

...

/// <summary> Application specific processing of the WmShellClose event. </summary>
/// <param name="source"> The widget, the ApplicationClose event is
/// assigned to. <see cref="XrwRectObj"/> </param>
/// <param name="e"> The event data. <see cref="XawClientMessageEvent"/> </param>
/// <remarks> Set XawClientMessageEvent.
/// Set result to nonzero to stop further event processing. </remarks>
void HandleShellClose (XrwRectObj source, XrwClientMessageEvent e)
{
    if (_fileMenuShell != null)
    {
        this.RemoveChild (_fileMenuShell);
        _fileMenuShell.Dispose ();
    }
    
    // Go on calling delegates...
    e.Result = 0;
}

Since the WmShellClose delegate is invoked in reverse order, the clean up process always processes from derived classes back to the base class.

/// <summary> Handle the ClientMessage event. </summary>
/// <param name="e"> The event data. <see cref="XawClientMessageEvent"/> </param>
/// <remarks> Set XawClientMessageEvent.
/// Set result to nonzero to stop further event processing. </remarks>
public void OnClose (XrwClientMessageEvent e)
{
    // Call the close delegates in reverse order!
    object[]    param = new object[] {this, e};
    Delegate[]    delegates = WmShellClose.GetInvocationList();
    for (int i=delegates.Length-1;i>=0;i--)
        delegates[i].DynamicInvoke (param);
        
    //WmShellCloseDelegate wmShellClose = WmShellClose;
    //if (wmShellClose != null)
    //    wmShellClose (this, e);
}

This enables resource deallocation without memory leaks.

Usage of standard dialogs

Curently these standard dialogs are available:

  • XrwMessageBox for a notification only message box (no input except the choice between OK and Cancel).
  • XrwFileSelectionDialog for single file selection.
  • XrwBitmapAndVectorFontSelectionDialog to select a font using all X11 font information.

This is an image of the XrwMessageBox.

This is an image of the XrwFileSelectionDialog.

This is an image of the XrwBitmapAndVectorFontSelectionDialog.

This are images of the XrwColorSelectionDialog, using 16 predefined colors in 8 columns and 2 rows or 2 columns and 8 rows with color names.

The creation of XrwFileSelectionDialog, XrwBitmapAndVectorFontSelectionDialog and XrwColorSelectionDialog is straight forward.

The sample code shows how to use XrwFileSelectionDialog, XrwBitmapAndVectorFontSelectionDialog and XrwColorSelectionDialog.

/// <summary> Handle the Clicked event. </summary>
/// <param name="source"> The widget, the Clicked event is assigned to. <see cref="XrwRectObj"/> </param>
void HandleFileSelectionDialogButtonClicked (XrwRectObj source)
{
    XrwFileSelectionDialog fileDialog = XrwFileSelectionDialog.
        NewFileSelectionDialog (this, "Mono Develop - File selection", Environment.CurrentDirectory);
    fileDialog.SetMinimumSize (fileDialog.AssignedSize);

    ApplicationFramework.SetWmShellIcon (fileDialog, APPICON_FILEPATH);

    this.AddTransientShell (fileDialog);
    XrwDialogShell.Result result = fileDialog.Run ();

    if (result == XrwDialogShell.Result.OK)
    {
        if (XrwApplicationSettings.VERBOSE_OUTPUT_TO_CONSOLE)
            Console.WriteLine ("VERBOSE: " + CLASS_NAME + "::HandleFileSelectionDialogButtonClicked() " +
                               "File dialog closed with: OK, File selected is: " + fileDialog.SelectedFile);
        ApplicationFramework.WriteStatus ("File selection dialog closed with: OK");
    }
    else
    {
        if (XrwApplicationSettings.VERBOSE_OUTPUT_TO_CONSOLE)
            Console.WriteLine ("VERBOSE: " + CLASS_NAME + "::HandleFileSelectionDialogButtonClicked() " +
                                "File dialog closed with: Cancel");
        ApplicationFramework.WriteStatus ("File selection dialog closed with: Cancel");
    }
} 
 
 
/// <summary> Handle the Clicked event. </summary>
/// <param name="source"> The widget, the Clicked event is assigned to. <see cref="XrwRectObj"/> </param>
void HandleFontDialogButtonClicked (XrwRectObj source)
{
    XrwBitmapAndVectorFontSelectionDialog fontDialog = XrwBitmapAndVectorFontSelectionDialog.
        NewBitmapAndVectorFontSelectionDialog (this, "Mono Develop - Font selection");
    fontDialog.SetMinimumSize (fontDialog.AssignedSize);
 
    ApplicationFramework.SetWmShellIcon (fontDialog, APPICON_FILEPATH);
    
    this.AddTransientShell (fontDialog);
    XrwDialogShell.Result result = fontDialog.Run ();

    if (result == XrwDialogShell.Result.OK)
    {
        if (XrwApplicationSettings.VERBOSE_OUTPUT_TO_CONSOLE)
            Console.WriteLine ("VERBOSE: " + CLASS_NAME + "::HandleFontDialogButtonClicked() " +
                               "Font dialog closed with: OK");
        ApplicationFramework.WriteStatus ("Font selection dialog closed with: OK");
    }
    else
    {
        if (XrwApplicationSettings.VERBOSE_OUTPUT_TO_CONSOLE)
            Console.WriteLine ("VERBOSE: " + CLASS_NAME + "::HandleFontDialogButtonClicked() " +
                               "Font dialog closed with: Cancel");
        ApplicationFramework.WriteStatus ("Font selection dialog closed with: Cancel");
    }
}

/// <summary> Handle the Clicked event. </summary>
/// <param name="source"> The widget, the Clicked event is assigned to. <see cref="XrwRectObj"/> </param>
void HandleColorSelectionDialogButtonClicked (XrwRectObj source)
{
    XrwColorSelectionDialog colorDialog = XrwColorSelectionDialog.NewColorSelectionDialog8x2 (this,
                                              "Mono Develop - Color selection", 0x00ffffff);
    colorDialog.SetMinimumSize (colorDialog.AssignedSize);        
    ApplicationFramework.SetWmShellIcon (colorDialog, APPICON_FILEPATH);    
    this.AddTransientShell (colorDialog);
    XrwDialogShell.Result result = colorDialog.Run ();    
    if (result == XrwDialogShell.Result.OK)
    {
        SimpleLog.LogLine (TraceEventType.Verbose, CLASS_NAME +
                           "::HandleColorSelectionDialogButtonClicked () Color dialog closed with: OK, " +
                           "Color selected is: #{0:X000000}", colorDialog.SelectedColor);
        ApplicationFramework.WriteStatus ("Color selection dialog closed with: OK");
    }
    else
    {
        SimpleLog.LogLine (TraceEventType.Verbose, CLASS_NAME +
                           "::HandleColorSelectionDialogButtonClicked () Color dialog closed with: Cancel");
        ApplicationFramework.WriteStatus ("Color selection dialog closed with: Cancel");
    }
}

After the dialog instantiation these calls are recommended:

  • dialog.SetMinimumSize(dialog.AssignedSize) to prevent size underflow.
  • ApplicationFramework.SetWmShellIcon(dialog, APPICON_FILEPATH) to set the shell icon.
  • this.AddTransientShell(dialog) to register the dialog to the application's transient shell list.

XrwFileSelectionDialog and XrwBitmapAndVectorFontSelectionDialog are implemented as spplication modal dialogs. Hence the call XrwDialogShell.Result result = dialog.Run() waits for the dialog end and the result can be evaluated subsequently.

Specific aspects of event processing

During the window resize process a plenty of ConfigureNotify events are emitted by the windows manager. The application recalculates the layout of it's child widgets for every ConfigureNotify event. New sizes in turn lead to corresponding Expose events. Due to the asynchronous drawing model of X11 and - especially for complex layouts due to the layout recalculation time - redraw performance issues and/or flickering are the result.

To avoid this, Athena and Motif provide event compression flags with their wigets (compress_motion, compress_exposure, compress_enterleave). But this is no satisfying solution, because the events to compress must already be queued and immediate sequential. My tests with this approach didn't show a significant improvement.

The sample code shows a snippet of the XrwApplicationShell's DoEvent() method, that illustrates this event compression approach.

if (xevent.type == XEventName.ConfigureNotify)
{
    // ***************************************************************************************
    // Why does the GUI flicker and is there a way out?
    // http://fixunix.com/xwindows/556305-resizing-motif-xaw-xlib-apps-vs-resizing-gtk-qt-
    // apps-how-tospeed-up-xlib-app.html
    // ***************************************************************************************

    // This compression approach requires, that compressible events are ALREADY in the queue.
    // This is NOT very realistic!!!
    X11EventHelper.Matches = 0;
    X11lib.XCheckIfEvent (_display, ref X11EventHelper.Event,
                          X11EventHelper.CountConfigureMatchesProcPtr, xevent.ConfigureEvent.window);
    if (X11EventHelper.Matches > 0)
    {
        Console.WriteLine ("INFORMATION: " + CLASS_NAME + "::DoEvent () // CONFIGURE " +
                           "found subsequent configure events for window " +
                           xevent.ConfigureEvent.window.ToString("x") + " and skip this event.");
        return true;
    }

    ...
}
else if (xevent.type == XEventName.Expose)
{
    if (xevent.ExposeEvent.count > 0)
        return true;
    
    // ***************************************************************************************
    // Why does the GUI flicker and is there a way out?
    // http://fixunix.com/xwindows/556305-resizing-motif-xaw-xlib-apps-vs-resizing-gtk-qt-
    // apps-how-tospeed-up-xlib-app.html
    // ***************************************************************************************

    // This compression approach requires, that compressible events are ALREADY in the queue.
    // This is NOT very realistic!!!
    X11EventHelper.Matches = 0;
    X11lib.XCheckIfEvent (_display, ref X11EventHelper.Event,
                          X11EventHelper.CountExposeMatchesProcPtr, xevent.ExposeEvent.window);
    if (X11EventHelper.Matches > 0)
    {
        Console.WriteLine ("INFORMATION: " + CLASS_NAME + "::DoEvent () // EXPOSE " +
                           "found subsequent expose events for window " +
                           xevent.ExposeEvent.window.ToString("x") + " and skip this event.");
        return true;
    }

    ...
}

The best way i've found to avoid redraw performance issues and/or flickering, is to suspend every ConfigureNotify event for some milli-seconds and to compress all ConfigureNotify evens emmitted during this suspension. This causes a redrawing latency equal to the suspension interval, but the entire impression during a resizing process is much smoother.

The sample code shows a snippet of the XrwApplicationShell's DoEvent() method, that illustrates the event suspension approach.

/// <summary>Define the suspension interval in milli-seconds.</summary>
private ulong           _compressConfigureBySuspend = 350;
    
/// <summary>Remember the point in time the last configuration took place.</summary>
private ulong           _lastConfigureShell = 0;
    
/// <summary>Keep the latest configuration event to process it after suspension.</summary>
private XConfigureEvent _lastConfigureEvent = new XConfigureEvent();

...


/// <summary> Process the topmost event and remove it from the event queue. </summary>
/// <returns> True if efent processing must contionue, false otherwise. </returns>
public bool DoEvent()
{
    // Prevent event processing *** after dispose *** but *** before destruction ***.
    if (_display == IntPtr.Zero)
        return false;
    
    XEvent xevent = new XEvent ();
    
    // Ensure all events are queued.
    X11lib.XFlush (_display);
    
    // Check for suspended ConfigureEvent and process it after the suspension interval.
    if (X11lib.XQLength (_display) == 0 && _compressConfigureBySuspend > 0)
    {
        DateTime dt        = DateTime.Now;
        ulong timeStamp    = (ulong)(dt.Millisecond + dt.Second * 1000 + dt.Minute * 60000 +
                             dt.Hour * 3600000) + (ulong)dt.Day * (ulong)86400000;
        
        if (timeStamp - _lastConfigureShell > _compressConfigureBySuspend &&
            _lastConfigureEvent.window != IntPtr.Zero)
        {
            XrwConfigureEvent e = new XrwConfigureEvent (ref _lastConfigureEvent);
            OnConfigure (e);
            _lastConfigureEvent.window = IntPtr.Zero;
            _lastConfigureShell = timeStamp;
        }
        return true;
    }


    ...
}

The _compressConfigureBySuspend interval can be adjusted to the certain use case to find the optimum between latency and flickering. A value of 0 completely suppresses event suspension.

The only drawback is, that XrwPaned doen't benefit from this approach.

Widget set

The widget names and functionality follow the ideas of the "Athena widget set" with a little influence of the "Motif widget set" and GTK. The widget set is not complete, but continuously growing. Starting with version the widget set contains advanced widgets influenced by modern GUI toolkits. The widget hierarchy looks as follows:

Simple widgets

The simple widgest are, starting with , described within the new article Programming the Roma Widget Set (C# X11) - a zero dependency GUI application framework - Part 2, Simple widgets. They include:

XrwObject:IDisposable ultimate base object[1, ∅] of this widget set
⌊ XrwRectObject fundamental base object[1, ∅] with geometry
⌊ XrwVisibleRectObject fundamental base object[1, ∅] with drawing
⌊ XrwCore universal base gadget/widget[2/3, ∅]
⌊ XrwLabelBase static label base object[2/3, ∅]
| ⌊ XrwComboBox drop down selection widget[3]
| ⌊ XrwLabel static label[2/3]
| | ⌊ XrwCommand command button widget[3]
| | | ⌊ XrwMenuButton button widget[3], to pop up a simple menu
| | ⌊ XrwSme simple menu entry gadget[2]
| ⌊ XrwLabelAndColor label and color rectangle widget[3], select a color
| ⌊ XrwTextSpinButton spin button widget[3], to spin text constants
| ⌊ XrwToggle toggle button widget[3]
| ⌊ XrwRadio radio button widget[3]
| ⌊ XrwNotebookTab notebook tab button widget[3]
⌊ XrwSimple universal object[2/3]
⌊ XrwList list widget[3]
⌊ XrwRibbonCommandBase base object[2, ∅] of ribbon command gadgets
| ⌊ XrwRibbonButton command button gadget[2] for ribbon
| | ⌊ XrwRibbonSplitButton button gadget[2] for ribbon, to pop up a simple menu
| ⌊ XrwRibbonControlGroup gadget[2] for ribbon, to organize control group nodes
⌊ XrwScrollbar scroll bar widget[3]
⌊ XrwText single line text edit widget[3]
⌊ XrwTree toggle button widget[3]
⌊ XrwViewportGridViewHeader column header widget for viewport embedded grids[3]

[1] object = invisible and windowless, uses neither the ***parent*** window nor an ***onw*** window
[2] gadget = uses the ***parent*** window instead of an ***onw*** window, saves resources compared to widget, but can receive events only if forwarded from the widget it is contained in
[3] widget = has an ***onw*** window, can creceive events directly from the WM[4]
[4] WM = Windows Manager
[∅] do not instantiate

 

Composite widgets

The composite widgets are, starting with , described within the new article Programming the Roma Widget Set (C# X11) - a zero dependency GUI application framework - Programming the Roma Widget Set (C# X11) - a zero dependency GUI application framework - Part 3, Composite widgets. They include:

XrwObject:IDisposable ultimate base object[1, ∅]
⌊ XrwRectObject fundamental base object[1, ∅] with geometry
⌊ XrwVisibleRectObject fundamental base object[1, ∅] with drawing
⌊ XrwCore universal base gadget/widget[2/3, ∅]
⌊ XrwComposite container[2/3, ∅], managing many children
⌊ XrwConstraint container[2/3, ∅], with geometry management
| ⌊ XrwBox container[2/3], arranging children horiz./vert.
| | ⌊ XrwNotebook container[2/3], arranging children on pages
| | ⌊ XrwRadioBox gadget[2], arranging XrwRadio children horiz./vert.
| | ⌊ XrwSpinBox gadget[2], spinning invisible children to visible
| ⌊ XrwGridForm container[2/3], arranging children in a column/row grid
| ⌊ XrwColorSelectrorGridForm container[2/3], XrwGridForm for XrwLabelAndColor children
| ⌊ XrwPaned widget[3], controlling two or more paned children
| ⌊ XrwPortHole gadget[2], display only ***one*** child at any time
| ⌊ XrwPropertyGrid widget[3], browse and edit the properties of an object
| ⌊ XrwRibbon widget[3], that realizes the ribbon GUI
| ⌊ XrwRibbonPanel gadget[2], organizing command objects for ribbons
| ⌊ XrwRibbonTab gadget[2], arranging XrwRibbonPanel children horiz.
| ⌊ XrwViewport container[2/3], enabling ***one*** child to scroll
⌊ XrwShell fundamental shell widget[3]
⌊ XrwOverrideShell base popup shell, not interacting with the WM[4]
| ⌊ XrwBaseCellEditorShell popup editor shell[2] base class
| ⌊ XrwGenericCell-
| EditorShell
popup editor shell[2] for generic purpose
| ⌊ XrwRibbonAppMenu popup application menu shell[2] of a XrwRibbon
| ⌊ XrwSimpleMenu popup menu shell[2] for XrwSme gadget
| ⌊ XrwDropDownCell-
| | EditorShell
popup editor shell[2] for drop down
| ⌊ XrwSpinMenu popup scrollable menu shell of XrwSme gadgets[2]
⌊ XrwWmShell base shell, interacting with the WM[4]
⌊ XrwApplicationShell the common code of an X11 application
⌊ XrwTransientShell base class for popups, interacting with WM[4]
⌊ XrwDialogShell base class for dialogs, interacting with WM[4]

[1] object = invisible and windowless, uses neither the ***parent*** window nor an ***onw*** window
[2] gadget = uses the ***parent*** window instead of an ***onw*** window, saves resources compared to widget, but can receive events only if forwarded from the widget it is contained in
[3] widget = has an ***onw*** window, can creceive events directly from the WM[4]
[4] WM = Windows Manager
[∅] do not instantiate

Writing own widgets

Writing simple widgets

User designed simple widgets/gadgets (that do not manage any children) can be inherited from any class described in the article Programming the Roma Widget Set (C# X11) - a zero dependency GUI application framework - Part 2, Simple widgets.

A good approach is to go through all of the code regions the base class has and to override existing features - if required - and to add specific new features. The code regions include:

  1. Inner classes, only needed if complex or massive amouts of data have to be handeled. A better way to deal with such data is to define a data source interface and to connect a data source at runtime.
  2. Constants, to define the class identity and other constant values.
  3. Attributes, to define the class attributes. It is recommended to define protected class attributes and to provide public or internal get/set properties, if required.
  4. Construction, to deffine the constructors. It is recommended to define protected constructors and to provide public factory methods.
  5. Factory, to define public factory methods.
  6. Destruction, to implement the IDisposal interface and to provide traversable destruction from inherited to base classes and internal class instances via DisposeByParent().
  7. Properties, to define public or internal get/set properties for protected class attributes.
  8. Methods, to add specific new features.
  9. * override methods, to override existing features - if required.
  10. Event handler, to add specific event handlers.
  11. * override event handler, to override existing event handlers - if required.

Be careful with Destruction. Destroy only the classe's internal attributes and keep in mind, that DisposeByParent() travestes through the inheritance tree.

Writing manager widgets

User designed manager widgets/gadgets (that do manage an arbitary number of children) can be inherited from any class described in the article Programming the Roma Widget Set (C# X11) - a zero dependency GUI application framework - Part 3, Composite widgets.

The approach to write manager widgets/gadgets is the same as to write simple widgets/gadgets - except that manager widgets/gadgets

  1. typically override these XrwRectObj methods: CalculateChildLayout(), MinimumSize(), PreferredSize() and Redraw(),
  2. sometimes override these XrwCore methods: Realize() and Unrealize() and
  3. sometimes override these XrwComposite methods: AddChild(), InsertChild() and RemoveChild().

Wishes and requests

Request Appeared Solved
Add ComboBox widget with SpinMenu. version 0.1 version 0.2
Add SpinButton widget. version 0.1 version 0.2
Add support for 16 bit color model. version 0.1 version 0.2
Add a GTK compatible font selection dialog. version 0.1  
Add missing static XrwNotebook factory method NewBottomTabedNotebook. version 0.1 version 0.3
Change from 8 bit string to 16 bit string drawing to enable more than only ASCII characters. version 0.2  
Add a simple initial color dialog. version 0.2 version 0.5
Add a basic ribbon widget. version 0.2 version 0.3
Add missing static XrwNotebook factory methods NewLeftTabedNotebook and NewRightTabedNotebook. version 0.3  
Add a paned widget. version 0.3 version 0.4
Add a grid form widget. version 0.3 version 0.4
Add a basic property grid widget. version 0.3 version 0.4
Add enhanced tooltip to ribbon. version 0.3  
Add a labeled frame widget. version 0.3  
Add an input dialog. version 0.4  
Add alternative list views (Small icons, Large icons, List and Details). version 0.4 version 0.5
Add a more advanced color dialog. version 0.5  

Fixed errors

Fixed with :

  1. Double painting of XrwShell's children fixed.
  2. Missing background color initialization for widgets derived from XrwCore added.
  3. Fixed X11Graphic constructor arguments individualColormap and graphicDepth from application.IndividualColormap and application.ColorDepth to IntPtr.Zero and defaultColordepth (to use the root window's color map and depth, not the application's color map and depth), and fixed X11Graphic.CreateIndependentGraphicPixmap() / X11Graphic.CreateIndependentMaskPixmap() method argument window from application.Window to defaultRootWindow in XrwApplicationFramework.SetWmShellIcon(). Both was necessary to support 16 bit color model.
  4. Fixed X11lib.XCreateGC() method argument x11drawable from window to pixmap in X11Graphic.CreateIndependentGraphicPixmap(). It was necessary to support 16 bit color model.

Fixed with :

  1. Fixed exception during application closing, if any XrwOverrideShell is currently poped up, now the collection handling for parent's child list is correct. (Disposal of an XrwOverrideShell implies removal from it's parent child list - this alters the child list collection.)
  2. Fixed X11Graphic.StockIcon.Information16 size from 18x18 to 16x16.
  3. Fixed XrwVisibleRectObj.ExpandToAvailableHeight, XrwVisibleRectObj.ExpandToAvailableWidth, XrwVisibleRectObj.ExpandToMaxSiblingHeight and XrwVisibleRectObj.ExpandToMaxSiblingWidth on any fixed dimension, now setting true is suppressed, if a fixed height/width is assigned.
  4. Fixed XrwVisibleRectObj.SetFixedHeight and XrwVisibleRectObj.SetFixedWidth on any dimension expansion is set, now XrwVisibleRectObj.ExpandToAvailableHeight and XrwVisibleRectObj.ExpandToAvailableWidth or XrwVisibleRectObj.ExpandToMaxSiblingHeight and XrwVisibleRectObj.ExpandToMaxSiblingWidth are reset to false if formerly true.
  5. Fixed XrwRectObj.GeometryManagerAccess.SetAssignedGeometry() for a fixed height assignment, now XrwVisibleRectObj.FixedSize.Height is applied correctly - only if XrwVisibleRectObj.IsFixedHeight is true.

Fixed with :

  1. Fixed XrwTree's calculation of PreferredSize().
  2. Fixed drawing error in XrwVisibleRectObj.DrawFrame(). One pixel frames now don't overrun right/bottom coordinate.
  3. Fixed X11Graphic.StockIcon.Question16 and X11Graphic.StockIcon.Error16 size from 18x18 to 16x16.
  4. Fixed XrwFileSelectionDialog height adaption. Width adaption has already been correct. Now a height change of the dialog leads to height change of the places and files viewports.
  5. Fixed XrwBitmapAndVectorFontSelectionDialog height adaption. Width adaption has already been correct. Now a height change of the dialog leads to height change of the font style, font resolution and font size viewports.
  6. Fixed scroll bar update for a XrwViewport containing a XrwTree on tree node collapse or expand. Now the XrwTree calls the registered SizePreferenceChanged delegates.
  7. Fixed positioning of a manager widget inside a manager gadget. E. g. a XrwPaned (horizontal) widged inside a XrwBox gadget (vertical) is positioned correct. Now the GeometryManagerAccess.SetAssignedGeometry() method resets not only a widget's assigned position to 0,0, but also the position offset of it's children. This is because a widget has it's own X11 window and all positions must be measured relativle to the window.
  8. Fixed crash if application has a working folder different to the installation folder. Now the X11Graphic loader also looks up the installation folder for a graphic file not found in the working folder.

Fixed with :

  1. Fixed XrwViewport's calculation of CalculateChildLayout(). For children, whose size needs one scroll bar only, and the display of this scroll bar decreases the available size in a manner that requires a second scroll bar, now the second scroll bar will be displayed.
  2. Fixed redrawing problem of GUI parts, obscured (covered) by XrwSimpleMenu, XrwSpinMenu or XrwDropDownCellEditorShell and uncovered after menu popdown, if any selected XrwSme invokes a dialog. (This is because a dialog implements an internal event processing loop.) Now the sme's OnButtonReleased delegate will not be called directly by the sme's ButtonRelease event. Instead a CustomMessage event will be generated, that goes to the end of the message queue. The CustomMessage event only calls the sme's OnButtonReleased delegate, if it is his turn (in the message queue). This procedure guarantees the processing of any menu's Unmap event before the sme's ButtonRelease event.

Improvements

Improved with :

  • Generic drawing method to draw arrows for scroll bars, forth and back buttons XrwVisibleRectObj.DrawArrow().
  • New method signature for X11lib.XAllocWMHints(), now returning the unmanaged memory handle of WMHints and the marshaled strurture as reference argument. This enables to call X11lib.Free() with the unmanaged memory handle of WMHints.

Improvements with :

  • Removal of needles X11 events from the event queue (events for an X11 window, that just has been unrealized) on XrwApplicationShell.RemoveCild() and XrwCore.DisposeByParent().
  • Additional themes XrwTheme.GeneralStyle.WinLuna, XrwTheme.GeneralStyle.WinRoyale and XrwTheme.GeneralStyle.WinMidori.
  • Extensions to the XrwNotebook to support bottom tabs.
  • A ribbon widget, that supports application menu button/application menu, tabs, panels, buttons, split buttons and control groups as well as theming.

Improvements with :

  • New optional column header display for XrwViewport, if Child implements XrwIGridView interface (like XrwList and XrwTree do).
  • Ability to display multiple columns for XrwList and, if embedded in a XrwViewport, optional column header.
  • Ability to display multiple columns for XrwTree and, if embedded in a XrwViewport, optional column header.
  • Reduced needles redrawing of XrwComposite's children by calling InvokeRedraw() for gadgets (children without own window) only (widgets receive the expose event from the WM anyway).
  • Reduced flickering during the application window's resizing process (see "Specific aspects of event processing" for details).
  • Multiple root nodes for XrwTree.
  • Added a paned manager widget XrwPaned, that supports child resizing without any parent size change, and a grid form manager gadget XrwGridForm, that supports column/row based child layout (including column/row span capabilities and fixed or dynamic column/row dimensions).
  • Convenience functions to set user defined font specification and explicit assignment of the current DefaultFontName to every newly created widget's GC (graphics context).
  • XrwList and XrwTree show boolean values as toggle images now, instead of as text.
  • Added editability for XrwTree (required for a simple property grid widget).
  • Added a simple property grid widget XrwPropertyGrid, using reflection to determine the properties to display and edit. Properties of type string, bool, ThreeState and enum are editable (utilize the provided standard editors).

Improvements with :

  • Replacement of the proprietrary data types TSize, TPoint and TRectangle by System.Drawing.Size, System.Drawing.Point, System.Drawing.Rectangle and some extension methods.
  • XrwList now supports the view types ViewType.List, ViewType.SmallIcon and ViewType.LargeIcon in addition to ViewType.Details.
  • XrwList now supports multi selection.
  • Reduced flickering on mouse move inside XrwList and XrwTree. Mouse move handler calls RedrawContent() directly now (instead of calling InvokeRedraw(), that is always deleting the background first - the reason for flickering - and calling RedrawContent() afterwards).
  • Added column resizig for XrwList and XrwTree.
  • Added clipping to text output, important for XrwList and XrwTree column resizing below column's preferred size.
  • Added in-place editing for XrwList and XrwTree, build-in editors provided for single line text, boolean values, three-state values and enumerations.
  • Introduction of the X11Surface class to centralize all rendering associated properties for XrwVisibleRect and derived widgets and to prepare for easy switch to "Cairo" rendering in later versions of the widget set (see Programming Cairo text output beyond the 'toy' text API (C#/X11) - a prrof of concept meanwhile).
  • Added column reordering for XrwList and XrwTree.
  • Introduction and exclusive usage of new static log class SimpleLog, implemented through X11wrapper solution, instead of heterogeneous Console.WriteLine() calls.
  • The XrwGridForm now overrides the MinimumSize now PreferredSize methods of  XrwComposite with more suitable size calculations.

Points of Interest

It was surprising how little effort is required to create a simple widget set with an attractive design.
This work should also animate other programmers to deal with Mono on Linux or Linux-like platforms.

Still working on the completion of Athena widget set compatible widgets.

After the implementation of the biggest part of the Athena widget set compatible widgets, the idea did not let up to go beyond this and to create higher sophisticated widgets, e. g. ribbon and property grid.

The idea to create higher sophisticated widgets goes on with panned and grid form widget.

To unlesh the power of list and tree widgets, features like column resizing and reordering as well as in-place editing have been added.

History

The first public version of the Roma widget set is version from 20. January 2014.
The second public version of the Roma widget set is version from 07. March 2014.
The third public version of the Roma widget set is version from 01. Aplil 2014.
The fourth public version of the Roma widget set is version from 13. May 2014.
The fifth public version of the Roma widget set is version  from 15. August 2014.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Steffen Ploetz
CEO Ploetz + Zeller GmbH
Germany Germany
I am CEO at Ploetz + Zeller GmbH, Munich Germany (www.p-und-z.com)
 
Ploetz + Zeller GmbH is a consulting and software services company committed to pro-active and professional governance and optimization of our clients' company processes. Furthermore it offers Symbio (www.symbioworld.com) software, a very powerful and easy to use business process management suite.
 
My responsibilities range from product ownership of Symbio via responsibility for the architecture of some Symbio software components to implementation of software core parts (e. g. automatic layout).
 
I started programming 1986 with C64 BASIC and came via Pascal, Turbo Pascal, C, Turbo C, C++ and Java to C#. I like the potential of C++ very much, but now my favorite language is C#.
 
I believe a lot in free knowledge sharing. I'm author at German Wikipedia and, after 10 years of passive membership, author at CODE PROJECT.

Comments and Discussions

 
QuestionGood work, Steffen PinprofessionalSlacker00716-Aug-14 0:26 
QuestionHoly sh*t! Pinmemberbombersa13-May-14 12:01 
AnswerRe: Holy sh*t! PinprofessionalSteffen Ploetz13-May-14 21:02 
GeneralOutstanding work PinprotectorMarc Clifton8-Mar-14 8:51 
QuestionEpic PinmemberPieter Van Parys7-Mar-14 4:08 
QuestionSplit into multiple articles. PinmemberMalli_S7-Mar-14 3:50 
AnswerRe: Split into multiple articles. PinprofessionalSteffen Ploetz11-Mar-14 1:24 
SuggestionRe: Split into multiple articles. PinmemberMalli_S11-Mar-14 21:19 
GeneralRe: Split into multiple articles. PinprofessionalSteffen Ploetz12-Mar-14 7:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140921.1 | Last Updated 15 Aug 2014
Article Copyright 2014 by Steffen Ploetz
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid