引言
本文介绍如何使用 Mono Develop 从 C# 访问大多数 Xfwf/Free Widget Foundation 部件。许多 API 调用已经定义并测试完毕,可供直接使用,并且一些挑战也已攻克,例如设置正确的依赖项(以编译 Xfwf/Free Widget Foundation 部件)、修正编译错误以及优化显示效果。本文旨在指出,使用 C# 编程 Xfwf/Free Widget Foundation 部件可以轻松实现,并能极大地改善用户体验(附有示例)。本文提供了一个示例应用程序的 32 位和 64 位完整项目。
背景
这是一系列探讨如何使用 Mono Develop 从 C# 调用 X* API 的第四篇文章。第一篇文章是《使用 Mono Develop 进行 Xlib 编程 - 第 1 部分:底层(概念验证)》,内容涉及 Xlib/X11。第二篇文章是《使用 Mono Develop 进行 Xlib 编程 - 第 2 部分:Athena 部件(概念验证)》,内容涉及 Xt/Athena。第三篇文章是《使用 Mono Develop 进行 Xlib 编程 - 第 3 部分:Motif 部件(概念验证)》,内容涉及 Xm/Motif。当前这篇文章进一步探讨 Xfwf/Free Widget Foundation 部件,并展示了如何从 C#/Mono 这样的现代语言/IDE 中使用它们。重点是与 Xt/Athena 兼容的 Xfwf/Free Widget Foundation 部件。
本文阐述了使用 C# 调用 Xfwf API 编程 Xfwf/Free Widget Foundation 是多么容易实现。大多数部件是基于 Xt/Athena 的,但也有一些是基于 Xm/Motif 的。自从 Open Motif 在公共许可证下开放了 Motif 的源代码,几乎所有的 XWindow 系统都可以免费使用 Motif 部件。因此,所有 Xfwf/Free Widget Foundation 部件都可用,应用程序可以任意混合使用 Xt/Athena、Xm/Motif 和 Xfwf/Free Widget Foundation 的部件。
使用代码
Xfwf/Free Widget Foundation 部件的最新已知版本是“FWF Version 4.0, 18 Apr 1996”,可以在许多服务器上以
fwf-4.0.tar.gz 的形式下载。该项目自 1996 年以来一直没有维护,但这些部件仍然非常有用,并且与任何 Xt/Athena 或 Xm/Motif 部件都无可比拟。Free Widget Foundation 和主要程序员 Brian K Totty(他在伊利诺伊大学厄巴纳-香槟分校计算机科学系期间编写了许多 Free Widget Foundation 部件,并维护该发行版至 3.671 版本)都没有主页。Bert Bos(他在格罗宁根大学期间也编写了许多 Free Widget Foundation 部件,并从 3.7 版本开始维护该发行版)有一个主页,其中简要提到了 Xfwf/Free Widget Foundation 部件。
使用这些部件的常规方法是按照 README.BUILD 文件中的描述编译源代码树,并在项目中引用该库。但这个过程行不通。由于 Xfwf/Free Widget Foundation 部件自 1996 年后未曾维护,一些声明和引用已经过时,必须进行修正。此外,不仅 FileComp/getod.c、EzMenu/EzME.c、CMap/Cmap.c、HDial/Hdial.c、Shistogram/Shistogram.c 和 IconBox/IconBoxT.c 存在编译错误需要修复,而且子目录 HTML2 和 SSGML 根本无法编译。
因此,本文采用了一种不同的方法,将部件逐个整合到示例应用程序解决方案中一个名为 FWF 的 Mono C 项目(目标是 libXfwf.so),并单独修改部件源代码以使其能够编译。
该示例应用程序是使用 Mono Develop 2.4.1 for Mono 2.8.1 在 OPEN SUSE 11.3 Linux 32 bit EN 和 GNOME 桌面上编写的。移植到任何更旧或更新的版本应该都不是问题。但是,必须安装
X11、
Xt 和
Xpm 软件包。示例应用程序的解决方案包含五个项目(完整源代码提供下载):
- FWF 包含了 Xfwf/Free Widget Foundation 部件的大部分原始源代码树(只要已整合到示例应用程序中),并编译成 libXfwf.so
- X11Wrapper 为调用 libX11.so 的 Xlib/X11 定义了函数原型、结构体和类型(已在本系列的第一篇文章中介绍过)
- XawNative 包含少量本地 C 代码,用于访问 Athena 部件类记录并将托管数据转换为本地结构,编译为 libXawNative.so(已在本系列的第二篇文章中介绍过)
- XtWrapper 定义了调用 libXt.so 的 Xt 函数原型、结构体和类型(已在本系列的第二篇文章中介绍过)
- Xfwf 包含了基于 Xt/Athena 和 Xfwf/Free Widget Foundation 部件的示例应用程序
位解决方案是定义一些类型,正如本系列第一篇文章中所述。
应用程序对下面 FWF 部件层级结构 中描述的每个 Xfwf/Free Widget Foundation 部件都有测试代码。


GNOME 桌面 2.30.0(32 位)上的观感。
32 位 vs. 64 位
该示例应用程序也已在 OPEN SUSE 12.3 Linux 64 bit DE 和 GNOME 桌面、IceWM、TWM 及 Xfce 环境下,使用 Mono Develop 3.0.6 for Mono 3.0.4 进行了测试。32 位和 64 位解决方案之间唯一的区别是一些类型的定义,正如本系列第一篇文章中的“使用代码”/“32 位 vs. 64 位”一章所述。
核心
⌊ 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
Xfwf/Free Widget Foundation 部件集是“一套免费、可自由再分发的 X 图形用户界面部件”。接下来的章节包含了描述,这些描述或多或少基于 Xfwf/Free Widget Foundation 发行版中包含的相应部件的手册页,并附有截图、示例代码和提示。
XfwfCircPerc 部件可用于指示应用程序取得的进展,例如在冗长的计算中。它通过显示一个圆形来实现,其中一个彩色的扇形表示已完成的工作量,圆形的其余部分用另一种颜色填充,表示尚未完成的工作量。完成的百分比可以精确到两位小数。 |  |
Core --> XfwfCircPerc
新资源
名称 | 类 | 类型 | 默认值 |
XXtNborderColor | XtCBorderColor | Pixel | black |
XfwfNcompletedColor | XtCCompletedColor | Pixel | yellow |
XfwfNinteriorColor | XtCInteriorColor | Pixel | red |
XfwfNpercentageCompleted | XtCPercentageCompleted | int | 0 |
用法
IntPtr circPerc = Xtlib.XtCreateManagedWidget("CircularPercentage",
Xfwflib.Xt_XfwfCircularPercentageWidgetClass(), circpercBox,
Arg.Zero, (XCardinal)0);
...
// Add 10 percent (that is to shift by 2 digits).
_circularPercValue += 1000;
Xfwflib.XfwfCircularPercentageSetPercentage (circPerc, _circularPercValue);
XfwfPcBarc 部件用于显示一个水平(或垂直)的矩形框,其中一个从 0% 到 100% 的百分比由一个横跨(或向上延伸)框体的条形来表示。实际的百分比值可以可选地以文本形式显示在框体中央。 |  |
Core --> XfwfPcBar
新资源
名称 | 类 | 类型 | 默认值 |
XtNforeground | XtCForegroundPixel | Pixel | XtDefaultForeground |
XfwfNpercentage | XtCPercentage | int | 0 |
XfwfNdisplaypc | XtCDisplaypc | Boolean | 假 |
XfwfNvertical | XtNvertical | Boolean | False |
XtNfont | XtNfont | FontStruct | XtDefaultFont |
用法
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);
XfwfThumbWheel 部件是一个非常基础的垂直放置的数值调节器实现,可以向上或向下转动。它可以用作滚动条或数值调节器。转动效果是通过连续显示一系列预备好的图像来实现的。 |  |
如果 Xpm 可用,图像是平滑的灰度图。否则,备用图像是像素化的。
Core --> XfwfThumbWheel
代码变更
新增默认转换,现在支持以下键盘绑定:
- <Btn1Down> 使用 step 资源值作为步长转动滚轮
- <Btn2Down> 使用 step 资源值的一半作为步长转动滚轮
- <Btn3Down> 使用 step 资源值的四分之一作为步长转动滚轮
- <Key>Up 和 <Key>Left 向上转动,使用 step 资源值作为步长
- Shift<Key>Up 和 Shift<Key>Left 向上转动,使用 step 资源值的一半作为步长
- Ctrl<Key>Up 和 Ctrl<Key>Left 向上转动,使用 step 资源值的四分之一作为步长
- <Key>Down 和 <Key>Right 向下转动,使用 step 资源值作为步长
- Shift<Key>Down 和 Shift<Key>Right 向下转动,使用 step 资源值的一半作为步长
- Ctrl<Key>Down 和 Ctrl<Key>Right 向下转动,使用 step 资源值的四分之一作为步长
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNnumberOfPictures | XtCNumberOfPictures | int | 0 |
XfwfNpictures | XtCPictures | ImageList | NULL |
XfwfNvertical | XtCVertical | 布尔值 | True |
XfwfNclickArea | XtCClickArea | 维度 | 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 | 回调 | NULL |
XfwfNscrollResponse | XtNscrollResponse | 回调 | scroll_response |
用法
Arg[] thwheelArgs = { new Arg(XfwfNames.XfwfNvertical, (XtArgVal)0) };
IntPtr thWheel = Xtlib.XtCreateManagedWidget("ThumbWheel3",
Xfwflib.Xt_XfwfThumbWheelWidgetClass(), thwheelBox,
thwheelArgs, (XCardinal)1);
回调用法
通过
XfwfNames.XfwfNscrollCallback
连接回调函数。
/// <summary> The callback for any thumb wheel scroll event within the dialog. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
public void ThumbWheelScrollCallback (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);
Console.WriteLine ("ThumbWheel position {0}", val);
}
XfwfThumbWheel2 与 XfwfThumbWheel 部件几乎相同,但不需要 Xpm,图像总是像素化的,并且不支持水平方向。 |  |
Core --> XfwfThumbWheel2
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNnumberOfPictures | XtCNumberOfPictures | int | 0 |
XfwfNpictures | XtCPictures | ImageList | NULL |
XfwfNclickArea | XtCClickArea | 维度 | 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 | 回调 | NULL |
XfwfNscrollResponse | XtNscrollResponse | 回调 | scroll_response |
用法
请参阅 XfwfThumbWheel
。
回调用法
请参阅
XfwfThumbWheel
。
XfwfCommon
部件作为许多其他部件的超类。它定义了一些资源、类型、转换器等,并实现了键盘遍历功能。
Core --> Composite --> XfwfCommon
新资源
名称 | 类 | 类型 | 默认值 |
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 | 无 |
XfwfNnextTop | XtCNextTop | Callback | NULL |
XfwfNuserData | XtCUserData | Pointer | NULL |
用法
不要实例化
XfwfCommon
。
XfwfMultiList 部件是一个字符串列表部件,类似于 Xt/Athena 的 List 部件,但有以下显著区别:
|  |
除了使用 Set() 和 Unset() 动作来设置和取消设置项目外,XfwfMultiList
还支持使用 Toggle() 进行切换(已选项变为未选,未选项变为已选)和使用 Open() 打开对象(例如,可用于双击操作)。
返回结构现在更复杂,列出了生成回调的操作类型(高亮项目、取消高亮项目、打开项目、请求当前状态)、点击哪个项目产生了此回调,以及当前已选项目的列表。通过设置敏感度数组,可以单独禁用项目。internalWidth 和 internalHeight 资源已被移除。
Core --> Simple --> XfwfMultiList
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNborder | XtCBorder | Pixel | XtDefaultForeground |
XtNcallback | XtCCallback | 回调 | NULL |
XfwfNcolumnWidth | XtCColumnWidth | 维度 | 0 |
XfwfNcolumnSpacing | XtCColumnSpacing | 维度 | 8 |
XfwfNcursor | XtCCursor | 光标 | left_ptr |
XfwfNdefaultColumns | XtCDefaultColumns | int | 1 |
XtNfont | XtCFont | XFontStruct | XtDefaultFont |
XfwfNforceColumns | XtCForceColumns | 布尔值 | False |
XtNforeground | XtCForeground | Pixel | XtDefaultForeground |
XfwfNhighlightBackground | XtCHighlightBackground | Pixel | XtDefaultForeground |
XfwfNhighlightForeground | XtCHighlightForeground | Pixel | XtDefaultBackground |
XfwfNinsensitiveBorder | XtCInsensitiveBorder | Pixmap | Gray |
XfwfNlist | XtCList | 字符串 | NULL |
XfwfNlongest | XtCLongest | int | 0 |
XfwfNmaxSelectable | XtCMaxSelectable | int | 1 |
XfwfNnumberStrings | XtCNumberStrings | int | 0 |
XfwfNpasteBuffer | XtCPasteBuffer | 布尔值 | 假 |
XfwfNrowHeight | XtCRowHeight | 维度 | 0 |
XfwfNrowSpacing | XtCRowSpacing | 维度 | 2 |
XfwfNsensitiveArray | XtCSensitiveArray | 布尔值 | 假 |
XfwfNtabList | XtCTabList | 字符串 | NULL |
XfwfNtabs | XtCTabs | int | 0 |
XfwfNverticalList | XtCVerticalList | 布尔值 | 假 |
用法
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) };
回调用法
通过
XtNames.XtNcallback
连接回调函数。
/// <summary> The callback for any multi list selection event within the dialog. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
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);
}
XfwfFrame 部件是一个复合部件,只接受一个子部件。其唯一目的是为那些本身没有边框的部件绘制一个边框。它总是使用其子部件的大小,并为边框增加 一点额外空间。有几种边框类型可供选择,可以通过资源进行设置。 |  |
Core --> Composite -->
XfwfCommon --> XfwfFrame
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNcursor | XtCCursor | 光标 | 无 |
XfwfNframeType | XtCFrameType | FrameType | XfwfRaised |
XfwfNframeWidth | XtCFrameWidth | 维度 | 0 |
XfwfNouterOffset | XtCOuterOffset | 维度 | 0 |
XfwfNinnerOffset | XtCInnerOffset | 维度 | 0 |
XfwfNshadowScheme | XtCShadowScheme | ShadowScheme | XfwfAuto |
XfwfNtopShadowColor | XtCTopShadowColor | Color | compute_topcolor |
XfwfNbottomShadowColor | XtCBottomShadowColor | Color | compute_bottomcolor |
XfwfNtopShadowStipple | XtCTopShadowStipple | Bitmap | NULL |
XfwfNbottomShadowStipple | XtCBottomShadowStipple | Bitmap | NULL |
用法
通常情况下,
XfwfFrame
部件有一个 2 像素宽的边框,使用标签的背景色绘制。要将
XfwfFrame
部件无缝地嵌入其周围环境,必须将
XfwfCommon
的
XfwfNhighlightThickness
资源设置为 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);
XfwfTextOut 部件是一个多色、多字体的文本显示部件。可以添加多达 8 种颜色和 4 种字体的文本块,每种都可以通过资源选择。 |  |
Core --> Composite -->
XfwfCommon --> XfwfTextOut
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNinternalOffset | XtCInternalOffset | 维度 | 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 |
用法
通常情况下,
XfwfTextOut
部件有一个 2 像素宽的边框,使用标签的背景色绘制。要将
XfwfTextOut
部件无缝地嵌入其周围环境,必须将
XfwfCommon
的
XfwfNhighlightThickness
资源设置为 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);
XfwfStack 部件是一个与 X toolkit(如果使用 MOTIF 标志编译,则也与 Motif 兼容)兼容的部件,是 constraint 的子类。堆叠部件一次只允许管理一个子部件。 | 这两个 XfwfButton 实现了在 XfwfStack 子部件之间的切换。
 |
Core --> Composite --> Constraint --> XfwfStack
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNdata | XfwfCData | XtPointer | NULL |
XfwfNmargin | XfwfCMargin | 维度 | 2 |
XfwfNsameSize | XfwfCSameSize | 布尔值 | 假 |
XfwfNfill | XfwfCFill | Boolean | False |
XfwfNstackWidget | XfwfCStackWidget | Widget | NULL |
XfwfNstackType | XfwfCStackTyp | XfwfStackType | XfwfSTACK_END_TO_END |
用法
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);
}
XfwfBoard 部件可以用作其他部件的父容器。 子部件可以是任意大小和任意位置。 |  |
location 资源也提供了一种比基于 Xt/Athena
Core
的 x、y、width 和 height 几何管理更强大的指定大小和位置的方式。
Core --> Composite -->
XfwfCommon -->
XfwfFrame --> XfwfBoard
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNabs_x | XtCAbs_x | 职位 | 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 | 职位 | 0 |
XfwfNrel_width | XtCRel_width | float | 0.0 |
XfwfNabs_height | XtCAbs_height | 职位 | 0 |
XfwfNrel_height | XtCRel_height | float | 0.0 |
XfwfNhunit | XtCHunit | float | 0.0 |
XfwfNvunit | XtCVunit | float | 0.0 |
XfwfNlocation | XtCLocation | String | NULL |
用法
通常情况下,
XfwfBoard
部件有一个 2 像素宽的边框,使用标签的背景色绘制。要将
XfwfBoard
部件无缝地嵌入其周围环境,必须将
XfwfCommon
的
XfwfNhighlightThickness
资源设置为 0。
Arg[] boardArgs = { new Arg(XfwfNames.XfwfNframeWidth, (XtArgVal)2),
new Arg(XfwfNames.XfwfNframeType, (XtArgVal)XfwfFrameType.XfwfRaised),
// Use location or width/height
// new Arg (XfwfNames.XfwfNlocation,
// X11.X11Utils.StringToSByteArray ("0 0 406 300\0")) };
new Arg(XtNames.XtNwidth, (XtArgVal)400),
new Arg(XtNames.XtNheight, (XtArgVal)300) };
IntPtr board = Xtlib.XtCreateManagedWidget("SliderViewport",
Xfwflib.Xt_XfwfBoardWidgetClass(), slider4Box,
boardArgs, (XCardinal)4);
XfwfTextMenu 部件实现了一个简单的菜单,由一系列标签组成。它被称为 XfwfTextMenu ,因为它不支持除显示简单字符串之外的任何其他内容。 |  |
当选择一个菜单项时,会调用 XfwfNactivate
回调函数,并将该项的编号和标签作为 call_data 参数传递(编号从 0 开始)。
当用户从一个菜单项移动到另一个菜单项时,会调用 XfwfNchangeSelection
回调。即使对于非活动(灰色)项,也会调用此回调。例如,它可以用于在鼠标悬停在某个项上时显示该项的解释。
Core --> Composite --> Shell --> OverrideShell --> XfwfTextMenu
新资源
名称 | 类 | 类型 | 默认值 |
XtNfont | XtCFont | FontStruct | XtDefaultFont |
XtNforeground | XtCForeground | Pixel | XtDefaultForeground |
XfwfNtabList | XtCTablist | String | NULL |
XfwfNmenu | XtCMenu | 字符串 | "empty" |
XfwfNactive | XtCActive | long | 0xFFFFFFFF |
XfwfNselection | XfwfNselection | int | -1 |
XfwfNcursor | XtCCursor | 光标 | arrow |
XfwfNactivate | XtCActivate | 回调 | NULL |
XfwfNchangeSelection | XtCChangeSelection | Callback | NULL |
用法
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);
XfwfAnimator 部件以固定速率循环播放一组图像。这些图像通常从 XPM 文件中读取。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfAnimator
新资源
名称 | 类 | 类型 | 默认值 |
XtNimages | XtCImages | ImageList | NULL |
XtNintervals | XtCIntervals | CardinalList | NULL |
XtNdefaultInterval | XtCDefaultInterval | Cardinal | 500 |
XtNcycle | XtCCycle | Boolean | True |
用法
分配动画图像最简单的方法是使用应用程序的备用资源。目前无法动态创建图像。请参阅 Alert 部件 以了解动态创建图像的原型。
编译后的应用程序必须能够访问这些图像。通常情况下,XfwfAnimator
部件有一个 2 像素宽的边框,使用标签的背景色绘制。要将 XfwfAnimator
部件无缝地嵌入其周围环境,必须将 XfwfCommon
的 XfwfNhighlightThickness
资源设置为 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);
XfwfArrow 部件显示一个指向四个方向之一的三角形。它通常是 XfwfScrollbar 的一部分。当鼠标按住不放时,它会重复调用一个回调函数。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfArrow
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNdirection | XtCDirection | 对齐 | XfwfTop |
XtNforeground | XtCForeground | Color | XtDefaultBackground |
XfwfNarrowShadow | XtCArrowShadow | 维度 | 2 |
XfwfNinitialDelay | XtCInitialDelay | Cardinal | 500 |
XfewfNrepeatDelay | XtCRepeatDelay | Cardinal | 50 |
XtNcallback | XtCCallback | 回调 | NULL |
用法
通常情况下,
XfwfArrow
部件有一个 2 像素宽的边框,使用标签的背景色绘制。要将
XfwfArrow
部件无缝地嵌入其周围环境,必须将
XfwfCommon
的
XfwfNhighlightThickness
资源设置为 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);
回调用法
通过
XtNames.XtNcallback
连接回调函数。
XfwfEnforcer 部件可用于将位置资源应用于非 XfwfBoard 子类的部件。 |  |
该部件接受单个子部件,并强制该子部件与其自身大小相同(减去边框)。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfEnforcer
新资源
无。
用法
通常情况下,
XfwfEnforcer
部件有一个 2 像素宽的边框,使用标签的背景色绘制。要将
XfwfEnforcer
部件无缝地嵌入其周围环境,必须将
XfwfCommon
的
XfwfNhighlightThickness
资源设置为 0。
// Enforcer.
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);
// Enforced//Label
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);
XfwfIcon 部件用于显示一个图标,该图标通常从 XPM 文件中读取。也有一些内置图标。该部件使用形状扩展来创建非矩形或 透明的图标。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfIcon
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNimage | XtCImage | 图标 | NULL |
XfwfNactivate | XtCActivate | 回调 | NULL |
用法
分配图标图像最简单的方法是使用应用程序的备用资源。目前无法动态创建图像。请参阅
Alert 部件 以了解动态创建图像的原型。
编译后的应用程序必须能够访问这些图像。通常情况下,
XfwfIcon
部件有一个 2 像素宽的边框,使用标签的背景色绘制。要将
XfwfIcon
部件无缝地嵌入其周围环境,必须将
XfwfCommon
的
XfwfNhighlightThickness
资源设置为 0。
fallbackResources.Add (AppShellName + "*" + Icon1Name + "*image: FATAL");
...
Xtlib.XtCreateManagedWidget(Icon1Name, Xfwflib.Xt_XfwfIconWidgetClass(),
iconBox, Arg.Zero, (XCardinal)0);
回调用法
通过
XfwfNames.XfwfNactivate
连接回调函数。
XfwfLabel 部件显示一行或多行文本,可选择性地使用制表符并与某一侧对齐。此外,还可以使用 XfwfN rvStart 和 XfwfN rvLength 资源反转(文本和背景色)文本的一部分,并使用 XfwfN hlStart 和 XfwfN hlLength 资源高亮显示文本的一部分。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfLabel
新资源
名称 | 类 | 类型 | 默认值 |
XtNlabel | XtCLabel | 字符串 | NULL |
XfwfNtabList | XtCTablist | 字符串 | NULL |
XtNfont | XtCFont | FontStruct | XtDefaultFont |
XtNforeground | XtCForeground | Color | XtDefaultForeground |
XfwfNhlForeground | XtCHlForeground | Color | XtDefaultForeground |
XfwfNalignment | XtCAlignment | 对齐 | 0 |
XfwfNtopMargin | XtCTopMargin | 维度 | 2 |
XfwfNbottomMargin | XtCBottomMargin | 维度 | 2 |
XfwfNleftMargin | XtCLeftMargin | Dimension | 2 |
XfwfNrightMargin | XtCRightMargin | 维度 | 2 |
XfwfNshrinkToFit | XtCShrinkToFit | Boolean | 假 |
XfwfNrvStart | XtCRvStart | int | 0 |
XfwfNrvLength | XtCRvLength | int | 0 |
XfwfNhlStart | XtCHlStart | int | 0 |
XfwfNhlLength | XtCHlLength | int | 0 |
用法
XfwfLabel
部件提供了许多资源来定义外观。通常情况下,
XfwfLabel
部件有一个 2 像素宽的边框,使用标签的背景色绘制。要将
XfwfLabel
部件无缝地嵌入其周围环境,必须将
XfwfCommon
的
XfwfNhighlightThickness
资源设置为 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);
XfwfRowCol 部件强制其所有子部件排列成行和列。子部件保持其首选大小,但首选位置被忽略。资源决定了应该有多少行或多少列(或尽可能多地容纳),以及子部件是按行还是按列布局。在这两种方法中,子部件都放置在一个网格上,网格的大小由最宽(最高)的子部件的宽度(高度)决定。 子部件可以以多种方式对齐:它们可以放置在网格单元的中心或靠边。这由 alignment 资源控制。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfRowCol
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNstoreByRow | XtCStoreByRow | 布尔值 | True |
XfwfNrows | XtCRows | int | 0 |
XfwfNcolumns | XtCColumn | int | 0 |
XfwfNalignment | XtCAlignment | Alignment | XfwfTopLeft |
XfwfNshrinkToFit | XtCShrinkToFit | 布尔值 | False |
用法
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);
要切换子部件排列的方向,请更改资源
XfwfNcolumns
和
XfwfNstoreByRows
。
new Arg(XfwfNames.XfwfNcolumns, (XtArgVal)((_rowcolOrientationIsRow) != true ? 2 : 4))
new Arg (XfwfNames.XfwfNstoreByRow, (XtArgVal)((_rowcolOrientationIsRow) != true ? 0 : 1))
XfwfRows 部件强制其所有子部件紧密排列成行,可以在顶部或底部对齐。子部件保持其首选大小,但首选位置被忽略。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfRows
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNalignTop | XtCAlignTop | Boolean | True |
用法
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);
XfwfScrollbar 部件有四个部分:一个供 XfwfSlider2 上下(或左右)移动的槽道和两个 XfwfArrow 部件。点击和拖动不同部分会调用一个带有不同参数的回调函数,这可能会导致另一个部件滚动。滚动条的回调列表与 XfwfSlider2 相同。
点击箭头会向该方向移动数据。在箭头上按住鼠标按钮,只要鼠标按钮被按下,数据就会以小增量移动。拖动滑块会根据滑块比例移动数据,可以随着鼠标移动而移动,也可以在释放鼠标按钮时一次性移动。在滑块外的矩形上按下鼠标按钮会以较大增量移动数据。 |  |
XfwfScrollbar
作为 XfwfHScrollbar
和 XfwfVScrollbar
的超类。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfScrollbar
代码变更
Scroll()
方法被重写,现在无论
XfwfNvertical
资源是 True 还是 False,都支持键盘滚动。添加了
XfwfGetScrollbarSlider()
方法以支持
XfwfSlider2
的方法,如
XfwfMoveThumb()
或
XfwfResizeThumb()
。
新资源
名称 | 类 | 类型 | 默认值 |
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 |
用法
请实例化
XfwfHScrollbar
或
XfwfVScrollbar
。
XfwfScrolledWindow 部件是一个复合部件,由两个 XfwfScrollbar 和一个 XfwfBoard 组成,全部包含在一个 XfwfFrame 内,并且大概有一个作为 XfwfBoard 子部件的曾孙部件。这个曾孙部件被称为受控部件(CW)。通常,受控部件比 XfwfBoard 大,其原点将具有负的 x 和 y 坐标。 |  |
受控部件由 XfwfScrolledWindow
在 XfwfBoard
内移动,以响应用户点击滚动条的操作。因此,它会被 XfwfBoard
裁剪。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfScrolledWindow
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNspacing | XtCSpacing | 维度 | 4 |
XfwfNscrollbarWidth | XtCScrollbarWidth | 维度 | 22 |
XfwfNshadowWidth | XtCShadowWidth | 维度 | 2 |
XfwfNhideHScrollbar | XtCHideHScrollbar | 布尔值 | False |
XfwfNhideVScrollbar | XtCHideVScrollbar | 布尔值 | 假 |
XfwfNhScrollAmount | XtCHScrollAmount | int | 20 |
XfwfNvScrollAmount | XtCVScrollAmount | int | copy_vScrollAmount |
XfwfNinitialX | XtCInitialX | Position | 0 |
XfwfNinitialY | XtCInitialY | Position | 0 |
XfwfNscrollCallback | XtSCcrollCallback | 回调 | NULL |
XfwfNscrollResponse | XtCScrollResponse | XtCallbackProc | NULL |
用法
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);
回调用法
通过
XfwfNames.XfwfNscrollCallback
连接回调函数。
/// <summary> The callback for step button activate event. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
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))
{
; // Evaluate
}
}
}
XfwfScrolledWindow3 部件是一个复合部件,包含 4 个 XfwfBoard 和两个 XfwfScrollbar 。第一个板是左上角的一个小区域,可以放置一个标签部件。沿顶部的一个板和沿左侧的一个板用于列和行标题(通常是 XfwfLabel 部件)。两个滚动条分别位于右侧和底部。中间是最大的板,用于显示主要数据。 |  |
作为大
XfwfBoard
的子部件添加的部件称为受控部件(CW),放置在顶部板中的部件称为列受控部件(CCW),放置在左侧板中的部件是行受控部件(RCW)。
通常,受控部件比板大,其原点将具有负的 x 和 y 坐标。它们由
XfwfScrolledWindow3
在
XfwfBoard
内部移动,以响应用户点击滚动条。CCW 左右移动,RCW 上下移动,CW 在所有方向移动。因此,受控部件会被板裁剪。
附加到
XfwfScrolledWindow3
的第一个子部件成为左上角板的子部件。第二个子部件成为 CCW,第三个成为 RCW,第四个成为 CW。
CCW 通常是一个带有制表符列表的
XfwfLabel
部件,用于提供列标题,并且仅水平滚动。CW 通常是一个带有制表符列表的单列
XfwfMultiList
部件,并且水平和垂直都滚动。
此翻译不完整。请再试一次。
XfwfScrolledWindow3
提供了一个回调函数,但大多数应用程序不需要它,因为它已经移动了 CW。回调函数在 CW 移动后被调用。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfScrolledWindow3
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNspacing | XtCSpacing | 维度 | 4 |
XfwfNscrollbarWidth | XtCScrollbarWidth | 维度 | 22 |
XfwfNcolHdrHeight | XtNcolHdrHeight | 维度 | 22 |
XfwfNrowHdrWidth | XtNrowHdrWidth | 维度 | 22 |
XfwfNshadowWidth | XtCShadowWidth | 维度 | 2 |
XfwfNhideHScrollbar | XtCHideHScrollbar | 布尔值 | False |
XfwfNhideVScrollbar | XtCHideVScrollbar | 布尔值 | 假 |
XfwfNhScrollAmount | XtCHScrollAmount | int | 20 |
XfwfNvScrollAmount | XtCVScrollAmount | int | copy_vScrollAmount |
XfwfNinitialX | XtCInitialX | Position | 0 |
XfwfNinitialY | XtCInitialY | Position | 0 |
XfwfNscrollCallback | XtSCcrollCallback | 回调 | NULL |
XfwfNscrollResponse | XtCScrollResponse | XtCallbackProc | NULL |
用法
// ScrollWin3.
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);
// Corner label.
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);
// ColumnHeader label.
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);
// Array preparation.
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");
// RowHeader label.
Arg[] rowhdrLabelArgs = { new Arg (XfwfNames.XfwfNlist, rowHrd.Data),
// Omit this to show all list entries sensitive.
new Arg (XfwfNames.XfwfNsensitiveArray, rowSens.Data),
// The number of visible list entries, 0 for all.
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);
// Content label.
Arg[] contentLabelArgs = { new Arg (XfwfNames.XfwfNlist, contentTxt.Data),
// Omit this to show all list entries sensitive.
new Arg (XfwfNames.XfwfNsensitiveArray, rowSens.Data),
// The number of visible list entries, 0 for all.
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);
// Array disposal.
rowSens.Dispose();
contentTxt.Dispose();
rowHrd.Dispose();
回调用法
通过
XfwfNames.XfwfNscrollCallback
连接回调函数。
XfwfTabs 部件显示一系列选项卡,类似于索引卡顶部的字母选项卡。一个选项卡,即最前面的一个,完全可见,其他的则部分隐藏在它后面。每个选项卡都可以用鼠标点击。此实现不参与键盘遍历,并且没有 3D 边框。
|  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfTabs
新资源
名称 | 类 | 类型 | 默认值 |
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 | 回调 | NULL |
用法
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.XfwfNtabWidthPercentage, (XtArgVal)40),
new Arg (XfwfNames.XfwfNframeWidth, (XtArgVal)1),
// Use default corner width.
//new Arg (XfwfNames.XfwfNcornerWidth, (XtArgVal)4),
// Use default corner height.
//new Arg (XfwfNames.XfwfNcornerHeight, (XtArgVal)4),
// Visible tabs left from currently activated tab.
new Arg (XfwfNames.XfwfNlefttabs, (XtArgVal)0),
// Visible tabs right from currently activated tab.
new Arg (XfwfNames.XfwfNrighttabs, (XtArgVal)1) };
IntPtr tab = Xtlib.XtCreateManagedWidget(Tab1Name,
Xfwflib.Xt_XfwfTabsWidgetClass(), tabBox,
tab1Args, (XCardinal)10);
回调用法
通过
XfwfNames.XfwfNactivate
连接回调函数。
/// <summary> The callback for any crollbar scroll event within the dialog. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
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 = { // Visible tabs left from currently activated tab.
new Arg (XfwfNames.XfwfNlefttabs, (XtArgVal)0),
// Visible tabs right from currently activated tab.
new Arg (XfwfNames.XfwfNrighttabs, (XtArgVal)1) };
Xtlib.XtSetValues (widget, tabArgs, (XCardinal)2);
}
else if (relativeTabIndex > 0)
{
Arg[] tabArgs = { // Visible tabs left from currently activated tab.
new Arg (XfwfNames.XfwfNlefttabs, (XtArgVal)1),
// Visible tabs right from currently activated tab.
new Arg (XfwfNames.XfwfNrighttabs, (XtArgVal)0) };
Xtlib.XtSetValues (widget, tabArgs, (XCardinal)2);
}
}
XfwfButton 部件只是一个带有鼠标点击回调的 XfwfLabel 。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel --> XfwfButton
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNactivate | XtCActivate | Callback | NULL |
XfwfNenter | XtCEnter | Callback | NULL |
XfwfNleave | XtCLeave | Callback | NULL |
回调用法
通过
XfwfNames.XfwfNactivate
、
XfwfNames.XfwfNenter
或
XfwfNames.XfwfNleave
连接回调函数。
/// <summary> The callback for any button press event within the dialog. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
public void ButtonPressCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
string sWidgetName = Xtlib.XtNameAsString (widget);
Console.WriteLine ("Button pressed {0}", sWidgetName);
}
XfwfSlider2 部件显示一个滑块(具有水平和垂直位置两个自由度),可以用鼠标移动。
应用程序可以通过回调使用它来移动或滚动其他对象。
|  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel --> XfwfSlider2
新资源
名称 | 类 | 类型 | 默认值 |
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 |
用法
使用
XfwfResizeThumb()
调整滑块大小,并使用
XfwfConnectScrollingWidgets()
将滑块与要移动的部件连接起来。
回调用法
通过
XfwfNames.XfwfNscrollCallback
连接回调函数。
/// <summary> The callback for slider2 move event within the dialog. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
public void Slider2ThumbCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
if (callData != IntPtr.Zero)
{
XfwfScrollInfo scrollInfo = (XfwfScrollInfo)
Marshal.PtrToStructure (callData, typeof(XfwfScrollInfo));
// Don't update during move.
// if (scrollInfo.reason != XfwfSReason.XfwfSDrag)
{
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);
}
}
}
XfwfSpinLabel 部件提供了与其超类 XfwfLabel 几乎相同的功能,但此外还可以使用两个箭头按钮来操作标签。通过这些按钮,用户可以增加/减少数值或滚动浏览字符串列表。 |  |
每次按下其中一个箭头时,都会调用 XfwfNactivate
回调。XfwfSpinLabel
部件也提供了一个键盘接口。通过回调,程序员可以自由决定让用户滚动浏览什么内容。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel --> XfwfSpinLabel
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNarrowForeground | XtCArrowForeground | Color | copy_background |
XtNcallback | XtCCallback | Callback | NULL |
XfwfNlabelFrameWidth | XtCLabelframeWidth | 维度 | 0 |
XfwfNlabelFrameType | XtCLabelframeType | XfwfFrameType | XfwfSunken |
XfwfNhorizontal | XtCHorizontal | 布尔值 | True |
用法
/// <summary> The strings to be displayed in a spin label XfwfTabs. </summary>
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);
回调用法
通过
XtNames.XtNcallback
连接回调函数。
/// <summary> The callback for any spin label event within the canvas. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
public void SpinLabelCallback (IntPtr widget, IntPtr clientData, IntPtr callData)
{
IntPtr spinWidget = IntPtr.Zero;
// The widget might be one of the arrows.
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"))
{
...
}
}
}
XfwfGroup 部件在 XfwfRowCol 已有功能的基础上增加了两项内容:一个位于 左上角的标签,以及使多个 XfwfToggle 按钮充当单选按钮的能力。
|  |
标签是一小段单行文本,显示在左上角边框的上方。边框在该点被中断。由于这种效果与
XfwfLedged
或
XfwfChiseled
边框类型配合最佳,默认边框为
XfwfChiseled
。
对单选按钮的特殊支持工作原理如下:当添加子部件时,
XfwfGroup
部件会检查它是否是
XfwfToggle
类或其子类。如果是,
XfwfGroup
部件会为其安装一个回调。当
XfwfToggle
按钮被激活时,
XfwfGroup
部件会确定需要关闭哪些其他按钮。所有
XfwfToggle
按钮都被赋予一个隐式编号。第一个是 0 号。
selectionStyle 资源支持
XfwfSingleSelection
(零个或一个切换按钮开启)、
XfwfOneSelection
(任何时候都只有一个切换按钮开启)和
XfwfMultipleSelection
(任意数量的切换按钮开启)模式。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard --> XfwfRowCol --> XfwfGroup
新资源
名称 | 类 | 类型 | 默认值 |
XtNlabel | XtCLabel | 字符串 | NULL |
XtNfont | XtCFont | FontStruct | XtDefaultFont |
XtNforeground | XtCForeground | Color | XtDefaultForeground |
XfwfNselectionStyle | XtCSelectionStyle | SelectionType | XfwfSingleSelection |
XfwfNselection | XtCSelection | long | 0 |
XfwfNactivate | XtCActivate | Callback | NULL |
用法
创建一个
XfwfGroup
部件并添加
XfwfToggle
类或任何子类的子部件。
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),
/* Allocate enough space for group title.*/
new Arg(XfwfNames.XfwfNouterOffset, (XtArgVal)5) };
IntPtr group = Xtlib.XtCreateManagedWidget(SimpleGroupName,
Xfwflib.Xt_XfwfGroupWidgetClass(), radiogrpBox,
groupArgs, (XCardinal)8);
回调用法
XfwfGroup
部件不需要注册回调。可选地,可以通过
XfwfNames.XfwfNonCallback
将切换按钮连接到回调以获得即时反馈。
XfwfNselection
资源随时保存切换按钮的状态(如果有的话)。如果
XfwfNselectionType
=
XfwfSingleSelection
或
XfwfOneSelection
,它保存当前开启的按钮的索引,如果都关闭则为 -1。如果
XfwfNselectionType
=
XfwfMultipleSelection
,它是一个位图,每个开启的按钮对应一个设置位。
XfwfMenuBar 部件将按钮显示在水平行中。它假定这些按钮控制下拉菜单,并允许用户将鼠标从一个菜单拖动到另一个菜单。 |  |
MenuBar 将自身附加到由子部件弹出的菜单 shell 的 XtNpopdownCallback
回调上,并将其插入到 Xt 维护的指针抓取列表中。这对于能够将鼠标从一个菜单拖动到另一个菜单,同时收起第一个菜单并弹出第二个菜单是必需的。如果您使用 XfwfRowCol
部件而不是 XfwfMenuBar
,您会发现从一个菜单切换到下一个菜单需要释放鼠标然后再按一次。
为了找到菜单 shell,会向子部件查询其 XtNpopup
资源。XfwfPullDown
按钮有此资源,其他按钮可能没有。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfRows --> XfwfMenuBar
新资源
无。
用法
只需创建
XfwfPullDown
部件作为子部件即可。
XfwfHScrollbar
部件与
XfwfScrollbar
部件几乎相同,只是它有用于向上/向下滚动、向上/向下翻页和 home/end 的默认转换,并且
XfwfNvertical
资源的默认值为 False。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfScrollbar --> XfwfHScrollbar
新资源
无。
代码变更
修正了默认转换参数(大小写)。新增默认转换,现在支持以下键盘绑定:
- <Key>Left 向左滚动一步
- <Key>Right 向右滚动一步
- Ctrl<Key>Left 和 <Key>Prior 向左滚动一页
- Ctrl<Key>Right 和 <Key>Next 向右滚动一页
- <Key>Home, Shift<Key>End 和 Ctrl<Key>Prior 滚动到开头(左侧)
- Shift<Key>Home, <Key>End 和 Ctrl<Key>Next 滚动到末尾(右侧)
用法
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);
回调用法
通过
XfwfNames.XfwfNscrollCallback
连接回调函数。
/// <summary> The callback for any scrollbar scroll event within the dialog. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
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);
}
XfwfVScrollbar
部件与
XfwfScrollbar
部件几乎相同,只是它有用于向左/向右滚动、向左/向右翻页和 home/end 的默认转换,并且
XfwfNvertical
资源的默认值为 True。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfScrollbar --> XfwfVScrollbar
新资源
无。
代码变更
修正了默认转换参数(大小写)。新增默认转换,现在支持以下键盘绑定:
- <Key>Up 向上滚动一步
- <Key>Down 向下滚动一步
- Ctrl<Key>Up 和 <Key>Prior 向上滚动一页
- Ctrl<Key>Down 和 <Key>Next 向下滚动一页
- <Key>Home, Shift<Key>End 和 Ctrl<Key>Prior 滚动到开头(顶部)
- Shift<Key>Home, <Key>End 和 Ctrl<Key>Next 滚动到末尾(底部)
用法
请参阅
XfwfHScrollbar
。
回调用法
请参阅
XfwfHScrollbar
。
XfwfPullDown 部件是一个带有下拉菜单的按钮。菜单可以通过两种方式指定:作为字符串或作为部件。 |  |
如果给定一个字符串,它必须是 XfwfTextMenu
部件的正确语法,并且会自动创建一个部件。如果给定一个部件,它必须是一个能够弹出的部件:换句话说,一个 Shell 部件或 Shell 的子类。还支持热键,但尚不能正常工作。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel -->
XfwfButton --> XfwfPullDown
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNpopup | XtCPopup | Widget | NULL |
XfwfNmenu | XtCMenu | String | NULL |
XfwfNcascaded | XtCCascaded | Boolean | False |
XfwfNhotkey | XtCHotkey | String | NULL |
XfwfNmenuCursor | XtCMenuCursor | Cursor | arrow |
XfwfNprepare | XtCPrepare | 回调 | NULL |
XfwfNchangeSelection | XtCChangeSelection | 回调 | NULL |
用法
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);
回调用法
通过
XfwfNames.XfwfNactivate
、
XfwfNames.XfwfNprepare
或
XfwfNames.XfwfNchangeSelection
连接回调函数。
/// <summary> The callback for any pulldown select event within the dialog. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
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);
}
}
XfwfToggle 部件每次激活(默认是每次鼠标点击)都会切换状态。状态命名为 on 和 off。这些状态可以通过标签前的图标来指示。 |  |
两个回调函数向应用程序报告状态变化:当按钮切换到 on 时调用 XfwfNonCallback
,当按钮切换回 off 时调用 XfwfNoffCallback
。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel -->
XfwfButton --> XfwfToggle
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNonCallback | XtCOnCallback | Callback | NULL |
XfwfNoffCallback | XtCOffCallback | Callback | NULL |
XfwfNon | XtCOn | Boolean | 假 |
XfwfNonIcon | XtCOnIcon | 图标 | filledsquare |
XfwfNoffIcon | XtCOffIcon | 图标 | emptysquare |
用法
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);
回调用法
通过 XfwfNames.XfwfNonCallback
和 XfwfNames.XfwfNoffCallback
连接回调函数。
/// <summary> The callback for any toggle press event within the dialog. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
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);
}
XfwfSlider4 部件与 XfwfSlider2 部件几乎相同(具有四个自由度:水平和垂直位置以及宽度和高度),只是在滑块的右下角增加了一个调整手柄,可以用它来调整滑块的大小。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel -->
XfwfSlider2 --> XfwfSlider4
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNsashColor | XtCSashColor | Color | XtDefaultBackground |
XfwfNsashPixmap | XtCSashPixmap | Pixmap | NULL |
XfwfNsashFrameType | XtCSashFrameType | FrameType | XfwfRaised |
XfwfNsashFrameWidth | XtCSashFrameWidth | Dimension | 2 |
回调用法
请参阅
XfwfSlider2
。
XfwfRadioGroup 部件是 XfwfGroup 部件的一个更方便的简单特化,用于组中只包含 XfwfToggle 按钮的情况。它有一个额外的资源 labels,用于保存自动创建的 XfwfToggle 按钮的标签。它也远不那么灵活,当默认值不满足要求时,很难更改单选按钮的资源(默认值为 XfwfNshrinkToFit = True, XtNborderWidth = 0, XfwfNframeWidth = 0)。 |  |
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfRowCol -->
XfwfGroup --> XfwfRadioGroup
新资源
名称 | 类 | 类型 | 默认值 |
XfwfNlabels | XtCLabels | StringArray | NULL |
用法
XfwfRadioGroup
部件会自动创建其子部件。
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),
/* Allocate enough space for group title.*/
new Arg(XfwfNames.XfwfNouterOffset, (XtArgVal)5) };
IntPtr radiogrp = Xtlib.XtCreateManagedWidget(RadioGroup1Name,
Xfwflib.Xt_XfwfRadioGroupWidgetClass(), radiogrpBox,
radioArgs, (XCardinal)11);
回调用法
请参阅
XfwfGroup
部件。
XfwfOptionButton 部件是一个带有下拉菜单的按钮,显示只能选择一个的选项。最近选择的选项在菜单关闭后仍然可见。 |  |
它非常像一个 XfwfPullDown
按钮,只是按钮的标签会自动设置为上次选择的菜单项的标签。
Core --> Composite -->
XfwfCommon -->
XfwfFrame -->
XfwfBoard -->
XfwfLabel -->
XfwfButton -->
XfwfPullDown --> XfwfOptionButton
新资源
无。
回调用法
通过
XfwfNames.XfwfNactivate
连接回调函数。
/// <summary> The callback for any option button press event within the canvas. </summary>
/// <param name="widget"> The widget, that initiated the callback procedure.
/// <see cref="System.IntPtr"/> </param>
/// <param name="clientData"> Additional callback data from the client.
/// <see cref="System.IntPtr"/> </param>
/// <param name="callData"> Additional data defined for the call.
/// <see cref="System.IntPtr"/> </param>
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);
}
}
关注点
除了设置正确的依赖项(以编译 Xfwf/Free Widget Foundation 部件)、修正编译错误和优化显示效果等挑战外,还需要提及
部件初始化和资源名称
C#
Arg
结构体自本系列
第二篇文章起就已可用。本项目增加了一些选项,提供了结构体成员
intValue
和
floatValue
的替代方案。此外,新的辅助类
XtString
、
XtStringArray
、
XtByteArray
和
XtIntegerArray
简化了
Arg
的创建。
为避免混淆,所有 Xfwf/Free Widget Foundation 部件的资源名称都以
XfwfN
为前缀,例如
XfwfNames.XfwfNactivate
。
无法让
scr/Alert/Alert.c 中的
XfwfAlert
部件运行。取而代之的是,
scr/Alert/AlertModal.c 实现了替代的
XfwfAlertModal
部件,并展示了用纯 C 语言编程
Xfwf/Free Widget Foundation 部件是多么容易。
XfwfAlertModal
部件包含
CreateIconFromData()
方法,该方法动态创建一个图标。此方法可以作为动态图标创建的原型,并且对于
XfwfIcon
和
XfwfAnimator
也可能有用。
历史
- 2013 年 10 月 28 日,这是关于从 C# 和 Mono Develop 对 X11 API 进行本地调用的第四篇文章。它涉及 Xfwf/Free Widget Foundation 部件。重点是与 Xt/Athena 兼容的 Xfwf/Free Widget Foundation 部件。本系列的第一篇文章仅关于 Xlib。 第二篇文章仅关于 Xt。 第三篇文章仅关于 Xm/Motif。计划撰写更多文章,更深入地探讨 Xlib、Xt/Athena 或 Xm/Motif。