Getting XmText to save position of cursor for a tail like program - Motif

This is a discussion on Getting XmText to save position of cursor for a tail like program - Motif ; Hi, I have an XmText widget that displays data from a file, similar to the tail command. When the cursor is at the end of the display and new data is added, the cursor moves with the data. In my ...

+ Reply to Thread
Results 1 to 3 of 3

Thread: Getting XmText to save position of cursor for a tail like program

  1. Getting XmText to save position of cursor for a tail like program

    Hi,

    I have an XmText widget that displays data from a file, similar to the
    tail command. When the cursor is at the end of the display and new data
    is added, the cursor moves with the data. In my application, this is
    how things are normally supposed to work, so that the user always sees
    the latest data. The client wants to also be able to lock this
    movement, so that the cursor stays where it was located. For example,
    if the user scrolls up using the scrollbar, it should stay where they
    are currently looking. Note that the real program has a button to
    toggle this mode on or off. It seems that a XmText widget works for
    this lock mode only if the cursor is not at the bottom of the data.

    Below is a cut down version of the program. It adds data to the XmText
    widget every few seconds in this demo. Notice that the cursor is always
    at the end of the data if it starts there. If the cursor is moved (say
    up one line), then the XmText widget stays there while data is appended
    to it.

    My question is how do I get the XmText widget to keep the cursor where
    it was when the cursor was at the end of the data (if I am stating this
    clear) without a hack like progammatically moving the cursor up a line?

    Tim
    Replace nospam with execpc to reply via email.
    Also note that I do not have Usenet access at work, so there may be some
    delay to answer any questions.

    Example code:


    #include
    #include

    XtAppContext appContext;
    Widget textDisplay;

    static void updateTimer(XtPointer *client_data, XtIntervalId *id);

    static int timerDelay = 1500; /* timer update delay in milliseconds */

    /************************************************** ************************
    setUpdateTimer() - Sets the update timer callback function

    RETURN VALUE: None
    ************************************************** ************************/

    void setUpdateTimer(XtAppContext appContext)
    {
    XtAppAddTimeOut(
    appContext,
    timerDelay,
    (XtTimerCallbackProc)updateTimer,
    0
    );
    }

    /************************************************** ************************
    updateTimer() - Timer callback to load and display any new data

    RETURN VALUE: None
    ************************************************** ************************/

    static void updateTimer(XtPointer *client_data, XtIntervalId *id)
    {
    static int count=0;
    char data[256];

    XmTextPosition lastPos;

    /* add callback to ourself so we get called again */
    setUpdateTimer(appContext);

    sprintf(data,"data line %d\n", count);
    lastPos=XmTextGetLastPosition(textDisplay);
    XmTextReplace(textDisplay, lastPos, lastPos, data);
    count++;

    XmUpdateDisplay(textDisplay);
    }

    /************************************************** ************************
    createTextWidget() - Creates the main text widget for displaying the data.

    RETURN VALUE: The text widget
    ************************************************** ************************/

    Widget createTextWidget(Widget parent)
    {
    int ii;
    Arg args[25];

    ii=0;
    XtSetArg(args[ii], XmNeditMode, XmMULTI_LINE_EDIT);
    ii++;
    XtSetArg(args[ii], XmNeditable, False);
    ii++;
    XtSetArg(args[ii], XmNrows, 23);
    ii++;
    XtSetArg(args[ii], XmNcolumns, 80);
    ii++;
    XtSetArg(args[ii], XmNmarginWidth, 10);
    ii++;
    XtSetArg(args[ii], XmNmarginHeight, 10);
    ii++;
    XtSetArg(args[ii], XmNscrollHorizontal, False);
    ii++;
    XtSetArg(args[ii], XmNwordWrap, True);
    ii++;

    return XmCreateScrolledText(parent, "textDisplay", args, ii);
    }

    /************************************************** ************************
    main() -

    RETURN VALUE: None
    ************************************************** ************************/

    int main(int argc, char **argv)
    {
    Widget appShell;
    Widget mainWindow;
    Arg args[25];
    int ii;

    /* create the ApplicationShell widget */

    ii=0;
    XtSetArg(args[ii], XmNtitle, "Text");
    ii++;
    appShell=XtAppInitialize(
    &appContext,
    NULL,
    NULL,
    0,
    &argc,
    argv,
    NULL,
    args,
    ii
    );

    mainWindow = XmCreateMainWindow(appShell, "MainWindow", NULL, 0);

    textDisplay=createTextWidget(mainWindow);

    /* manage the widgets */
    XtManageChild(textDisplay);
    XtManageChild(mainWindow);

    /* Realize the widgets */
    XtRealizeWidget(appShell);

    setUpdateTimer(appContext);

    /* enter the event processing loop */
    XtAppMainLoop(appContext);

    return 0;
    }


  2. Re: Getting XmText to save position of cursor for a tail like program

    "Timothy J. Grunewald" wrote in message news:<3F554C36.1020101@nospam.com>...


    > I have an XmText widget that displays data from a file, similar to the
    > tail command. When the cursor is at the end of the display and new data
    > is added, the cursor moves with the data. In my application, this is
    > how things are normally supposed to work, so that the user always sees
    > the latest data. The client wants to also be able to lock this
    > movement, so that the cursor stays where it was located. For example,
    > if the user scrolls up using the scrollbar, it should stay where they
    > are currently looking. Note that the real program has a button to
    > toggle this mode on or off. It seems that a XmText widget works for
    > this lock mode only if the cursor is not at the bottom of the data.


    XmTextShowPosition may provide the behavior you want. Take a look at the
    code of the TextAppend funcion in my Motif version of xconsole:

    http://www.urisan.tche.br/~casantos/...ole-1.0.tar.gz

    --- Casantos

  3. Re: Getting XmText to save position of cursor for a tail like program

    Fred,

    Thanks for the info. To get the functionality that I wanted, I also had
    to get the value of the insert position before adding data to the text
    widget and then set it to the saved value. I also had to call
    XtVaSetValues() with XmNautoShowCursorPosition set to False. Now the
    demo program stays put no matter where the user scrolls the data. My
    revised demo program is shown below. Diffs are here:

    $ diff Text*.c
    43a44
    > XmTextPosition cursorPos;

    48a50,53
    >
    > cursorPos=XmTextGetCursorPosition(textDisplay);
    > XtVaSetValues(textDisplay, XmNautoShowCursorPosition, False, NULL);
    >

    50a56,58
    >
    > XmTextSetInsertionPosition(textDisplay, cursorPos);


    Tim

    #include
    #include

    XtAppContext appContext;
    Widget textDisplay;

    static void updateTimer(XtPointer *client_data, XtIntervalId *id);

    static int timerDelay = 1500; /* timer update delay in milliseconds */

    /************************************************** ************************
    setUpdateTimer() - Sets the update timer callback function

    RETURN VALUE: None
    ************************************************** ************************/

    void setUpdateTimer(XtAppContext appContext)
    {
    XtAppAddTimeOut(
    appContext,
    timerDelay,
    (XtTimerCallbackProc)updateTimer,
    0
    );
    }

    /************************************************** ************************
    updateTimer() - Timer callback to load and display any new data

    RETURN VALUE: None
    ************************************************** ************************/

    static void updateTimer(XtPointer *client_data, XtIntervalId *id)
    {
    static int count=0;
    char data[256];

    XmTextPosition lastPos;
    XmTextPosition cursorPos;

    /* add callback to ourself so we get called again */
    setUpdateTimer(appContext);

    sprintf(data,"data line %d\n", count);

    cursorPos=XmTextGetCursorPosition(textDisplay);
    XtVaSetValues(textDisplay, XmNautoShowCursorPosition, False, NULL);

    lastPos=XmTextGetLastPosition(textDisplay);
    XmTextReplace(textDisplay, lastPos, lastPos, data);

    XmTextSetInsertionPosition(textDisplay, cursorPos);

    count++;

    XmUpdateDisplay(textDisplay);
    }

    /************************************************** ************************
    createTextWidget() - Creates the main text widget for displaying the data.

    RETURN VALUE: The text widget
    ************************************************** ************************/

    Widget createTextWidget(Widget parent)
    {
    int ii;
    Arg args[25];

    ii=0;
    XtSetArg(args[ii], XmNeditMode, XmMULTI_LINE_EDIT);
    ii++;
    XtSetArg(args[ii], XmNeditable, False);
    ii++;
    XtSetArg(args[ii], XmNrows, 23);
    ii++;
    XtSetArg(args[ii], XmNcolumns, 80);
    ii++;
    XtSetArg(args[ii], XmNmarginWidth, 10);
    ii++;
    XtSetArg(args[ii], XmNmarginHeight, 10);
    ii++;
    XtSetArg(args[ii], XmNscrollHorizontal, False);
    ii++;
    XtSetArg(args[ii], XmNwordWrap, True);
    ii++;

    return XmCreateScrolledText(parent, "textDisplay", args, ii);
    }

    /************************************************** ************************
    main() -

    RETURN VALUE: None
    ************************************************** ************************/

    int main(int argc, char **argv)
    {
    Widget appShell;
    Widget mainWindow;
    Arg args[25];
    int ii;

    /* create the ApplicationShell widget */

    ii=0;
    XtSetArg(args[ii], XmNtitle, "Text");
    ii++;
    appShell=XtAppInitialize(
    &appContext,
    NULL,
    NULL,
    0,
    &argc,
    argv,
    NULL,
    args,
    ii
    );

    mainWindow = XmCreateMainWindow(appShell, "MainWindow", NULL, 0);

    textDisplay=createTextWidget(mainWindow);

    /* manage the widgets */
    XtManageChild(textDisplay);
    XtManageChild(mainWindow);

    /* Realize the widgets */
    XtRealizeWidget(appShell);

    setUpdateTimer(appContext);

    /* enter the event processing loop */
    XtAppMainLoop(appContext);

    return 0;
    }


    Fred L. Kleinschmidt wrote:
    >
    > "Timothy J. Grunewald" wrote:
    >
    >>Hi,
    >>
    >>I have an XmText widget that displays data from a file, similar to the
    >>tail command. When the cursor is at the end of the display and new data
    >>is added, the cursor moves with the data. In my application, this is
    >>how things are normally supposed to work, so that the user always sees
    >>the latest data. The client wants to also be able to lock this
    >>movement, so that the cursor stays where it was located. For example,
    >>if the user scrolls up using the scrollbar, it should stay where they
    >>are currently looking. Note that the real program has a button to
    >>toggle this mode on or off. It seems that a XmText widget works for
    >>this lock mode only if the cursor is not at the bottom of the data.
    >>
    >>Below is a cut down version of the program. It adds data to the XmText
    >>widget every few seconds in this demo. Notice that the cursor is always
    >>at the end of the data if it starts there. If the cursor is moved (say
    >>up one line), then the XmText widget stays there while data is appended
    >>to it.
    >>
    >>My question is how do I get the XmText widget to keep the cursor where
    >>it was when the cursor was at the end of the data (if I am stating this
    >>clear) without a hack like progammatically moving the cursor up a line?
    >>
    >>Tim
    >>Replace nospam with execpc to reply via email.
    >>Also note that I do not have Usenet access at work, so there may be some
    >>delay to answer any questions.
    >>
    >>Example code:
    >>
    >>#include
    >>#include
    >>
    >>XtAppContext appContext;
    >>Widget textDisplay;
    >>
    >>static void updateTimer(XtPointer *client_data, XtIntervalId *id);
    >>
    >>static int timerDelay = 1500; /* timer update delay in milliseconds */
    >>
    >>/************************************************** ************************
    >>setUpdateTimer() - Sets the update timer callback function
    >>
    >>RETURN VALUE: None
    >>************************************************** ************************/
    >>
    >>void setUpdateTimer(XtAppContext appContext)
    >>{
    >> XtAppAddTimeOut(
    >> appContext,
    >> timerDelay,
    >> (XtTimerCallbackProc)updateTimer,
    >> 0
    >> );
    >>}
    >>
    >>/************************************************** ************************
    >>updateTimer() - Timer callback to load and display any new data
    >>
    >>RETURN VALUE: None
    >>************************************************** ************************/
    >>
    >>static void updateTimer(XtPointer *client_data, XtIntervalId *id)
    >>{
    >> static int count=0;
    >> char data[256];
    >>
    >> XmTextPosition lastPos;
    >>
    >> /* add callback to ourself so we get called again */
    >> setUpdateTimer(appContext);
    >>
    >> sprintf(data,"data line %d\n", count);
    >> lastPos=XmTextGetLastPosition(textDisplay);
    >> XmTextReplace(textDisplay, lastPos, lastPos, data);
    >> count++;
    >>
    >> XmUpdateDisplay(textDisplay);
    >>}
    >>
    >>/************************************************** ************************
    >>createTextWidget() - Creates the main text widget for displaying the data.
    >>
    >>RETURN VALUE: The text widget
    >>************************************************** ************************/
    >>
    >>Widget createTextWidget(Widget parent)
    >>{
    >> int ii;
    >> Arg args[25];
    >>
    >> ii=0;
    >> XtSetArg(args[ii], XmNeditMode, XmMULTI_LINE_EDIT);
    >> ii++;
    >> XtSetArg(args[ii], XmNeditable, False);
    >> ii++;
    >> XtSetArg(args[ii], XmNrows, 23);
    >> ii++;
    >> XtSetArg(args[ii], XmNcolumns, 80);
    >> ii++;
    >> XtSetArg(args[ii], XmNmarginWidth, 10);
    >> ii++;
    >> XtSetArg(args[ii], XmNmarginHeight, 10);
    >> ii++;
    >> XtSetArg(args[ii], XmNscrollHorizontal, False);
    >> ii++;
    >> XtSetArg(args[ii], XmNwordWrap, True);
    >> ii++;
    >>
    >> return XmCreateScrolledText(parent, "textDisplay", args, ii);
    >>}
    >>
    >>/************************************************** ************************
    >>main() -
    >>
    >>RETURN VALUE: None
    >>************************************************** ************************/
    >>
    >>int main(int argc, char **argv)
    >>{
    >> Widget appShell;
    >> Widget mainWindow;
    >> Arg args[25];
    >> int ii;
    >>
    >> /* create the ApplicationShell widget */
    >>
    >> ii=0;
    >> XtSetArg(args[ii], XmNtitle, "Text");
    >> ii++;
    >> appShell=XtAppInitialize(
    >> &appContext,
    >> NULL,
    >> NULL,
    >> 0,
    >> &argc,
    >> argv,
    >> NULL,
    >> args,
    >> ii
    >> );
    >>
    >> mainWindow = XmCreateMainWindow(appShell, "MainWindow", NULL, 0);
    >>
    >> textDisplay=createTextWidget(mainWindow);
    >>
    >> /* manage the widgets */
    >> XtManageChild(textDisplay);
    >> XtManageChild(mainWindow);
    >>
    >> /* Realize the widgets */
    >> XtRealizeWidget(appShell);
    >>
    >> setUpdateTimer(appContext);
    >>
    >> /* enter the event processing loop */
    >> XtAppMainLoop(appContext);
    >>
    >> return 0;
    >>}

    >
    >
    > call:
    > XmTextSetInsertionPosition( textDisplay, lastPos );
    > after you modifyu the text.



+ Reply to Thread