Горизонтально нарисованный класс RowColumn для библиотеки мотивов (C)? - PullRequest
1 голос
/ 18 апреля 2020

Я использую Motif Library для своей работы. Если кто-то не знаком с этой библиотекой, вы можете найти список файлов здесь https://packages.ubuntu.com/xenial/amd64/libmotif-dev/filelist, а также другой вопрос здесь Мотив 1.2 X11 об использовании виджета RowColumn внутри ScrolledWindow .

Моя проблема заключается в том, что класс xmRowColumnWidgetClass рисуется вертикально, что означает, что он будет * * * * * * * * это столбец за столбцом (начинается слева вверху, двигается вниз слева, затем перемещается вправо к следующему столбцу и т. Д. c. )

Делаем что-то вроде этого:

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

Моя проблема в том, что я хочу, чтобы некоторые из них были рядом, а не сверху-внизу.

И, предположим, для этого я задаю такой порядок: button 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. Это будет выглядеть так this:

button 1    button 5    button 9

button 4    button 8    button 10

button 7    button 3

button 2    button 6

Это выглядит наихудшим образом, поскольку добавление новой кнопки увеличивает нормаль строк до 4 вместо 3, что меняет весь макет.


To Кто-нибудь знаком с этой библиотекой:

Как мне создать экземпляр xmRowColumnWidgetClass, который dr aws горизонтально (построчно) вместо вертикально? (столбец за столбцом)

Или как мне расширить эту библиотеку и, возможно, создать класс xmHorRowColumnWidgetClass, который делает то, что я хочу?


Другая группа примеры этой библиотеки:
https://github.com/spartrekus/Motif-C-Examples
https://github.com/spartrekus/Motif-C-Examples/blob/master/rowcol.c

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Используйте класс XmForm и играйте с ограниченными ресурсами, прикрепленными к дочерним элементам. Вы можете создать XmATTACH_POSITION в дочернем элементе и установить сетку в форме, чтобы она (сетка) растягивалась и сжималась с изменением размера родительского элемента. Например, вы можете привязать четыре границы дочернего элемента к воображаемой сетке ячейки 4x3, требующей родительского виджета (XmForm), и прикрепить дочерние элементы к фиксированным позициям в родительском элементе, поэтому при удалении одной из них отверстие не заполняется. по соседним виджетам. См. Do c для XmForm, IMHO - виджет, который вы должны использовать.

клавиатура. c

Ниже приведен пример простой клавиатуры usint 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).

0 голосов
/ 20 апреля 2020

Чтобы сделать экземпляр xmRowColumnWidgetClass горизонтальным, добавьте XmNorientation, XmHORIZONTAL к коду:

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

Это позволяет рисовать строку за строкой, а не столбец за столбцом.

XmNnumColumns теперь относится к числу строк, а не столбцов по какой-то причине, но это отдельная проблема, и поэтому приведенный выше код действительно отвечает на мой первоначальный вопрос.

...