Why PtListReplaceItemPos() might not work?

Hi,

At first I used PtSetResources() to update my PtList widget items. It works
fine, but has one major disadvantage. When I have a list long enough to be
scrolled, after every data update the list jumps to its topmost position. I
decided to check does the PtListReplaceItemPos() behaves the same way.
Unfortunately, the function doesn’t do anything (I mean anything visible) at
all. What is wrong in this example?

Thanks in advance,

Serge

/*

  • With ‘-f’ option program uses PtListReplaceItemPos()function to update
    list items.
  • By default Pt_ARG_ITEM is used.
    */
    #include <Pt.h>

int use_func;

void *thread( void *data )
{
PtWidget_t *list = (PtWidget_t *) data;
PtArg_t arg[ 1 ];
int i, j;
char *pitems[ 5 ];
char items[ 5 ][ 1024 ];
char *labels[ 5 ] = {
“Line 1”,
“Line 2”,
“Line 3”,
“Line 4”,
“Line 5”
};

for( i = 0; i < 5; i++ )
pitems[ i ] = items[ i ];

for( i = 0; ; i += 5 ) {
for( j = 0; j < 5; j++ )
sprintf( pitems[ j ], “%s\t%d\t%d”, labels[ j ], i + j, i +
j + 1 );

PtEnter( 0 );

if( use_func ) {
PtListReplaceItemPos( list, (const char **) pitems, 5, 1 );
}
else {
PtSetArg( &arg[ 0 ], Pt_ARG_ITEMS, pitems, 5 );
PtSetResources( list, 1, arg );
}

PtLeave( 0 );

delay( 1000 );
}

return NULL;
}


int main( int argc, char *argv[] )
{
int i, n;
PtArg_t arg[ 5 ];
PhArea_t area = {{ 0, 0 }, { 400, 400 }};
PtWidget_t *window, *list, *divider;
PhDim_t but[ 3 ] = {{100, 5}, {50, 5}, {50, 5}};
PtListColumnAttributes_t atr[ 3 ] = {
{ Pt_LIST_COLUMN_LEFT },
{ Pt_LIST_COLUMN_RIGHT },
{ Pt_LIST_COLUMN_RIGHT }
};
while( -1 != ( n = getopt( argc, argv, “f” ))) {
switch( n ) {
case ‘f’:

use_func = 1;
break;
}
}

if( -1 == PtInit( NULL )) {
perror( “PtInit()” );
PtExit( EXIT_FAILURE );
}

n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_WINDOW_TITLE, “PtList Test”, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );

if( NULL == ( window = PtCreateWidget( PtWindow, Pt_NO_PARENT, n, arg ))) {
perror( “PtCreateWidget()” );
PtExit( EXIT_FAILURE );
}

n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_LIST_COLUMN_ATTR, atr, 3 );
PtSetArg( &arg[ n++ ], Pt_ARG_LIST_FLAGS, Pt_TRUE, Pt_LIST_NON_SELECT );
PtSetArg( &arg[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_BOTTOM,
Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_BOTTOM );

list = PtCreateWidget( PtList, window, n, arg );

area.size.h = but[ 0 ].h;
n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_TOP,
Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_TOP );
divider = PtCreateWidget( PtDivider, list, n, arg );

for( i = 0; i < 3; i++ ) {
n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_DIM, &but[ i ], 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_FLAGS, Pt_FALSE, Pt_GETS_FOCUS );

PtCreateWidget( PtButton, divider, n, arg );
}

PtRealizeWidget( window );

pthread_create( NULL, NULL, thread, list );

PtMainLoop();

return( EXIT_SUCCESS );
}

The thing is that you have no items to replace. You have to have some data
into the list first and then you will be able to replace them.
-Misha.

“Serge Yuschenko” <serge.yuschenko@rogers.com> wrote in message
news:b05cgv$2v0$1@inn.qnx.com

Hi,

At first I used PtSetResources() to update my PtList widget items. It
works
fine, but has one major disadvantage. When I have a list long enough to be
scrolled, after every data update the list jumps to its topmost position.
I
decided to check does the PtListReplaceItemPos() behaves the same way.
Unfortunately, the function doesn’t do anything (I mean anything visible)
at
all. What is wrong in this example?

Thanks in advance,

Serge

/*

  • With ‘-f’ option program uses PtListReplaceItemPos()function to update
    list items.
  • By default Pt_ARG_ITEM is used.
    */
    #include <Pt.h

int use_func;

void *thread( void *data )
{
PtWidget_t *list = (PtWidget_t *) data;
PtArg_t arg[ 1 ];
int i, j;
char *pitems[ 5 ];
char items[ 5 ][ 1024 ];
char *labels[ 5 ] = {
“Line 1”,
“Line 2”,
“Line 3”,
“Line 4”,
“Line 5”
};

for( i = 0; i < 5; i++ )
pitems[ i ] = items[ i ];

for( i = 0; ; i += 5 ) {
for( j = 0; j < 5; j++ )
sprintf( pitems[ j ], “%s\t%d\t%d”, labels[ j ], i + j, i
+
j + 1 );

PtEnter( 0 );

if( use_func ) {
PtListReplaceItemPos( list, (const char **) pitems, 5,
1 );
}
else {
PtSetArg( &arg[ 0 ], Pt_ARG_ITEMS, pitems, 5 );
PtSetResources( list, 1, arg );
}

PtLeave( 0 );

delay( 1000 );
}

return NULL;
}


int main( int argc, char *argv[] )
{
int i, n;
PtArg_t arg[ 5 ];
PhArea_t area = {{ 0, 0 }, { 400, 400 }};
PtWidget_t *window, *list, *divider;
PhDim_t but[ 3 ] = {{100, 5}, {50, 5}, {50, 5}};
PtListColumnAttributes_t atr[ 3 ] = {
{ Pt_LIST_COLUMN_LEFT },
{ Pt_LIST_COLUMN_RIGHT },
{ Pt_LIST_COLUMN_RIGHT }
};
while( -1 != ( n = getopt( argc, argv, “f” ))) {
switch( n ) {
case ‘f’:

use_func = 1;
break;
}
}

if( -1 == PtInit( NULL )) {
perror( “PtInit()” );
PtExit( EXIT_FAILURE );
}

n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_WINDOW_TITLE, “PtList Test”, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );

if( NULL == ( window = PtCreateWidget( PtWindow, Pt_NO_PARENT, n, arg )))
{
perror( “PtCreateWidget()” );
PtExit( EXIT_FAILURE );
}

n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_LIST_COLUMN_ATTR, atr, 3 );
PtSetArg( &arg[ n++ ], Pt_ARG_LIST_FLAGS, Pt_TRUE, Pt_LIST_NON_SELECT );
PtSetArg( &arg[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_BOTTOM,
Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_BOTTOM );

list = PtCreateWidget( PtList, window, n, arg );

area.size.h = but[ 0 ].h;
n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_TOP,
Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_TOP );
divider = PtCreateWidget( PtDivider, list, n, arg );

for( i = 0; i < 3; i++ ) {
n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_DIM, &but[ i ], 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_FLAGS, Pt_FALSE, Pt_GETS_FOCUS );

PtCreateWidget( PtButton, divider, n, arg );
}

PtRealizeWidget( window );

pthread_create( NULL, NULL, thread, list );

PtMainLoop();

return( EXIT_SUCCESS );
}

Thank you Misha. Finally I figured this out. Probably this detail is worth
mentioning in the Library Reference as a note.

By the way. A couple more question about my example.

I create a PtDivider same width as its parent PtList. In this case
rightmost column of the list gets clipped too much if data in the column
is right justified. Is it the only solution to make PtDivider narrower
than its parent?

In the PtDivider default value for Pt_ARG_GROUP_SPACING is 0. In this case
there is a few pixels gap between buttons placed on this divider. When I
try to set the spacing to -1 or -2 the buttons get closer, but I loose
ability to change a column width with a mouse. Cursor just never turns to
“resize” mode.

Sincerely,

Serge

Misha Nefedov wrote:

The thing is that you have no items to replace. You have to have some data
into the list first and then you will be able to replace them.
-Misha.

“Serge Yuschenko” <> serge.yuschenko@rogers.com> > wrote in message
news:b05cgv$2v0$> 1@inn.qnx.com> …
Hi,

At first I used PtSetResources() to update my PtList widget items. It
works
fine, but has one major disadvantage. When I have a list long enough to be
scrolled, after every data update the list jumps to its topmost position.
I
decided to check does the PtListReplaceItemPos() behaves the same way.
Unfortunately, the function doesn’t do anything (I mean anything visible)
at
all. What is wrong in this example?

Thanks in advance,

Serge

/*

  • With ‘-f’ option program uses PtListReplaceItemPos()function to update
    list items.
  • By default Pt_ARG_ITEM is used.
    */
    #include <Pt.h

int use_func;

void *thread( void *data )
{
PtWidget_t *list = (PtWidget_t *) data;
PtArg_t arg[ 1 ];
int i, j;
char *pitems[ 5 ];
char items[ 5 ][ 1024 ];
char *labels[ 5 ] = {
“Line 1”,
“Line 2”,
“Line 3”,
“Line 4”,
“Line 5”
};

for( i = 0; i < 5; i++ )
pitems[ i ] = items[ i ];

for( i = 0; ; i += 5 ) {
for( j = 0; j < 5; j++ )
sprintf( pitems[ j ], “%s\t%d\t%d”, labels[ j ], i +
j, i
+
j + 1 );

PtEnter( 0 );

if( use_func ) {
PtListReplaceItemPos( list, (const char **) pitems, 5,
1 );
}
else {
PtSetArg( &arg[ 0 ], Pt_ARG_ITEMS, pitems, 5 );
PtSetResources( list, 1, arg );
}

PtLeave( 0 );

delay( 1000 );
}

return NULL;
}


int main( int argc, char *argv[] )
{
int i, n;
PtArg_t arg[ 5 ];
PhArea_t area = {{ 0, 0 }, { 400, 400 }};
PtWidget_t *window, *list, *divider;
PhDim_t but[ 3 ] = {{100, 5}, {50, 5}, {50, 5}};
PtListColumnAttributes_t atr[ 3 ] = {
{ Pt_LIST_COLUMN_LEFT },
{ Pt_LIST_COLUMN_RIGHT },
{ Pt_LIST_COLUMN_RIGHT }
};
while( -1 != ( n = getopt( argc, argv, “f” ))) {
switch( n ) {
case ‘f’:

use_func = 1;
break;
}
}

if( -1 == PtInit( NULL )) {
perror( “PtInit()” );
PtExit( EXIT_FAILURE );
}

n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_WINDOW_TITLE, “PtList Test”, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );

if( NULL == ( window = PtCreateWidget( PtWindow, Pt_NO_PARENT, n, arg )))
{
perror( “PtCreateWidget()” );
PtExit( EXIT_FAILURE );
}

n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_LIST_COLUMN_ATTR, atr, 3 );
PtSetArg( &arg[ n++ ], Pt_ARG_LIST_FLAGS, Pt_TRUE, Pt_LIST_NON_SELECT );
PtSetArg( &arg[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_BOTTOM,
Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_BOTTOM );

list = PtCreateWidget( PtList, window, n, arg );

area.size.h = but[ 0 ].h;
n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_TOP,
Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_TOP );
divider = PtCreateWidget( PtDivider, list, n, arg );

for( i = 0; i < 3; i++ ) {
n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_DIM, &but[ i ], 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_FLAGS, Pt_FALSE, Pt_GETS_FOCUS );

PtCreateWidget( PtButton, divider, n, arg );
}

PtRealizeWidget( window );

pthread_create( NULL, NULL, thread, list );

PtMainLoop();

return( EXIT_SUCCESS );
}

“Serge Yuschenko” <serge.yuschenko@rogers.com> wrote in message
news:b06h33$gaf$1@tiger.openqnx.com

Thank you Misha. Finally I figured this out. Probably this detail is worth
mentioning in the Library Reference as a note.

By the way. A couple more question about my example.

I create a PtDivider same width as its parent PtList. In this case
rightmost column of the list gets clipped too much if data in the column
is right justified. Is it the only solution to make PtDivider narrower
than its parent?
The width of you divider is the same as the list width, this is not what

you want.
What you want is probably this:
{
/* Calculate the internal width of the list */
PhRect_t r = PtCalcCanvas( list, NULL );
/
This width should be given to the divider. */
area.size.w = r->lr.x - r->ul.x + 1;
}

In the PtDivider default value for Pt_ARG_GROUP_SPACING is 0. In this case
there is a few pixels gap between buttons placed on this divider. When I
try to set the spacing to -1 or -2 the buttons get closer, but I loose
ability to change a column width with a mouse. Cursor just never turns to
“resize” mode.
I would suggest to play with the Pt_ARG_BASIC_FLAGS of the header buttons.

I am sure that you need at least to disable the Pt_ALL_ETHES.
-Misha.

Sincerely,

Serge

Misha Nefedov wrote:

The thing is that you have no items to replace. You have to have some
data
into the list first and then you will be able to replace them.
-Misha.

“Serge Yuschenko” <> serge.yuschenko@rogers.com> > wrote in message
news:b05cgv$2v0$> 1@inn.qnx.com> …
Hi,

At first I used PtSetResources() to update my PtList widget items. It
works
fine, but has one major disadvantage. When I have a list long enough
to be
scrolled, after every data update the list jumps to its topmost
position.
I
decided to check does the PtListReplaceItemPos() behaves the same way.
Unfortunately, the function doesn’t do anything (I mean anything
visible)
at
all. What is wrong in this example?

Thanks in advance,

Serge

/*

  • With ‘-f’ option program uses PtListReplaceItemPos()function to
    update
    list items.
  • By default Pt_ARG_ITEM is used.
    */
    #include <Pt.h

int use_func;

void *thread( void *data )
{
PtWidget_t *list = (PtWidget_t *) data;
PtArg_t arg[ 1 ];
int i, j;
char *pitems[ 5 ];
char items[ 5 ][ 1024 ];
char *labels[ 5 ] = {
“Line 1”,
“Line 2”,
“Line 3”,
“Line 4”,
“Line 5”
};

for( i = 0; i < 5; i++ )
pitems[ i ] = items[ i ];

for( i = 0; ; i += 5 ) {
for( j = 0; j < 5; j++ )
sprintf( pitems[ j ], “%s\t%d\t%d”, labels[ j ], i
+
j, i
+
j + 1 );

PtEnter( 0 );

if( use_func ) {
PtListReplaceItemPos( list, (const char **) pitems, 5,
1 );
}
else {
PtSetArg( &arg[ 0 ], Pt_ARG_ITEMS, pitems, 5 );
PtSetResources( list, 1, arg );
}

PtLeave( 0 );

delay( 1000 );
}

return NULL;
}


int main( int argc, char *argv[] )
{
int i, n;
PtArg_t arg[ 5 ];
PhArea_t area = {{ 0, 0 }, { 400, 400 }};
PtWidget_t *window, *list, *divider;
PhDim_t but[ 3 ] = {{100, 5}, {50, 5}, {50, 5}};
PtListColumnAttributes_t atr[ 3 ] = {
{ Pt_LIST_COLUMN_LEFT },
{ Pt_LIST_COLUMN_RIGHT },
{ Pt_LIST_COLUMN_RIGHT }
};
while( -1 != ( n = getopt( argc, argv, “f” ))) {
switch( n ) {
case ‘f’:

use_func = 1;
break;
}
}

if( -1 == PtInit( NULL )) {
perror( “PtInit()” );
PtExit( EXIT_FAILURE );
}

n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_WINDOW_TITLE, “PtList Test”, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );

if( NULL == ( window = PtCreateWidget( PtWindow, Pt_NO_PARENT, n,
arg )))
{
perror( “PtCreateWidget()” );
PtExit( EXIT_FAILURE );
}

n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_LIST_COLUMN_ATTR, atr, 3 );
PtSetArg( &arg[ n++ ], Pt_ARG_LIST_FLAGS, Pt_TRUE,
Pt_LIST_NON_SELECT );
PtSetArg( &arg[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_BOTTOM,
Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_BOTTOM );

list = PtCreateWidget( PtList, window, n, arg );

area.size.h = but[ 0 ].h;
n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_AREA, &area, 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_ANCHOR_FLAGS, Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_TOP,
Pt_LEFT_ANCHORED_LEFT |
Pt_RIGHT_ANCHORED_RIGHT |
Pt_TOP_ANCHORED_TOP |
Pt_BOTTOM_ANCHORED_TOP );
divider = PtCreateWidget( PtDivider, list, n, arg );

for( i = 0; i < 3; i++ ) {
n = 0;
PtSetArg( &arg[ n++ ], Pt_ARG_DIM, &but[ i ], 0 );
PtSetArg( &arg[ n++ ], Pt_ARG_FLAGS, Pt_FALSE, Pt_GETS_FOCUS );

PtCreateWidget( PtButton, divider, n, arg );
}

PtRealizeWidget( window );

pthread_create( NULL, NULL, thread, list );

PtMainLoop();

return( EXIT_SUCCESS );
}



\

Thanks again.

All you suggested works just fine. Although solutions don’t look obvious
to me. After reading documentation I couldn’t have came up with this. At
least not right away.

Serge


Misha Nefedov wrote:

“Serge Yuschenko” <> serge.yuschenko@rogers.com> > wrote in message
news:b06h33$gaf$> 1@tiger.openqnx.com> …
Thank you Misha. Finally I figured this out. Probably this detail is worth
mentioning in the Library Reference as a note.

By the way. A couple more question about my example.

I create a PtDivider same width as its parent PtList. In this case
rightmost column of the list gets clipped too much if data in the column
is right justified. Is it the only solution to make PtDivider narrower
than its parent?
The width of you divider is the same as the list width, this is not what
you want.
What you want is probably this:
{
/* Calculate the internal width of the list */
PhRect_t r = PtCalcCanvas( list, NULL );
/
This width should be given to the divider. */
area.size.w = r->lr.x - r->ul.x + 1;
}

In the PtDivider default value for Pt_ARG_GROUP_SPACING is 0. In this case
there is a few pixels gap between buttons placed on this divider. When I
try to set the spacing to -1 or -2 the buttons get closer, but I loose
ability to change a column width with a mouse. Cursor just never turns to
“resize” mode.
I would suggest to play with the Pt_ARG_BASIC_FLAGS of the header buttons.
I am sure that you need at least to disable the Pt_ALL_ETHES.
-Misha.

[snip]