Motif库的水平绘制RowColumn类(C)



我的工作使用Motif库。如果有人不熟悉这个库,你可以在这里找到文件列表https://packages.ubuntu.com/xenial/amd64/libmotif-dev/filelist,以及Motif 1.2 X11关于在ScrolledWindow中使用RowColumn小部件的另一个问题。

我的问题是xmRowColumnWidgetClass是垂直绘制的,这意味着它逐列绘制(从左上角开始,移动到左下角,然后向右移动到下一列,等等(

这样做:

Widget parentWidget, rowColumn;
XtAppContext app;
parentWidget = XtVaAppInitialize(&app, "rowColumn", NULL, 0,
&argc, argv, NULL, NULL);

然后像这样:

rowColumn = XtVaCreateManagedWidget("rowcolumn",
xmRowColumnWidgetClass,
parentWidget,
XmNnumColumns, 3,
XmNpacking, XmPACK_COLUMN,
XmNspacing, 6,
NULL);
(void) XtVaCreateManagedWidget("button 1",
xmPushButtonWidgetClass, rowColumn, NULL);
(void) XtVaCreateManagedWidget("button 2",
xmPushButtonWidgetClass, rowColumn, NULL);
(void) XtVaCreateManagedWidget("button 3",
xmPushButtonWidgetClass, rowColumn, NULL);

(void) XtVaCreateManagedWidget("button 4",
xmPushButtonWidgetClass, rowColumn, NULL);
(void) XtVaCreateManagedWidget("button 5",
xmPushButtonWidgetClass, rowColumn, NULL);
(void) XtVaCreateManagedWidget("button 6",
xmPushButtonWidgetClass, rowColumn, NULL);
(void) XtVaCreateManagedWidget("button 7",
xmPushButtonWidgetClass, rowColumn, NULL);
(void) XtVaCreateManagedWidget("button 8",
xmPushButtonWidgetClass, rowColumn, NULL);
(void) XtVaCreateManagedWidget("button 9",
xmPushButtonWidgetClass, rowColumn, NULL);

所以上面的代码会创建这样的小工具:

button 1    button 4    button 7
button 2    button 5    button 8
button 3    button 6    button 9

我的问题是,我希望某些项目并排,而不是在下面。

假设我指定了这样的顺序:按钮1、按钮4、按钮7、按钮2、按钮5、按钮8、按钮3、按钮6、按钮9。看起来是这样的:

button 1    button 2    button 3
button 4    button 5    button 6
button 7    button 8    button 9

然而,如果我想删除一个按钮或添加一个新按钮,这会把一切都搞砸。假设我删除了";按钮4";从上面的例子来看,顺序是这样的:按钮1、按钮7、按钮2、按钮5、按钮8、按钮3、按钮6、按钮9。看起来是这样的:

button 1    button 5    button 6
button 7    button 8    button 9
button 2    button 3

正如你所看到的,实际上没有什么东西应该并排在一起,现在却挨着在一起。

当你添加一个新按钮时也会出现这个问题:假设我们想在末尾添加一个按钮10:按钮1、按钮4、按钮7、按钮2、按钮5、按钮8、按钮3、按钮6、按钮9、按钮10。这看起来像这样:

button 1    button 5    button 9
button 4    button 8    button 10
button 7    button 3
button 2    button 6

到目前为止,这看起来是最糟糕的,因为添加一个新按钮会将行的法线增加到4而不是3,从而改变整个布局。


任何熟悉这个库的人:

如何创建一个水平绘制(逐行绘制(而不是垂直绘制的xmRowColumnWidgetClass实例?(逐列(

或者,我如何扩展这个库,并可能生成一个xmHorRowColumnWidgetClass来满足我的需求


此库的另一组示例:
https://github.com/spartrekus/Motif-C-Examples
https://github.com/spartrekus/Motif-C-Examples/blob/master/rowcol.c

使用XmForm类,并使用附加到孩子身上的受限资源。您可以在子级中生成XmATTACH_POSITION,并在窗体中设置网格,使其(网格(随着父级的大小调整而拉伸和压缩。例如,您可以将子对象的四个边界附加到包含父对象(XmForm(小部件的4x3单元假想网格上,并将子对象附加到父对象中的固定位置,因此,如果删除其中一个,则相邻小部件不会填充该孔。请参阅XmForm的文档,IMHO是您应该使用的小部件。

keypad.c

下面是一个使用XmForm的简单键盘示例,说明如何初始化资源。它显示了要触摸的最小硬连线资源。

/* main.c -- main program to create a keypad with an XmForm
widget.
* Author: Luis Colorado <luiscoloradourcola@gmail.com>
* Date: Tue Apr 21 16:15:28 EEST 2020
* Copyright: (C) 2020 Luis Colorado.  All rights reserved.
* License: BSD.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/PushBG.h>
#define F(_fmt) __FILE__":%d:%s: " _fmt, __LINE__, __func__
/* XmForm has a coordinate set based on a common denominator
* that it applies to x and y coordinates, in order to subdivide
* the grid (that has the same subdivisions along the x axis, as
* it has along the y axis, so in order to make a 4x3 grid we
* calculate the MCM(3, 4) = 12 to use as the denominator to
* divide the x and y sides of it.  This makes the coordinates 
* to go as the drawing marks.
*      0   4   8  12
*      +---+---+---+  0
*      | 1 | 2 | 3 |
*      +---+---+---+  3
*      | 4 | 5 | 6 |
*      *---+---+---+  6
*      | 7 | 8 | 9 |
*      +---+---+---+  9
*      | * | 0 | # |
*      +---+---+---+ 12
*/
struct but_desc {
int left_x, top_y;
int right_x, bot_y;
char *name;
char *out;
void (*cb)(Widget, XtPointer, XtPointer);
};
void callback(Widget w, XtPointer data, XtPointer cd);
static struct but_desc
pos_tab[] = {
{ 4, 9,  8, 12, "b0",        "0", callback, },
{ 0, 0,  4,  3, "b1",        "1", callback, },
{ 4, 0,  8,  3, "b2",        "2", callback, },
{ 8, 0, 12,  3, "b3",        "3", callback, },
{ 0, 3,  4,  6, "b4",        "4", callback, },
{ 4, 3,  8,  6, "b5",        "5", callback, },
{ 8, 3, 12,  6, "b6",        "6", callback, },
{ 0, 6,  4,  9, "b7",        "7", callback, },
{ 4, 6,  8,  9, "b8",        "8", callback, },
{ 8, 6, 12,  9, "b9",        "9", callback, },
{ 8, 9, 12, 12, "bhash",     "#", callback, },
{ 0, 9,  4, 12, "basterisk", "*", callback, },
{ 0, 0,  0,  0, NULL, NULL, },
};
int
main(int argc, char **argv)
{
XtAppContext app_ctx;
char *class_name = "XKeypad";
Widget topLevel = XtVaAppInitialize(
&app_ctx,
class_name,
NULL, 0, /* XrmOptionDescRec array */
&argc, argv, /* args to main */
NULL, /* default resources */
NULL); /* empty list of arguments */
if (!topLevel) {
fprintf(stderr,
F("Couldnt create main widget"));
exit(EXIT_FAILURE);
}
char *form_name = "form";
Widget form = XtVaCreateManagedWidget(
form_name,
xmFormWidgetClass,
topLevel,
XmNfractionBase, 12,
NULL);
if (!form) {
fprintf(stderr,
F("Couldn't create form '%s'n"),
form_name);
exit(EXIT_FAILURE);
}
struct but_desc *p;
for (p = pos_tab; p->name; ++p) {
printf(F("Creando botón '%s'@{(%d,%d),(%d,%d)}n"),
p->name, p->left_x, p->top_y, p->right_x, p->bot_y);
Widget button =
XtVaCreateManagedWidget(
p->name,
xmPushButtonGadgetClass,
form,
XmNleftAttachment, XmATTACH_POSITION,
XmNrightAttachment, XmATTACH_POSITION,
XmNtopAttachment, XmATTACH_POSITION,
XmNbottomAttachment, XmATTACH_POSITION,
XmNleftPosition, p->left_x,
XmNrightPosition, p->right_x,
XmNtopPosition, p->top_y,
XmNbottomPosition, p->bot_y,
NULL, NULL);
if (!button) {
fprintf(stderr,
F("Couldnt create button '%s'n"),
p->name);
exit(EXIT_FAILURE);
}
XtAddCallback(button, XmNactivateCallback, p->cb, p);
}
XtRealizeWidget(topLevel);
XtAppMainLoop(app_ctx);
} /* main */
void callback(Widget w, XtPointer p, XtPointer cd)
{
struct but_desc *data = p;
write(1, data->out, strlen(data->out));
}

我用下面的示例代码添加了这个存储库。存储库包括Makefile和默认资源文件(XKeypad(。

要使xmRowColumnWidgetClass实例水平绘制,请将XmNorientation, XmHORIZONTAL添加到代码中:

rowColumn = XtVaCreateManagedWidget("rowcolumn",
xmRowColumnWidgetClass,
parentWidget,
XmNnumColumns, 3,
XmNorientation, XmHORIZONTAL,
XmNpacking, XmPACK_COLUMN,
XmNspacing, 6,
NULL);

这使得它可以逐行绘制,而不是逐列绘制。

由于某种原因,XmNnumColumns现在指的是行数而不是列数,但这是一个单独的问题,因此上面的代码确实回答了我最初的问题。

最新更新