Introduction
This article shows how to access most of the Xfwf/Free Widget Foundation widgets from C# using Mono Develop. A lot of API calls are ready-to-use defined and tested and some challenges are mastered, e.g. setting the right dependencies (to compile the Xfwf/Free Widget Foundation widgets), correction of compilation errors and optimization of the impression. This article is aimed to point out that programming Xfxf/Free Widget Foundation widgets with C# can be easyly achieved and greatly improve the user experience (showcase). It provides a sample application's complete project for 32 bit and 64 bit.
Background
This is the fourth article in a series of articles examining X* API calls from C# using Mono Develop. The first article was Programming Xlib with Mono Develop - Part 1: Low-level (proof of concept) and dealed with Xlib/X11. The second article was Programming Xlib with Mono Develop - Part 2: Athena widgets (proof of concept) and dealed with Xt/Athena. And the third article was Programming Xlib with Mono Develop - Part 3: Motif widgets (proof of concept) and dealed with Xm/Motif. The current article goes ahead to the Xfwf/Free Widget Foundation widgets and shows how to use them from a modern language/IDE like C#/Mono. The focus is on the Xt/Athena compatible Xfwf/Free Widget Foundation widgets.
This article illustrates how easy programming Xfwf/Free Widget Foundation using Xfwf API calls from C# is to achieve. Most of the widgets are Xt/Athena based but there are some Xm/Motif based widgets too. Since Open Motif made Motif available with source code and under a public license, almost every XWindow system can deal with the Motif widgets royalty free. So all Xfwf/Free Widget Foundation widgets are available and an application can utilize any mix of Xt/Athena, Xm/Motif and Xfwf/Free Widget Foundation widgets.
Using the code
The latest known version of Xfwf/Free Widget Foundation widgets is "FWF Version 4.0, 18 Apr 1996" and can be found on many servers for download as
fwf-4.0.tar.gz. The project hasn't been maintained since 1996, but the widgets are still very useful and not comparable to any Xt/Athena or Xm/Motif widgets. Neither Free Widget Foundation nor the major programmer Brian K Totty (who wrote a lot of the Free Widget Foundation widgets during his time at Department of Computer Science * University Of Illinois at Urbana-Champaign and maintained the distribution until version 3.671) have a home page. Bert Bos (who also wrote a lot of the Free Widget Foundation widgets during his time at the University of Groningen and maintained the distribution starting with version 3.7) has a home page, where Xfwf/Free Widget Foundation widgets is mentioned briefly.
The common way to use the widgets is to compile the source tree as described in the README.BUILD file and to reference the library from the project. But this procedure didn't work. Since the Xfwf/Free Widget Foundation widgets have not been maintained after 1996, some declarations and references are outdated and have to be corrected. Moreover not only that FileComp/getod.c, EzMenu/EzME.c, CMap/Cmap.c, HDial/Hdial.c, Shistogram/Shistogram.c and IconBox/IconBoxT.c have compilation errors to fix, but the sub directories HTML2 and SSGML can't be compiled at all.
That's why this article follows a different approach and incorporates widget by widget into a Mono C project named FWF (targeting the libXfwf.so) of the sample application's solution and modifies the widget sources individually to compile.
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. However the software packsges
X11,
Xt and
Xpm must be installed. The sample application's solution consists of five projects (the complete sources are provided for download):
- FWF containes a large part of the original source code tree of Xfxf/Free Widget Foundation widgets (as far as incorporated into the sample application) and compiles to the libXfwf.so
- X11Wrapper defines the function prototypes, structures and types for Xlib/X11 calls to the libX11.so (already known from the first article of this series)
- XawNative contains a very little amount of native C code to access Athena widget class records and to transform managed data into natice structures and compiles to libXawNative.so (already known from the second article of this series)
- XtWrapper defines the function prototypes, structures and types for Xt calls to the libXt.so (already known from the second article of this series)
- Xfwf contains the sample application based on Xt/Athena and Xfwf/Free Widget Foundation widgets
bit solution is the definition of some types, as already described in the first article of this series.
The application hast test code for every Xfwf/Free Widget Foundation widget described below in the FWF Widget hierarchy.
Look & feel on GNOME desktop 2.30.0 (32 bit).
32 bit vs. 64 bit
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 of this series, chapter Using the code/32 bit vs. 64 bit.
Core
⌊ XfwfCircPerc
⌊ Composite
| ⌊ XfwfCommon
| | ⌊ XfwfFrame
| | | ⌊ XfwfBoard
| | | | ⌊ XfwfAnimator
| | | | ⌊ XfwfArrow
| | | | ⌊ XfwfEnforcer
| | | | ⌊ XfwfIcon
| | | | ⌊ XfwfLabel
| | | | | ⌊ XfwfButton
| | | | | | ⌊ XfwfPullDown
| | | | | | | ⌊ XfwfOptionButton
| | | | | | ⌊ XfwfToggle
| | | | | ⌊ XfwfSlider2
| | | | | | ⌊ XfwfSlider4
| | | | | ⌊ XfwfSpinLabel
| | | | ⌊ XfwfRowCol
| | | | | ⌊ XfwfGroup
| | | | | | ⌊ XfwfRadioGroup
| | | | ⌊ XfwfRows
| | | | | ⌊ XfwfMenuBar
| | | | ⌊ XfwfScrollbar
| | | | | ⌊ XfwfHScrollbar
| | | | | ⌊ XfwfVScrollbar
| | | | ⌊ XfwfScrolledWindow
| | | | ⌊ XfwfScrolledWindow3
| | | | ⌊ XfwfTabs
| | ⌊ Constraint
| | | ⌊ XfwfStack
⌊ Shell
| ⌊ OverrideShell
| ⌊ XfwfTextMenu
⌊ Simple
| ⌊ XfwfMultiList
⌊ XfwfPcBar
⌊ XfwfThumbWheel
⌊ XfwfThumbWheel2
The Xfwf/Free Widget Foundation widget set is a "a collection of no-cost, freely redistributable X graphical user interface widgets". The next chapters contain descriptions, that are more or less based on the respective widget's man page, included in the Xfwf/Free Widget Foundation distribution, extended by screen shots, sample code and hints.
The XfwfCircPerc widget can be used to indicate the progress that is made by an application, for example in a lengthy computation. This is done by displaying a circle, in which a colored pie-slice indicates the amount of work already done, and in which the remainder of the circle, filled in with another color, indicates the amount of work yet to be done. The percentage done can be indicated with a two decimal accuracy. | |
Inheritance (↑)
Core --> XfwfCircPerc
New Resources
Name | Class | Type | Default |
XXtNborderColor | XtCBorderColor | Pixel | black |
XfwfNcompletedColor | XtCCompletedColor | Pixel | yellow |
XfwfNinteriorColor | XtCInteriorColor | Pixel | red |
XfwfNpercentageCompleted | XtCPercentageCompleted | int | 0 |
Usage
IntPtr circPerc = Xtlib.XtCreateManagedWidget("CircularPercentage",
Xfwflib.Xt_XfwfCircularPercentageWidgetClass(), circpercBox,
Arg.Zero, (XCardinal)0);
...
_circularPercValue += 1000;
Xfwflib.XfwfCircularPercentageSetPercentage (circPerc, _circularPercValue);
The XfwfPcBarc widget is used to display a horizontal (or vertical) rectangular box in which a percentage from 0% to 100% is indicated by a bar that extends across (or up) the box. The actual percentage value can optionally be displayed in text form, centered in the box. | |
Inheritance (↑)
Core --> XfwfPcBar
New Resources
Name | Class | Type | Default |
XtNforeground | XtCForegroundPixel | Pixel | XtDefaultForeground |
XfwfNpercentage | XtCPercentage | int | 0 |
XfwfNdisplaypc | XtCDisplaypc | Boolean | False |
XfwfNvertical | XtNvertical | Boolean | False |
XtNfont | XtNfont | FontStruct | XtDefaultFont |
Usage
Arg[] pcBarArgs = { new Arg (XtNames.XtNwidth, (XtArgVal)25),
new Arg (XtNames.XtNheight, (XtArgVal)120),
new Arg (XfwfNames.XfwfNvertical, (XtArgVal)1),
new Arg (XfwfNames.XfwfNpercentage, (XtArgVal)0),
new Arg (XfwfNames.XfwfNdisplaypc, (XtArgVal)1),
new Arg (XfwfNames.XfwfNshowZero, (XtArgVal)1) };
IntPtr pcboxPerc = Xtlib.XtCreateManagedWidget("PercentageBar1",
Xfwflib.Xt_XfwfPcBarWidgetClass(), pcBarBox,
pcBarArgs, (XCardinal)6);
...
Xfwflib.XfwfPcBarSetPercentage (_pcbox1Perc, pcboxPerc);
The XfwfThumbWheel widget is a very basic implementation of a vertically placed valuator that can be turned up or down. It can serve as a scroller or valuator. The turning effect is achieved by showing a series of prepared images one after the other. | |
If Xpm is available, the images are smooth gray scale. Otherwise the fallback images are pixelated.
Inheritance (↑)
Core --> XfwfThumbWheel
Code canges
Additional default translations, now these keyboard bindings are supported:
- < Btn1Down> turn the wheel using step resource value as step width
- < Btn2Down> turn the wheel using step resource half value as step width
- < Btn3Down> turn the wheel using step resource quarter value as step width
- < Key>Up and <Key>Left to turn up using step resource value as step width
- Shift<Key>Up and Shift<Key>Left to turn up using step resource half value as step width
- Ctrl<Key>Up and Ctrl<Key>Left to turn up using step resource quarter value as step width
- < Key>Down and <Key>Right to turn down using step resource value as step width
- Shift<Key>Down and Shift<Key>Right to turn down using step resource half value as step width
- Ctrl<Key>Down and Ctrl<Key>Right to turn down using step resource quarter value as step width
New Resources
Name | Class | Type | Default |
XfwfNnumberOfPictures | XtCNumberOfPictures | int | 0 |
XfwfNpictures | XtCPictures | ImageList | NULL |
XfwfNvertical | XtCVertical | Boolean | True |
XfwfNclickArea | XtCClickArea | Dimension | 7 |
XfwfNmaxValue | XtCMaxValu | int | 100 |
XfwfNminValue | XtCMinValue | int | 0 |
XtNvalue | XtCValue | int | 0 |
XfwfNstep | XtSCtep | int | 1 |
XfwfNinitialDelay | XtCInitialDelay | int | 500 |
XfwfNrepeatDelay | XtCRepeatDelay | int | 50 |
XfwfNsensitivity | XtCSensitivity | int | 2 |
XfwfNscrollCallback | XtCScrollCallback | Callback | NULL |
XfwfNscrollResponse | XtNscrollResponse | Callback | scroll_response |
Usage
Arg[] thwheelArgs = { new Arg(XfwfNames.XfwfNvertical, (XtArgVal)0) };
IntPtr thWheel = Xtlib.XtCreateManagedWidget("ThumbWheel3",
Xfwflib.Xt_XfwfThumbWheelWidgetClass(), thwheelBox,
thwheelArgs, (XCardinal)1);
Callback usage
Connect the callback via
XfwfNames.XfwfNscrollCallback
.
public void ThumbWheelScrollCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
TInt val = Xtlib.XtGetValueOfInt (widget, XtNames.XtNvalue);
Console.WriteLine ("ThumbWheel position {0}", val);
}
The XfwfThumbWheel2 is almost the same as the XfwfThumbWheel widget, but Xpm is not required, the images are always pixelated, and a horizontal orientation is not supported. | |
Inheritance (↑)
Core --> XfwfThumbWheel2
New Resources
Name | Class | Type | Default |
XfwfNnumberOfPictures | XtCNumberOfPictures | int | 0 |
XfwfNpictures | XtCPictures | ImageList | NULL |
XfwfNclickArea | XtCClickArea | Dimension | 7 |
XfwfNmaxValue | XtCMaxValu | int | 100 |
XfwfNminValue | XtCMinValue | int | 0 |
XtNvalue | XtCValue | int | 0 |
XfwfNstep | XtSCtep | int | 1 |
XfwfNinitialDelay | XtCInitialDelay | int | 500 |
XfwfNrepeatDelay | XtCRepeatDelay | int | 50 |
XfwfNsensitivity | XtCSensitivity | int | 2 |
XfwfNscrollCallback | XtCScrollCallback | Callback | NULL |
XfwfNscrollResponse | XtNscrollResponse | Callback | scroll_response |
Usage
See XfwfThumbWheel
.
Callback usage
See
XfwfThumbWheel
.
The
XfwfCommon
widget serves as superclass for many other widgets. It defines some resources, types, converters, etc. and implements keyboard traversal.
Inheritance (↑)
Core --> Composite --> XfwfCommon
New Resources
Name | Class | Type | Default |
XfwfNuseXCC | XtCUseXCC | Boolean | True |
XfwfNusePrivateColormap | XtCUsePrivateColormap | Boolean | False |
XfwfNuseStandardColormaps | XtCUseStandardColormaps | Boolean | True |
XfwfNstandardColormap | XtCStandardColormap | Atom | 0 |
XfwfNxcc | XtCXcc | XCC | create_xcc |
XfwfNtraversalOn | XtCTraversalOn | Boolean | True |
XfwfNhighlightThickness | XtCHighlightThickness | Dimension | 2 |
XfwfNhighlightColor | XtCHighlightColor | Color | XtDefaultForeground |
XtNbackground | XtNbackground | Color | XtDefaultBackground |
XfwfNhighlightPixmap | XtCHighlightPixmap | Pixmap | None |
XfwfNnextTop | XtCNextTop | Callback | NULL |
XfwfNuserData | XtCUserData | Pointer | NULL |
Usage
Do not instantiate
XfwfCommon
.
The XfwfMultiList widget is a string list widget, similar to the Xt/Athena List widget, but with the following significant differences:
- Multiple items can be selected at one time.
- Colors can be specified for highlighting.
| |
In addition to setting and unsetting items with the Set() and Unset() actions, XfwfMultiList
also supports toggling (selected item becomes unselected, unselected item becomes selected) with Toggle() and opening of objects (e.g. might be used with a double-click) with Open().
The return structure is now more complicated, listing what type of operation generated the callback (highlighting an item, unhighlighting an item, opening an item, requesting the current status), what item was clicked on to produce this callback, and the list of what items are currently selected. Items can be individually disabled, by setting the sensitivity array. internalWidth and internalHeight resources have been removed.
Inheritance (↑)
Core --> Simple --> XfwfMultiList
New Resources
Name | Class | Type | Default |
XfwfNborder | XtCBorder | Pixel | XtDefaultForeground |
XtNcallback | XtCCallback | Callback | NULL |
XfwfNcolumnWidth | XtCColumnWidth | Dimension | 0 |
XfwfNcolumnSpacing | XtCColumnSpacing | Dimension | 8 |
XfwfNcursor | XtCCursor | Cursor | left_ptr |
XfwfNdefaultColumns | XtCDefaultColumns | int | 1 |
XtNfont | XtCFont | XFontStruct | XtDefaultFont |
XfwfNforceColumns | XtCForceColumns | Boolean | False |
XtNforeground | XtCForeground | Pixel | XtDefaultForeground |
XfwfNhighlightBackground | XtCHighlightBackground | Pixel | XtDefaultForeground |
XfwfNhighlightForeground | XtCHighlightForeground | Pixel | XtDefaultBackground |
XfwfNinsensitiveBorder | XtCInsensitiveBorder | Pixmap | Gray |
XfwfNlist | XtCList | String | NULL |
XfwfNlongest | XtCLongest | int | 0 |
XfwfNmaxSelectable | XtCMaxSelectable | int | 1 |
XfwfNnumberStrings | XtCNumberStrings | int | 0 |
XfwfNpasteBuffer | XtCPasteBuffer | Boolean | False |
XfwfNrowHeight | XtCRowHeight | Dimension | 0 |
XfwfNrowSpacing | XtCRowSpacing | Dimension | 2 |
XfwfNsensitiveArray | XtCSensitiveArray | Boolean | False |
XfwfNtabList | XtCTabList | String | NULL |
XfwfNtabs | XtCTabs | int | 0 |
XfwfNverticalList | XtCVerticalList | Boolean | False |
Usage
string[] mlText = { "Happy New Year", "To You",
"Your Family", "And Friends",
"Peace And Joy", "Best wishes 2013!",
"(insensitive)", null};
TBoolean[] mlSensi = { (TBoolean)1, (TBoolean)1,
(TBoolean)1, (TBoolean)1,
(TBoolean)1, (TBoolean)1, (TBoolean)0};
Arg[] mlistT1Args = { new Arg(XfwfNames.XfwfNlist, mlText),
new Arg(XfwfNames.XfwfNsensitiveArray, mlSensi),
new Arg(XfwfNames.XfwfNmaxSelectable, (XtArgVal)3),
new Arg(XfwfNames.XfwfNdefaultColumns, (XtArgVal)2),
new Arg(XfwfNames.XfwfNnumberStrings, (XtArgVal)7),
new Arg(XtNames.XtNbackground, (XtArgVal)_backgroundPixel),
new Arg(XtNames.XtNborderWidth, (XtArgVal)2),
new Arg(XtNames.XtNborderColor, (XtArgVal)_lightborderPixel) };
Callback usage
Connect the callback via
XtNames.XtNcallback
.
public void MultiListCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
if (callData == IntPtr.Zero)
{
Console.WriteLine ("Multilist selected.");
return;
}
XfwfMultiListReturnStruct mlrs = (callData != IntPtr.Zero ? (XfwfMultiListReturnStruct)
Marshal.PtrToStructure (callData, typeof(XfwfMultiListReturnStruct)) :
new XfwfMultiListReturnStruct());
string[] MultiListActionNames =
{
"NOTHING",
"HIGHLIGHT",
"UNHIGHLIGHT",
"OPEN",
"STATUS"
};
string recentEntry = (mlrs.text != IntPtr.Zero ? Marshal.PtrToStringAuto (mlrs.text) :
"NULL");
string completeSelection = "";
for (int index = 0; index < (int)mlrs.num_selected; index++)
{
if (completeSelection != "")
completeSelection += "; ";
completeSelection += Marshal.ReadInt32 (mlrs.selected_items,
index * sizeof (TInt)).ToString ();
}
Console.WriteLine ("MultiList action: {0}; {1} string(s) selected; " +
"Recent entry: {2}; Complete selection: {3}",
MultiListActionNames[(int)mlrs.action],
(int)mlrs.num_selected, recentEntry, completeSelection);
}
The XfwfFrame widget is a composite widget that accepts just one child. Its only purpose is to draw a frame around widgets that do not have a frame of their own. It always uses the size of its child, with a little extra for the frame. There are several types of frames available, selectable with a resource. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon --> XfwfFrame
New Resources
Name | Class | Type | Default |
XfwfNcursor | XtCCursor | Corsor | None |
XfwfNframeType | XtCFrameType | FrameType | XfwfRaised |
XfwfNframeWidth | XtCFrameWidth | Dimension | 0 |
XfwfNouterOffset | XtCOuterOffset | Dimension | 0 |
XfwfNinnerOffset | XtCInnerOffset | Dimension | 0 |
XfwfNshadowScheme | XtCShadowScheme | ShadowScheme | XfwfAuto |
XfwfNtopShadowColor | XtCTopShadowColor | Color | compute_topcolor |
XfwfNbottomShadowColor | XtCBottomShadowColor | Color | compute_bottomcolor |
XfwfNtopShadowStipple | XtCTopShadowStipple | Bitmap | NULL |
XfwfNbottomShadowStipple | XtCBottomShadowStipple | Bitmap | NULL |
Usage
Typically the
XfwfFrame
widget has a border of 2 pixels width, drawn with the label's background color. To embed a
XfwfFrame
widget seamlessly into it's surroundings, the
XfwfCommon
's
XfwfNhighlightThickness
resource has to be set to 0.
IntPtr cursor = X11lib.XCreateFontCursor (Xtlib.XtDisplay (_shell),
X11lib.CursorFontShape.XC_pencil);
Arg[] frameArgs = { new Arg(XtNames.XtNborderColor, (XtArgVal)_darkborderPixel),
new Arg(XtNames.XtNforeground, (XtArgVal)_lightborderPixel),
new Arg(XfwfNames.XfwfNcursor, (XtArgVal)cursor),
new Arg(XfwfNames.XfwfNframeWidth, (XtArgVal)6),
new Arg(XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfRaised),
new Arg(XfwfNames.XfwfNinnerOffset, (XtArgVal)4),
new Arg(XfwfNames.XfwfNouterOffset, (XtArgVal)2) };
IntPtr frame = Xtlib.XtCreateManagedWidget("FrameT1",
Xfwflib.Xt_XfwfFrameWidgetClass(), frameBox,
frameArgs, (XCardinal)7);
The XfwfTextOut widget is a multi-color, multi-font text display widget. Chunks of text can be added in upto 8 colors and 4 fonts, each selecatble by resources. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon --> XfwfTextOut
New Resources
Name | Class | Type | Default |
XfwfNinternalOffset | XtCInternalOffset | Dimension | 2 |
XfwfNfont1 | XtCFont1 | FontStruct | XtDefaultFont |
XfwfNfont2 | XtCFont2 | FontStruct | XtDefaultFont |
XfwfNfont3 | XtCFont3 | FontStruct | XtDefaultFont |
XfwfNfont4 | XtCFont4 | FontStruct | XtDefaultFont |
XfwfNcolor1 | XtCColor1 | Pixel | XtDefaultForeground |
XfwfNcolor2 | XtCColor2 | Pixel | XtDefaultForeground |
XfwfNcolor3 | XtCColor3 | Pixel | XtDefaultForeground |
XfwfNcolor4 | XtCColor4 | Pixel | XtDefaultForeground |
XfwfNcolor5 | XtCColor5 | Pixel | XtDefaultForeground |
XfwfNcolor6 | XtCColor6 | Pixel | XtDefaultForeground |
XfwfNcolor7 | XtCColor7 | Pixel | XtDefaultForeground |
XfwfNcolor8 | XtCColor8 | Pixel | XtDefaultForeground |
Usage
Typically the
XfwfTextOut
widget has a border of 2 pixels width, drawn with the label's background color. To embed a
XfwfTextOut
widget seamlessly into it's surroundings, the
XfwfCommon
's
XfwfNhighlightThickness
resource has to be set to 0.
fallbackResources.Add (AppShellName + "*" + TextOutName +
".font1: -adobe-times-medium-r-normal--12-*-*-*-p-*-iso8859-1");
fallbackResources.Add (AppShellName + "*" + TextOutName +
".font2: -adobe-times-medium-i-normal--12-*-*-*-p-*-iso8859-1");
fallbackResources.Add (AppShellName + "*" + TextOutName +
".font3: -adobe-helvetica-medium-r-normal--12-*-*-*-p-*-iso8859-1");
fallbackResources.Add (AppShellName + "*" + TextOutName +
".font4: -adobe-helvetica-bold-r-normal--12-*-*-*-p-*-iso8859-1");
fallbackResources.Add (AppShellName + "*" + TextOutName + ".color1: black");
fallbackResources.Add (AppShellName + "*" + TextOutName + ".color2: red");
fallbackResources.Add (AppShellName + "*" + TextOutName + ".color3: blue");
fallbackResources.Add (AppShellName + "*" + TextOutName + ".color4: darkgreen");
...
Arg[] textoutArgs = { new Arg(XtNames.XtNwidth, (XtArgVal)120),
new Arg(XtNames.XtNheight, (XtArgVal)60) };
IntPtr textOut = Xtlib.XtCreateManagedWidget(TextOutName,
Xfwflib.Xt_XfwfTextOutWidgetClass(), textoutBox,
textoutArgs, (XCardinal)2);
Xfwflib.XfwfAddText(textOut, "fred ", 1, 1, 0);
Xfwflib.XfwfAddText(textOut, "fred ", 2, 2, 0);
Xfwflib.XfwfAddText(textOut, "fred ", 3, 3, 0);
Xfwflib.XfwfAddText(textOut, "fred", 4, 4, 1);
Xfwflib.XfwfAddText(textOut, "Second line.", 2, 0, 1);
Xfwflib.XfwfAddText(textOut, "Big long text to see if line sizing is OK.", 4, 4, 1);
Xfwflib.XfwfAddText(textOut, null, 0, 0, 0);
The XfwfStack widget is an X toolkit (and Motif if compiled with MOTIF flag) compatible widget that is a subclass of constraint. The stack widget allows only one child to be managed at a time. | These two XfwfButton s realize the switching between the XfwfStack child widgets.
|
Inheritance (↑)
Core --> Composite --> Constraint --> XfwfStack
New Resources
Name | Class | Type | Default |
XfwfNdata | XfwfCData | XtPointer | NULL |
XfwfNmargin | XfwfCMargin | Dimension | 2 |
XfwfNsameSize | XfwfCSameSize | Boolean | False |
XfwfNfill | XfwfCFill | Boolean | False |
XfwfNstackWidget | XfwfCStackWidget | Widget | NULL |
XfwfNstackType | XfwfCStackTyp | XfwfStackType | XfwfSTACK_END_TO_END |
Usage
Arg[] stackArgs = { new Arg(XtNames.XtNfromVert, menuBoard) };
IntPtr stack = Xtlib.XtCreateManagedWidget("Stack",
Xfwflib.Xt_XfwfStackWidgetClass(), rootForm,
stackArgs, (XCardinal)1);
IntPtr stackPage2 = Xtlib.XtCreateManagedWidget("Page2ForStack",
Xtlib.XawFormWidgetClass(), stack,
Arg.Zero, (XCardinal)0);
IntPtr stackPage1 = Xtlib.XtCreateManagedWidget("Page1ForStack",
Xtlib.XawFormWidgetClass(), stack,
Arg.Zero, (XCardinal)0);
...
if (_currentStackPage == 0)
{
_currentStackPage ++;
Xfwflib.XfwfStackNextWidget (stack);
}
else
{
_currentStackPage --;
Xfwflib.XfwfStackPreviousWidget (stack);
}
The XfwfBoard widget can be used as the parent for other widgets.
Children can be any size and anywhere. | |
The location resource also provides a more powerful way of specifying size and position than the geometry management based on Xt/Athena
Core
's x, y, width and height.
Inheritance(↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame --> XfwfBoard
New Resources
Name | Class | Type | Default |
XfwfNabs_x | XtCAbs_x | Position | 0 |
XfwfNrel_x | XtCRel_x | float | 0.0 |
XfwfNabs_y | XfwfNabs_y | Position | 0 |
XfwfNrel_y | XtCRel_y | float | 0.0 |
XfwfNabs_width | XtCAbs_width | Position | 0 |
XfwfNrel_width | XtCRel_width | float | 0.0 |
XfwfNabs_height | XtCAbs_height | Position | 0 |
XfwfNrel_height | XtCRel_height | float | 0.0 |
XfwfNhunit | XtCHunit | float | 0.0 |
XfwfNvunit | XtCVunit | float | 0.0 |
XfwfNlocation | XtCLocation | String | NULL |
Usage
Typically the
XfwfBoard
widget has a border of 2 pixels width, drawn with the label's background color. To embed a
XfwfBoard
widget seamlessly into it's surroundings, the
XfwfCommon
's
XfwfNhighlightThickness
resource has to be set to 0.
Arg[] boardArgs = { new Arg(XfwfNames.XfwfNframeWidth, (XtArgVal)2),
new Arg(XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfRaised),
new Arg(XtNames.XtNwidth, (XtArgVal)400),
new Arg(XtNames.XtNheight, (XtArgVal)300) };
IntPtr board = Xtlib.XtCreateManagedWidget("SliderViewport",
Xfwflib.Xt_XfwfBoardWidgetClass(), slider4Box,
boardArgs, (XCardinal)4);
The XfwfTextMenu widget implements a simple menu, consisting of a series of labels. It is called XfwfTextMenu because it has no support for anything other than simple strings to be displayed. | |
When a menu item is selected, the XfwfNactivate
callback function is called with the number of the item and the label as call_data argument (numbering starts at 0).
When the user moves from one menu item to another, the XfwfNchangeSelection
callback is called. This callback is called even for inactive (grayed out) items. It can be used, for example, to display an explanation of the selected item while the mouse is on it.
Inheritance (↑)
Core --> Composite --> Shell --> OverrideShell --> XfwfTextMenu
New Resources
Name | Class | Type | Default |
XtNfont | XtCFont | FontStruct | XtDefaultFont |
XtNforeground | XtCForeground | Pixel | XtDefaultForeground |
XfwfNtabList | XtCTablist | String | NULL |
XfwfNmenu | XtCMenu | String | "empty" |
XfwfNactive | XtCActive | long | 0xFFFFFFFF |
XfwfNselection | XfwfNselection | int | -1 |
XfwfNcursor | XtCCursor | Cursor | arrow |
XfwfNactivate | XtCActivate | Callback | NULL |
XfwfNchangeSelection | XtCChangeSelection | Callback | NULL |
Usage
Arg[] textMenuArgs = { new Arg(XfwfNames.XfwfNmenu,
X11.X11Utils.StringToSByteArray ("A _Zeroth item\nA Firs_t item\n" +
"A _Second item\nA _Third item\n-----------\nA _Close\0")) };
IntPtr textMenu = Xtlib.XtCreatePopupShell (TextMenuName,
Xfwflib.Xt_XfwfTextMenuWidgetClass(), _shell,
textMenuArgs, (XCardinal)1);
The XfwfAnimator widget cycles through a set of images at a fixed rate. The images are usually read from XPM files. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfAnimator
New Resources
Name | Class | Type | Default |
XtNimages | XtCImages | ImageList | NULL |
XtNintervals | XtCIntervals | CardinalList | NULL |
XtNdefaultInterval | XtCDefaultInterval | Cardinal | 500 |
XtNcycle | XtCCycle | Boolean | True |
Usage
The easiest way to assign the animated images is to use the application's fallback resources. Currently there is no way to create images dynamically. See the Alert widget for a prototyp to create images dynamically.
The images must be accessible for the compiled application. Typically the XfwfAnimator
widget has a border of 2 pixels width, drawn with the label's background color. To embed a XfwfAnimator
widget seamlessly into it's surroundings, the XfwfCommon
's XfwfNhighlightThickness
resource has to be set to 0.
fallbackResources.Add (AppShellName + "*" + Animator1Name +
".images: Anim00.xpm Anim05.xpm Anim10.xpm Anim15.xpm Anim20.xpm " +
"Anim25.xpm Anim30.xpm Anim35.xpm Anim40.xpm Anim45.xpm Anim50.xpm " +
"Anim55.xpm Anim60.xpm Anim65.xpm Anim70.xpm Anim75.xpm");
...
IntPtr amination1 = Xtlib.XtCreateManagedWidget(Animator1Name,
Xfwflib.Xt_XfwfAnimatorWidgetClass(), animatorBox,
Arg.Zero, (XCardinal)0);
The XfwfArrow widget displays a triangle, pointing in one of four directions. It is usually part of a XfwfScrollbar . It calls a callback repeatedly while a mouse is kept pressed. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfArrow
New Resources
Name | Class | Type | Default |
XfwfNdirection | XtCDirection | Alignment | XfwfTop |
XtNforeground | XtCForeground | Color | XtDefaultBackground |
XfwfNarrowShadow | XtCArrowShadow | Dimension | 2 |
XfwfNinitialDelay | XtCInitialDelay | Cardinal | 500 |
XfewfNrepeatDelay | XtCRepeatDelay | Cardinal | 50 |
XtNcallback | XtCCallback | Callback | NULL |
Usage
Typically the
XfwfArrow
widget has a border of 2 pixels width, drawn with the label's background color. To embed a
XfwfArrow
widget seamlessly into it's surroundings, the
XfwfCommon
's
XfwfNhighlightThickness
resource has to be set to 0.
Arg[] arrowArgs = { new Arg (XtNames.XtNborderColor, (XtArgVal)_darkborderPixel),
new Arg (XtNames.XtNwidth, (XtArgVal)20),
new Arg (XtNames.XtNheight, (XtArgVal)20),
new Arg (XfwfNames.XfwfNdirection, (XtArgVal)XfwfAlignment.XfwfLeft) };
IntPtr arrow = Xtlib.XtCreateManagedWidget("Arrow1",
Xfwflib.Xt_XfwfArrowWidgetClass(), arrowBox,
arrowArgs, (XCardinal)4);
Callback usage
Connect the callback via
XtNames.XtNcallback
.
The XfwfEnforcer widget can be used to apply location resources to a widget that is not a subclass of XfwfBoard . | |
The Widget accepts a single child and forces that child to the same size as itself (minus the frame).
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfEnforcer
New Resources
None.
Usage
Typically the
XfwfEnforcer
widget has a border of 2 pixels width, drawn with the label's background color. To embed a
XfwfEnforcer
widget seamlessly into it's surroundings, the
XfwfCommon
's
XfwfNhighlightThickness
resource has to be set to 0.
Arg[] enforcerArgs = { new Arg(XfwfNames.XfwfNframeWidth, (XtArgVal)2),
new Arg(XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfRaised),
new Arg(XfwfNames.XfwfNinnerOffset, (XtArgVal)4),
new Arg(XtNames.XtNwidth, (XtArgVal)400),
new Arg(XtNames.XtNheight, (XtArgVal)40) };
IntPtr enforcer = Xtlib.XtCreateManagedWidget("Enforcer",
Xfwflib.Xt_XfwfEnforcerWidgetClass(), enforcerBox,
enforcerArgs, (XCardinal)5);
Arg[] enforcedArgs = { new Arg(XtNames.XtNlabel, X11.X11Utils.StringToSByteArray
("Enforced label.\0")),
new Arg(XtNames.XtNbackground, (XtArgVal)_backgroundPixel),
new Arg(XtNames.XtNborderWidth, (XtArgVal)0) };
Xtlib.XtCreateManagedWidget("EnforcedLabel",
Xtlib.XawCommandWidgetClass(), enforcerBoard,
enforcedArgs, (XCardinal)3);
The XfwfIcon widget is used to display an icon, which is normally read from an XPM file. There are also a few built-in icons. The widget uses the shape extension to create icons that are non-rectangular or
transparent. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfIcon
New Resources
Name | Class | Type | Default |
XfwfNimage | XtCImage | Icon | NULL |
XfwfNactivate | XtCActivate | Callback | NULL |
Usage
The easiest way to assign the icon image is to use the
application's fallback resources. Currently there is no way to create
images dynamically. See the
Alert widget for a prototyp to create images dynamically.
The images must be accessible for the compiled application. Typically the
XfwfIcon
widget has a border of 2 pixels width, drawn with the label's background color. To embed a
XfwfIcon
widget seamlessly into it's surroundings, the
XfwfCommon
's
XfwfNhighlightThickness
resource has to be set to 0.
fallbackResources.Add (AppShellName + "*" + Icon1Name + "*image: FATAL");
...
Xtlib.XtCreateManagedWidget(Icon1Name, Xfwflib.Xt_XfwfIconWidgetClass(),
iconBox, Arg.Zero, (XCardinal)0);
Callback usage
Connect the callback via
XfwfNames.XfwfNactivate
.
The XfwfLabel widget displays a text of one or more lines, optionally tabed and aligned with one of the sides. In addition it is possible to reverse (the text and background color on) one portion of the text using the XfwfN rvStart and XfwfN rvLength resources and to highlight one portion of the text using the XfwfN hlStart and XfwfN hlLength resources. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfLabel
New Resources
Name | Class | Type | Default |
XtNlabel | XtCLabel | String | NULL |
XfwfNtabList | XtCTablist | String | NULL |
XtNfont | XtCFont | FontStruct | XtDefaultFont |
XtNforeground | XtCForeground | Color | XtDefaultForeground |
XfwfNhlForeground | XtCHlForeground | Color | XtDefaultForeground |
XfwfNalignment | XtCAlignment | Alignment | 0 |
XfwfNtopMargin | XtCTopMargin | Dimension | 2 |
XfwfNbottomMargin | XtCBottomMargin | Dimension | 2 |
XfwfNleftMargin | XtCLeftMargin | Dimension | 2 |
XfwfNrightMargin | XtCRightMargin | Dimension | 2 |
XfwfNshrinkToFit | XtCShrinkToFit | Boolean | False |
XfwfNrvStart | XtCRvStart | int | 0 |
XfwfNrvLength | XtCRvLength | int | 0 |
XfwfNhlStart | XtCHlStart | int | 0 |
XfwfNhlLength | XtCHlLength | int | 0 |
Usage
The
XfwfLabel
widget provides a lot of resources to define the appearance. Typically the
XfwfLabel
widget has a border of 2 pixels width, drawn with the label's background color. To embed a
XfwfLabel
widget seamlessly into it's surroundings, the
XfwfCommon
's
XfwfNhighlightThickness
resource has to be set to 0.
IntPtr cursor = X11lib.XCreateFontCursor (Xtlib.XtDisplay (_shell),
X11lib.CursorFontShape.XC_question_arrow);
Arg[] lblArgs = { new Arg(XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray ("Label test\0")),
new Arg(XfwfNames.XfwfNtabList,
X11.X11Utils.StringToSByteArray ("20 60\0")),
new Arg(XtNames.XtNwidth, (XtArgVal)120),
new Arg(XtNames.XtNheight, (XtArgVal)50),
new Arg(XfwfNames.XfwfNcursor, (XtArgVal)cursor),
new Arg(XfwfNames.XfwfNhlStart, (XtArgVal)0),
new Arg(XfwfNames.XfwfNhlLength, (XtArgVal)3),
new Arg(XfwfNames.XfwfNrvStart, (XtArgVal)5),
new Arg(XfwfNames.XfwfNrvLength, (XtArgVal)3),
new Arg(XfwfNames.XfwfNframeWidth, (XtArgVal)6),
new Arg(XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfSunken),
new Arg(XfwfNames.XfwfNinnerOffset, (XtArgVal)0),
new Arg(XfwfNames.XfwfNouterOffset, (XtArgVal)(-2)) };
Xtlib.XtCreateManagedWidget("Label",
Xfwflib.Xt_XfwfLabelWidgetClass(), labelBox,
labelT2Args, (XCardinal)13);
The XfwfRowCol widget forces all its children into rows and columns. The children keep their preferred size, but the preferred position is ignored. Resources determine how many rows or columns there should be (or as many as will fit) and if the children should be layed out in rows or in columns. In both methods, the children are placed on a grid, the size of which is determined by the width (height) of the widest (tallest) child. The children can be aligned in several ways: they can be placed in the center of their grid cell or against the edges. This is controlled by a resource alignment. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfRowCol
New Resources
Name | Class | Type | Default |
XfwfNstoreByRow | XtCStoreByRow | Boolean | True |
XfwfNrows | XtCRows | int | 0 |
XfwfNcolumns | XtCColumn | int | 0 |
XfwfNalignment | XtCAlignment | Alignment | XfwfTopLeft |
XfwfNshrinkToFit | XtCShrinkToFit | Boolean | False |
Usage
Arg[] rowcolArgs = { new Arg (XtNames.XtNlabel, X11.X11Utils.StringToSByteArray ("Rowlol\0")),
new Arg (XtNames.XtNwidth, (XtArgVal)250),
new Arg (XtNames.XtNheight, (XtArgVal)250),
new Arg (XfwfNames.XfwfNalignment, (XtArgVal)XfwfAlignment.XfwfBottomRight),
new Arg (XfwfNames.XfwfNstoreByRow, (XtArgVal)1),
new Arg (XfwfNames.XfwfNcolumns, (XtArgVal)4),
new Arg (XfwfNames.XfwfNframeWidth, (XtArgVal)2),
new Arg (XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfRaised),
new Arg (XfwfNames.XfwfNinnerOffset, (XtArgVal)2),
new Arg (XfwfNames.XfwfNouterOffset, (XtArgVal)(-2)) };
IntPtr rowcol = Xtlib.XtCreateManagedWidget(RowcolOrientationName,
Xfwflib.Xt_XfwfRowColWidgetClass(), rowcolBox,
rowcolT1Args, (XCardinal)10);
To toggle the orientation of the children's arrangement, change the resources
XfwfNcolumns
and
XfwfNstoreByRows
.
new Arg(XfwfNames.XfwfNcolumns, (XtArgVal)((_rowcolOrientationIsRow) != true ? 2 : 4))
new Arg (XfwfNames.XfwfNstoreByRow, (XtArgVal)((_rowcolOrientationIsRow) != true ? 0 : 1))
The XfwfRows widget forces all its children into tightly packed rows,
where they can be aligned top or bottom. The children keep their
preferred size, but the preferred position is ignored. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfRows
New Resources
Name | Class | Type | Default |
XfwfNalignTop | XtCAlignTop | Boolean | True |
Usage
Arg[] rowsArgs = { new Arg(XtNames.XtNwidth, (XtArgVal)260),
new Arg(XtNames.XtNheight, (XtArgVal)55),
new Arg(XfwfNames.XfwfNalignTop, (XtArgVal)1) };
IntPtr rows = Xtlib.XtCreateManagedWidget(TestRowsName,
Xfwflib.Xt_XfwfRowsWidgetClass(), rowBox,
rowsArgs, (XCardinal)3);
The XfwfScrollbar widget has four parts: a trough in which a XfwfSlider2
moves up and down (or left and right) and two XfwfArrow widgets.
Clicking and dragging on the different parts causes a callback to be
invoked with different arguments, which presumably causes another widget
to scroll. The scrollbar has the same callback list as the XfwfSlider2 . Clicking an arrow moves the data in that direction. Pressing the mouse button on an arrow and holding it, moves the data by small increments as long as the mouse button is down. Dragging the slider moves the data proportionally with the slider, either along with the movement of the mouse, or all at once when the mouse button is released. Pressing the mouse button on the rectangle outside the slider moves the data in larger increments. | |
The XfwfScrollbar
serves as superclass for XfwfHScrollbar
and XfwfVScrollbar
.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfScrollbar
Code canges
The
Scroll()
method was rewritten and supports keyboard srolling regardles the
XfwfNvertical
resource is True or False now. The
XfwfGetScrollbarSlider()
method has been added to support the
XfwfSlider2
methods like
XfwfMoveThumb()
or
XfwfResizeThumb()
.
New Resources
Name | Class | Type | Default |
XfwfNvertical | XtCVertical | Boolean | True |
XfwfNscrollCallback | XtCScrollCallback | Callback | NULL |
XfwftNscrollResponse | XtCScrollResponse | XtCallbackProc | scroll_response |
XfwfNinitialDelay | XtCInitialDelay | Cardinal | 500 |
XfwfNrepeatDelay | XtCRepeatDelay | Cardinal | 50 |
XfwfNincrement | XtCIncrement | float | 0.05 |
XfwfNscrollbarForeground | XtCScrollbarForeground | Color | copy_background |
XfwfNshadow | XtCShadow | Dimension | 2 |
XfwfNminSize | XtCMinSize | Dimension | 20 |
Usage
Instanciate
XfwfHScrollbar
or
XfwfVScrollbar
instead.
The XfwfScrolledWindow widget is a composite widget composed of two
XfwfScrollbar s and a XfwfBoard within a XfwfFrame , and presumably a
grandgrandchild which is a child of the XfwfBoard . The grandgrandchild
is called the controlled widget (CW). Usually, the controlled widget is
larger than the XfwfBoard , and its origin will have negative x and y
coordinates. | |
The controlled widget is moved about inside the XfwfBoard
by the
XfwfScrolledWindow
, in reaction to the user clicking on the scrollbars. It is therefore clipped by the XfwfBoard
.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfScrolledWindow
New Resources
Name | Class | Type | Default |
XfwfNspacing | XtCSpacing | Dimension | 4 |
XfwfNscrollbarWidth | XtCScrollbarWidth | Dimension | 22 |
XfwfNshadowWidth | XtCShadowWidth | Dimension | 2 |
XfwfNhideHScrollbar | XtCHideHScrollbar | Boolean | False |
XfwfNhideVScrollbar | XtCHideVScrollbar | Boolean | False |
XfwfNhScrollAmount | XtCHScrollAmount | int | 20 |
XfwfNvScrollAmount | XtCVScrollAmount | int | copy_vScrollAmount |
XfwfNinitialX | XtCInitialX | Position | 0 |
XfwfNinitialY | XtCInitialY | Position | 0 |
XfwfNscrollCallback | XtSCcrollCallback | Callback | NULL |
XfwfNscrollResponse | XtCScrollResponse | XtCallbackProc | NULL |
Usage
Arg[] scollWinArgs = { new Arg (XfwfNames.XfwfNlocation,
X11.X11Utils.StringToSByteArray ("0 20 1.0 1.0-20\0")),
new Arg (XtNames.XtNbackground, (XtArgVal)_backgroundPixel) };
IntPtr scrollWin = Xtlib.XtCreateManagedWidget("ScrollWin",
Xfwflib.Xt_XfwfScrolledWindowWidgetClass(), scrollWinBox,
scollWinArgs, (XCardinal)2);
Callback usage
Connect the callback via
XfwfNames.XfwfNscrollCallback
.
public void ScrolledWindowScrollCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
XfwfScrollInfo scrollInfo = (callData != IntPtr.Zero ? (XfwfScrollInfo)
Marshal.PtrToStructure (callData, typeof(XfwfScrollInfo)) :
new XfwfScrollInfo());
if (callData != IntPtr.Zero)
{
if (scrollInfo.flags == (XfwfSFlags.XFWF_HPOS | XfwfSFlags.XFWF_VPOS))
{
; }
}
}
The XfwfScrolledWindow3 widget is a composite widget that contains 4
XfwfBoards and two XfwfScrollbars . The first board is a small area in
the top left corner, where a label widget can be put. One board along
the top and one along the left side are used for column and row titles
(usually XfwfLabel widgets). The two scroll bars are along the right
side and the bottom. In the middle is the largest board, in which the
main data will be displayed. | |
The widget that is added as the child of the large
XfwfBoard
is called the
controlled widget (CW), the widget that is put in the top board is
called the column controlled widget (CCW), the widget that is put in the left board is the row controlled widget (RCW).
Usually, the controlled widgets are larger than the boards, and their origins will have negative x and y coordinates. They are moved about inside the
XfwfBoard
s by the
XfwfScrolledWindow3
, in reaction to the user clicking on the scroll bars. The CCW moves left/right, the RCW moves up/down, the CW moves in all directions. The controlled widgets are therefore clipped by the boards.
The first child widget attached to
XfwfScrolledWindow3
becomes the child of the top left board. The second child widget becomes the CCW, the third the RCW, and the fourth the CW.
The CCW is typically a
XfwfLabel
widget with a tablist to provide column headers, and only scrolls horizontally. The CW is typically a single column
XfwfMultiList
widget with a tablist, and scrolls boths
horizontally and vertically.
The
XfwfScrolledWindow3
provides a callback, but most application will not need it, since it already moves the CW. The callback is invoked after the CW is moved.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfScrolledWindow3
New Resources
Name | Class | Type | Default |
XfwfNspacing | XtCSpacing | Dimension | 4 |
XfwfNscrollbarWidth | XtCScrollbarWidth | Dimension | 22 |
XfwfNcolHdrHeight | XtNcolHdrHeight | Dimension | 22 |
XfwfNrowHdrWidth | XtNrowHdrWidth | Dimension | 22 |
XfwfNshadowWidth | XtCShadowWidth | Dimension | 2 |
XfwfNhideHScrollbar | XtCHideHScrollbar | Boolean | False |
XfwfNhideVScrollbar | XtCHideVScrollbar | Boolean | False |
XfwfNhScrollAmount | XtCHScrollAmount | int | 20 |
XfwfNvScrollAmount | XtCVScrollAmount | int | copy_vScrollAmount |
XfwfNinitialX | XtCInitialX | Position | 0 |
XfwfNinitialY | XtCInitialY | Position | 0 |
XfwfNscrollCallback | XtSCcrollCallback | Callback | NULL |
XfwfNscrollResponse | XtCScrollResponse | XtCallbackProc | NULL |
Usage
Arg[] scollWin3Args = { new Arg (XfwfNames.XfwfNlocation,
new XtString ("0 20 1.0 1.0-20\0")),
new Arg (XtNames.XtNbackground,
(XtArgVal)_backgroundPixel),
new Arg (XfwfNames.XfwfNcolHdrHeight, (XtArgVal)22),
new Arg (XfwfNames.XfwfNrowHdrWidth, (XtArgVal)50) };
IntPtr scrollWin3 = Xtlib.XtCreateManagedWidget("ScrollWin3",
Xfwflib.Xt_XfwfScrolledWindow3WidgetClass(), scrollWin3Box,
scollWin3Args, (XCardinal)4);
Arg[] conerLabelArgs = { new Arg (XtNames.XtNlabel, new XtString ("login")),
new Arg (XtNames.XtNbackground,
(XtArgVal)_backgroundPixel),
new Arg (XfwfNames.XfwfNalignment,
(XtArgVal)XfwfAlignment.XfwfTopLeft),
new Arg (XtNames.XtNx, (XtArgVal)0),
new Arg (XtNames.XtNy, (XtArgVal)0) };
Xtlib.XtCreateManagedWidget("ScrollWin3_Corner",
Xfwflib.Xt_XfwfLabelWidgetClass(), scrollWin3,
conerLabelArgs, (XCardinal)5);
Arg[] colhdrLabelArgs = { new Arg (XtNames.XtNlabel,
new XtString ("uid\tgid\tname\tshell\0")),
new Arg (XtNames.XtNbackground,
(XtArgVal)_backgroundPixel),
new Arg (XfwfNames.XfwfNalignment,
(XtArgVal)XfwfAlignment.XfwfTopLeft),
new Arg (XfwfNames.XfwfNtabList,
new XtString ("50 100 280")) };
Xtlib.XtCreateManagedWidget("ScrollWin3_ColumnHeader",
Xfwflib.Xt_XfwfLabelWidgetClass(), scrollWin3,
colhdrLabelArgs, (XCardinal)4);
XtStringArray rowHrd = new XtStringArray("root|rick|bert|brian|fwf|gene|steve|" +
"gone|erik|joe|herman", '|');
XtStringArray contentTxt= new XtStringArray(" 0\t0\tSystem Administrator\t/bin/sh|" +
"400\t1\tRick Richardson\t/bin/ksh|" +
"367\t4\tBert Bos\t/bin/ksh|" +
"368\t5\tBrian Totty\t/bin/ksh|" +
"369\t6\tFree Widget Foundation\t/bin/ksh|" +
"364\t2\tGene Olson\t/bin/bash|" +
"365\t3\tSteve Wahl\t/bin/ksh|" +
"370\t7\tDeleted User\t/bin/csh|" +
"371\t7\tDeleted User\t/bin/sh|" +
"372\t7\tDeleted User\t/bin/rsh|" +
"373\t7\tHerman Hermans\t/bin/ksh", '|');
XtByteArray rowSens = new XtByteArray("1 1 1 1 1 1 1 0 0 0 1");
Arg[] rowhdrLabelArgs = { new Arg (XfwfNames.XfwfNlist, rowHrd.Data),
new Arg (XfwfNames.XfwfNsensitiveArray, rowSens.Data),
new Arg (XfwfNames.XfwfNnumberStrings, (XtArgVal)0),
new Arg (XfwfNames.XfwfNdefaultColumns, (XtArgVal)1),
new Arg (XtNames.XtNborderWidth, (XtArgVal)0),
new Arg (XtNames.XtNx, (XtArgVal)0),
new Arg (XtNames.XtNy, (XtArgVal)0) };
Xtlib.XtCreateManagedWidget("ScrollWin3_RowHeader",
Xfwflib.Xt_XfwfMultiListWidgetClass(), scrollWin3,
rowhdrLabelArgs, (XCardinal)7);
Arg[] contentLabelArgs = { new Arg (XfwfNames.XfwfNlist, contentTxt.Data),
new Arg (XfwfNames.XfwfNsensitiveArray, rowSens.Data),
new Arg (XfwfNames.XfwfNnumberStrings, (XtArgVal)0),
new Arg (XfwfNames.XfwfNtabList,
new XtString ("50 100 280")),
new Arg (XfwfNames.XfwfNdefaultColumns, (XtArgVal)1),
new Arg (XtNames.XtNborderWidth, (XtArgVal)0),
new Arg (XtNames.XtNx, (XtArgVal)1),
new Arg (XtNames.XtNy, (XtArgVal)1) };
Xtlib.XtCreateManagedWidget("ScrollWin3_Content",
Xfwflib.Xt_XfwfMultiListWidgetClass(), scrollWin3,
contentLabelArgs, (XCardinal)8);
rowSens.Dispose();
contentTxt.Dispose();
rowHrd.Dispose();
Callback usage
Connect the callback via
XfwfNames.XfwfNscrollCallback
.
The XfwfTabs widget displays a series of tabs, similar to the alphabet
tabs along the top of index cards. One tab, the front one, is completely
visible, the others are partially hidden behind it. Each of the tabs
can be clicked on with the mouse. This implementation does not take part
in keyboard traversal, and it has no 3D frame.
| |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfTabs
New Resources
Name | Class | Type | Default |
XtNforeground | XtCForeground | Pixel | XtDefaultForeground |
XtNorientation | XtCOrientationTabs | Orientation | XfwfUpTabs |
XfwfNlefttabs | XtCLefttabs | int | 0 |
XfwfNrighttabs | XtCRighttabs | int | 0 |
XfwfNlabels | XtCLabels | StringArray | NULL |
XfwfNcornerHeight | XtCCornerHeight | int | 3 |
XfwfNcornerWidth | XtCCornerWidth | int | 3 |
XfwfNtextMargin | XtCTextmargin | int | 3 |
XfwfNtabColor | XtCTabcolor | Pixel | copy_bg |
XtNfont | XtCFont | FontStruct | XtDefaultFont |
XfwfNactivate | XtCActivate | Callback | NULL |
Usage
string[] tabs = { "Introduction", "Top" };
Arg[] tabArgs = { new Arg (XtNames.XtNborderColor, (XtArgVal)_darkborderPixel),
new Arg (XfwfNames.XfwfNlocation,
X11.X11Utils.StringToSByteArray ("35 25 1.0-70 30\0")),
new Arg (XfwfNames.XfwfNorientation,
(XtArgVal)XfwfTabsOrientation.XfwfUpTabs),
new Arg (XfwfNames.XfwfNlabels, tabs),
new Arg (XfwfNames.XfwfNtextMargin, (XtArgVal)4),
new Arg (XfwfNames.XfwfNtabColor, (XtArgVal)_lightborderPixel),
new Arg (XtNames.XtNforeground, (XtArgVal)_darkborderPixel),
new Arg (XfwfNames.XfwfNframeWidth, (XtArgVal)1),
new Arg (XfwfNames.XfwfNlefttabs, (XtArgVal)0),
new Arg (XfwfNames.XfwfNrighttabs, (XtArgVal)1) };
IntPtr tab = Xtlib.XtCreateManagedWidget(Tab1Name,
Xfwflib.Xt_XfwfTabsWidgetClass(), tabBox,
tab1Args, (XCardinal)10);
Callback usage
Connect the callback via
XfwfNames.XfwfNactivate
.
public void TabActivateCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
string sWidgetName = Xtlib.XtNameAsString (widget);
int relativeTabIndex = (int)callData;
Console.WriteLine ("Tab index of {0} is {1}", sWidgetName, relativeTabIndex);
if (relativeTabIndex < 0)
{
Arg[] tabArgs = { new Arg (XfwfNames.XfwfNlefttabs, (XtArgVal)0),
new Arg (XfwfNames.XfwfNrighttabs, (XtArgVal)1) };
Xtlib.XtSetValues (widget, tabArgs, (XCardinal)2);
}
else if (relativeTabIndex > 0)
{
Arg[] tabArgs = { new Arg (XfwfNames.XfwfNlefttabs, (XtArgVal)1),
new Arg (XfwfNames.XfwfNrighttabs, (XtArgVal)0) };
Xtlib.XtSetValues (widget, tabArgs, (XCardinal)2);
}
}
The XfwfButton widget is simply an XfwfLabel with a callback for mouse clicks. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel --> XfwfButton
New Resources
Name | Class | Type | Default |
XfwfNactivate | XtCActivate | Callback | NULL |
XfwfNenter | XtCEnter | Callback | NULL |
XfwfNleave | XtCLeave | Callback | NULL |
Callback usage
Connect callbacks via
XfwfNames.XfwfNactivate
,
XfwfNames.XfwfNenter
or
XfwfNames.XfwfNleave
.
public void ButtonPressCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
string sWidgetName = Xtlib.XtNameAsString (widget);
Console.WriteLine ("Button pressed {0}", sWidgetName);
}
The XfwfSlider2 widget displays a thumb (with two degrees of freedom: horizontal and vertical position), that can be moved with the mouse.
Applications can use this to move or scroll other objects via callbacks.
| |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel --> XfwfSlider2
New Resources
Name | Class | Type | Default |
XfwfNthumbColor | XtCThumbColor | Color | XtDefaultBackground |
XfwfNthumbPixmap | XtCThumbPixmap | Pixmap | NULL |
XfwfNminSize | XtCMinsize | Dimension | 20 |
XfwfNthumbFrameWidth | XtCThumbFrameWidth | Dimension | 2 |
XfwfNthumbFrameType | XtCThumbFrameType | FrameType | XfwfRaised |
XfwfNscrollCallback | XtCScrollCallback | Callback | NULL |
XfwfNscrollResponse | XtCScrollResponse | XtCallbackProc | scroll_response |
Usage
Resize the thumb using
XfwfResizeThumb()
and connect the thumb with a widget to be moved using
XfwfConnectScrollingWidgets()
.
Callback usage
Connect the callback via
XfwfNames.XfwfNscrollCallback
.
public void Slider2ThumbCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
if (callData != IntPtr.Zero)
{
XfwfScrollInfo scrollInfo = (XfwfScrollInfo)
Marshal.PtrToStructure (callData, typeof(XfwfScrollInfo));
{
float x = 0.0F;
float y = 0.0F;
if (((int)(scrollInfo.flags) & (int)(XfwfSFlags.XFWF_HPOS)) != 0)
x = scrollInfo.hpos;
if (((int)(scrollInfo.flags) & (int)(XfwfSFlags.XFWF_VPOS)) != 0)
y = scrollInfo.vpos;
string position = string.Format ("x = {0}\ny = {1}\0", x, y);
Arg[] newText = { new Arg (XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray (position)) };
Xtlib.XtSetValues(_slider2LocationLabel, newText, (XCardinal)1);
}
}
}
The XfwfSpinLabel widget provides nearly the same features as its superclass XfwfLabel but additionally it is possible to manipulate the labels using two arrow buttons. With these the user is able to increase/decrease a numerical value or scroll trough a list of strings. | |
Every time one of the arrows is pressed, the XfwfNactivate
callback is invoked. The XfwfSpinLabel
widget provides a keyboard interface too. Using a callback the programmer is free to decide trough what he let the user scroll.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel --> XfwfSpinLabel
New Resources
Name | Class | Type | Default |
XfwfNarrowForeground | XtCArrowForeground | Color | copy_background |
XtNcallback | XtCCallback | Callback | NULL |
XfwfNlabelFrameWidth | XtCLabelframeWidth | Dimension | 0 |
XfwfNlabelFrameType | XtCLabelframeType | XfwfFrameType | XfwfSunken |
XfwfNhorizontal | XtCHorizontal | Boolean | True |
Usage
private string[] _spin1Texts = { "0\0",
"1\0",
"2\0",
"3\0",
"4\0",
"5\0",
"6\0",
"7\0"};
...
Arg[] spinArgs = { new Arg (XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray (_spinTexts[(int)_spinIndex])),
new Arg (XtNames.XtNwidth, (XtArgVal)25),
new Arg (XtNames.XtNheight, (XtArgVal)75),
new Arg (XfwfNames.XfwfNhorizontal, (XtArgVal)0),
new Arg (XfwfNames.XfwfNarrowForeground,(XtArgVal)_lightborderPixel) };
IntPtr spin = Xtlib.XtCreateManagedWidget("SpinTest",
Xfwflib.Xt_XfwfSpinLabelWidgetClass(), spinBox,
spinArgs, (XCardinal)5);
Callback usage
Connect the callback via
XtNames.XtNcallback
.
public void SpinLabelCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
IntPtr spinWidget = IntPtr.Zero;
if (Xtlib.XtIsSubclass (widget, Xfwflib.Xt_XfwfArrowWidgetClass()) != 0)
spinWidget = Xtlib.XtParent (widget);
else if (Xtlib.XtIsSubclass (widget, Xfwflib.Xt_XfwfSpinLabelWidgetClass()) != 0)
spinWidget = widget;
else
return;
string sWidgetName = Xtlib.XtNameAsString (spinWidget);
XfwfSpinType diff = (XfwfSpinType) callData;
if (diff == XfwfSpinType.XfwfFirst)
{
if (sWidgetName.EndsWith("1"))
{
_spinIndex = (TInt)0;
Arg[] spinArgs = { new Arg(XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray (_spinTexts[(int)_spinIndex])) };
Xtlib.XtSetValues (spinWidget, spinArgs, (XCardinal)1);
}
else if (sWidgetName.EndsWith("2"))
{
...
}
}
else if (diff == XfwfSpinType.XfwfLast)
{
if (sWidgetName.EndsWith("1"))
{
_spinIndex = (TInt)_spinTexts.Length - 1;
Arg[] spinArgs = { new Arg(XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray (_spinTexts[(int)_spinIndex])) };
Xtlib.XtSetValues (spinWidget, spinArgs, (XCardinal)1);
}
else if (sWidgetName.EndsWith("2"))
{
...
}
}
else if (diff == XfwfSpinType.XfwfNext)
{
if (sWidgetName.EndsWith("1"))
{
_spinIndex = (TInt)(_spinIndex + 1);
_spinIndex = ((int)_spinIndex <= _spinTexts.Length - 1 ?
_spinIndex : (TInt)(_spinTexts.Length - 1));
Arg[] spinArgs = { new Arg(XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray (_spinTexts[(int)_spinIndex])) };
Xtlib.XtSetValues (spinWidget, spinArgs, (XCardinal)1);
}
else if (sWidgetName.EndsWith("2"))
{
...
}
}
else if (diff == XfwfSpinType.XfwfPrev)
{
if (sWidgetName.EndsWith("1"))
{
_spinIndex = (TInt)(_spinIndex - 1);
_spinIndex = ((int)_spinIndex >= 0 ? _spinIndex : (TInt)0);
Arg[] spinArgs = { new Arg(XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray (_spinTexts[(int)_spinIndex])) };
Xtlib.XtSetValues (spinWidget, spinArgs, (XCardinal)1);
}
else if (sWidgetName.EndsWith("2"))
{
...
}
}
}
The XfwfGroup widget adds two things to the capabilities already present in XfwfRowCol , a label
in the upper left hand corner and the ability to make a number of
XfwfToggle buttons act as radio buttons. | |
The label is a short, one line
piece of text, that is displayed over the border in the top left corner.
The border is interupted at that point. Since this works best with
XfwfLedged
or
XfwfChiseled
border types, the default border is
XfwfChiseled
.
The special support for radio buttons works as follows: When a child is added, the
XfwfGroup
widget checks if it is of class
XfwfToggle
or a subclass thereof. If so, the
XfwfGroup
widget installs a callback in it. When the
XfwfToggle
button is then activated, the
XfwfGroup
widget determines which other buttons need to be turned off. All
XfwfToggle
buttons are given an implicit number. The first one is number 0.
The selectionStyle resource supports the modes
XfwfSingleSelection
(none or one of the toggles is on),
XfwfOneSelection
(all times exactly one toggle is on) and
XfwfMultipleSelection
(any number of toggles is on).
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfRowCol --> XfwfGroup
New Resources
Name | Class | Type | Default |
XtNlabel | XtCLabel | String | NULL |
XtNfont | XtCFont | FontStruct | XtDefaultFont |
XtNforeground | XtCForeground | Color | XtDefaultForeground |
XfwfNselectionStyle | XtCSelectionStyle | SelectionType | XfwfSingleSelection |
XfwfNselection | XtCSelection | long | 0 |
XfwfNactivate | XtCActivate | Callback | NULL |
Usage
Create a
XfwfGroup
widget and add children of class
XfwfToggle
or any subclass.
Arg[] groupArgs = { new Arg(XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray ("XfwfGroup with toggles:\0")),
new Arg(XfwfNames.XfwfNlocation,
X11.X11Utils.StringToSByteArray ("5 5 140 50\0")),
new Arg(XfwfNames.XfwfNcolumns, (XtArgVal)2),
new Arg(XfwfNames.XfwfNshrinkToFit, (XtArgVal)1),
new Arg(XfwfNames.XfwfNframeWidth, (XtArgVal)2),
new Arg(XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfRaised),
new Arg(XfwfNames.XfwfNinnerOffset, (XtArgVal)2),
new Arg(XfwfNames.XfwfNouterOffset, (XtArgVal)5) };
IntPtr group = Xtlib.XtCreateManagedWidget(SimpleGroupName,
Xfwflib.Xt_XfwfGroupWidgetClass(), radiogrpBox,
groupArgs, (XCardinal)8);
Callback usage
The
XfwfGroup
widget doesn't need a callback to be registered. Optionally the toggles can be connect to a callback via
XfwfNames.XfwfNonCallback
for immediate feedback.
The
XfwfNselection
resource holds at any time the state of the toggle buttons (if any). If
XfwfNselectionType
=
XfwfSingleSelection
or
XfwfOneSelection
, it holds the index of the button that is currently on, or -1 if they are all off. If
XfwfNselectionType
=
XfwfMultipleSelection
, it is a bitmap with one bit set for each button that is on.
The XfwfMenuBar widget displays buttons in a horizontal row. It assumes the buttons control drop-down menus and it makes it possible to drag the mouse from one menu to another. | |
The MenuBar attaches itself to the XtNpopdownCallback
callback of the menu shell that is popped up by the children, and inserts itself in the list of pointer grabs that Xt maintains. This is necessary to be able to drag the mouse from one menu into another, popping down the first one and popping up the second. If you use a XfwfRowCol
widget instead of a XfwfMenuBar
, you will find that switching from one menu to the next involves releasing the mouse and then pressing it again.
To find the menu shell, the children are asked for their XtNpopup
resource. XfwfPullDown
buttons have this resource, others may not.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfRows --> XfwfMenuBar
New Resources
None.
Usage
Just create
XfwfPullDown
widget(s) als child(ren).
The
XfwfHScrollbar
widget is almost the same as the
XfwfScrollbar
widget, except that it has default translations for scroll up/down, page up/down and home/end and the default value of the
XfwfNvertical
resource is False.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfScrollbar --> XfwfHScrollbar
New Resources
None.
Code canges
Correction of the default translation parameters (capitalization). Additional default translations, now these keyboard bindings are supported:
- < Key>Left to scroll one step left
- < Key>Right to scroll one step right
- Ctrl<Key>Left and <Key>Prior to scroll one page left
- Ctrl<Key>Right and <Key>Next to scroll one page right
- < Key>Home, Shift<Key>End and Ctrl<Key>Prior to scroll to the start (left side)
- Shift<Key>Home, <Key>End and Ctrl<Key>Next to scroll to the end (right side)
Usage
Arg[] scrollArgs = { new Arg (XtNames.XtNborderColor, (XtArgVal)_darkborderPixel),
new Arg (XtNames.XtNwidth, (XtArgVal)98),
new Arg (XtNames.XtNheight, (XtArgVal)20),
new Arg (XfwfNames.XfwfNscrollbarForeground,(XtArgVal)_darkgreenPixel),
new Arg (XfwfNames.XfwfNincrement, 0.02F),
new Arg (XfwfNames.XfwfNvertical, (XtArgVal)0) };
IntPtr scrollBar = Xtlib.XtCreateManagedWidget("Scroll",
Xfwflib.Xt_XfwfHScrollbarWidgetClass(), scrollBox,
scrollArgs, (XCardinal)6);
Xfwflib.XfwfSetScrollbar (scrollBar3, 0.4, 0.2);
Callback usage
Connect the callback via
XfwfNames.XfwfNscrollCallback
.
public void ScrollbarScrollCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
XfwfScrollInfo scrollInfo = (callData != IntPtr.Zero ? (XfwfScrollInfo)
Marshal.PtrToStructure (callData, typeof(XfwfScrollInfo)) :
new XfwfScrollInfo());
TInt val = Xtlib.XtGetValueOfInt (widget, XtNames.XtNvalue);
if (callData != IntPtr.Zero)
{
if (scrollInfo.flags == XfwfSFlags.XFWF_VPOS)
{
IntPtr slider = Xfwflib.XfwfGetScrollbarSlider (widget);
Xfwflib.XfwfMoveThumb (slider, scrollInfo.hpos, scrollInfo.vpos);
val = (TInt)(1000.0 * scrollInfo.vpos);
}
else if (scrollInfo.flags == XfwfSFlags.XFWF_HPOS)
{
IntPtr slider = Xfwflib.XfwfGetScrollbarSlider (widget);
Xfwflib.XfwfMoveThumb (slider, scrollInfo.hpos, scrollInfo.vpos);
val = (TInt)(1000.0 *scrollInfo.hpos);
}
}
Console.WriteLine ("Scrollbar position {0}", val);
}
The
XfwfVScrollbar
widget is almost the same as the
XfwfScrollbar
widget, except that it has default translations for scroll left/right, page left/right and home/end and the default value of the
XfwfNvertical
resource is True.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfScrollbar --> XfwfVScrollbar
New Resources
None.
Code canges
Correction of the default translation parameters (capitalization). Additional default translations, now these keyboard bindings are supported:
- < Key>Up to scroll one step up
- < Key>Down to scroll one step down
- Ctrl<Key>Up and <Key>Prior to scroll one page up
- Ctrl<Key>Down and <Key>Next to scroll one page down
- < Key>Home, Shift<Key>End and Ctrl<Key>Prior to scroll to the start (top)
- Shift<Key>Home, <Key>End and Ctrl<Key>Next to scroll to the end (bottom)
Usage
See
XfwfHScrollbar
.
Callback usage
See
XfwfHScrollbar
.
The XfwfPullDown widget is a button with a pull-down menu.
The menu can be specified in two ways: as a string or as a widget. | |
If a
string is given, it must be in the correct syntax for the XfwfTextMenu
widget and a widget will be created automatically. If a widget is given
instead, it must be a widget that is able to pop up: in other words: a
Shell widget or a subclass of Shell. There is also support for a hotkey,
but it doesn't work yet.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel -->
XfwfButton --> XfwfPullDown
New Resources
Name | Class | Type | Default |
XfwfNpopup | XtCPopup | Widget | NULL |
XfwfNmenu | XtCMenu | String | NULL |
XfwfNcascaded | XtCCascaded | Boolean | False |
XfwfNhotkey | XtCHotkey | String | NULL |
XfwfNmenuCursor | XtCMenuCursor | Cursor | arrow |
XfwfNprepare | XtCPrepare | Callback | NULL |
XfwfNchangeSelection | XtCChangeSelection | Callback | NULL |
Usage
Arg[] pdArgs = { new Arg (XtNames.XtNlabel, X11.X11Utils.StringToSByteArray ("Menu 2\0")),
new Arg (XfwfNames.XfwfNhotkey, X11.X11Utils.StringToSByteArray ("Alt<Key>2\0")),
new Arg (XfwfNames.XfwfNmenu, X11.X11Utils.StringToSByteArray ("_first item" +
"\ns_econd item\nth_ird item\nfou_rth item\0")) };
IntPtr pulld = Xtlib.XtCreateManagedWidget("PullDown2",
Xfwflib.Xt_XfwfPullDownWidgetClass(), menuRowCol,
pdArgs, (XCardinal)3);
Callback usage
Connect callbacks via
XfwfNames.XfwfNactivate
,
XfwfNames.XfwfNprepare
or
XfwfNames.XfwfNchangeSelection
.
public void PullDownSelectCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
string sWidgetName = Xtlib.XtNameAsString (widget);
XfwfTextMenuData textMenuData = (callData != IntPtr.Zero ? (XfwfTextMenuData)
Marshal.PtrToStructure (callData, typeof(XfwfTextMenuData)) :
new XfwfTextMenuData());
if (callData != IntPtr.Zero && textMenuData.n >= 0)
{
string sMenuEntry = Marshal.PtrToStringAuto (textMenuData.label);
Console.WriteLine ("Pulldown {0} selected {1}", sWidgetName, sMenuEntry);
}
else
{
Console.WriteLine ("Pulldown {0} selected", sWidgetName);
}
}
The XfwfToggle widget switches states with every activation (which is by
default with every mouse click). The states are named on and off. The
states can be indicated with an icon before label. | |
Two callbacks report
the changed state to the application: XfwfNonCallback
is called when the
button switches to on, XfwfNoffCallback
is called when the button switches
back to off.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel -->
XfwfButton --> XfwfToggle
New Resources
Name | Class | Type | Default |
XfwfNonCallback | XtCOnCallback | Callback | NULL |
XfwfNoffCallback | XtCOffCallback | Callback | NULL |
XfwfNon | XtCOn | Boolean | False |
XfwfNonIcon | XtCOnIcon | Icon | filledsquare |
XfwfNoffIcon | XtCOffIcon | Icon | emptysquare |
Usage
Arg[] toggleArgs = { new Arg(XtNames.XtNlabel, X11.X11Utils.StringToSByteArray ("Toggle\0")),
new Arg(XtNames.XtNwidth, (XtArgVal)90),
new Arg(XtNames.XtNheight, (XtArgVal)50),
new Arg(XtNames.XtNforeground, (XtArgVal)_lightborderPixel),
new Arg(XfwfNames.XfwfNframeWidth, (XtArgVal)2),
new Arg(XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfRaised),
new Arg(XfwfNames.XfwfNinnerOffset, (XtArgVal)2),
new Arg(XfwfNames.XfwfNouterOffset, (XtArgVal)(-2)) };
IntPtr toggleBtn = Xtlib.XtCreateManagedWidget(Toggle1Name,
Xfwflib.Xt_XfwfToggleWidgetClass(), toggleBox,
toggleArgs, (XCardinal)8);
Callback usage
Connect callbacks via XfwfNames.XfwfNonCallback
and XfwfNames.XfwfNoffCallback
.
public void TogglePressCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
Arg[] toggleArgs = { new Arg (XtNames.XtNforeground, (XtArgVal)
(((int)clientData) == 0 ? _lightborderPixel : _blackPixel)),
new Arg (XfwfNames.XfwfNon, (XtArgVal)clientData),
new Arg (XfwfNames.XfwfNframeType, (XtArgVal)
(((int)clientData) == 0 ? XfwfFrameType.XfwfRaised : XfwfFrameType.XfwfChiseled)),
new Arg (XfwfNames.XfwfNframeWidth, (XtArgVal)
2 + (((int)clientData) == 0 ? 0 : 2)) };
Xtlib.XtSetValues (widget, toggleArgs, (XCardinal)4);
string sWidgetName = Xtlib.XtNameAsString (widget);
Console.WriteLine ("Toggle switched {0}", sWidgetName);
}
The XfwfSlider4 widget is almost the same as the XfwfSlider2 widget (with four derees of freedom: horizontal and vertical position as well as width and height), except for the addition of a sash in the lower right corner of the thumb, with which the thumb can be resized. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel -->
XfwfSlider2 --> XfwfSlider4
New Resources
Name | Class | Type | Default |
XfwfNsashColor | XtCSashColor | Color | XtDefaultBackground |
XfwfNsashPixmap | XtCSashPixmap | Pixmap | NULL |
XfwfNsashFrameType | XtCSashFrameType | FrameType | XfwfRaised |
XfwfNsashFrameWidth | XtCSashFrameWidth | Dimension | 2 |
Callback usage
See
XfwfSlider2
.
The XfwfRadioGroup widget is a more convenient simple specialization of
the XfwfGroup widget for the case that the group contains only XfwfToggle
buttons. It has an extra resource, labels, which holds the labels of the XfwfToggle buttons that are created automatically. It is also much less
flexible and it is very difficult to change resources (defaults are XfwfNshrinkToFit = True, XtNborderWidth = 0, XfwfNframeWidth = 0) of the radio
buttons, when the defaults are not satisfactory. | |
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfRowCol -->
XfwfGroup --> XfwfRadioGroup
New Resources
Name | Class | Type | Default |
XfwfNlabels | XtCLabels | StringArray | NULL |
Usage
The
XfwfRadioGroup
widget creates it's children automatically.
String[] items = { "plum", "cranberry", "cherry", "banana", string.Empty };
Arg[] radioArgs = { new Arg(XtNames.XtNlabel,
X11.X11Utils.StringToSByteArray ("XfwfRadioGroup:\0")),
new Arg(XfwfNames.XfwfNlocation,
X11.X11Utils.StringToSByteArray ("5 5 260 75\0")),
new Arg(XfwfNames.XfwfNcolumns, (XtArgVal)2),
new Arg(XfwfNames.XfwfNlabels, items),
new Arg(XfwfNames.XfwfNselection, (XtArgVal)1),
new Arg(XfwfNames.XfwfNselectionStyle,
(XtArgVal)XfwfSelectionType.XfwfSingleSelection),
new Arg(XfwfNames.XfwfNshrinkToFit, (XtArgVal)0),
new Arg(XfwfNames.XfwfNframeWidth, (XtArgVal)2),
new Arg(XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfRaised),
new Arg(XfwfNames.XfwfNinnerOffset, (XtArgVal)8),
new Arg(XfwfNames.XfwfNouterOffset, (XtArgVal)5) };
IntPtr radiogrp = Xtlib.XtCreateManagedWidget(RadioGroup1Name,
Xfwflib.Xt_XfwfRadioGroupWidgetClass(), radiogrpBox,
radioArgs, (XCardinal)11);
Callback usage
See
XfwfGroup
widget.
The XfwfOptionButton widget is a button with a drop-down menu that displays options from which only one can be chosen. The most recently chosen option remains visible after the menu is closed. | |
It is very much like a XfwfPullDown
button, except that the label of the button is automatically set to the label of the last selected menu item.
Inheritance (↑)
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel -->
XfwfButton -->
XfwfPullDown --> XfwfOptionButton
New Resources
None.
Callback usage
Connect the callback via
XfwfNames.XfwfNactivate
.
public void OptionButtonPressCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
string sWidgetName = Xtlib.XtNameAsString (widget);
XfwfTextMenuData textMenuData = (callData != IntPtr.Zero ? (XfwfTextMenuData)
Marshal.PtrToStructure (callData, typeof(XfwfTextMenuData)) :
new XfwfTextMenuData());
if (callData != IntPtr.Zero && textMenuData.n >= 0)
{
Console.WriteLine ("OptionButton {0} changed to {1}.", sWidgetName, textMenuData.n);
}
else
{
Console.WriteLine ("OptionButton {0} changed.", sWidgetName);
}
}
Points of Interest
Beside the challenges to set the right dependencies (to compile the Xfwf/Free Widget Foundation widgets), correct the compilation errors and optimize the impression is to mention:
Widget initialization and resource names
The C#
Arg
struct is available since the
second article of this series . This project added some options, providing the struct member
intValue
and
floatValue
alternatively. Furthermore the new helper classes
XtString
,
XtStringArray
,
XtByteArray
and
XtIntegerArray
simplify the
Arg
creation.
To avoid confusion, all Xfwf/Free Widget Foundation widget resource names are prefixed
XfwfN
, e. g.
XfwfNames.XfwfNactivate
.
It was inpossible to get the
XfwfAlert
widget from
scr/Alert/Alert.c running. Instead the
scr/Alert/AlertModal.c implements the alternative
XfwfAlertModal
widget and shows how easy it is to program
Xfwf/Free Widget Foundation widgets in plain C too.
The
XfwfAlertModal
widget contains the
CreateIconFromData()
method, that dynamically creates an icon. This method can be a prototype for a dynamic icon creation and can be useful for
XfwfIcon
and
XfwfAnimator
too.
History
-
28. October 2013, This is the fourth article about native calls from C# and
Mono Develop to X11 API. It deals with the Xfwf/Free Widget Foundation widgets. The focus is on the Xt/Athena compatible Xfwf/Free Widget Foundation widgets. The first article of this series was about the Xlib only. The second article was about the Xt only. The third atricle was about the Xm/Motif only. Further articles
are planned, that dive deeper into Xlib, Xt/Athena or Xm/Motif.