cunixwidgetx11motif

How do you add a scrolled text widget that grows with the size of its manager and takes the whole height?


I am trying to add a scrolled text widget that grows with the size of the application window. It will take all available space. It is intended to be a message area on the bottom of a Main application, but here I have reduced the problem to a more easy to replicate one.

This is what I have tried:

#include <Xm/Xm.h>
#include <Xm/Text.h>
#include <Xm/ScrolledW.h>
#include <Xm/RowColumn.h>

int main(int argc, char** argv)
{
    XtAppContext app;
    Widget topLevelShell;
    Widget mainWidget;
    Widget scrolledText;

    topLevelShell = XtVaAppInitialize(&app, "Application", NULL, 0, &argc, argv, NULL, NULL);

    mainWidget = XtVaCreateManagedWidget("mainWidget", xmRowColumnWidgetClass, topLevelShell,
                                         XmNorientation, XmVERTICAL,
                                         NULL);

    // Create a ScrolledWindow widget
    scrolledText = XtVaCreateManagedWidget("scrolledText", xmScrolledWindowWidgetClass, mainWidget,
                                           XmNscrollingPolicy, XmAUTOMATIC,
                                           NULL);

    // Create a Text widget inside the ScrolledWindow
    Widget textWidget = XtVaCreateManagedWidget("textWidget", xmTextWidgetClass, scrolledText,
                                                XmNeditable, True,
                                                XmNscrollVertical, True,
                                                XmNscrollHorizontal, False,
                                                NULL);

    // Set the attachments to make the ScrolledText stretch vertically
    XtVaSetValues(scrolledText, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, mainWidget,
                  XmNbottomAttachment, XmATTACH_FORM,
                  XmNleftAttachment, XmATTACH_FORM,
                  XmNrightAttachment, XmATTACH_FORM,
                  NULL);

    XtVaSetValues(textWidget, XmNtopAttachment, XmATTACH_FORM,
                  XmNbottomAttachment, XmATTACH_FORM,
                  XmNleftAttachment, XmATTACH_FORM,
                  XmNrightAttachment, XmATTACH_FORM,
                  NULL);

    XtRealizeWidget(topLevelShell);
    XtAppMainLoop(app);

    return 0;
}

If you compile it is clear that it is not getting the intended effect.

I also include the makefile (for FreeBSD) to simplify the test:

CC = cc
CFLAGS = -Wall -Wextra -I/usr/local/include
LIBS = -lXm -lXt -lX11
LDFLAGS = -L/usr/local/lib

SRCS = main.c
OBJS = $(SRCS:.c=.o)
TARGET = test

all: $(TARGET)

$(TARGET): $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)

%.o: %.c
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f $(OBJS) $(TARGET)

Solution

  • I suppose the following is what you want:

    Use a Form, not a rowColumn, and attach the scrollwindow to the edges of the Form.

    #include <Xm/Xm.h>
    #include <Xm/Text.h>
    #include <Xm/ScrolledW.h>
    #include <Xm/Form.h>
    
    int main(int argc, char** argv)
    {
        XtAppContext app;
        Widget topShell;
        Widget form;
        Widget scrolledText;
    
        topShell = XtVaAppInitialize(&app, "Application", NULL, 0, &argc, argv, NULL, NULL);
    
        form    = XtVaCreateManagedWidget("form", xmFormWidgetClass, topShell,
                                               NULL);
    
    
        // Create a ScrolledWindow widget
        scrolledText = XtVaCreateManagedWidget("scrolledText",
                                               xmScrolledWindowWidgetClass, form,
                                               XmNscrollBarDisplayPolicy, XmSTATIC,
                                               XmNtopAttachment,    XmATTACH_FORM,
                                               XmNbottomAttachment, XmATTACH_FORM,
                                               XmNleftAttachment, XmATTACH_FORM,
                                               XmNrightAttachment, XmATTACH_FORM,
                                               NULL);
    
    
    
        // Create a Text widget inside the ScrolledWindow
        Widget textWidget = XtVaCreateManagedWidget("textWidget",
                                                xmTextWidgetClass, scrolledText,
                                                XmNeditable, True,
                                                XmNscrollVertical, True,
                                                XmNscrollHorizontal, False,
                                                XmNeditMode, XmMULTI_LINE_EDIT,
                                                NULL);
    
    
        XtRealizeWidget(topShell);
        XtAppMainLoop(app);
    
        return 0;
    }