Home
Developer Resources
QNX RTOS v4
QNX RTOS v4 Knowledge Base

QNX RTOS v4 Knowledge Base

Foundry27
Foundry27
QNX RTOS v4 project
Resources

QNX RTOS v4 Knowledge Base

Title How do I scroll the MultiText edit fields in my Photon application?
Ref. No. QNX.000009302
Category(ies) Development
Issue My Photon application includes forms for data entry. For some of the data-entry fields, I use MultiText widgets. Mostly, these work fine, except when descriptions get very long. What I need is a way to scroll the MultiText edit fields. Is this easy to do?


Solution In short, yes it is. In fact, here at QNX we are in the process of enhancing the MultiText widget with capabilities like scrollbars and tab expansion to make working with larger bodies of text more manageable. In the meantime, it's still easy to add scrolling programatically, as I've illustrated below.

To keep things intelligible, I've provided a complete working example. Note, however, that you don't have to "hand-code" the main() function to create a main window, MultiText widget, slider, and so on. You can do all that interactively within the Photon Application Builder (PhAB). As you are about to see, to add scrolling functionality you only have to write a few lines of code.
x09For more ways to simplify and extend your control over PtMultiText resources, see the several convenience functions we've provided, including PtMultiTextInfo().

/**************************************************************/
/** This example illustrates two forms of scrolling forx09**/
/** PtMultiText widgets : character-based and line-basedx09**/
/**************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <Ph.h>
#include <Pt.h>

FtWidget_t *window, *line_text, *char_text, *line_slider; *char_slider;

// Forward declaration.
int char_scroll( PtWidget_t *, void *data, PtCallbackinfo_t *);
int char_textcb( PtWidget_t *, void *, PtCallbackinfo_t *);
int line_scroll( PtWidget_t *, void *, PtCallbackinfo_t *);
int line_textcb( PtWidget_t *, void *, PtCallbackinfo_t *);

// Everything in main() can be done interactively in PhAB!

main()
{
x09PhArea_t area;
x09PtArg_t argt[10];
x09PtCallback_t callbacks[]=
x09{
x09x09{ line_textcb, NULL },// line text widget motion callback
x09x09{ line_scroll, NULL },// line text widget's companion slider's callback
x09x09{ char_textcb, NULL },// col text widget motion callback
x09x09{ char_scroll, NULL },// col text widget's companion slider's callback

x09// Create our main window. It will automatically
x09// size to fit the widgets we place inside it.
x09window = PtAppInit( NULL, NULL, NULL, 0, NULL );

x09// Create a MultiText widget for line scrolling
x09area.pos.x = 14;
x09area.pos.y = 28;
x09area.size.w = 210;
x09area.size.h = 138;
x09PtSetArg( &argt[0], Pt_ARG_AREA, {&area, 0 );
x09PtSetArg( &argt[1], Pt_CB_MOTION_VERIFY, &callbacks[0], 1 );
x09line_text = PtCreateWidget( PtMultiText, NULL, 2, argt );

x09// Create a MultiText widget for character scrolling
x09area.pos.x = 282;
x09PtSetArg( &argt[0], Pt_ARG_AREA, &area, 0 );
x09PtSetArg( &argt[1], Pt_CB_MOTION_VERIFY, &callbacks[2], 1 );
x09char_text = PtCreateWidget( PtMultiText, NULL, 2, argt );

x09// Create a Slider to control line scrolling of "line_text"
x09area.pos.x = 227;
x09area.pos.y = 21;
x09area.size.w = 18;
x09area.size.h = 155;
x09// This resource set is used by the next widget as well!!
x09PtSetArg( &argt[0], Pt_ARG_AREA, &area, 0 );
x09PtSetArg( &argt[1], Pt_ARG_BORDER_WIDTH, 1, 0 );
x09PtSetArg( &argt[2], Pt_ARG_FLAGS, Pt_SET, Pt_SET | Pt_GETS_FOCUS );
x09PtSetArg( &argt[3], Pt_ARG_SLIDER_FLAGS, Pt_FALSE, Pt_TRUE );
x09PtSetArg( &argt[4], Pt_ARG_SLIDER_HANDLE_HEIGHT, 14, 0 );
x09PtSetArg( &argt[5], Pt_ARG_SLIDER_THROUGH_SIZE, 16, 0 );
x09PtSetArg( &argt[6], Pt_ARG_GAUGE_MAXIMUM, 1, 0 );
x09PtSetArg( &argt[7], Pt_ARG_GAUGE_ORIENTATION, Pt_VERTICAL, 0 );
x09PtSetArg( &argt[8], Pt_ARG_GAUGE_MINIMUM, 1, 0 );
x09PtSetArg( &argt[9], Pt_CB_SLIDER_MOVE, &callbacks[1], 1 );
x09line_slider = PtCreateWidget( PtSlider, NULL, 10, argt );

x09// Create a Slider to control character scrolling of "char_text"
x09// use same resources as line_slider
x09// ( except change the last two, and modify the contents of area )
x09area.pos.x = 495;
x09PtSetArg( &argt[8], Pt_ARG_GAUGE_MINIMUM, 0, 0 );
x09PtSetArg( &argt[9], Pt_CB_SLIDER_MOVE, &callbacks[3], 1 );
x09char_slider = PtCreateWidget( PtSlider, NULL, 10, argt );

x09// Label stuff.
x09area.pos.x = 9;
x09area.pos.y = 6;
x09PtSetArg( &argt[0], Pt_ARG_POS, &area.pos, 0 );
x09PtSetArg( &argt[1], Pt_ARG_TEXT_STRING, "Line Scrolling", 0 );
x09PtCreateWidget( PtLabel, 0, 2, argt );

x09area.pos.x = 277;
x09PtSetArg( &argt[1], Pt_ARG_TEXT_STRING, "Character Scrolling", 0 );
x09PtCreateWidget( PtLabel, 0, 2, argt );

x09PtRealizeWidget( window );
x09PtMainLoop();

}

/*******************************/
/* Character-based scrollingx09*/
/*******************************/
// slider minimum should be set to 0.

int
char_scroll( PtWidget_t *widget, void *data, PtCallbackinfo_t *cbinfo )
{
x09PtSliderCallback_t *slider = (PtSliderCallback_t *)cbinfo->cbdata;
x09PtArg_t argt;
x09widget = widget;

x09/*** Handle Scrolling ***/
x09PtSetArg( &argt, Pt_ARG_CURSOR_POSITION, slider->position, 0 );
x09PtSetResources( char_text, 1, &argt );

x09return( PT_CONTINUE );

// This callback is attached to a motion_verify callback
//of a MultiText widget. So "widget" is an instance of a MultiText.
int

char_textcb( PtWidget_t *widget, void *data, PtCallbackinfo_t *cbinfo )
{
x09PtMultiTextCallback_t *mtcb = (PtMultiTextCallback_t *) cbinfo->cbdata;
x09PtArg_t argt[2];
x09int num;

x09widget = widget, data = data;

x09/*** Update slider Maximum and Position ***/
x09PtMultiTextGetAttributes( widget, -1, NULL, NULL, &num );
x09PtSetArg( &argt[0], Pt_ARG_GAUGE_MAXIMUM, num, 0 );
x09PtSetArg( &argt[1], Pt_ARG_GAUGE_VALUE, mtcb->new_insert, 0 );
x09PtSetResources( char_slider, 2, argt );

x09return( Pt_CONTINUE );

}

/**************************/
/* Line-based scrollingx09*/
/**************************/
// Slider minimum should be set to 1.

int
line_scroll( PtWidget_t *widget, void *data, PtCallbackinfo_t *cbinfo )
{
x09PtSliderCallback_t *slider = (PtSliderCallback_t *)cbinto->cbdata;
x09PtArg_t argt;
x09int offset;
x09widget = widget, data = data;

x09/*** Handle Scrolling ***/
x09PtMultiTextInfo( line_text, Pt_MT_QUERY_LINE, &offset, &slider->position,
x09x09NULL, NULL, NULL, NULL, NULL, NULL );
x09PtSetArg( &argt, Pt_ARG_CURSOR_POSITION, offset, 0 );
x09PtSetResources( line_text, 1, &argt );

x09return( PT_CONTINUE );

}

// This callback is attached to a motion_verity callback
// of a MultiText widget. So "widget" is an instance of a MultiText.
int
line_textcb( PtWidget_t *widget, void *data, PtCallbackinfo_t *cbinfo )
{
x09PtMultiTextCallback_t *mtcb = (PtMultiTextCallback_t *) cbinfo->cbdata;
x09PtArg_t argt[2];
x09int pos -1, line_num;

x09widget = widget, data = data;

x09/*** Update slider Max lines ***/
x09PtMultiTextinfo( widget, Pt_MT_QUERY_CHAR, &pos, &line_num,
x09x09NULL, NULL, NULL, NULL, NULL, NULL );
x09PtSetArg( &argt[0], Pt_ARG_GAUGE_MAXIMUM, line_num, 0 );

x09/*** Update slider value (current line) ***/
x09pos = mtcb->new_insert;
x09PtMultiTextinfo( widget, Pt_MT_GUERY_CHAR, &pos, &line_num, 0 );
x09x09NULL, NULL, NULL, NULL, NULL, NULL );
x09PtSetArg( &argt[1), Pt_ARG_GAUGE_VALUE, line_num, 0 );
x09PtSetResources( line_slider, 2, argt );

x09return( PT_CONTINUE );
}