Files correlati : Ricompilazione Demo : [ ] Commento : Allineato main trunk alla versione a 32 bit. git-svn-id: svn://10.65.10.50/trunk@10282 c028cbd2-c16b-5b4b-a496-9718f37d4682
4361 lines
122 KiB
C
Executable File
4361 lines
122 KiB
C
Executable File
/*******************************************************************************
|
|
* Copyright 1991-1996 by ORCA Software, Inc. *
|
|
* *
|
|
* All rights reserved. May not be reproduced or distributed, in printed or *
|
|
* electronic form, without permission of ORCA Software, Inc. May not be *
|
|
* distributed as object code, separately or linked with other object modules, *
|
|
* without permission. *
|
|
*******************************************************************************/
|
|
#define XI_INTERNAL
|
|
#define XI_R3_COMPAT
|
|
#include "xi.h"
|
|
#include "xitext.h"
|
|
#include "xistx.h"
|
|
#include "xilm.h"
|
|
#include "xilmst.h"
|
|
#include "xiutils.h"
|
|
#include "xi_int.h"
|
|
|
|
#if XIWS == XIWS_XM
|
|
#include <X11/Xatom.h>
|
|
#include <X11/Intrinsic.h>
|
|
#include <Xm/Xm.h>
|
|
#endif
|
|
|
|
#define MAXPIX 6000
|
|
|
|
#define VRCT_TO_PRCT( rp ) \
|
|
( rp )->left -= cur_delta_x; \
|
|
( rp )->right -= cur_delta_x; \
|
|
( rp )->top -= cur_delta_y; \
|
|
( rp )->bottom -= cur_delta_y;
|
|
|
|
|
|
/* ERROR CODES 20000-20089 */
|
|
|
|
BOOLEAN xi_false = FALSE;
|
|
void xi_finish_interface_create( XinWindow win );
|
|
extern XI_OBJ *xi_creating_itf;
|
|
|
|
static int xi_send_event( XI_OBJ * xi_obj, XinEvent * ep, BOOLEAN do_subtree );
|
|
|
|
#ifndef NO_PRIMARY_SELECTION
|
|
#if XIWS == XIWS_XM
|
|
|
|
static XI_OBJ *rp_xi_obj = NULL;
|
|
|
|
static void
|
|
receive_primesel( Widget widget, XtPointer data, Atom * selection,
|
|
Atom * type, XtPointer value, unsigned long *length, int *format )
|
|
{
|
|
char *s;
|
|
XinWindow win;
|
|
char *p;
|
|
|
|
/* printf("receive_primesel: ENTERED, widget %d, selection %d, type %d\n",
|
|
* widget, *selection, *type); */
|
|
/* printf(" length %d, format %d\n", length,
|
|
* *format); */
|
|
|
|
/* check if request for primary selection was successful */
|
|
if ( *selection != XA_PRIMARY || *type != XA_STRING || *format != 8 )
|
|
{
|
|
/* printf("receive_primesel: get primary selection failed\n"); */
|
|
return;
|
|
}
|
|
|
|
/* allocate space and fill in text from selection value */
|
|
s = XinMemoryAlloc( *length + 1 );
|
|
/* Assertion for out of memory? */
|
|
strncpy( s, ( char * ) value, *length );
|
|
s[*length] = '\0';
|
|
/* printf("receive_primesel: primary selection text = '%s'\n", s); */
|
|
XtFree( ( char * ) value ); /* this must be freed with XtFree */
|
|
|
|
/* xvt_dm_post_note("Text from Primary selection is '%s'", s); */
|
|
if ( rp_xi_obj )
|
|
{
|
|
win = xi_get_window( rp_xi_obj );
|
|
rp_xi_obj = NULL;
|
|
for ( p = s; *p != '\0'; ++p )
|
|
{
|
|
XinEvent ev;
|
|
|
|
MEMCLEAR( ev );
|
|
ev.type = XinEventCharacter;
|
|
ev.v.character.ch = ( unsigned char ) *p;
|
|
xi_event( win, &ev );
|
|
XinWindowPaintForce( win );
|
|
}
|
|
}
|
|
XinMemoryFree( s );
|
|
}
|
|
|
|
|
|
static void
|
|
get_primary_selection( XI_OBJ * itf, XinWindow win )
|
|
{
|
|
Widget widget;
|
|
|
|
rp_xi_obj = itf;
|
|
|
|
/* printf("get_primary_selection: ENTERED, win %d\n", win); */
|
|
|
|
/* request PRIMARY selection */
|
|
if ( rp_xi_obj {
|
|
widget = ( Widget ) XinWindowWidgetGet( win );
|
|
XtGetSelectionValue( widget, XA_PRIMARY, XA_STRING, receive_primesel, NULL,
|
|
XtLastTimestampProcessed( XtDisplay( widget ) ) );
|
|
}
|
|
|
|
/* printf("get_primary_selection: returning\n"); */
|
|
}
|
|
|
|
#endif
|
|
#endif
|
|
|
|
BOOLEAN
|
|
call_cb( XI_OBJ * itf, XI_EVENT * xiev )
|
|
{
|
|
XI_ITF_DATA *itf_data;
|
|
|
|
itf_data = itf->v.itf;
|
|
itf_data->in_callback++;
|
|
XinCoalesceInvalidates( itf_data->xin_win, TRUE );
|
|
( *itf_data->xi_eh ) ( ( struct _xi_obj * ) itf, xiev );
|
|
#ifdef WINRUNNER
|
|
xir_record( itf, xiev );
|
|
#endif
|
|
if ( xi_is_itf( itf ) )
|
|
{
|
|
XinCoalesceInvalidates( itf_data->xin_win, FALSE );
|
|
itf_data->in_callback--;
|
|
if ( itf_data->in_callback == 0 && itf_data->closing )
|
|
{
|
|
itf_data->closing = FALSE;
|
|
xi_close_window_internal( itf );
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static long
|
|
event_to_longchar( XinEvent * ep )
|
|
{
|
|
long c = ep->v.character.ch;
|
|
|
|
if ( ep->v.character.control )
|
|
c |= XI_MOD_CONTROL;
|
|
if ( ep->v.character.shift )
|
|
c |= XI_MOD_SHIFT;
|
|
if ( ep->v.character.alt )
|
|
c |= XI_MOD_ALT;
|
|
return ( c );
|
|
}
|
|
|
|
void
|
|
xi_column_set_pixel_width( XI_OBJ * column, int width )
|
|
{
|
|
int i;
|
|
XI_LIST_DATA *list;
|
|
LM_DATA *lm_data;
|
|
|
|
list = column->parent->v.list;
|
|
lm_data = ( LM_DATA * ) list->lm;
|
|
if ( column->type != XIT_COLUMN )
|
|
XinError( 20010, XinSeverityFatal, 0L );
|
|
lm_column_set_pixel_width( list->lm, xi_obj_to_idx( column ), width );
|
|
if ( list->sb_win && ( !list->width ) )
|
|
xi_move_list_scroll_bar( column->parent );
|
|
i = xi_obj_to_idx( column );
|
|
if ( i < lm_data->fixed_columns && list->hsb_win )
|
|
xi_move_list_hscroll_bar( column->parent );
|
|
}
|
|
|
|
void
|
|
xi_set_column_width( XI_OBJ * column, int width )
|
|
{
|
|
int width_in_chars;
|
|
|
|
if ( xi_get_xil_pref( column->itf ) )
|
|
width_in_chars = width;
|
|
else
|
|
width_in_chars = width / XI_FU_MULTIPLE;
|
|
|
|
xi_column_set_pixel_width( column, width_in_chars
|
|
* ( ( LM_DATA * ) column->parent->v.list->lm )
|
|
->pix_char_width );
|
|
}
|
|
|
|
static XI_OBJ *
|
|
xi_get_default( XI_OBJ * obj )
|
|
{
|
|
XI_OBJ **objlist;
|
|
XI_OBJ *temp;
|
|
int n;
|
|
|
|
temp = obj->itf->v.itf->focus_obj;
|
|
if ( temp != NULL && temp->type == XIT_BTN )
|
|
return temp;
|
|
|
|
if ( obj->type == XIT_BTN && obj->v.btn->dflt )
|
|
return obj;
|
|
|
|
switch ( obj->type )
|
|
{
|
|
case XIT_GROUP:
|
|
case XIT_CELL:
|
|
case XIT_ROW:
|
|
return NULL;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* search in child list */
|
|
objlist = xi_get_member_list( obj, &n );
|
|
for ( ; n > 0; n--, objlist++ )
|
|
{
|
|
/* call recursively for generality in future versions */
|
|
if ( ( temp = xi_get_default( *objlist ) ) != NULL )
|
|
return temp;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static XI_OBJ *
|
|
xi_get_cancel( XI_OBJ * obj )
|
|
{
|
|
XI_OBJ **objlist;
|
|
XI_OBJ *temp;
|
|
int n;
|
|
|
|
if ( obj->type == XIT_BTN && obj->v.btn->cancel )
|
|
return obj;
|
|
|
|
switch ( obj->type )
|
|
{
|
|
case XIT_GROUP:
|
|
case XIT_CELL:
|
|
case XIT_ROW:
|
|
return NULL;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* search in child list */
|
|
objlist = xi_get_member_list( obj, &n );
|
|
for ( ; n > 0; n--, objlist++ )
|
|
{
|
|
/* call recursively for generality in future versions */
|
|
if ( ( temp = xi_get_cancel( *objlist ) ) != NULL )
|
|
return temp;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
XI_OBJ *
|
|
xi_get_obj_from_mnemonic( XI_OBJ * obj, char ch )
|
|
{
|
|
XI_OBJ **objlist;
|
|
XI_OBJ *temp;
|
|
int n;
|
|
|
|
if ( obj->type == XIT_BTN && toupper( obj->v.btn->mnemonic ) == toupper( ch ) )
|
|
return obj;
|
|
if ( obj->type == XIT_FIELD && toupper( obj->v.field->mnemonic ) == toupper( ch ) )
|
|
return obj;
|
|
|
|
switch ( obj->type )
|
|
{
|
|
case XIT_GROUP:
|
|
case XIT_CELL:
|
|
case XIT_ROW:
|
|
return NULL;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* search in child list */
|
|
objlist = xi_get_member_list( obj, &n );
|
|
for ( ; n > 0; n--, objlist++ )
|
|
{
|
|
/* call recursively for generality in future versions */
|
|
if ( ( temp = xi_get_obj_from_mnemonic( *objlist, ch ) ) != NULL )
|
|
return temp;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
xi_hscroll_internal( XI_OBJ * xi_obj, int nbr_lines, int pos )
|
|
{
|
|
XI_OBJ *itf;
|
|
XI_OBJ *focus;
|
|
LM lm = xi_obj->v.list->lm;
|
|
|
|
itf = xi_obj->parent;
|
|
focus = xi_get_focus( itf );
|
|
if ( focus && focus->parent == xi_obj )
|
|
{
|
|
if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
|
|
{
|
|
lm_hscroll( lm, nbr_lines, pos );
|
|
}
|
|
else
|
|
{
|
|
if ( xi_move_focus( itf ) )
|
|
lm_hscroll( lm, nbr_lines, pos );
|
|
}
|
|
}
|
|
else
|
|
lm_hscroll( lm, nbr_lines, pos );
|
|
}
|
|
|
|
void
|
|
xi_hscroll( XI_OBJ * xi_obj, int nbr_lines )
|
|
{
|
|
xi_hscroll_internal( xi_obj, nbr_lines, 0 );
|
|
}
|
|
|
|
static void
|
|
control_event_hscroll( XI_OBJ * xi_obj, int nbr_lines, int pos )
|
|
{
|
|
XI_LIST_DATA *list_data;
|
|
XI_OBJ *other_list;
|
|
|
|
list_data = xi_obj->v.list;
|
|
xi_hscroll_internal( xi_obj, nbr_lines, pos );
|
|
if ( list_data->horz_sync_list &&
|
|
!list_data->scrolling_in_progress )
|
|
{
|
|
list_data->scrolling_in_progress = TRUE;
|
|
other_list = xi_get_obj( xi_obj->itf, list_data->horz_sync_list );
|
|
if ( other_list )
|
|
xi_hscroll_internal( other_list, nbr_lines, pos );
|
|
list_data->scrolling_in_progress = FALSE;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_control_event_scroll( XI_OBJ * xi_obj, int nbr_lines, int percent,
|
|
BOOLEAN same_cell )
|
|
{
|
|
XI_LIST_DATA *list_data;
|
|
XI_OBJ *other_list;
|
|
|
|
list_data = xi_obj->v.list;
|
|
xi_scroll_internal( xi_obj, nbr_lines, percent, same_cell );
|
|
if ( list_data->vert_sync_list &&
|
|
!list_data->scrolling_in_progress )
|
|
{
|
|
list_data->scrolling_in_progress = TRUE;
|
|
other_list = xi_get_obj( xi_obj->itf,
|
|
list_data->vert_sync_list );
|
|
if ( other_list )
|
|
xi_scroll_internal( other_list, nbr_lines, percent, same_cell );
|
|
list_data->scrolling_in_progress = FALSE;
|
|
}
|
|
}
|
|
|
|
static void
|
|
control_event( XI_OBJ * itf, XinWindow win, XinEvent * ep )
|
|
{
|
|
XI_ITF_DATA *itf_data;
|
|
XI_OBJ *xi_obj;
|
|
|
|
itf_data = itf->v.itf;
|
|
win = itf_data->xin_win;
|
|
if ( ep->v.control.control_id == XI_MULTILINE_SCROLLBAR_CID )
|
|
{
|
|
XI_TEXT *text;
|
|
|
|
text = xi_text_focus_get( itf_data->xin_win );
|
|
if ( text && xi_text_editing_is( text ) )
|
|
xi_text_event( text, ep, FALSE, NULL );
|
|
return;
|
|
}
|
|
if ( ( xi_obj = xi_get_obj( itf, ep->v.control.control_id ) ) != NULL )
|
|
{
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_FIELD:
|
|
{
|
|
XI_TEXT *text;
|
|
|
|
text = stx_xi_text_get( xi_obj->v.field->stx );
|
|
if ( text ) /* && xi_text_editing_is( text ) ) */
|
|
xi_text_event( text, ep, FALSE, NULL );
|
|
return;
|
|
}
|
|
case XIT_BTN:
|
|
{
|
|
XI_EVENT xiev;
|
|
|
|
XinWindow front_win = XinWindowFocusGet( );
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = xi_obj;
|
|
call_cb( itf, &xiev );
|
|
|
|
if ( xi_is_itf( itf ) && xi_is_window( win )
|
|
&& xi_get_focus( itf ) != xi_obj )
|
|
{
|
|
|
|
if ( win )
|
|
XinWindowFrontSet( win );
|
|
if ( front_win != win && front_win )
|
|
XinWindowFrontSet( front_win );
|
|
}
|
|
|
|
break;
|
|
}
|
|
case XIT_LIST:
|
|
{
|
|
switch ( ep->v.control.ctrl_info.v.scroll.action )
|
|
{
|
|
case XinScrollBarActionLineUp:
|
|
xi_control_event_scroll( xi_obj, -1, 0, TRUE );
|
|
break;
|
|
case XinScrollBarActionLineDown:
|
|
xi_control_event_scroll( xi_obj, 1, 0, TRUE );
|
|
break;
|
|
case XinScrollBarActionPageUp:
|
|
xi_control_event_scroll( xi_obj, XI_SCROLL_PGUP, 0, TRUE );
|
|
break;
|
|
case XinScrollBarActionPageDown:
|
|
xi_control_event_scroll( xi_obj, XI_SCROLL_PGDOWN, 0, TRUE );
|
|
break;
|
|
case XinScrollBarActionThumb:
|
|
case XinScrollBarActionThumbTrack:
|
|
if (ep->v.control.ctrl_info.v.scroll.action == XinScrollBarActionThumbTrack &&
|
|
xi_obj->v.list->scroll_on_thumb_track != TRUE)
|
|
break;
|
|
{
|
|
int percent = ep->v.control.ctrl_info.v.scroll.position;
|
|
|
|
if ( XinScrollBarProportionGet( ep->v.control.ctrl_info.win,
|
|
XinScrollBarTypeEither ) + percent == 100 )
|
|
xi_control_event_scroll( xi_obj, XI_SCROLL_LAST, 0, TRUE );
|
|
else
|
|
xi_control_event_scroll( xi_obj, XI_SCROLL_FIRST, percent, TRUE );
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ( xi_is_itf( itf ) &&
|
|
( xi_obj = xi_get_obj( itf, ep->v.control.control_id - HSCROLL_CID_CONST ) ) != NULL )
|
|
{
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_LIST:
|
|
switch ( ep->v.control.ctrl_info.v.scroll.action )
|
|
{
|
|
case XinScrollBarActionLineUp:
|
|
control_event_hscroll( xi_obj, -1, 0 );
|
|
break;
|
|
case XinScrollBarActionLineDown:
|
|
control_event_hscroll( xi_obj, 1, 0 );
|
|
break;
|
|
case XinScrollBarActionPageUp:
|
|
control_event_hscroll( xi_obj, XI_SCROLL_PGUP, 0 );
|
|
break;
|
|
case XinScrollBarActionPageDown:
|
|
control_event_hscroll( xi_obj, XI_SCROLL_PGDOWN, 0 );
|
|
break;
|
|
case XinScrollBarActionThumb:
|
|
case XinScrollBarActionThumbTrack:
|
|
if (ep->v.control.ctrl_info.v.scroll.action == XinScrollBarActionThumbTrack &&
|
|
xi_obj->v.list->scroll_on_thumb_track != TRUE)
|
|
break;
|
|
{
|
|
int prop;
|
|
int rng1,
|
|
rng2;
|
|
int pos;
|
|
|
|
prop = XinScrollBarProportionGet( ep->v.control.ctrl_info.win,
|
|
XinScrollBarTypeEither );
|
|
XinScrollBarRangeGet( ep->v.control.ctrl_info.win, XinScrollBarTypeEither,
|
|
&rng1, &rng2 );
|
|
pos = ( rng2 - rng1 - prop ) ?
|
|
( int ) ( ep->v.control.ctrl_info.v.scroll.position * 100L / ( rng2 - rng1 - prop ) ) : 0;
|
|
control_event_hscroll( xi_obj, XI_SCROLL_FIRST, pos );
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_trap_obj( XI_OBJ * xi_obj )
|
|
{
|
|
XI_OBJ *itf;
|
|
XI_ITF_DATA *itf_data;
|
|
|
|
itf = xi_obj->itf;
|
|
itf_data = itf->v.itf;
|
|
itf_data->trap_obj = xi_obj;
|
|
itf_data->trap_explicit = TRUE;
|
|
}
|
|
|
|
static void
|
|
destroy_controls( XI_OBJ * xi_obj )
|
|
{
|
|
XI_OBJ **objp;
|
|
int i;
|
|
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_LIST:
|
|
if ( xi_obj->v.list->font )
|
|
XinFontDestroy( xi_obj->v.list->font );
|
|
lm_cleanup( xi_obj->v.list->lm );
|
|
break;
|
|
case XIT_FIELD:
|
|
if ( xi_obj->v.field->font_set )
|
|
stx_destroy_font( xi_obj->v.field->stx );
|
|
break;
|
|
case XIT_TEXT:
|
|
if ( xi_obj->v.text->font )
|
|
XinFontDestroy( xi_obj->v.text->font );
|
|
break;
|
|
case XIT_ITF:
|
|
if ( xi_obj->v.itf->font )
|
|
XinFontDestroy( xi_obj->v.itf->font );
|
|
break;
|
|
case XIT_BTN:
|
|
xi_bitmap_destroy( xi_obj->v.btn->up_bitmap );
|
|
xi_bitmap_destroy( xi_obj->v.btn->down_bitmap );
|
|
xi_bitmap_destroy( xi_obj->v.btn->disabled_bitmap );
|
|
break;
|
|
}
|
|
objp = xi_obj->children;
|
|
for ( i = xi_obj->nbr_children; i > 0; i--, objp++ )
|
|
destroy_controls( *objp );
|
|
}
|
|
|
|
static void
|
|
copy_to_clip( XI_OBJ * focus_obj )
|
|
{
|
|
int b,
|
|
e;
|
|
char *buff;
|
|
|
|
xi_get_sel( focus_obj, &b, &e );
|
|
if ( b != e )
|
|
{
|
|
long len;
|
|
|
|
len = e - b;
|
|
buff = xi_get_text( focus_obj, NULL, 0 );
|
|
XinClipboardPut( XinClipboardFormatText, len, &buff[b] );
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_menus( void )
|
|
{
|
|
BOOLEAN paste_enable;
|
|
BOOLEAN cut_or_copy_enable = FALSE;
|
|
XI_OBJ *itf;
|
|
XI_ITF_DATA *itfdata;
|
|
XinWindow win;
|
|
|
|
win = XinWindowFocusGet( );
|
|
if ( win == XI_NULL_WINDOW || !xi_is_window( win ) )
|
|
return;
|
|
itf = xi_get_itf( win );
|
|
itfdata = itf->v.itf;
|
|
if ( itfdata->menu_win != XI_NULL_WINDOW )
|
|
win = itfdata->menu_win;
|
|
if ( itfdata->edit_menu )
|
|
{
|
|
XI_OBJ *focus_obj;
|
|
|
|
paste_enable = XinClipboardFormatAvail( XinClipboardFormatText );
|
|
XinWindowMenuItemEnable( win, XI_MENU_EDIT_PASTE, paste_enable );
|
|
focus_obj = xi_get_focus( itf );
|
|
if ( ( focus_obj && ( focus_obj->type == XIT_CELL ) ) ||
|
|
( focus_obj && ( focus_obj->type == XIT_FIELD ) ) )
|
|
{
|
|
int s,
|
|
e;
|
|
|
|
xi_get_sel( focus_obj, &s, &e );
|
|
if ( s != e )
|
|
cut_or_copy_enable = TRUE;
|
|
}
|
|
if ( paste_enable != itfdata->paste_enable )
|
|
{
|
|
XinWindowMenuItemEnable( win, XI_MENU_EDIT_PASTE, paste_enable );
|
|
itfdata->paste_enable = paste_enable;
|
|
}
|
|
if ( cut_or_copy_enable != itfdata->cut_or_copy_enable )
|
|
{
|
|
XinWindowMenuItemEnable( win, XI_MENU_EDIT_CUT, cut_or_copy_enable );
|
|
XinWindowMenuItemEnable( win, XI_MENU_EDIT_COPY, cut_or_copy_enable );
|
|
XinWindowMenuItemEnable( win, XI_MENU_EDIT_CLEAR, cut_or_copy_enable );
|
|
itfdata->cut_or_copy_enable = cut_or_copy_enable;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
do_edit_menu( XI_OBJ * itf, XinEvent * ep )
|
|
{
|
|
XI_OBJ *focus_obj;
|
|
unsigned long attrib = 0L;
|
|
|
|
focus_obj = xi_get_focus( itf );
|
|
if ( focus_obj && focus_obj->type != XIT_ITF )
|
|
{
|
|
switch ( focus_obj->type )
|
|
{
|
|
case XIT_FIELD:
|
|
attrib = xi_get_attrib( focus_obj );
|
|
break;
|
|
case XIT_CELL:
|
|
{
|
|
XI_OBJ *list;
|
|
XI_OBJ *column;
|
|
XI_OBJ **members;
|
|
int col_nbr,
|
|
nbr_members;
|
|
|
|
list = focus_obj->parent;
|
|
members = xi_get_member_list( list, &nbr_members );
|
|
col_nbr = focus_obj->v.cell.column;
|
|
column = members[col_nbr];
|
|
attrib = xi_get_attrib( column );
|
|
break;
|
|
}
|
|
}
|
|
if ( attrib & XI_ATR_EDITMENU )
|
|
{
|
|
int b,
|
|
e;
|
|
|
|
switch ( ep->v.menu_command.tag )
|
|
{
|
|
case XI_MENU_EDIT_CUT:
|
|
copy_to_clip( focus_obj );
|
|
/* fall through */
|
|
case XI_MENU_EDIT_CLEAR:
|
|
xi_get_sel( focus_obj, &b, &e );
|
|
if ( b != e )
|
|
{
|
|
XinEvent ev;
|
|
|
|
MEMCLEAR( ev );
|
|
ev.type = XinEventCharacter;
|
|
ev.v.character.ch = XI_KEY_DEL;
|
|
xi_event( xi_get_window( itf ), &ev );
|
|
}
|
|
update_menus( );
|
|
break;
|
|
case XI_MENU_EDIT_COPY:
|
|
copy_to_clip( focus_obj );
|
|
update_menus( );
|
|
break;
|
|
case XI_MENU_EDIT_PASTE:
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
if ( focus_obj->type == XIT_FIELD )
|
|
if ( xi_is_txedit( focus_obj ) )
|
|
if ( xi_get_pref( XI_PREF_MULTILINE_QUICK_PASTE ) )
|
|
break;
|
|
#endif
|
|
{
|
|
char *cb,
|
|
*p;
|
|
long size;
|
|
|
|
if ( ( cb = XinClipboardGet( XinClipboardFormatText, &size ) ) != NULL )
|
|
{
|
|
XinWindow win;
|
|
|
|
win = xi_get_window( itf );
|
|
itf->v.itf->pasting = TRUE;
|
|
p = cb;
|
|
if ( ( focus_obj->type == XIT_FIELD || focus_obj->type == XIT_CELL ) &&
|
|
xi_get_pref( XI_PREF_MULTILINE_QUICK_PASTE ) )
|
|
{
|
|
XI_TEXT *text;
|
|
|
|
text = xi_text_focus_get( win );
|
|
if ( text )
|
|
if ( text->multi_line )
|
|
{
|
|
xi_text_paste_internal( text, p );
|
|
itf->v.itf->pasting = FALSE;
|
|
XinMemoryFree( cb );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
while ( size-- > 0 )
|
|
{
|
|
XinEvent ev;
|
|
|
|
MEMCLEAR( ev );
|
|
ev.type = XinEventCharacter;
|
|
ev.v.character.ch = ( unsigned char ) *p++;
|
|
xi_event( win, &ev );
|
|
XinWindowPaintForce( win );
|
|
}
|
|
itf->v.itf->pasting = FALSE;
|
|
XinMemoryFree( cb );
|
|
}
|
|
}
|
|
update_menus( );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
count the number of children of xi_obj that have rectangles that will be completely
|
|
filled in when the child is drawn.
|
|
*/
|
|
static int
|
|
count_children( XI_OBJ * xi_obj )
|
|
{
|
|
int idx;
|
|
int count = 0;
|
|
XI_OBJ **child;
|
|
|
|
for ( idx = 0, child = xi_obj->children; idx < xi_obj->nbr_children; ++idx, ++child )
|
|
{
|
|
XI_OBJ_TYPE type = ( *child )->type;
|
|
|
|
if ( xi_get_attrib( *child ) & XI_ATR_VISIBLE )
|
|
{
|
|
/* do not count groups, lines, static texts, or columns, nor their
|
|
* children */
|
|
if ( type != XIT_GROUP && type != XIT_LINE && type != XIT_TEXT && type != XIT_COLUMN )
|
|
{
|
|
/* count the children of containers, forms, and the interface, but not
|
|
* containers, forms, and interfaces */
|
|
if ( ( *child )->type != XIT_LIST && ( *child )->children )
|
|
count += count_children( *child );
|
|
if ( type != XIT_CONTAINER &&
|
|
type != XIT_FORM &&
|
|
type != XIT_ITF &&
|
|
type != XIT_TEXT &&
|
|
type != XIT_BTN &&
|
|
type != XIT_FIELD )
|
|
++count;
|
|
}
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
static void
|
|
add_rects( XI_OBJ * xi_obj, XinRect * ra, int *ra_count )
|
|
{
|
|
int idx;
|
|
XI_OBJ **child;
|
|
|
|
for ( idx = 0, child = xi_obj->children; idx < xi_obj->nbr_children; ++idx, ++child )
|
|
{
|
|
XI_OBJ_TYPE type = ( *child )->type;
|
|
|
|
if ( xi_get_attrib( *child ) & XI_ATR_VISIBLE )
|
|
{
|
|
/* do not add rects for groups, lines, static texts, or columns, nor
|
|
* their children */
|
|
if ( type != XIT_GROUP && type != XIT_LINE && type != XIT_TEXT && type != XIT_COLUMN )
|
|
{
|
|
/* add rects for the children of containers, forms, and the interface,
|
|
* but not containers, forms, and interfaces */
|
|
if ( ( *child )->type != XIT_LIST && ( *child )->children )
|
|
add_rects( *child, ra, ra_count );
|
|
if ( type != XIT_CONTAINER &&
|
|
type != XIT_FORM &&
|
|
type != XIT_ITF &&
|
|
type != XIT_TEXT &&
|
|
type != XIT_BTN &&
|
|
type != XIT_FIELD )
|
|
{
|
|
xi_get_rect( ( *child ), &ra[*ra_count] );
|
|
++*ra_count;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if XIWS == XIWS_PM
|
|
static int _Optlink
|
|
#else
|
|
static int
|
|
#endif
|
|
compare( const void *arg1, const void *arg2 )
|
|
{
|
|
if ( *( int * ) arg1 == *( int * ) arg2 )
|
|
return 0;
|
|
if ( *( int * ) arg1 < *( int * ) arg2 )
|
|
return -1;
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
elim_dups( int *int_array, int int_count )
|
|
{
|
|
int index = 0;
|
|
int top = int_count - 1;
|
|
int *iap = int_array;
|
|
|
|
while ( index < top )
|
|
{
|
|
if ( *iap == *( iap + 1 ) )
|
|
{
|
|
if ( top > index )
|
|
memmove( iap + 1, iap + 2, ( top - index - 1 ) * sizeof( int ) );
|
|
--top;
|
|
}
|
|
else
|
|
{
|
|
++index;
|
|
++iap;
|
|
}
|
|
}
|
|
return top;
|
|
}
|
|
|
|
static void
|
|
draw_all_rects( XI_OBJ * itf )
|
|
{
|
|
XinRect *ra,
|
|
*rap;
|
|
XI_ITF_DATA *itf_data;
|
|
int count;
|
|
int cur_delta_x,
|
|
cur_delta_y;
|
|
int num_rects;
|
|
int ra_count;
|
|
int *hml,
|
|
*hmlp;
|
|
int hml_count,
|
|
hml_top;
|
|
int *vml,
|
|
*vmlp;
|
|
int vml_count,
|
|
vml_top;
|
|
int int_count;
|
|
int rect_count;
|
|
XinRect client_rect;
|
|
XinWindow win = xi_get_window( itf );
|
|
XI_BITMAP *bitmap;
|
|
|
|
itf_data = itf->v.itf;
|
|
bitmap = itf_data->bitmap;
|
|
cur_delta_x = itf_data->delta_x;
|
|
cur_delta_y = itf_data->delta_y;
|
|
num_rects = count_children( itf );
|
|
XinWindowRectGet( win, &client_rect );
|
|
if ( !num_rects )
|
|
{
|
|
if ( bitmap != NULL )
|
|
xi_bitmap_draw( bitmap, win, &client_rect, NULL, TRUE );
|
|
else
|
|
XinWindowRectDraw( win, &client_rect );
|
|
return;
|
|
}
|
|
ra = xi_tree_malloc( sizeof( XinRect ) * num_rects, itf );
|
|
ra_count = 0;
|
|
add_rects( itf, ra, &ra_count );
|
|
int_count = num_rects * 2 + 2;
|
|
/* hml is an acronym for horizontal mathmatical lines */
|
|
/* vml is an acronym for vertical mathmatical lines */
|
|
hml = xi_tree_malloc( sizeof( int ) * int_count, itf );
|
|
vml = xi_tree_malloc( sizeof( int ) * int_count, itf );
|
|
hmlp = hml;
|
|
vmlp = vml;
|
|
*hmlp = 0;
|
|
++hmlp;
|
|
*vmlp = 0;
|
|
++vmlp;
|
|
*hmlp = 9999;
|
|
++hmlp;
|
|
*vmlp = 9999;
|
|
++vmlp;
|
|
for ( count = 0, rap = ra; count < num_rects; ++count, ++rap )
|
|
{
|
|
*hmlp = rap->left;
|
|
++hmlp;
|
|
*hmlp = rap->right;
|
|
++hmlp;
|
|
*vmlp = rap->top;
|
|
++vmlp;
|
|
*vmlp = rap->bottom;
|
|
++vmlp;
|
|
}
|
|
qsort( ( void * ) hml, ( size_t ) int_count, sizeof( int ), compare );
|
|
qsort( ( void * ) vml, ( size_t ) int_count, sizeof( int ), compare );
|
|
hml_top = elim_dups( hml, int_count );
|
|
vml_top = elim_dups( vml, int_count );
|
|
for ( hml_count = 0, hmlp = hml; hml_count < hml_top; ++hml_count, ++hmlp )
|
|
{
|
|
for ( vml_count = 0, vmlp = vml; vml_count < vml_top; ++vml_count, ++vmlp )
|
|
{
|
|
/* use static for rect and new_rect, to allow the compiler to generate
|
|
* more efficient code */
|
|
static XinRect rect;
|
|
|
|
rect.left = *hmlp;
|
|
rect.right = *( hmlp + 1 );
|
|
rect.top = *vmlp;
|
|
rect.bottom = *( vmlp + 1 );
|
|
for ( rect_count = 0, rap = ra; rect_count < ra_count; ++rect_count, ++rap )
|
|
{
|
|
static XinRect new_rect;
|
|
|
|
new_rect = *rap;
|
|
if ( new_rect.top < rect.top )
|
|
new_rect.top = rect.top;
|
|
if ( new_rect.left < rect.left )
|
|
new_rect.left = rect.left;
|
|
if ( new_rect.bottom > rect.bottom )
|
|
new_rect.bottom = rect.bottom;
|
|
if ( new_rect.right > rect.right )
|
|
new_rect.right = rect.right;
|
|
/* if the intersection is not empty, then skip this rectangle */
|
|
if ( new_rect.bottom > new_rect.top && new_rect.right > new_rect.left )
|
|
break;
|
|
}
|
|
/* if we made it through all rectangles, then no rectangle intersected,
|
|
* and we should draw rect */
|
|
if ( ra_count && rect_count == ra_count )
|
|
{
|
|
rect.left -= cur_delta_x;
|
|
rect.right -= cur_delta_x;
|
|
rect.top -= cur_delta_y;
|
|
rect.bottom -= cur_delta_y;
|
|
if ( bitmap != NULL )
|
|
xi_bitmap_draw( bitmap, win, &client_rect, &rect, TRUE );
|
|
else
|
|
XinWindowRectDraw( win, &rect );
|
|
}
|
|
}
|
|
}
|
|
xi_tree_free( ra );
|
|
xi_tree_free( hml );
|
|
xi_tree_free( vml );
|
|
}
|
|
|
|
static void
|
|
draw_background( XI_OBJ * itf )
|
|
{
|
|
XI_ITF_DATA *itf_data = itf->v.itf;
|
|
XinWindow win = itf_data->xin_win;
|
|
|
|
if ( itf_data->back_color )
|
|
{
|
|
XinDrawTools t;
|
|
XinBrush cbrush;
|
|
|
|
XinWindowDrawToolsNormalGet( &t );
|
|
XinWindowDrawToolsSet( win, &t );
|
|
XinWindowPenSet( win, &hollow_cpen );
|
|
cbrush.pattern = XinBrushSolid;
|
|
cbrush.fore_color = itf_data->back_color;
|
|
XinWindowBrushSet( win, &cbrush );
|
|
xi_set_clip( win, NULL );
|
|
draw_all_rects( itf );
|
|
}
|
|
else if ( itf_data->bitmap != NULL )
|
|
{
|
|
xi_set_clip( win, NULL );
|
|
draw_all_rects( itf );
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
do_post_event( XI_OBJ * itf, XinEvent * ep )
|
|
{
|
|
XI_EVENT xiev;
|
|
|
|
if ( xi_is_itf( itf ) )
|
|
{
|
|
MEMCLEAR( xiev );
|
|
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
|
|
{
|
|
xiev.type = XIE_XIN_POST_EVENT;
|
|
xiev.v.xin_event = *ep;
|
|
}
|
|
#ifdef XI_USE_XVT
|
|
else
|
|
{
|
|
if ( ep->type != XinEventCharacter || !ep->v.character.alt )
|
|
{
|
|
xiev.type = XIE_XVT_POST_EVENT;
|
|
XinXvtEventGet( &xiev.v.xvte );
|
|
}
|
|
}
|
|
#endif
|
|
xiev.refused = FALSE;
|
|
if ( !call_cb( itf, &xiev ) )
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* get_text_ctools */
|
|
/* ------------------------------------------------------------------------ */
|
|
static XinDrawTools *
|
|
get_text_ctools( XI_ITF_DATA * itf_data, XinDrawTools * ct, XinFont ** p_font )
|
|
{
|
|
XinWindowDrawToolsNormalGet( ct );
|
|
ct->pen.fore_color = ct->text_fore_color = XI_COLOR_BLACK;
|
|
ct->opaque_text = FALSE;
|
|
if ( itf_data->font )
|
|
*p_font = itf_data->font;
|
|
else
|
|
*p_font = xi_get_system_font( );
|
|
return ( ct );
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* xi_draw_obj */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void
|
|
xi_draw_obj( XI_OBJ * xi_obj )
|
|
{
|
|
XinWindow win;
|
|
XI_ITF_DATA *itf_data;
|
|
|
|
itf_data = xi_obj->itf->v.itf;
|
|
win = itf_data->xin_win;
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_TEXT:
|
|
{
|
|
XI_TEXT_DATA *text;
|
|
XinDrawTools ct;
|
|
XinFont *font;
|
|
|
|
text = xi_obj->v.text;
|
|
get_text_ctools( itf_data, &ct, &font );
|
|
ct.text_back_color = itf_data->back_color;
|
|
ct.text_fore_color = XI_COLOR_BLACK;
|
|
if ( text->fore_color )
|
|
ct.text_fore_color = text->fore_color;
|
|
if ( text->back_color )
|
|
{
|
|
ct.opaque_text = TRUE;
|
|
ct.text_back_color = text->back_color;
|
|
}
|
|
XinWindowDrawToolsSet( win, &ct );
|
|
if ( text->font )
|
|
font = text->font;
|
|
if ( ( text->attrib & XI_ATR_ENABLED ) )
|
|
XinWindowColorTextForeSet( win, ct.text_fore_color );
|
|
else
|
|
XinWindowColorTextForeSet( win,
|
|
( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
|
|
XinWindowColorTextBackSet( win, ct.text_back_color );
|
|
xi_draw_clipped_text( win, font, text->text, &text->rct, &text->rct,
|
|
text->attrib | XI_ATR_VCENTER, FALSE, 0, -1,
|
|
text->mnemonic, text->mnemonic_instance, NULL );
|
|
break;
|
|
}
|
|
case XIT_LINE:
|
|
{
|
|
XI_LINE_DATA *line;
|
|
XinPoint pnt1,
|
|
pnt2;
|
|
|
|
XinWindowClipSet( win, NULL );
|
|
line = xi_obj->v.line;
|
|
if ( line->attrib & XI_ATR_VISIBLE )
|
|
{
|
|
pnt1 = line->pnt1;
|
|
pnt2 = line->pnt2;
|
|
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
|
|
xi_draw_3d_line( win, pnt1, pnt2, line->well );
|
|
else
|
|
{
|
|
XinPen cpen;
|
|
|
|
cpen = black_cpen;
|
|
if ( line->fore_color )
|
|
cpen.fore_color = line->fore_color;
|
|
XinWindowPenSet( win, &cpen );
|
|
if ( line->back_color )
|
|
XinWindowColorTextBackSet( win, line->back_color );
|
|
xi_move_to( win, pnt1 );
|
|
xi_draw_line( win, pnt2 );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case XIT_RECT:
|
|
{
|
|
XI_RECT_DATA *rect;
|
|
XinRect rct;
|
|
|
|
XinWindowClipSet( win, NULL );
|
|
rect = xi_obj->v.rect;
|
|
if ( rect->attrib & XI_ATR_VISIBLE )
|
|
{
|
|
rct = rect->rct;
|
|
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
|
|
{
|
|
xi_draw_3d_rect( win, &rct, rect->well, 1,
|
|
rect->hilight_color, rect->back_color,
|
|
rect->shadow_color );
|
|
if ( rect->ridge )
|
|
{
|
|
xi_inflate_rect( &rct, -1 );
|
|
xi_draw_3d_rect( win, &rct, ( BOOLEAN ) ( !rect->well ), 1,
|
|
rect->hilight_color, rect->back_color,
|
|
rect->shadow_color );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XinPen cpen;
|
|
XinBrush cbrush;
|
|
|
|
cpen = black_cpen;
|
|
if ( rect->fore_color )
|
|
cpen.fore_color = rect->fore_color;
|
|
XinWindowPenSet( win, &cpen );
|
|
cbrush.pattern = XinBrushSolid;
|
|
cbrush.fore_color = XI_COLOR_WHITE;
|
|
if ( rect->back_color )
|
|
cbrush.fore_color = rect->back_color;
|
|
XinWindowBrushSet( win, &cbrush );
|
|
xi_draw_rect( win, &rct );
|
|
}
|
|
if ( rect->bitmap != NULL )
|
|
{
|
|
xi_inflate_rect( &rct, -1 );
|
|
xi_bitmap_draw( rect->bitmap, win, &rct, NULL, FALSE );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* xi_draw_field_button */
|
|
/* ------------------------------------------------------------------------ */
|
|
void
|
|
xi_draw_field_button( XI_OBJ * xi_obj )
|
|
{
|
|
XI_FIELD_DATA *fd;
|
|
unsigned long attrib;
|
|
STX_DATA *stxd;
|
|
const XinColor color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
|
|
const XinColor color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
|
|
const XinColor color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
|
|
|
|
#if XIWS != XIWS_WM
|
|
int x,
|
|
y;
|
|
XinRect cr,
|
|
r;
|
|
|
|
#endif
|
|
XinWindow win;
|
|
|
|
attrib = xi_get_attrib( xi_obj );
|
|
if ( !( attrib & XI_ATR_VISIBLE ) )
|
|
return;
|
|
fd = xi_obj->v.field;
|
|
stxd = ( STX_DATA * ) fd->stx;
|
|
win = xi_obj->itf->v.itf->xin_win;
|
|
XinWindowDrawModeSet( win, XinDrawModeCopy );
|
|
xi_set_clip( win, NULL );
|
|
#if XIWS != XIWS_WM
|
|
r = fd->btn_rct;
|
|
r.top++;
|
|
r.left++;
|
|
r.bottom--;
|
|
r.right--;
|
|
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
|
|
xi_draw_3d_rect(win, &r, fd->down, 2, color_light, color_ctrl, color_dark);
|
|
else
|
|
{
|
|
XinWindowBrushSet( win, &white_cbrush );
|
|
XinWindowPenSet( win, &hollow_cpen );
|
|
xi_draw_rect( win, &r );
|
|
}
|
|
x = r.left + 3;
|
|
y = r.top + 2;
|
|
cr = r;
|
|
cr.top += 2;
|
|
cr.left += 2;
|
|
cr.bottom -= 2;
|
|
cr.right -= 2;
|
|
xi_set_clip( win, &cr );
|
|
if ( fd->button_bitmap != NULL )
|
|
xi_bitmap_draw( fd->button_bitmap, win, &cr, &cr, FALSE );
|
|
else
|
|
{
|
|
int icon_rid;
|
|
XinColor color = ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) ? color_ctrl : xi_get_pref( XI_PREF_COLOR_CTRL );
|
|
|
|
icon_rid = fd->icon_rid;
|
|
if ( icon_rid == 0 )
|
|
icon_rid = ( int ) xi_get_pref( XI_PREF_COMBO_ICON );
|
|
if ( fd->down )
|
|
xi_draw_icon( win, x, y + 1, icon_rid, XI_COLOR_BLACK, color );
|
|
else
|
|
xi_draw_icon( win, x, y, icon_rid, XI_COLOR_BLACK, color );
|
|
}
|
|
xi_set_clip( win, NULL );
|
|
XinWindowPenSet( win, &black_cpen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
xi_draw_rect( win, &fd->btn_rct );
|
|
#endif
|
|
#if XIWS == XIWS_WM
|
|
NOREF( stxd );
|
|
{
|
|
XinBrush black_cbrush;
|
|
|
|
black_cbrush = white_cbrush;
|
|
black_cbrush.fore_color = XI_COLOR_BLACK;
|
|
xi_set_clip( win, NULL );
|
|
XinWindowPenSet( win, &hollow_cpen );
|
|
XinWindowBrushSet( win, &black_cbrush );
|
|
xi_draw_rect( win, &fd->btn_rct );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* field_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void
|
|
field_event( XI_OBJ * xi_obj, XinEvent * ep )
|
|
{
|
|
XI_FIELD_DATA *field_data;
|
|
XinRect rct;
|
|
|
|
field_data = xi_obj->v.field;
|
|
rct = field_data->btn_rct;
|
|
switch ( ep->type )
|
|
{
|
|
case XinEventCharacter:
|
|
if ( field_data->button )
|
|
{
|
|
long button_key;
|
|
BOOLEAN shift,
|
|
control,
|
|
alt;
|
|
|
|
button_key = xi_get_pref( XI_PREF_BUTTON_KEY );
|
|
shift = ( BOOLEAN ) ( ( button_key & XI_MOD_SHIFT ) != 0 );
|
|
control = ( BOOLEAN ) ( ( button_key & XI_MOD_CONTROL ) != 0 );
|
|
alt = ( BOOLEAN ) ( ( button_key & XI_MOD_ALT ) != 0 );
|
|
button_key &= 0xffffffL;
|
|
if ( button_key == ep->v.character.ch &&
|
|
shift == ep->v.character.shift &&
|
|
control == ep->v.character.control &&
|
|
alt == ep->v.character.alt )
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = xi_obj;
|
|
itf = xi_obj->itf;
|
|
call_cb( itf, &xiev );
|
|
}
|
|
}
|
|
break;
|
|
case XinEventPaint:
|
|
if ( field_data->button )
|
|
xi_draw_field_button( xi_obj );
|
|
break;
|
|
case XinEventMouseDown:
|
|
{
|
|
unsigned long attrib;
|
|
|
|
attrib = stx_get_attrib( xi_obj->v.field->stx );
|
|
attrib &= ( XI_ATR_ENABLED | XI_ATR_VISIBLE );
|
|
if ( field_data->button &&
|
|
attrib == ( XI_ATR_ENABLED | XI_ATR_VISIBLE ) )
|
|
{
|
|
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) )
|
|
{
|
|
field_data->down = TRUE;
|
|
field_data->down_in_btn = TRUE;
|
|
xi_draw_field_button( xi_obj );
|
|
xi_set_trap_obj( xi_obj );
|
|
XinWindowMouseTrap( xi_obj->itf->v.itf->xin_win, TRUE );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case XinEventMouseMove:
|
|
if ( field_data->button && field_data->down_in_btn )
|
|
{
|
|
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) && !field_data->down )
|
|
{
|
|
field_data->down = TRUE;
|
|
xi_draw_field_button( xi_obj );
|
|
}
|
|
if ( !xi_pt_in_rect( &rct, ep->v.mouse.where ) && field_data->down )
|
|
{
|
|
field_data->down = FALSE;
|
|
xi_draw_field_button( xi_obj );
|
|
}
|
|
}
|
|
break;
|
|
case XinEventMouseUp:
|
|
if ( field_data->button && field_data->down_in_btn )
|
|
{
|
|
XinWindowMouseRelease( );
|
|
if ( field_data->down )
|
|
{
|
|
field_data->down = FALSE;
|
|
xi_draw_field_button( xi_obj );
|
|
}
|
|
field_data->down_in_btn = FALSE;
|
|
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) )
|
|
{
|
|
if ( xi_move_focus( xi_obj ) )
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = xi_obj;
|
|
itf = xi_obj->itf;
|
|
call_cb( itf, &xiev );
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_draw_foc_and_dflt( XI_OBJ * xi_obj )
|
|
{
|
|
XI_OBJ *dflt_obj,
|
|
*foc_obj;
|
|
XI_BTN_DATA *bd;
|
|
BOOLEAN enabled;
|
|
BOOLEAN visible;
|
|
BOOLEAN focus;
|
|
BOOLEAN dflt;
|
|
unsigned long attrib;
|
|
|
|
if ( xi_get_native_controls( xi_obj ) )
|
|
return;
|
|
dflt_obj = xi_get_default( xi_obj );
|
|
if ( dflt_obj )
|
|
{
|
|
bd = dflt_obj->v.btn;
|
|
attrib = xi_get_attrib( dflt_obj );
|
|
enabled = ( ( attrib & XI_ATR_ENABLED ) != 0 );
|
|
visible = ( ( attrib & XI_ATR_VISIBLE ) != 0 );
|
|
focus = ( xi_get_focus( dflt_obj->itf ) == dflt_obj );
|
|
dflt = bd->dflt;
|
|
xi_draw_button( dflt_obj, &bd->rct, enabled,
|
|
visible, focus, bd->down, dflt, bd->checked, FALSE, TRUE );
|
|
}
|
|
foc_obj = xi_get_focus( xi_obj );
|
|
if ( foc_obj && foc_obj->type == XIT_BTN && foc_obj != dflt_obj )
|
|
{
|
|
bd = foc_obj->v.btn;
|
|
attrib = xi_get_attrib( foc_obj );
|
|
enabled = ( ( attrib & XI_ATR_ENABLED ) != 0 );
|
|
visible = ( ( attrib & XI_ATR_VISIBLE ) != 0 );
|
|
focus = TRUE;
|
|
dflt = bd->dflt;
|
|
xi_draw_button( foc_obj, &bd->rct, enabled,
|
|
visible, focus, bd->down, dflt, bd->checked, FALSE, TRUE );
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* form_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
static BOOLEAN
|
|
form_event( XI_OBJ * xi_obj, XinEvent * ep )
|
|
{
|
|
BOOLEAN retval = FALSE;
|
|
XI_OBJ *focus_obj = xi_obj->itf->v.itf->focus_obj;
|
|
XI_OBJ *itf = xi_obj->itf;
|
|
BOOLEAN focus_is_cell = (focus_obj != NULL && focus_obj->type == XIT_CELL);
|
|
|
|
switch ( ep->type )
|
|
{
|
|
case XinEventMenuCommand:
|
|
/* TODO -- navigation */
|
|
break;
|
|
case XinEventCharacter:
|
|
{
|
|
long c = event_to_longchar( ep );
|
|
XI_OBJ *next_obj = NULL;
|
|
|
|
/* navigation character event */
|
|
if ( ( c == '\r' || c == '\n' ) && xi_obj->itf->v.itf->tab_on_enter
|
|
&& xi_obj->type != XIT_BTN )
|
|
c = xi_get_pref( XI_PREF_FORM_TAB_CHAR );
|
|
if ( c == xi_get_pref( XI_PREF_FORM_TAB_CHAR ) || c == XI_KEY_DOWN )
|
|
{
|
|
next_obj = xi_find_next_obj( focus_obj, XI_NEXT_FORM_TAB, c );
|
|
}
|
|
else if ( c == xi_get_pref( XI_PREF_FORM_BACKTAB_CHAR ) ||
|
|
c == XI_KEY_UP )
|
|
{
|
|
next_obj = focus_obj;
|
|
do
|
|
{
|
|
next_obj = xi_find_next_obj( next_obj, XI_NEXT_FORM_BACKTAB, c );
|
|
} while ( next_obj != NULL && next_obj != focus_obj &&
|
|
( next_obj->type == XIT_FORM || next_obj->type == XIT_CONTAINER ) );
|
|
}
|
|
if ( next_obj != NULL )
|
|
{
|
|
xi_move_focus_internal( next_obj, TRUE, TRUE,
|
|
( ( c == xi_get_pref( XI_PREF_FORM_TAB_CHAR ) ) || ( c == XI_KEY_DOWN ) ) ? 1 : 2 );
|
|
retval = TRUE;
|
|
}
|
|
if ( next_obj && (focus_is_cell || xi_is_obj( focus_obj, itf )) )
|
|
xi_draw_foc_and_dflt_if_necessary( focus_obj, next_obj );
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* invalidate_button_rect */
|
|
/* ------------------------------------------------------------------------ */
|
|
static BOOLEAN
|
|
invalidate_button_rect( XI_OBJ * xi_obj, XI_BTN_DATA * bd, XinRect * rct )
|
|
{
|
|
if ( ( bd->type == XIBT_BUTTON || bd->type == XIBT_BUTTON_CHECKBOX ||
|
|
bd->type == XIBT_RADIOBTN ) && bd->drawable || bd->type == XIBT_TABBTN )
|
|
{
|
|
XinRect r;
|
|
XinWindow win;
|
|
|
|
r = *rct;
|
|
xi_inflate_rect( &r, -4 );
|
|
win = xi_get_window( xi_obj->itf );
|
|
xi_invalidate_rect( win, &r );
|
|
XinWindowPaintForce( win );
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* btn_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
static BOOLEAN
|
|
btn_event( XI_OBJ * xi_obj, XinEvent * ep )
|
|
{
|
|
BOOLEAN enabled;
|
|
BOOLEAN visible;
|
|
BOOLEAN focus;
|
|
BOOLEAN dflt;
|
|
BOOLEAN send_to_form = TRUE;
|
|
BOOLEAN ret_val;
|
|
XinRect rct;
|
|
unsigned long attrib;
|
|
XI_BTN_DATA *bd;
|
|
|
|
if ( !xi_get_native_controls( xi_obj ) )
|
|
{
|
|
attrib = xi_get_attrib( xi_obj );
|
|
enabled = ( ( attrib & XI_ATR_ENABLED ) != 0 );
|
|
visible = ( ( attrib & XI_ATR_VISIBLE ) != 0 );
|
|
focus = ( xi_get_focus( xi_obj->itf ) == xi_obj );
|
|
bd = xi_obj->v.btn;
|
|
dflt = bd->dflt;
|
|
rct = bd->rct;
|
|
switch ( ep->type )
|
|
{
|
|
case XinEventTimer:
|
|
return FALSE;
|
|
case XinEventCharacter:
|
|
if ( ep->v.character.ch == ' ' && focus )
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
int obj_cid;
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = xi_obj;
|
|
itf = xi_obj->itf;
|
|
obj_cid = xi_obj->cid;
|
|
call_cb( itf, &xiev );
|
|
if ( !xi_is_itf( itf ) || xi_get_obj( itf, obj_cid ) == NULL )
|
|
send_to_form = FALSE;
|
|
}
|
|
break;
|
|
case XinEventPaint:
|
|
xi_draw_button( xi_obj, &rct, enabled,
|
|
visible, focus, bd->down, dflt, bd->checked, FALSE, TRUE );
|
|
break;
|
|
case XinEventMouseDouble:
|
|
if ( !xi_get_pref( XI_PREF_DBL_PRESSES_BUTTON ) )
|
|
break;
|
|
/* else fall through */
|
|
case XinEventMouseDown:
|
|
{
|
|
XinRect hit_rct;
|
|
|
|
if ( ( enabled == FALSE ) || ( visible == FALSE ) )
|
|
break;
|
|
hit_rct = rct;
|
|
if ( bd->packed == TRUE )
|
|
xi_inflate_rect( &hit_rct,
|
|
-( ( int ) xi_get_pref( XI_PREF_CONTAINER_GRID_WIDTH ) ) );
|
|
if ( xi_pt_in_rect( &hit_rct, ep->v.mouse.where ) )
|
|
{
|
|
bd->down = TRUE;
|
|
bd->down_in_btn = TRUE;
|
|
if ( !invalidate_button_rect( xi_obj, bd, &rct ) )
|
|
xi_draw_button( xi_obj, &rct, enabled, visible, focus, bd->down,
|
|
dflt, bd->checked, FALSE, FALSE );
|
|
xi_set_trap_obj( xi_obj );
|
|
XinWindowMouseTrap( xi_get_window( xi_obj->itf ), TRUE );
|
|
}
|
|
break;
|
|
}
|
|
case XinEventMouseMove:
|
|
if ( bd->down_in_btn )
|
|
{
|
|
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) && !bd->down )
|
|
{
|
|
bd->down = TRUE;
|
|
if ( !invalidate_button_rect( xi_obj, bd, &rct ) )
|
|
xi_draw_button( xi_obj, &rct, enabled, visible, focus, bd->down,
|
|
dflt, bd->checked, FALSE, FALSE );
|
|
}
|
|
else if ( !xi_pt_in_rect( &rct, ep->v.mouse.where ) &&
|
|
bd->down )
|
|
{
|
|
bd->down = FALSE;
|
|
if ( !invalidate_button_rect( xi_obj, bd, &rct ) )
|
|
xi_draw_button( xi_obj, &rct,
|
|
enabled, visible, focus, bd->down, dflt,
|
|
bd->checked, FALSE, FALSE );
|
|
}
|
|
}
|
|
break;
|
|
case XinEventMouseUp:
|
|
if ( bd->down_in_btn )
|
|
{
|
|
bd->down_in_btn = FALSE;
|
|
if ( bd->down )
|
|
{
|
|
bd->down = FALSE;
|
|
if ( !invalidate_button_rect( xi_obj, bd, &rct ) )
|
|
xi_draw_button( xi_obj, &rct,
|
|
enabled, visible, focus, bd->down, dflt,
|
|
bd->checked, FALSE, FALSE );
|
|
}
|
|
XinWindowMouseRelease( );
|
|
if ( ep->type == XinEventMouseUp &&
|
|
xi_pt_in_rect( &rct, ep->v.mouse.where ) )
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
int obj_cid;
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = xi_obj;
|
|
itf = xi_obj->itf;
|
|
obj_cid = xi_obj->cid;
|
|
call_cb( itf, &xiev );
|
|
if ( !xi_is_itf( itf ) || xi_get_obj( itf, obj_cid ) == NULL )
|
|
send_to_form = FALSE;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
ret_val = TRUE;
|
|
if ( send_to_form )
|
|
ret_val = form_event( xi_obj, ep );
|
|
return ret_val;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* draw_list_button */
|
|
/* ------------------------------------------------------------------------ */
|
|
#define P_OFFSET 3
|
|
static void
|
|
draw_list_button( XinWindow win, XinRect * rct, BOOLEAN down )
|
|
{
|
|
#if XIWS != XIWS_WM
|
|
int x,
|
|
y,
|
|
plus_width,
|
|
plus_height;
|
|
XinPoint p;
|
|
XinRect r;
|
|
BOOLEAN x2;
|
|
|
|
r = *rct;
|
|
xi_set_clip( win, NULL ); // XI forgot this!
|
|
|
|
XinWindowPenSet( win, &black_cpen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
xi_draw_rect( win, &r );
|
|
r.top++;
|
|
r.left++;
|
|
r.bottom--;
|
|
r.right--;
|
|
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
|
|
{
|
|
const XinColor color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
|
|
const XinColor color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
|
|
const XinColor color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
|
|
|
|
xi_draw_3d_rect(win, &r, down, 2, color_light, color_ctrl, color_dark);
|
|
}
|
|
else
|
|
{
|
|
XinWindowBrushSet( win, &white_cbrush );
|
|
xi_draw_rect( win, &r );
|
|
}
|
|
|
|
p.h = rct->left;
|
|
p.v = rct->top - 1;
|
|
XinWindowPenSet( win, &black_cpen );
|
|
xi_move_to( win, p );
|
|
p.h = rct->right;
|
|
xi_draw_line( win, p );
|
|
|
|
plus_width = r.right - r.left;
|
|
plus_height = plus_width + 4;
|
|
x = r.left + plus_width / 2;
|
|
y = r.top + plus_height / 2;
|
|
x2 = !( ( r.right + r.left ) % 2 );
|
|
if ( x2 )
|
|
x--;
|
|
y--;
|
|
XinWindowPenSet( win, &black_cpen );
|
|
|
|
/* draw vertical lines */
|
|
p.h = x;
|
|
p.v = r.top + P_OFFSET + down;
|
|
xi_move_to( win, p );
|
|
p.v = r.top + plus_height - P_OFFSET + down;
|
|
xi_draw_line( win, p );
|
|
p.h = x + 1;
|
|
p.v = r.top + P_OFFSET + down;
|
|
xi_move_to( win, p );
|
|
p.v = r.top + plus_height - P_OFFSET + down;
|
|
xi_draw_line( win, p );
|
|
|
|
/* draw horizontal lines */
|
|
p.v = y + down;
|
|
p.h = r.left + P_OFFSET;
|
|
xi_move_to( win, p );
|
|
p.h = r.left + plus_width - P_OFFSET;
|
|
xi_draw_line( win, p );
|
|
p.v = y + down + 1;
|
|
p.h = r.left + P_OFFSET;
|
|
xi_move_to( win, p );
|
|
p.h = r.left + plus_width - P_OFFSET;
|
|
xi_draw_line( win, p );
|
|
#else
|
|
NOREF( rct );
|
|
NOREF( down );
|
|
NOREF( win );
|
|
#endif
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* list_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void
|
|
list_event( XI_OBJ * xi_obj, XinEvent * ep )
|
|
{
|
|
XI_LIST_DATA *list_data;
|
|
XinRect rct;
|
|
LM_DATA *lmp;
|
|
|
|
list_data = xi_obj->v.list;
|
|
lmp = ( LM_DATA * ) list_data->lm;
|
|
if ( lmp->attrib & XI_ATR_VISIBLE )
|
|
{
|
|
rct = list_data->sbb_rct;
|
|
switch ( ep->type )
|
|
{
|
|
case XinEventPaint:
|
|
if ( list_data->scroll_bar_button )
|
|
draw_list_button( lmp->win, &rct, list_data->down );
|
|
break;
|
|
case XinEventMouseDown:
|
|
if ( list_data->scroll_bar_button )
|
|
{
|
|
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) )
|
|
{
|
|
list_data->down = TRUE;
|
|
list_data->down_in_btn = TRUE;
|
|
draw_list_button( lmp->win, &rct, TRUE );
|
|
xi_set_trap_obj( xi_obj );
|
|
XinWindowMouseTrap( xi_obj->itf->v.itf->xin_win, TRUE );
|
|
}
|
|
}
|
|
break;
|
|
case XinEventMouseMove:
|
|
if ( list_data->scroll_bar_button && list_data->down_in_btn )
|
|
{
|
|
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) && !list_data->down )
|
|
{
|
|
list_data->down = TRUE;
|
|
draw_list_button( lmp->win, &rct, TRUE );
|
|
}
|
|
if ( !xi_pt_in_rect( &rct, ep->v.mouse.where ) && list_data->down )
|
|
{
|
|
list_data->down = FALSE;
|
|
draw_list_button( lmp->win, &rct, FALSE );
|
|
}
|
|
}
|
|
break;
|
|
case XinEventMouseUp:
|
|
if ( list_data->scroll_bar_button && list_data->down_in_btn )
|
|
{
|
|
XinWindowMouseRelease( );
|
|
if ( list_data->down )
|
|
{
|
|
list_data->down = FALSE;
|
|
draw_list_button( lmp->win, &rct, FALSE );
|
|
}
|
|
list_data->down_in_btn = FALSE;
|
|
if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) )
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = xi_obj;
|
|
itf = xi_obj->itf;
|
|
call_cb( itf, &xiev );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* itf_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
static BOOLEAN
|
|
itf_event( XI_OBJ * xi_obj, XinEvent * ep )
|
|
{
|
|
BOOLEAN retval = FALSE;
|
|
XI_ITF_DATA *itf_data;
|
|
XI_OBJ *focus_obj;
|
|
|
|
itf_data = xi_obj->itf->v.itf;
|
|
focus_obj = itf_data->focus_obj;
|
|
switch ( ep->type )
|
|
{
|
|
case XinEventMenuCommand:
|
|
/* TODO -- navigation */
|
|
break;
|
|
case XinEventResize:
|
|
if ( itf_data->bitmap != NULL
|
|
&& xi_bitmap_draw_all_on_resize( itf_data->bitmap ) )
|
|
XinWindowRectInvalidate( xi_get_window( xi_obj ), NULL );
|
|
break;
|
|
case XinEventCharacter:
|
|
{
|
|
long c = event_to_longchar( ep );
|
|
XI_OBJ *next_obj = NULL;
|
|
|
|
if ( focus_obj->itf != xi_obj )
|
|
XinError( 20030, XinSeverityFatal, 0L );
|
|
|
|
/* navigation character event */
|
|
if ( c == xi_get_pref( XI_PREF_ITF_TAB_CHAR ) )
|
|
next_obj = xi_find_next_obj( focus_obj, XI_NEXT_ITF_TAB, c );
|
|
else if ( c == xi_get_pref( XI_PREF_ITF_BACKTAB_CHAR ) )
|
|
next_obj = xi_find_next_obj( focus_obj, XI_NEXT_ITF_BACKTAB,
|
|
c );
|
|
else if ( c == xi_get_pref( XI_PREF_FORM_TAB_CHAR ) &&
|
|
focus_obj->type == XIT_ITF )
|
|
next_obj = xi_search_itf( focus_obj, XI_SEARCH_FOR_FOCUSABLE,
|
|
0 );
|
|
if ( c == '\r' || c == '\n' )
|
|
{
|
|
XI_OBJ *dflt_obj;
|
|
|
|
dflt_obj = xi_get_default( xi_obj->itf );
|
|
if ( dflt_obj && ( xi_get_attrib( dflt_obj ) & ( XI_ATR_ENABLED
|
|
| XI_ATR_VISIBLE ) ) == ( XI_ATR_ENABLED | XI_ATR_VISIBLE ) )
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = dflt_obj;
|
|
itf = xi_obj->itf;
|
|
call_cb( itf, &xiev );
|
|
retval = TRUE;
|
|
}
|
|
}
|
|
if ( c == '\033' )
|
|
{
|
|
XI_OBJ *cancel_obj;
|
|
|
|
cancel_obj = xi_get_cancel( xi_obj->itf );
|
|
if ( cancel_obj && ( xi_get_attrib( cancel_obj ) & ( XI_ATR_ENABLED
|
|
| XI_ATR_VISIBLE ) ) == ( XI_ATR_ENABLED | XI_ATR_VISIBLE ) )
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = cancel_obj;
|
|
itf = xi_obj->itf;
|
|
call_cb( itf, &xiev );
|
|
retval = TRUE;
|
|
}
|
|
}
|
|
if ( ep->v.character.alt )
|
|
{
|
|
XI_OBJ *obj;
|
|
|
|
obj = xi_get_obj_from_mnemonic( xi_obj->itf, ( char ) ep->v.character.ch );
|
|
if ( obj )
|
|
{
|
|
switch ( obj->type )
|
|
{
|
|
case XIT_BTN:
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = obj;
|
|
itf = xi_obj->itf;
|
|
call_cb( itf, &xiev );
|
|
ep->v.character.consumed = TRUE;
|
|
break;
|
|
}
|
|
case XIT_FIELD:
|
|
xi_move_focus( obj );
|
|
ep->v.character.consumed = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if ( next_obj != NULL )
|
|
{
|
|
xi_move_focus_internal( next_obj, TRUE, FALSE, 0 );
|
|
retval = TRUE;
|
|
}
|
|
/* if the last focus was a button, and the current focus is not, or if
|
|
* the last focus was not a button, and the current focus is, then draw
|
|
* the default button, followed by the focus button. */
|
|
if ( xi_is_itf( xi_obj ) )
|
|
{
|
|
xi_draw_foc_and_dflt_if_necessary( focus_obj, next_obj );
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return ( retval );
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* draw_rectangles */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void
|
|
draw_rectangles( XI_OBJ* itf )
|
|
{
|
|
int num, num_members, num_rects, sorted_rects, rect_num;
|
|
XI_OBJ** objlist;
|
|
XI_OBJ** cur_obj;
|
|
XI_OBJ** rect_list;
|
|
|
|
/* Count the rectangles in the interface */
|
|
objlist = xi_get_member_list( itf, &num_members );
|
|
num_rects = 0;
|
|
for ( num = 0, cur_obj = objlist; num < num_members; num++, cur_obj++ )
|
|
if ( (*cur_obj)->type == XIT_RECT )
|
|
num_rects++;
|
|
if ( num_rects == 0 )
|
|
return;
|
|
|
|
/* Sort rectangles into proper drawing order */
|
|
rect_list = (XI_OBJ**)xi_tree_malloc( num_rects * sizeof(XI_OBJ*), NULL );
|
|
sorted_rects = 0;
|
|
for ( num = 0, cur_obj = objlist; num < num_members; num++, cur_obj++ )
|
|
if ( (*cur_obj)->type == XIT_RECT )
|
|
{
|
|
for ( rect_num = 0; rect_num < sorted_rects; rect_num++ )
|
|
{
|
|
XinRect intersect;
|
|
XinRect* sort_rect = &rect_list[ rect_num ]->v.rect->rct;
|
|
XinRectIntersect( &intersect, sort_rect, &(*cur_obj)->v.rect->rct );
|
|
if ( intersect.top == sort_rect->top && intersect.bottom == sort_rect->bottom
|
|
&& intersect.left == sort_rect->left && intersect.right == sort_rect->right )
|
|
break;
|
|
}
|
|
if ( rect_num == sorted_rects )
|
|
rect_list[ sorted_rects++ ] = *cur_obj;
|
|
else
|
|
{
|
|
memmove( rect_list + rect_num + 1, rect_list + rect_num,
|
|
( sorted_rects - rect_num ) * sizeof(XI_OBJ*) );
|
|
rect_list[ rect_num ] = *cur_obj;
|
|
sorted_rects++;
|
|
}
|
|
}
|
|
|
|
/* Draw rectangles in sorted order */
|
|
for ( num = 0; num < num_rects; num++ )
|
|
xi_draw_obj( rect_list[ num ] );
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* xi_send_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
static int
|
|
xi_send_event( XI_OBJ * xi_obj, XinEvent * ep, BOOLEAN do_subtree )
|
|
{
|
|
int n;
|
|
XI_OBJ **objlist;
|
|
BOOLEAN send_to_parent = FALSE;
|
|
int retval = 0;
|
|
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_TEXT:
|
|
case XIT_LINE:
|
|
if ( ep->type == XinEventPaint )
|
|
xi_draw_obj( xi_obj );
|
|
break;
|
|
case XIT_FIELD:
|
|
field_event( xi_obj, ep );
|
|
retval = stx_event( xi_obj->v.field->stx, ep );
|
|
send_to_parent = !retval;
|
|
|
|
/* don't send any character events (for navigation to the parent if
|
|
* pasting */
|
|
if ( ep->type == XinEventCharacter && xi_obj->itf->v.itf->pasting )
|
|
send_to_parent = FALSE;
|
|
break;
|
|
case XIT_CONTAINER:
|
|
send_to_parent = TRUE;
|
|
break;
|
|
case XIT_FORM:
|
|
send_to_parent = !form_event( xi_obj, ep );
|
|
break;
|
|
case XIT_BTN:
|
|
send_to_parent = !btn_event( xi_obj, ep );
|
|
break;
|
|
case XIT_LIST:
|
|
{
|
|
XI_OBJ *itf;
|
|
|
|
itf = xi_obj->itf;
|
|
if ( xi_obj->itf->v.itf->update_obj )
|
|
{
|
|
lm_event( itf, xi_obj->v.list->lm, ep );
|
|
send_to_parent = FALSE;
|
|
do_subtree = FALSE;
|
|
}
|
|
else
|
|
{
|
|
list_event( xi_obj, ep );
|
|
retval = lm_event( itf, xi_obj->v.list->lm, ep );
|
|
send_to_parent = !retval;
|
|
/* Don't broadcast events to columns */
|
|
do_subtree = FALSE;
|
|
}
|
|
if ( xi_is_itf( itf ) )
|
|
if ( xi_obj->itf->v.itf->pasting )
|
|
send_to_parent = FALSE;
|
|
break;
|
|
}
|
|
case XIT_ITF:
|
|
itf_event( xi_obj, ep );
|
|
break;
|
|
case XIT_CELL:
|
|
/* Send events to list as there is no handler for individual cells */
|
|
send_to_parent = TRUE;
|
|
break;
|
|
case XIT_COLUMN:
|
|
default:
|
|
/* ignored */
|
|
break;
|
|
}
|
|
if ( do_subtree && xi_obj->type != XIT_GROUP )
|
|
{
|
|
int retval;
|
|
XI_OBJ *itf = xi_obj->itf;
|
|
|
|
if ( xi_obj->type == XIT_ITF && ep->type == XinEventPaint )
|
|
draw_rectangles( xi_obj );
|
|
|
|
/* loop over sub-objects */
|
|
objlist = xi_get_member_list( xi_obj, &n );
|
|
for ( ; n > 0; n--, objlist++ )
|
|
{
|
|
retval = xi_send_event( *objlist, ep, do_subtree );
|
|
if (!xi_is_itf( itf ))
|
|
return retval;
|
|
/* after everything else is drawn, then if focus is on a button, draw it,
|
|
* and if there is a default button, draw it. */
|
|
if ( retval )
|
|
{
|
|
if ( xi_obj->type == XIT_ITF && ep->type == XinEventPaint )
|
|
xi_draw_foc_and_dflt( xi_obj );
|
|
return retval;
|
|
}
|
|
}
|
|
if ( xi_obj->type == XIT_ITF && ep->type == XinEventPaint )
|
|
xi_draw_foc_and_dflt( xi_obj );
|
|
}
|
|
if ( send_to_parent )
|
|
{
|
|
retval = xi_send_event( xi_obj->parent, ep, FALSE );
|
|
return retval;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
void
|
|
xi_event( XinWindow win, XinEvent * ep )
|
|
{
|
|
XI_OBJ *itf;
|
|
XI_EVENT xiev;
|
|
XI_ITF_DATA *itf_data;
|
|
BOOLEAN retval;
|
|
XinCursor new_cursor;
|
|
|
|
if ( win == XI_NULL_WINDOW )
|
|
win = XinWindowFocusGet( );
|
|
if ( win == XI_NULL_WINDOW )
|
|
return;
|
|
if ( ( itf = xi_get_itf( win ) ) == NULL )
|
|
{
|
|
if ( ep->type == XinEventCreate && xi_creating_itf != NULL )
|
|
{
|
|
xi_finish_interface_create( win );
|
|
xi_creating_itf = NULL;
|
|
if ( ( itf = xi_get_itf( win ) ) == NULL )
|
|
return;
|
|
if ( itf->v.itf->dequeue == XI_DEQUEUE_INIT && itf->v.itf->modal_wait )
|
|
{
|
|
xi_dequeue( );
|
|
itf->v.itf->dequeue = XI_DEQUEUE_COMPLETE;
|
|
}
|
|
}
|
|
else
|
|
return;
|
|
}
|
|
itf_data = itf->v.itf;
|
|
|
|
MEMCLEAR( xiev );
|
|
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
|
|
{
|
|
xiev.type = XIE_XIN_EVENT;
|
|
xiev.v.xin_event = *ep;
|
|
}
|
|
#ifdef XI_USE_XVT
|
|
else
|
|
{
|
|
xiev.type = XIE_XVT_EVENT;
|
|
XinXvtEventGet( &xiev.v.xvte );
|
|
}
|
|
#endif
|
|
xiev.refused = FALSE;
|
|
if ( !call_cb( itf, &xiev ) )
|
|
return;
|
|
if ( xiev.refused )
|
|
return;
|
|
|
|
/* RGM: Do we need to allow the event to change with R3 support? */
|
|
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_R4_API ) )
|
|
*ep = xiev.v.xin_event;
|
|
|
|
if ( ep->type == XinEventMouseUp )
|
|
XinWindowMouseRelease( );
|
|
|
|
if ( !xi_eh( win, ep ) )
|
|
return;
|
|
|
|
if ( itf_data->dequeue == XI_DEQUEUE_CALL && !itf_data->modal_wait )
|
|
{
|
|
xi_dequeue( );
|
|
itf_data->dequeue = XI_DEQUEUE_COMPLETE;
|
|
if (itf_data->needs_update)
|
|
XinWindowRectInvalidate( itf_data->xin_win, NULL );
|
|
}
|
|
MEMCLEAR( xiev );
|
|
switch ( ep->type )
|
|
{
|
|
case XinEventTimer:
|
|
{
|
|
xi_send_event( itf, ep, TRUE );
|
|
break;
|
|
}
|
|
case XinEventPaint:
|
|
{
|
|
if ( itf_data->dequeue != XI_DEQUEUE_COMPLETE )
|
|
{
|
|
itf_data->needs_update = TRUE;
|
|
do_post_event( itf, ep );
|
|
return;
|
|
}
|
|
if ( itf_data->update_obj )
|
|
{
|
|
xi_send_event( itf_data->update_obj, ep, FALSE );
|
|
itf_data->update_obj = NULL;
|
|
}
|
|
else
|
|
{
|
|
itf->v.itf->half_baked = FALSE;
|
|
draw_background( itf );
|
|
|
|
xi_send_event( itf, ep, TRUE );
|
|
}
|
|
break;
|
|
}
|
|
case XinEventMouseDown:
|
|
case XinEventMouseDouble:
|
|
{
|
|
XI_OBJ *itf2;
|
|
|
|
itf2 = itf;
|
|
itf_data->mouse_is_down = TRUE;
|
|
xi_send_event( itf, ep, TRUE );
|
|
if ( xi_is_itf( itf2 ) )
|
|
if ( !itf_data->trap_explicit )
|
|
itf_data->trap_obj = itf_data->focus_obj;
|
|
break;
|
|
}
|
|
case XinEventCharacter:
|
|
if ( ep->v.character.ch == XI_KEY_BTAB )
|
|
ep->v.character.shift = FALSE;
|
|
if ( itf_data->focus_obj != NULL )
|
|
xi_send_event( itf_data->focus_obj, ep, FALSE );
|
|
update_menus( );
|
|
break;
|
|
case XinEventResize:
|
|
xi_send_event( itf, ep, TRUE );
|
|
break;
|
|
case XinEventMouseUp:
|
|
#ifndef NO_PRIMARY_SELECTION
|
|
#if XIWS == XIWS_XM
|
|
if ( ep->v.mouse.button == 2 )
|
|
get_primary_selection( itf, win );
|
|
#endif
|
|
#endif
|
|
itf_data->mouse_is_down = FALSE;
|
|
if ( xi_get_drag_list_obj( ) )
|
|
lm_event( itf, xi_get_drag_list_obj( )->v.list->lm, ep );
|
|
else if ( itf_data->trap_obj != NULL )
|
|
xi_send_event( itf_data->trap_obj, ep, FALSE );
|
|
if ( xi_is_itf( itf ) )
|
|
{
|
|
itf_data->trap_obj = NULL;
|
|
itf_data->trap_explicit = FALSE;
|
|
update_menus( );
|
|
}
|
|
break;
|
|
case XinEventMouseMove:
|
|
if ( xi_get_drag_list_obj( ) )
|
|
lm_event( itf, xi_get_drag_list_obj( )->v.list->lm, ep );
|
|
else if ( itf_data->trap_obj != NULL )
|
|
xi_send_event( itf_data->trap_obj, ep, FALSE );
|
|
else
|
|
{
|
|
if ( !itf_data->mouse_is_down )
|
|
{
|
|
retval = xi_send_event( itf, ep, TRUE );
|
|
switch ( retval )
|
|
{
|
|
case 0:
|
|
new_cursor = XI_CURSOR_ARROW;
|
|
break;
|
|
case 1:
|
|
new_cursor = XI_CURSOR_IBEAM;
|
|
break;
|
|
case 2:
|
|
new_cursor =
|
|
( XinCursor ) xi_get_pref( XI_PREF_SIZE_CURSOR_RID );
|
|
break;
|
|
case 3:
|
|
new_cursor =
|
|
( XinCursor ) xi_get_pref( XI_PREF_HAND_CURSOR_RID );
|
|
break;
|
|
case 4:
|
|
new_cursor = XI_CURSOR_CROSS;
|
|
break;
|
|
case 5:
|
|
new_cursor = XI_CURSOR_ARROW;
|
|
break;
|
|
case 6:
|
|
new_cursor =
|
|
( XinCursor ) xi_get_pref( XI_PREF_VSIZE_CURSOR_RID );
|
|
break;
|
|
}
|
|
if ( itf_data->cursor != new_cursor && !itf_data->cursor_override )
|
|
{
|
|
XinWindowCursorSet( itf_data->xin_win, new_cursor );
|
|
itf_data->cursor = new_cursor;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case XinEventMenuCommand:
|
|
{
|
|
XinWindow win;
|
|
|
|
xiev.v.cmd.tag = ep->v.menu_command.tag;
|
|
xiev.v.cmd.shift = ep->v.menu_command.shift;
|
|
xiev.v.cmd.control = ep->v.menu_command.control;
|
|
xiev.type = XIE_COMMAND;
|
|
win = itf_data->xin_win;
|
|
call_cb( itf, &xiev );
|
|
if ( xi_is_window( win ) )
|
|
if ( itf_data->focus_obj != NULL )
|
|
xi_send_event( itf_data->focus_obj, ep, FALSE );
|
|
}
|
|
if ( xi_is_itf( itf ) )
|
|
do_edit_menu( itf, ep );
|
|
break;
|
|
case XinEventFocus:
|
|
update_menus( );
|
|
break;
|
|
case XinEventDestroy:
|
|
{
|
|
itf->v.itf->in_event_destroy = TRUE;
|
|
destroy_controls( itf );
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
xi_xvt_tx_event( win, ep );
|
|
#endif
|
|
xiev.type = XIE_CLEANUP;
|
|
xiev.v.xi_obj = itf;
|
|
call_cb( itf, &xiev );
|
|
xi_remove_window_from_list( win );
|
|
|
|
/* free the whole interface tree */
|
|
xi_tree_free( ( char * ) itf );
|
|
break;
|
|
}
|
|
case XinEventCloseButton:
|
|
xiev.type = XIE_CLOSE;
|
|
xiev.v.xi_obj = itf;
|
|
call_cb( itf, &xiev );
|
|
if ( xi_is_itf( itf ) && !xiev.refused )
|
|
xi_delete( itf );
|
|
break;
|
|
case XinEventQuit:
|
|
if ( ep->v.quit.query )
|
|
XinAppQuitOk( );
|
|
else
|
|
XinAppTerminate( );
|
|
break;
|
|
case XinEventHScroll:
|
|
case XinEventVScroll:
|
|
/* handle XinEventHScroll, etc if list is using window scroll bars */
|
|
break;
|
|
case XinEventControl:
|
|
control_event( itf, win, ep );
|
|
update_menus( );
|
|
break;
|
|
case XinEventHelp:
|
|
{
|
|
XI_OBJ *focus = xi_get_focus( itf );
|
|
if (focus != NULL && focus->help_key != NULL)
|
|
XinNativeHelp( win, focus->help_key );
|
|
else if ( itf->help_key != NULL )
|
|
XinNativeHelp( win, itf->help_key );
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( ep->type == XinEventPaint )
|
|
{
|
|
/* send XVT event */
|
|
MEMCLEAR( xiev );
|
|
xiev.type = XIE_UPDATE;
|
|
xiev.v.xin_event = *ep;
|
|
xiev.refused = FALSE;
|
|
call_cb( itf, &xiev );
|
|
xi_set_clip( xi_get_window( itf ), NULL );
|
|
}
|
|
|
|
do_post_event( itf, ep );
|
|
}
|
|
|
|
long
|
|
xi_get_app_data( XI_OBJ * xi_obj )
|
|
{
|
|
return ( xi_obj->app_data );
|
|
}
|
|
|
|
long
|
|
xi_get_app_data2( XI_OBJ * xi_obj )
|
|
{
|
|
return ( xi_obj->app_data2 );
|
|
}
|
|
|
|
unsigned long
|
|
xi_get_attrib( XI_OBJ * xi_obj )
|
|
{
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_COLUMN:
|
|
return ( lm_get_attrib( xi_obj->parent->v.list->lm, LM_COLUMN,
|
|
xi_obj_to_idx( xi_obj ), 0, FALSE ) );
|
|
case XIT_LIST:
|
|
return ( lm_get_attrib( xi_obj->v.list->lm, LM_LIST, 0, 0, FALSE ) );
|
|
case XIT_ROW:
|
|
return ( lm_get_attrib( xi_obj->parent->v.list->lm, LM_ROW,
|
|
xi_obj->v.row, 0, FALSE ) );
|
|
case XIT_CELL:
|
|
return ( lm_get_attrib( xi_obj->parent->v.list->lm, LM_CELL,
|
|
xi_obj->v.cell.row, xi_obj->v.cell.column,
|
|
xi_obj->v.cell.is_vert_scrolled ) );
|
|
case XIT_BTN:
|
|
return ( xi_obj->v.btn->attrib );
|
|
case XIT_CONTAINER:
|
|
/* pretend that containers have attributes, and that they are always
|
|
* visible and enabled */
|
|
return XI_ATR_ENABLED | XI_ATR_VISIBLE;
|
|
case XIT_FORM:
|
|
return ( xi_obj->v.form->attrib );
|
|
case XIT_FIELD:
|
|
return ( stx_get_attrib( xi_obj->v.field->stx ) );
|
|
case XIT_TEXT:
|
|
return ( xi_obj->v.text->attrib );
|
|
case XIT_LINE:
|
|
return ( xi_obj->v.line->attrib );
|
|
case XIT_RECT:
|
|
return ( xi_obj->v.rect->attrib );
|
|
case XIT_GROUP:
|
|
return 0L;
|
|
default:
|
|
XinError( 20018, XinSeverityFatal, 0L );
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
XI_OBJ *
|
|
xi_get_focus( XI_OBJ * itf )
|
|
{
|
|
XinWindow win;
|
|
|
|
if ( itf != NULL )
|
|
return ( itf->v.itf->focus_obj );
|
|
else if ( ( win = XinWindowFocusGet( ) ) == XI_NULL_WINDOW )
|
|
return ( NULL );
|
|
else if ( xi_is_window( win ) )
|
|
{
|
|
XI_OBJ *itf;
|
|
|
|
itf = xi_get_itf( win );
|
|
return ( itf->v.itf->focus_obj );
|
|
}
|
|
else
|
|
return ( NULL );
|
|
}
|
|
|
|
long *
|
|
xi_get_list_info( XI_OBJ * xi_obj, int *nbr_recs )
|
|
{
|
|
if ( xi_obj->type != XIT_LIST )
|
|
XinError( 20020, XinSeverityFatal, 0L );
|
|
return lm_get_list_info( xi_obj->v.list->lm, nbr_recs );
|
|
}
|
|
|
|
XI_OBJ **
|
|
xi_get_member_list( XI_OBJ * xi_obj, int *nbr_members )
|
|
{
|
|
int i;
|
|
XI_OBJ *obj;
|
|
XI_GROUP_DATA *groupdata;
|
|
|
|
if ( xi_obj->type == XIT_GROUP )
|
|
{
|
|
groupdata = xi_obj->v.group;
|
|
if ( groupdata->objlist != NULL )
|
|
xi_tree_free( groupdata->objlist );
|
|
groupdata->objlist =
|
|
( XI_OBJ * * ) xi_tree_malloc( sizeof( XI_OBJ * ) * groupdata->nbr_cids, xi_obj );
|
|
*nbr_members = 0;
|
|
for ( i = 0; i < groupdata->nbr_cids; i++ )
|
|
{
|
|
obj = xi_get_obj( xi_obj->itf, groupdata->cidlist[i] );
|
|
if ( obj != NULL )
|
|
{
|
|
groupdata->objlist[*nbr_members] = obj;
|
|
( *nbr_members )++;
|
|
}
|
|
}
|
|
return ( groupdata->objlist );
|
|
}
|
|
else
|
|
{
|
|
*nbr_members = xi_obj->nbr_children;
|
|
return ( xi_obj->children );
|
|
}
|
|
}
|
|
|
|
/*
|
|
xi_get_obj: retrieve an XI_OBJ from the interface tree given its cid.
|
|
Although externally documented to work only on XIT_ITF,
|
|
this will start searching at any point in the interface tree.
|
|
|
|
xi_get_obj will ignore NULL objects so it can be used in the middle
|
|
of creating an interface tree.
|
|
*/
|
|
XI_OBJ *
|
|
xi_get_obj( XI_OBJ * obj, int cid )
|
|
{
|
|
XI_OBJ **objlist;
|
|
XI_OBJ *temp;
|
|
int n;
|
|
|
|
if ( obj->cid == cid )
|
|
return ( obj );
|
|
|
|
switch ( obj->type )
|
|
{
|
|
case XIT_GROUP:
|
|
case XIT_CELL:
|
|
case XIT_ROW:
|
|
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_ASSERT_ON_NULL_CID ) )
|
|
XinError( 30207, XinSeverityFatal, 0L );
|
|
return ( NULL );
|
|
default:
|
|
break;
|
|
}
|
|
|
|
/* search in child list */
|
|
objlist = xi_get_member_list( obj, &n );
|
|
for ( ; n > 0; n--, objlist++ )
|
|
{
|
|
/* call recursively for generality in future versions */
|
|
if ( ( temp = xi_get_obj( *objlist, cid ) ) != NULL )
|
|
return ( temp );
|
|
}
|
|
return ( NULL );
|
|
}
|
|
|
|
XinRect *
|
|
xi_get_rect( XI_OBJ * xi_obj, XinRect * rctp )
|
|
{
|
|
return xi_get_rect_internal( xi_obj, rctp, NULL, NULL );
|
|
}
|
|
|
|
XinRect *
|
|
xi_get_rect_internal( XI_OBJ * xi_obj, XinRect * rctp, XinRect * old_win_rct, XinRect * new_win_rct )
|
|
{
|
|
XI_OBJ **objp;
|
|
XinRect rct;
|
|
int i,
|
|
n;
|
|
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_CONTAINER:
|
|
*rctp = xi_obj->v.container->rct;
|
|
break;
|
|
case XIT_BTN:
|
|
*rctp = xi_obj->v.btn->rct;
|
|
break;
|
|
case XIT_COLUMN:
|
|
lm_get_rect( xi_obj->parent->v.list->lm, LM_COLUMN,
|
|
xi_obj_to_idx( xi_obj ), rctp );
|
|
break;
|
|
case XIT_ROW:
|
|
if ( xi_obj->v.row_data.is_vert_scrolled )
|
|
memset( ( char * ) rctp, 0, sizeof( *rctp ) );
|
|
else
|
|
{
|
|
lm_get_rect( xi_obj->parent->v.list->lm, LM_ROW,
|
|
xi_obj->v.row, rctp );
|
|
}
|
|
break;
|
|
case XIT_LIST:
|
|
lm_get_rect( xi_obj->v.list->lm, LM_LIST, 0, rctp );
|
|
if ( xi_obj->v.list->scroll_bar )
|
|
{
|
|
xi_get_sb_rect( xi_obj, &rct );
|
|
rctp->right = rct.right;
|
|
}
|
|
if ( xi_obj->v.list->width )
|
|
{
|
|
xi_get_hsb_rect( xi_obj, &rct );
|
|
rctp->bottom = rct.bottom;
|
|
}
|
|
if ( old_win_rct )
|
|
{
|
|
rctp->bottom = ( int ) ( ( long ) rctp->bottom * new_win_rct->bottom / old_win_rct->bottom );
|
|
rctp->right = ( int ) ( ( long ) rctp->right * new_win_rct->right / old_win_rct->right );
|
|
}
|
|
break;
|
|
case XIT_ITF:
|
|
case XIT_FORM:
|
|
{
|
|
BOOLEAN first_rect = TRUE;
|
|
|
|
objp = xi_obj->children;
|
|
n = xi_obj->nbr_children;
|
|
for ( i = 0; i < n; objp++, i++ )
|
|
{
|
|
if ( xi_get_rect_internal( *objp, &rct, old_win_rct, new_win_rct ) != NULL )
|
|
{
|
|
if ( first_rect )
|
|
{
|
|
first_rect = FALSE;
|
|
*rctp = rct;
|
|
}
|
|
else
|
|
XinRectEnclose( rctp, &rct, rctp );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case XIT_FIELD:
|
|
{
|
|
XI_FIELD_DATA *fd;
|
|
|
|
fd = xi_obj->v.field;
|
|
stx_get_rect( fd->stx, rctp );
|
|
if ( fd->button )
|
|
{
|
|
if ( fd->button_on_left )
|
|
rctp->left = fd->btn_rct.left;
|
|
else
|
|
rctp->right = fd->btn_rct.right;
|
|
}
|
|
break;
|
|
}
|
|
case XIT_TEXT:
|
|
*rctp = xi_obj->v.text->rct;
|
|
break;
|
|
case XIT_RECT:
|
|
*rctp = xi_obj->v.rect->rct;
|
|
break;
|
|
case XIT_LINE:
|
|
{
|
|
XI_LINE_DATA *line;
|
|
|
|
line = xi_obj->v.line;
|
|
rctp->top = min( line->pnt1.v, line->pnt2.v );
|
|
rctp->bottom = max( line->pnt1.v, line->pnt2.v );
|
|
rctp->left = min( line->pnt1.h, line->pnt2.h );
|
|
rctp->right = max( line->pnt1.h, line->pnt2.h );
|
|
break;
|
|
}
|
|
case XIT_GROUP:
|
|
/* bounding rect is undefined */
|
|
return ( NULL );
|
|
case XIT_CELL:
|
|
{
|
|
XI_OBJ row;
|
|
XI_OBJ *col;
|
|
XI_OBJ **members;
|
|
int nbr_members;
|
|
int row_nbr,
|
|
col_nbr;
|
|
XinRect row_rct,
|
|
col_rct;
|
|
|
|
if ( xi_obj->v.cell.is_vert_scrolled )
|
|
memset( ( char * ) rctp, 0, sizeof( *rctp ) );
|
|
else
|
|
{
|
|
row_nbr = xi_obj->v.cell.row;
|
|
col_nbr = xi_obj->v.cell.column;
|
|
XI_MAKE_ROW( &row, xi_obj->parent, row_nbr );
|
|
xi_get_rect_internal( &row, &row_rct, old_win_rct, new_win_rct );
|
|
members = xi_get_member_list( xi_obj->parent, &nbr_members );
|
|
col = members[col_nbr];
|
|
xi_get_rect_internal( col, &col_rct, old_win_rct, new_win_rct );
|
|
xi_rect_intersect( rctp, &row_rct, &col_rct );
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
XinError( 20021, XinSeverityFatal, 0L );
|
|
}
|
|
return ( rctp );
|
|
}
|
|
|
|
void
|
|
xi_set_rect_internal( XI_OBJ * xi_obj, XinRect * rctp )
|
|
{
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_CONTAINER:
|
|
{
|
|
xi_container_set_rect_internal( xi_obj, rctp );
|
|
break;
|
|
}
|
|
case XIT_BTN:
|
|
xi_obj->v.btn->rct = *rctp;
|
|
break;
|
|
case XIT_LIST:
|
|
lm_set_rect( xi_obj->v.list->lm, rctp );
|
|
break;
|
|
case XIT_FIELD:
|
|
{
|
|
xi_field_set_rect_internal( xi_obj, rctp );
|
|
break;
|
|
}
|
|
case XIT_TEXT:
|
|
xi_obj->v.text->rct = *rctp;
|
|
break;
|
|
case XIT_RECT:
|
|
xi_obj->v.rect->rct = *rctp;
|
|
break;
|
|
case XIT_LINE:
|
|
{
|
|
/* We generate a point which is the change between old and new. */
|
|
XI_LINE_DATA *line;
|
|
XinPoint point;
|
|
|
|
line = xi_obj->v.line;
|
|
point.v = min( line->pnt1.v, line->pnt2.v );
|
|
point.v = rctp->top - point.v;
|
|
point.h = min( line->pnt1.h, line->pnt2.h );
|
|
point.h = rctp->left - point.h;
|
|
line->pnt1.v += point.v;
|
|
line->pnt1.h += point.h;
|
|
line->pnt2.v += point.v;
|
|
line->pnt2.h += point.h;
|
|
break;
|
|
}
|
|
default:
|
|
XinError( 20032, XinSeverityFatal, 0L );
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_rect( XI_OBJ * xi_obj, XinRect * rctp, BOOLEAN do_invalidates )
|
|
{
|
|
XinRect old_rect;
|
|
XinWindow win;
|
|
if (do_invalidates)
|
|
{
|
|
win = xi_get_window( xi_obj );
|
|
xi_get_rect_internal( xi_obj, &old_rect, NULL, NULL );
|
|
XinWindowRectInvalidate( win, &old_rect );
|
|
}
|
|
|
|
xi_set_rect_internal( xi_obj, rctp );
|
|
|
|
if (do_invalidates)
|
|
{
|
|
xi_get_rect_internal( xi_obj, &old_rect, NULL, NULL );
|
|
XinWindowRectInvalidate( win, &old_rect );
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_get_sel( XI_OBJ * xi_obj, int *selstart, int *selstop )
|
|
{
|
|
XI_OBJ *focus_obj;
|
|
BOOLEAN is_focus;
|
|
|
|
focus_obj = xi_get_focus( xi_obj->itf );
|
|
/* check if the passed object is the focus object */
|
|
if ( focus_obj == NULL )
|
|
is_focus = FALSE; /* no focus */
|
|
else if ( focus_obj == xi_obj )
|
|
is_focus = TRUE; /* object is the focus object */
|
|
else if ( focus_obj->type != XIT_CELL || xi_obj->type != XIT_CELL )
|
|
is_focus = FALSE; /* objects are not both cells */
|
|
else /* both objects are temporary cell objects */
|
|
is_focus = ( xi_obj->v.cell.row == focus_obj->v.cell.row
|
|
&& xi_obj->v.cell.column == focus_obj->v.cell.column );
|
|
/* it's the focus if the row & column are */
|
|
/* the same */
|
|
if ( !is_focus )
|
|
{
|
|
/* selection is only valid for focus object */
|
|
*selstart = *selstop = 0;
|
|
return;
|
|
}
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_CELL:
|
|
if ( focus_obj->v.cell.is_vert_scrolled )
|
|
lm_focus_cell_selection_get( ( LM_DATA * ) xi_obj->parent->v.list->lm, selstart, selstop );
|
|
else
|
|
lm_get_sel( xi_obj->parent->v.list->lm, selstart, selstop );
|
|
break;
|
|
case XIT_FIELD:
|
|
stx_get_sel( xi_obj->v.field->stx, selstart, selstop );
|
|
break;
|
|
case XIT_COLUMN:
|
|
case XIT_ITF:
|
|
case XIT_LIST:
|
|
case XIT_ROW:
|
|
case XIT_BTN:
|
|
case XIT_FORM:
|
|
case XIT_GROUP:
|
|
case XIT_TEXT:
|
|
XinError( 20022, XinSeverityFatal, 0L );
|
|
break;
|
|
}
|
|
}
|
|
|
|
char *
|
|
xi_get_text( XI_OBJ * xi_obj, char *s, int len )
|
|
{
|
|
char *b;
|
|
|
|
b = NULL;
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_CELL:
|
|
b = lm_get_text( xi_obj->parent->v.list->lm, s, len,
|
|
xi_obj->v.cell.row, xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled );
|
|
break;
|
|
case XIT_COLUMN:
|
|
b = lm_get_text( xi_obj->parent->v.list->lm, s, len,
|
|
LM_HEADING_TEXT, xi_obj_to_idx( xi_obj ), FALSE );
|
|
break;
|
|
case XIT_ITF:
|
|
b = XinWindowTitleGet( xi_obj->v.itf->xin_win );
|
|
break;
|
|
case XIT_ROW:
|
|
XinError( 20023, XinSeverityFatal, 0L );
|
|
case XIT_BTN:
|
|
b = xi_obj->v.btn->text;
|
|
break;
|
|
case XIT_FIELD:
|
|
b = stx_get_text( xi_obj->v.field->stx, s, len );
|
|
break;
|
|
case XIT_TEXT:
|
|
{
|
|
XI_TEXT_DATA *text_data;
|
|
|
|
text_data = xi_obj->v.text;
|
|
b = text_data->text;
|
|
}
|
|
break;
|
|
case XIT_LIST:
|
|
case XIT_GROUP:
|
|
case XIT_FORM:
|
|
if ( s )
|
|
*s = '\0';
|
|
break;
|
|
}
|
|
if ( s && b )
|
|
tstrncpy( s, b, len );
|
|
return b;
|
|
}
|
|
|
|
XinWindow
|
|
xi_get_window( XI_OBJ * xi_obj )
|
|
{
|
|
return ( xi_obj->itf->v.itf->xin_win );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
function: xi_scroll_rec
|
|
xi_obj: list object to scroll. Must be a list object.
|
|
rec: first record to go to
|
|
color: color of row
|
|
attrib: attribute of row
|
|
-------------------------------------------------------------------------*/
|
|
int
|
|
xi_scroll_rec( XI_OBJ * xi_obj, long rec, XinColor color, unsigned long attrib, int row_height )
|
|
{
|
|
LM_SCROLL_ARG arg;
|
|
|
|
if ( xi_obj->type != XIT_LIST )
|
|
XinError( 20024, XinSeverityFatal, 0L );
|
|
xi_obj->v.list->done_initial_xi_scroll = TRUE;
|
|
MEMCLEAR( arg );
|
|
arg.lm = xi_obj->v.list->lm;
|
|
/* arg.nbr_lines = 0; arg.percent = 0; arg.same_cell = 0; */
|
|
arg.rec = rec;
|
|
arg.have_rec = TRUE;
|
|
arg.color = color;
|
|
arg.attrib = attrib;
|
|
arg.row_height = row_height;
|
|
arg.rec_at_top = TRUE;
|
|
return lm_scroll( &arg );
|
|
}
|
|
|
|
/*
|
|
typedef struct _xi_scroll_record_arg
|
|
{
|
|
XI_OBJ* xi_obj;
|
|
long record;
|
|
COLOR row_color;
|
|
unsigned long attrib;
|
|
int row_height;
|
|
BOOLEAN rec_at_top;
|
|
} XI_SCROLL_RECORD_ARG;
|
|
*/
|
|
int
|
|
xi_scroll_record( XI_SCROLL_RECORD_ARG * arg )
|
|
{
|
|
LM_SCROLL_ARG lm_scroll_arg;
|
|
XI_OBJ *xi_obj = arg->xi_obj;
|
|
|
|
xi_obj->v.list->done_initial_xi_scroll = TRUE;
|
|
MEMCLEAR( lm_scroll_arg );
|
|
lm_scroll_arg.lm = xi_obj->v.list->lm;
|
|
/* lm_scroll_arg.nbr_lines = 0; lm_scroll_arg.percent = 0;
|
|
* lm_scroll_arg.same_cell = 0; */
|
|
lm_scroll_arg.rec = arg->record;
|
|
lm_scroll_arg.have_rec = TRUE;
|
|
lm_scroll_arg.color = arg->row_color;
|
|
lm_scroll_arg.attrib = arg->attrib;
|
|
lm_scroll_arg.row_height = arg->row_height;
|
|
lm_scroll_arg.rec_at_top = arg->rec_at_top;
|
|
return lm_scroll( &lm_scroll_arg );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------------
|
|
function: xi_scroll_internal
|
|
xi_obj: list object to scroll. Must be a list object.
|
|
nbr_lines: nbr of lines to scroll, may be positive or negative, may be set
|
|
to XI_SCROLL_FIRST, XI_SCROLL_LAST, XI_SCROLL_PGUP, or XI_SCROLL_PGDN
|
|
percent: passed with XI_SCROLL_FIRST event
|
|
same_cell: sometimes the focus goes back onto the same cell. In other cases,
|
|
for instance, XI_SCROLL_FIRST, XI_SCROLL_LAST, XI_SCROLL_PGUP, and
|
|
XI_SCROLL_PGDN, we don't want to put the focus back on the same cell,
|
|
but instead, want to put the focus on the first or last fully visible
|
|
row.
|
|
invalidate: indicates whether to invalidate the list. This is only set to FALSE when xi_scroll_internal is
|
|
called when the interface is created.
|
|
-------------------------------------------------------------------------*/
|
|
int
|
|
xi_scroll_internal( XI_OBJ * xi_obj, int nbr_lines, int percent,
|
|
BOOLEAN same_cell )
|
|
{
|
|
LM_SCROLL_ARG arg;
|
|
|
|
if ( xi_obj->type != XIT_LIST )
|
|
XinError( 20037, XinSeverityFatal, 0L );
|
|
xi_obj->v.list->done_initial_xi_scroll = TRUE;
|
|
MEMCLEAR( arg );
|
|
arg.lm = xi_obj->v.list->lm;
|
|
arg.nbr_lines = nbr_lines;
|
|
arg.percent = percent;
|
|
arg.same_cell = same_cell;
|
|
arg.rec_at_top = TRUE;
|
|
/* arg.rec = 0; arg.have_rec = FALSE; arg.color = 0L; arg.attrib = 0L;
|
|
* arg.row_height = 0; */
|
|
return lm_scroll( &arg );
|
|
}
|
|
|
|
BOOLEAN
|
|
xi_delete_row( XI_OBJ * xi_obj )
|
|
{
|
|
int row;
|
|
XI_OBJ *list_obj;
|
|
BOOLEAN rv;
|
|
|
|
if ( xi_obj->type != XIT_ROW )
|
|
XinError( 20025, XinSeverityFatal, 0L );
|
|
list_obj = xi_obj->parent;
|
|
row = xi_obj->v.row;
|
|
rv = lm_delete_row( list_obj->v.list->lm, row );
|
|
return rv;
|
|
}
|
|
|
|
BOOLEAN
|
|
xi_insert_row( XI_OBJ * list, int row )
|
|
{
|
|
BOOLEAN rv;
|
|
|
|
if ( list->type != XIT_LIST )
|
|
XinError( 20026, XinSeverityFatal, 0L );
|
|
rv = lm_insert_row( list->v.list->lm, row );
|
|
return rv;
|
|
}
|
|
|
|
int
|
|
xi_scroll( XI_OBJ * xi_obj, int nbr_lines )
|
|
{
|
|
return ( xi_scroll_internal( xi_obj, nbr_lines, 0, ( BOOLEAN ) ( nbr_lines < 1000 ) ) );
|
|
}
|
|
|
|
int
|
|
xi_scroll_percent( XI_OBJ * xi_obj, int percent )
|
|
{
|
|
return ( xi_scroll_internal( xi_obj, XI_SCROLL_FIRST, percent, FALSE ) );
|
|
}
|
|
|
|
void
|
|
xi_set_app_data( XI_OBJ * xi_obj, long app_data )
|
|
{
|
|
xi_obj->app_data = app_data;
|
|
}
|
|
|
|
void
|
|
xi_set_app_data2( XI_OBJ * xi_obj, long app_data )
|
|
{
|
|
xi_obj->app_data2 = app_data;
|
|
}
|
|
|
|
void
|
|
xi_set_fore_color( XI_OBJ * xi_obj, XinColor color )
|
|
{
|
|
XinRect rct;
|
|
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_ROW:
|
|
lm_set_color( xi_obj->parent->v.list->lm, LM_ROW, xi_obj->v.row,
|
|
0, FALSE, color, FALSE );
|
|
break;
|
|
case XIT_CELL:
|
|
{
|
|
LM_DATA *lmp = LMP( xi_obj->parent->v.list->lm );
|
|
int idx = xi_obj->v.cell.row;
|
|
int idx2 = xi_obj->v.cell.column;
|
|
BOOLEAN do_redraw = ( lmp->cell_data[idx][idx2].color != color );
|
|
|
|
lm_set_color( xi_obj->parent->v.list->lm, LM_CELL, xi_obj->v.cell.row,
|
|
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled, color,
|
|
FALSE );
|
|
if ( do_redraw )
|
|
{
|
|
xi_get_rect( xi_obj, &rct );
|
|
xi_invalidate_rect( xi_get_window( xi_obj->itf ), &rct );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_attrib( XI_OBJ * xi_obj, unsigned long attrib )
|
|
{
|
|
int n;
|
|
XI_OBJ **objlist;
|
|
unsigned long attrib_diff;
|
|
XinWindow win = xi_obj->itf->v.itf->xin_win;
|
|
|
|
attrib_diff = xi_get_attrib( xi_obj ) ^ attrib;
|
|
if ( !( attrib & XI_ATR_VISIBLE ) )
|
|
{
|
|
XI_OBJ *focus_obj,
|
|
*next_obj;
|
|
|
|
focus_obj = xi_get_focus( xi_obj->itf );
|
|
if ( focus_obj == xi_obj ||
|
|
( focus_obj != NULL && focus_obj->type == XIT_CELL && focus_obj->parent == xi_obj ) )
|
|
{
|
|
if ( xi_obj->itf->v.itf->moving_focus )
|
|
return;
|
|
next_obj = xi_find_next_obj( focus_obj, XI_NEXT_ITF_TAB,
|
|
XI_PREF_ITF_TAB_CHAR );
|
|
if ( next_obj == focus_obj || ( focus_obj->type == XIT_CELL && focus_obj->parent == next_obj ) )
|
|
next_obj = next_obj->itf;
|
|
xi_move_focus( next_obj );
|
|
}
|
|
}
|
|
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_BTN:
|
|
if ( !xi_get_native_controls( xi_obj ) )
|
|
{
|
|
XI_BTN_DATA *bd;
|
|
XinRect r;
|
|
|
|
bd = xi_obj->v.btn;
|
|
r = bd->rct;
|
|
if ( bd->type == XIBT_TABBTN )
|
|
r.bottom += 2;
|
|
xi_invalidate_rect( win, &r );
|
|
}
|
|
else
|
|
{
|
|
if ( attrib_diff & XI_ATR_VISIBLE )
|
|
{
|
|
XinWindow btn_win;
|
|
|
|
btn_win = xi_obj->v.btn->btnctl;
|
|
XinWindowShow( btn_win, ( BOOLEAN ) ( ( attrib & XI_ATR_VISIBLE )
|
|
!= 0 ) );
|
|
xi_invalidate_rect( win, &xi_obj->v.btn->rct );
|
|
}
|
|
if ( attrib_diff & XI_ATR_ENABLED )
|
|
XinWindowEnable( xi_obj->v.btn->btnctl,
|
|
( BOOLEAN ) ( ( attrib & XI_ATR_ENABLED ) != 0 ) );
|
|
}
|
|
xi_obj->v.btn->attrib = attrib;
|
|
break;
|
|
case XIT_FORM:
|
|
/* loop over sub-objects */
|
|
objlist = xi_get_member_list( xi_obj, &n );
|
|
for ( ; n > 0; n--, objlist++ )
|
|
xi_set_attrib( *objlist, attrib );
|
|
break;
|
|
case XIT_FIELD:
|
|
{
|
|
XinRect rct;
|
|
XI_FIELD_DATA *fd;
|
|
|
|
stx_set_attrib( xi_obj->v.field->stx, attrib );
|
|
fd = xi_obj->v.field;
|
|
rct = fd->rct;
|
|
if ( fd->button )
|
|
if ( !fd->button_on_left )
|
|
rct.right = fd->btn_rct.right;
|
|
xi_invalidate_rect( win, &rct );
|
|
break;
|
|
}
|
|
case XIT_GROUP:
|
|
/* it is not clear how to get the proper behaviour here */
|
|
break;
|
|
case XIT_LINE:
|
|
{
|
|
XinRect rct;
|
|
XI_LINE_DATA *ld;
|
|
|
|
ld = xi_obj->v.line;
|
|
rct.top = min( ld->pnt1.v, ld->pnt2.v );
|
|
rct.bottom = max( ld->pnt1.v, ld->pnt2.v );
|
|
rct.left = min( ld->pnt1.h, ld->pnt2.h );
|
|
rct.right = max( ld->pnt1.h, ld->pnt2.h );
|
|
--rct.top;
|
|
rct.bottom += 3;
|
|
--rct.left;
|
|
rct.right += 3;
|
|
xi_obj->v.line->attrib = attrib;
|
|
xi_invalidate_rect( win, &rct );
|
|
break;
|
|
}
|
|
case XIT_RECT:
|
|
xi_obj->v.rect->attrib = attrib;
|
|
xi_invalidate_rect( win, &xi_obj->v.rect->rct );
|
|
break;
|
|
case XIT_TEXT:
|
|
xi_obj->v.text->attrib = attrib;
|
|
xi_invalidate_rect( win, &xi_obj->v.text->rct );
|
|
break;
|
|
case XIT_ITF:
|
|
/* it is not clear how to get the proper behaviour here */
|
|
break;
|
|
case XIT_COLUMN:
|
|
lm_set_attrib( xi_obj->parent->v.list->lm, LM_COLUMN,
|
|
xi_obj_to_idx( xi_obj ), 0, FALSE, attrib, FALSE );
|
|
break;
|
|
case XIT_LIST:
|
|
{
|
|
XI_LIST_DATA *ld;
|
|
|
|
ld = xi_obj->v.list;
|
|
if ( attrib & XI_ATR_VISIBLE && !ld->done_initial_xi_scroll )
|
|
{
|
|
ld->done_initial_xi_scroll = TRUE;
|
|
xi_scroll_internal( xi_obj, XI_SCROLL_FIRST, ld->start_percent, FALSE );
|
|
}
|
|
lm_set_attrib( ld->lm, LM_LIST, 0, 0, FALSE, attrib, FALSE );
|
|
if ( ld->sb_win )
|
|
{
|
|
XinWindowShow( ld->sb_win, ( BOOLEAN ) ( ( attrib & XI_ATR_VISIBLE ) != 0 ) );
|
|
XinWindowEnable( ld->sb_win, ( BOOLEAN ) ( ( attrib & XI_ATR_ENABLED ) != 0 ) );
|
|
}
|
|
if ( ld->hsb_win )
|
|
{
|
|
XinWindowShow( ld->hsb_win, ( BOOLEAN ) ( ( attrib & XI_ATR_VISIBLE ) != 0 ) );
|
|
XinWindowEnable( ld->hsb_win, ( BOOLEAN ) ( ( attrib & XI_ATR_ENABLED ) != 0 ) );
|
|
}
|
|
break;
|
|
}
|
|
case XIT_ROW:
|
|
lm_set_attrib( xi_obj->parent->v.list->lm, LM_ROW, xi_obj->v.row, 0, FALSE,
|
|
attrib, FALSE );
|
|
break;
|
|
case XIT_CELL:
|
|
lm_set_attrib( xi_obj->parent->v.list->lm, LM_CELL, xi_obj->v.cell.row,
|
|
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled,
|
|
attrib, FALSE );
|
|
break;
|
|
default:
|
|
XinError( 20027, XinSeverityFatal, 0L );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_bufsize( XI_OBJ * xi_obj, int size )
|
|
{
|
|
XI_OBJ **objp;
|
|
int i;
|
|
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_FIELD:
|
|
stx_set_bufsize( xi_obj->v.field->stx, ( short ) size );
|
|
break;
|
|
case XIT_COLUMN:
|
|
lm_set_buf_size( xi_obj->parent->v.list->lm, LM_COLUMN,
|
|
xi_obj_to_idx( xi_obj ), size );
|
|
break;
|
|
case XIT_LIST:
|
|
case XIT_FORM:
|
|
objp = xi_obj->children;
|
|
for ( i = xi_obj->nbr_children; i > 0; i--, objp++ )
|
|
xi_set_bufsize( *objp, size );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_sel( XI_OBJ * xi_obj, int selstart, int selstop )
|
|
{
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_CELL:
|
|
xi_set_focus( xi_obj );
|
|
lm_set_sel( xi_obj->parent->v.list->lm, xi_obj->v.cell.row,
|
|
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled,
|
|
selstart, selstop );
|
|
break;
|
|
case XIT_FIELD:
|
|
xi_set_focus( xi_obj );
|
|
stx_set_sel( xi_obj->v.field->stx, selstart, selstop );
|
|
break;
|
|
case XIT_BTN:
|
|
case XIT_FORM:
|
|
case XIT_GROUP:
|
|
case XIT_TEXT:
|
|
case XIT_COLUMN:
|
|
case XIT_ITF:
|
|
case XIT_LIST:
|
|
case XIT_ROW:
|
|
XinError( 20028, XinSeverityFatal, 0L );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_text( XI_OBJ * xi_obj, char *s )
|
|
{
|
|
char *buf;
|
|
size_t buf_size = 256;
|
|
BOOLEAN ddd;
|
|
BOOLEAN do_compare = TRUE;
|
|
|
|
if ( xi_obj == xi_obj->itf->v.itf->focus_obj )
|
|
xi_obj->itf->v.itf->chg_flag = FALSE;
|
|
buf = XinMemoryAlloc( buf_size );
|
|
if (xi_obj->type == XIT_CELL)
|
|
{
|
|
XI_OBJ *list = xi_obj->parent;
|
|
int row = xi_obj->v.cell.row;
|
|
int column = xi_obj->v.cell.column;
|
|
LM_DATA *lmp = LMP(list->v.list->lm);
|
|
LM_CELL_DATA col_data = lmp->cell_data[row][column];
|
|
if (!col_data.valid_data)
|
|
do_compare = FALSE;
|
|
}
|
|
if (do_compare)
|
|
{
|
|
xi_get_text( xi_obj, buf, buf_size );
|
|
if ( !strcmp( s, buf ) )
|
|
{
|
|
XinMemoryFree( buf );
|
|
return;
|
|
}
|
|
}
|
|
XinMemoryFree( buf );
|
|
ddd = !xi_get_native_controls( xi_obj );
|
|
switch ( xi_obj->type )
|
|
{
|
|
case XIT_BTN:
|
|
{
|
|
XI_BTN_DATA *btn;
|
|
|
|
btn = xi_obj->v.btn;
|
|
btn->text = ( char * ) xi_tree_realloc( btn->text, strlen( s ) + 1 );
|
|
strcpy( btn->text, s );
|
|
if ( ddd )
|
|
{
|
|
if ( ( xi_get_attrib( xi_obj ) & XI_ATR_VISIBLE ) != 0 )
|
|
xi_invalidate_rect( xi_obj->itf->v.itf->xin_win, &btn->rct );
|
|
}
|
|
else
|
|
XinWindowTitleSet( btn->btnctl, s );
|
|
break;
|
|
}
|
|
case XIT_CELL:
|
|
lm_set_text( xi_obj->parent->v.list->lm, s, xi_obj->v.cell.row,
|
|
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled );
|
|
break;
|
|
case XIT_COLUMN:
|
|
lm_set_text( xi_obj->parent->v.list->lm, s, LM_HEADING_TEXT,
|
|
xi_obj_to_idx( xi_obj ), FALSE );
|
|
break;
|
|
case XIT_FIELD:
|
|
{
|
|
/* XinRect rct; */
|
|
|
|
stx_set_text( xi_obj->v.field->stx, s );
|
|
/* TODO change approach, simply draw text xi_get_rect(xi_obj, &rct);
|
|
* xi_invalidate_rect(xi_obj->itf->v.itf->xin_win, &rct); */
|
|
break;
|
|
}
|
|
case XIT_ITF:
|
|
XinWindowTitleSet( xi_obj->v.itf->xin_win, s );
|
|
break;
|
|
case XIT_ROW:
|
|
XinError( 20029, XinSeverityFatal, 0L );
|
|
case XIT_TEXT:
|
|
{
|
|
XI_TEXT_DATA *text_data;
|
|
XinRect rct;
|
|
|
|
text_data = xi_obj->v.text;
|
|
text_data->text = ( char * ) xi_tree_realloc( text_data->text, strlen( s ) + 1 );
|
|
strcpy( text_data->text, s );
|
|
if ( ( xi_get_attrib( xi_obj ) & XI_ATR_VISIBLE ) != 0 )
|
|
{
|
|
xi_get_rect( xi_obj, &rct );
|
|
xi_invalidate_rect( xi_obj->itf->v.itf->xin_win, &rct );
|
|
}
|
|
break;
|
|
}
|
|
case XIT_GROUP:
|
|
case XIT_FORM:
|
|
case XIT_LIST:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_override_cursor( XI_OBJ* itf, XinCursor cursor, BOOLEAN flag )
|
|
{
|
|
itf->v.itf->cursor_override = flag;
|
|
if ( xi_is_itf( itf ) && flag && itf->v.itf->cursor != cursor )
|
|
{
|
|
XinWindowCursorSet( itf->v.itf->xin_win, cursor );
|
|
itf->v.itf->cursor = cursor;
|
|
}
|
|
}
|
|
|
|
XinColor
|
|
xi_get_underlying_color( XI_OBJ * itf, XinPoint point )
|
|
{
|
|
XinColor back_color = itf->v.itf->back_color;
|
|
int num, num_members;
|
|
XI_OBJ** objlist;
|
|
XI_OBJ** cur_obj;
|
|
XinRect* back_rect = NULL;
|
|
|
|
objlist = xi_get_member_list( itf, &num_members );
|
|
|
|
/* Determine if the point is contained on any rectangles in the itf */
|
|
for ( num = 0, cur_obj = objlist; num < num_members; num++, cur_obj++ )
|
|
if ( (*cur_obj)->type == XIT_RECT )
|
|
{
|
|
XinRect intersect;
|
|
XinRect* cur_rct = &(*cur_obj)->v.rect->rct;
|
|
if (XinRectPointContained( cur_rct, &point ) )
|
|
{
|
|
if ( back_rect != NULL )
|
|
{
|
|
XinRectIntersect( &intersect, back_rect, cur_rct );
|
|
if ( intersect.top == cur_rct->top
|
|
&& intersect.bottom == cur_rct->bottom
|
|
&& intersect.left == cur_rct->left
|
|
&& intersect.right == cur_rct->right )
|
|
{
|
|
if ( (*cur_obj)->v.rect->back_color != 0 )
|
|
{
|
|
back_color = (*cur_obj)->v.rect->back_color;
|
|
back_rect = &(*cur_obj)->v.rect->rct;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( (*cur_obj)->v.rect->back_color != 0 )
|
|
{
|
|
back_color = (*cur_obj)->v.rect->back_color;
|
|
back_rect = &(*cur_obj)->v.rect->rct;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return back_color;
|
|
}
|
|
|
|
void
|
|
xi_draw_button( XI_OBJ * xi_obj, XinRect * rct,
|
|
BOOLEAN enabled, BOOLEAN visible, BOOLEAN focus, BOOLEAN down,
|
|
BOOLEAN dflt, BOOLEAN checked, BOOLEAN box_only, BOOLEAN draw_border )
|
|
{
|
|
XI_BTN_DATA *bd;
|
|
XinColor fore_color;
|
|
XinColor border_color;
|
|
XinPen fore_cp;
|
|
XinWindow win;
|
|
XI_OBJ *itf;
|
|
XI_ITF_DATA *id;
|
|
int leading,
|
|
ascent,
|
|
descent;
|
|
XI_OBJ *focus_obj;
|
|
XinColor color_light = 0L;
|
|
XinColor color_ctrl = 0L;
|
|
XinColor color_dark = 0L;
|
|
|
|
if ( !visible )
|
|
return;
|
|
itf = xi_obj->itf;
|
|
id = itf->v.itf;
|
|
if ( id->half_baked )
|
|
return;
|
|
win = xi_get_window( itf );
|
|
xi_set_clip( win, NULL );
|
|
bd = xi_obj->v.btn;
|
|
fore_color = XI_COLOR_BLACK;
|
|
if (bd->type == XIBT_BUTTON)
|
|
{
|
|
color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
|
|
color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
|
|
color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
|
|
}
|
|
fore_cp = black_cpen;
|
|
if ( bd->fore_color )
|
|
{
|
|
fore_cp.fore_color = bd->fore_color;
|
|
fore_color = bd->fore_color;
|
|
}
|
|
switch ( bd->type )
|
|
{
|
|
case XIBT_BUTTON:
|
|
case XIBT_BUTTON_CHECKBOX:
|
|
case XIBT_BUTTON_RADIOBTN:
|
|
{
|
|
int grid_width;
|
|
int bline = -1;
|
|
XinRect r;
|
|
XinPen back_pen;
|
|
BOOLEAN cr_ok;
|
|
XinPoint pnt;
|
|
XinColor underlying_color;
|
|
pnt.h = rct->left;
|
|
pnt.v = rct->top;
|
|
underlying_color = xi_get_underlying_color ( itf, pnt );
|
|
|
|
r = *rct;
|
|
back_pen = black_cpen;
|
|
back_pen.fore_color = underlying_color;
|
|
XinWindowPenSet( win, &back_pen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
if ( draw_border )
|
|
xi_draw_rect( win, &r );
|
|
xi_inflate_rect( &r, -1 );
|
|
xi_draw_rect( win, &r );
|
|
r = *rct;
|
|
if ( xi_obj->v.btn->packed == TRUE )
|
|
{
|
|
grid_width = ( int ) xi_get_pref( XI_PREF_CONTAINER_GRID_WIDTH );
|
|
xi_inflate_rect( &r, -grid_width );
|
|
}
|
|
else
|
|
{
|
|
XI_BTN_TYPE bt;
|
|
|
|
bt = xi_obj->v.btn->type;
|
|
if ( bt == XIBT_BUTTON || bt == XIBT_BUTTON_CHECKBOX ||
|
|
bt == XIBT_BUTTON_RADIOBTN )
|
|
xi_inflate_rect( &r, -3 );
|
|
}
|
|
XinWindowDrawModeSet( win, XinDrawModeCopy );
|
|
xi_draw_3d_rect( win, &r, ( BOOLEAN ) ( down || bd->checked ), 2, color_light, color_ctrl, color_dark );
|
|
if ( bd->up_icon_rid )
|
|
{
|
|
int x,
|
|
y;
|
|
XinRect r2;
|
|
|
|
x = r.left + 2 + bd->icon_x;
|
|
y = r.top + 2 + bd->icon_y;
|
|
r2 = r;
|
|
xi_inflate_rect( &r2, -2 );
|
|
xi_set_clip( win, &r2 );
|
|
if ( down )
|
|
xi_draw_icon( win, x, y + 1, bd->down_icon_rid, XI_COLOR_BLACK,
|
|
color_ctrl );
|
|
else
|
|
{
|
|
if ( enabled || !bd->disabled_icon_rid )
|
|
xi_draw_icon( win, x, y, bd->up_icon_rid, XI_COLOR_BLACK,
|
|
color_ctrl );
|
|
else
|
|
xi_draw_icon( win, x, y, bd->disabled_icon_rid, XI_COLOR_BLACK,
|
|
color_ctrl );
|
|
}
|
|
xi_set_clip( win, NULL );
|
|
}
|
|
else if ( bd->up_bitmap != NULL )
|
|
{
|
|
XinRect r2;
|
|
|
|
r2 = r;
|
|
xi_inflate_rect( &r2, -2 );
|
|
if ( down )
|
|
xi_bitmap_draw( bd->down_bitmap, win, &r2, &r2, FALSE );
|
|
else if ( enabled || bd->disabled_bitmap == NULL )
|
|
xi_bitmap_draw( bd->up_bitmap, win, &r2, &r2, FALSE );
|
|
else
|
|
xi_bitmap_draw( bd->disabled_bitmap, win, &r2, &r2, FALSE );
|
|
xi_set_clip( win, NULL );
|
|
}
|
|
else
|
|
{
|
|
unsigned long attrib;
|
|
XinRect text_rect;
|
|
// XinColor color;
|
|
XinFont *fontp;
|
|
|
|
attrib = XI_ATR_VCENTER | XI_ATR_HCENTER | XI_ATR_VISIBLE;
|
|
if ( enabled )
|
|
XinWindowColorTextForeSet( win, fore_color );
|
|
else
|
|
XinWindowColorTextForeSet( win,
|
|
( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
|
|
text_rect = r;
|
|
if ( down )
|
|
text_rect.top += 2;
|
|
fontp = xi_obj->v.btn->font;
|
|
if ( fontp == NULL )
|
|
fontp = xi_obj->itf->v.itf->font;
|
|
if ( fontp == NULL )
|
|
fontp = xi_get_system_font( );
|
|
XinWindowColorTextBackSet( win, color_ctrl );
|
|
XinWindowTextOpaqueSet( win, FALSE );
|
|
XinWindowFontMap( win, fontp );
|
|
XinFontMetricsGet( fontp, &leading, &ascent, &descent );
|
|
xi_draw_clipped_text( win, fontp, bd->text, &text_rect, &text_rect, attrib, FALSE, 0, -1,
|
|
bd->mnemonic, bd->mnemonic_instance, &bline );
|
|
}
|
|
|
|
/* draw the solid line around the button that shows that it will be
|
|
* pressed if the user presses cr */
|
|
focus_obj = xi_get_focus( itf );
|
|
cr_ok = FALSE;
|
|
if ( focus_obj && focus_obj->type != XIT_BTN && !xi_cr_is_ok( focus_obj ) )
|
|
cr_ok = TRUE;
|
|
if ( ( dflt && cr_ok ) || focus )
|
|
border_color = XI_COLOR_BLACK;
|
|
else
|
|
border_color = underlying_color;
|
|
if ( draw_border )
|
|
{
|
|
XinRect rct2;
|
|
XinPen pen;
|
|
|
|
rct2 = r;
|
|
xi_inflate_rect( &rct2, 1 );
|
|
pen.width = 1;
|
|
pen.fore_color = border_color;
|
|
pen.pattern = XinPenSolid;
|
|
XinWindowPenSet( win, &pen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
xi_draw_rect( win, &rct2 );
|
|
}
|
|
|
|
/* draw the dashed line inside the button that shows focus */
|
|
if ( focus && bd->up_icon_rid == 0 && bd->up_bitmap == NULL )
|
|
{
|
|
XinRect rct2;
|
|
/*
|
|
int middle;
|
|
int font_height;
|
|
int font_top;
|
|
*/
|
|
XinPen pen;
|
|
|
|
rct2 = r;
|
|
xi_inflate_rect( &rct2, -3 );
|
|
/* middle = ( rct2.top + rct2.bottom ) / 2;
|
|
font_height = ascent + descent + leading;
|
|
font_top = middle - font_height / 2;
|
|
rct2.top = middle - font_height / 2 - 3;
|
|
rct2.bottom = font_top + font_height + 2;
|
|
if ( bline != -1 )
|
|
rct2.bottom = bline + descent + 2;
|
|
rct2.top = max( rct2.top, r.top + 3 );
|
|
rct2.bottom = min( rct2.bottom, r.bottom ); */
|
|
pen.width = 1;
|
|
pen.fore_color = XI_COLOR_BLACK;
|
|
pen.pattern = XinPenSolid;
|
|
XinWindowPenSet( win, &pen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
xi_draw_dotted_rect( win, &rct2 );
|
|
}
|
|
break;
|
|
}
|
|
case XIBT_RADIOBTN:
|
|
{
|
|
XinRect rbrct,
|
|
rct2;
|
|
unsigned long attrib;
|
|
XinRect text_rect;
|
|
XinColor color;
|
|
|
|
rbrct = *rct;
|
|
rbrct.bottom -= 4;
|
|
rct2 = rbrct;
|
|
rct2.right = rct2.left + ( rct2.bottom - rct2.top );
|
|
XinWindowDrawModeSet( win, XinDrawModeCopy );
|
|
XinWindowPenSet( win, &hollow_cpen );
|
|
if ( id->back_color && !box_only )
|
|
{
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
xi_draw_rect( win, rct );
|
|
}
|
|
xi_draw_3d_diamond( win, &rct2, checked, down, down ? 2 : 1,
|
|
down ? bd->fore_color : 0L );
|
|
if ( checked )
|
|
{
|
|
XinRect rct;
|
|
|
|
rct = rct2;
|
|
rct.top += 4;
|
|
rct.left += 4;
|
|
rct.bottom -= 4;
|
|
rct.right -= 4;
|
|
xi_draw_3d_diamond( win, &rct, FALSE, TRUE, rct.right - rct.left,
|
|
enabled ? bd->fore_color : xi_get_pref( XI_PREF_COLOR_DISABLED ) );
|
|
}
|
|
if ( !box_only )
|
|
{
|
|
XinPen cpen;
|
|
XinFont *fontp;
|
|
|
|
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE;
|
|
if ( enabled )
|
|
XinWindowColorTextForeSet( win, fore_color );
|
|
else
|
|
XinWindowColorTextForeSet( win,
|
|
( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
|
|
text_rect = *rct;
|
|
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 2;
|
|
fontp = xi_obj->v.btn->font;
|
|
if ( fontp == NULL )
|
|
fontp = xi_obj->itf->v.itf->font;
|
|
if ( fontp == NULL )
|
|
fontp = xi_get_system_font( );
|
|
color = ( XinColor ) xi_get_pref( XI_PREF_COLOR_CTRL );
|
|
XinWindowColorTextBackSet( win, color );
|
|
XinWindowTextOpaqueSet( win, FALSE );
|
|
XinWindowFontMap( win, fontp );
|
|
xi_draw_clipped_text( win, fontp, bd->text, &text_rect, &text_rect, attrib, FALSE, 0, -1,
|
|
bd->mnemonic, bd->mnemonic_instance, NULL );
|
|
if ( focus )
|
|
{
|
|
cpen = black_cpen;
|
|
cpen.pattern = XinPenSolid;
|
|
XinWindowPenSet( win, &cpen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 4;
|
|
xi_draw_dotted_rect( win, &text_rect );
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
if ( id->back_color )
|
|
{
|
|
cpen = black_cpen;
|
|
cpen.fore_color = id->back_color;
|
|
XinWindowPenSet( win, &cpen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 4;
|
|
xi_draw_rect( win, &text_rect );
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case XIBT_TABBTN:
|
|
{
|
|
XinRect tab_rect,
|
|
rect;
|
|
XinBrush back_brush;
|
|
XinPen highlight_pen;
|
|
XinPen shadow_pen;
|
|
BOOLEAN checked_is_to_right;
|
|
BOOLEAN checked_is_to_left;
|
|
int index,
|
|
baseline;
|
|
XinFont *fontp;
|
|
unsigned long attrib;
|
|
|
|
back_brush.pattern = XinBrushSolid;
|
|
back_brush.fore_color = ( XinColor ) xi_get_pref( XI_PREF_COLOR_CTRL );
|
|
XinWindowBrushSet( win, &back_brush );
|
|
xi_set_clip( win, NULL );
|
|
XinWindowDrawModeSet( win, XinDrawModeCopy );
|
|
XinWindowPenSet( win, &hollow_cpen );
|
|
highlight_pen = black_cpen;
|
|
highlight_pen.fore_color = xi_get_pref( XI_PREF_COLOR_LIGHT );
|
|
shadow_pen = black_cpen;
|
|
shadow_pen.fore_color = xi_get_pref( XI_PREF_COLOR_DARK );
|
|
|
|
index = xi_obj_to_idx( xi_obj );
|
|
if ( index < xi_obj->parent->nbr_children - 1 )
|
|
checked_is_to_right = xi_obj->parent->children[index + 1]->v.btn->checked;
|
|
else
|
|
checked_is_to_right = FALSE;
|
|
if ( index > 0 )
|
|
checked_is_to_left = xi_obj->parent->children[index - 1]->v.btn->checked;
|
|
else
|
|
checked_is_to_left = FALSE;
|
|
tab_rect = *rct;
|
|
++tab_rect.bottom;
|
|
if ( xi_obj->v.btn->checked )
|
|
{
|
|
XinPoint p1,
|
|
p2;
|
|
|
|
{
|
|
XinRect temp = tab_rect;
|
|
|
|
temp.top++;
|
|
temp.left++;
|
|
xi_draw_rect( win, &temp );
|
|
}
|
|
|
|
XinWindowPenSet( win, &highlight_pen );
|
|
/* left line */
|
|
p1.h = tab_rect.left;
|
|
p1.v = tab_rect.bottom - 1;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.left;
|
|
p2.v = tab_rect.top + 2;
|
|
xi_draw_line( win, p2 );
|
|
|
|
/* diagonal line from left edge to top */
|
|
p1.h = tab_rect.left;
|
|
p1.v = tab_rect.top + 3;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.left + 3;
|
|
p2.v = tab_rect.top;
|
|
xi_draw_line( win, p2 );
|
|
|
|
/* top line */
|
|
p1.h = tab_rect.left + 2;
|
|
p1.v = tab_rect.top;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.right - 2;
|
|
p2.v = tab_rect.top;
|
|
xi_draw_line( win, p2 );
|
|
|
|
/* shadow and black lines on right */
|
|
XinWindowPenSet( win, &shadow_pen );
|
|
p1.h = tab_rect.right - 2;
|
|
p1.v = tab_rect.top;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.right - 2;
|
|
p2.v = tab_rect.bottom;
|
|
xi_draw_line( win, p2 );
|
|
|
|
XinWindowPenSet( win, &black_cpen );
|
|
p1.h = tab_rect.right - 1;
|
|
p1.v = tab_rect.top + 1;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.right - 1;
|
|
p2.v = tab_rect.bottom;
|
|
xi_draw_line( win, p2 );
|
|
}
|
|
else
|
|
{
|
|
XinPoint p1,
|
|
p2;
|
|
|
|
{
|
|
XinRect temp = tab_rect;
|
|
|
|
temp.top += 4;
|
|
if ( !checked_is_to_left )
|
|
temp.left++;
|
|
xi_draw_rect( win, &temp );
|
|
}
|
|
|
|
XinWindowPenSet( win, &highlight_pen );
|
|
/* draw line on left edge of tab */
|
|
if ( !checked_is_to_left )
|
|
{
|
|
p1.h = tab_rect.left;
|
|
p1.v = tab_rect.bottom - 2;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.left;
|
|
p2.v = tab_rect.top + 4;
|
|
xi_draw_line( win, p2 );
|
|
}
|
|
|
|
/* diagonal line from left edge to top */
|
|
if ( checked_is_to_left )
|
|
{
|
|
p1.h = tab_rect.left;
|
|
p1.v = tab_rect.top + 5;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.left + 2;
|
|
p2.v = tab_rect.top + 3;
|
|
xi_draw_line( win, p2 );
|
|
}
|
|
else
|
|
{
|
|
p1.h = tab_rect.left;
|
|
p1.v = tab_rect.top + 6;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.left + 3;
|
|
p2.v = tab_rect.top + 3;
|
|
xi_draw_line( win, p2 );
|
|
}
|
|
|
|
/* top line */
|
|
p1.h = tab_rect.left + 2;
|
|
p1.v = tab_rect.top + 3;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.right - 2;
|
|
p2.v = tab_rect.top + 3;
|
|
xi_draw_line( win, p2 );
|
|
|
|
/* shadow line on right */
|
|
XinWindowPenSet( win, &shadow_pen );
|
|
p1.h = tab_rect.right - 2;
|
|
p1.v = tab_rect.top + 3;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.right - 2;
|
|
p2.v = tab_rect.bottom - 2;
|
|
xi_draw_line( win, p2 );
|
|
|
|
/* black line on right */
|
|
if ( !checked_is_to_right )
|
|
{
|
|
XinWindowPenSet( win, &black_cpen );
|
|
p1.h = tab_rect.right - 1;
|
|
p1.v = tab_rect.top + 4;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.right - 1;
|
|
p2.v = tab_rect.bottom - 2;
|
|
xi_draw_line( win, p2 );
|
|
}
|
|
|
|
XinWindowPenSet( win, &highlight_pen );
|
|
p1.h = tab_rect.left;
|
|
p1.v = tab_rect.bottom - 1;
|
|
xi_move_to( win, p1 );
|
|
p2.h = tab_rect.right;
|
|
p2.v = tab_rect.bottom - 1;
|
|
xi_draw_line( win, p2 );
|
|
}
|
|
fontp = xi_obj->v.btn->font;
|
|
if ( !fontp )
|
|
fontp = xi_obj->itf->v.itf->font;
|
|
if ( !fontp )
|
|
fontp = xi_get_system_font( );
|
|
if ( checked )
|
|
{
|
|
XinFont *font;
|
|
|
|
XinFontCopy( &font, fontp );
|
|
XinFontBoldSet( font, TRUE );
|
|
fontp = font;
|
|
}
|
|
XinWindowFontMap( win, fontp );
|
|
XinFontMetricsGet( fontp, &leading, &ascent, &descent );
|
|
attrib = XI_ATR_HCENTER | XI_ATR_VCENTER | XI_ATR_VISIBLE;
|
|
rect = tab_rect;
|
|
++rect.left;
|
|
rect.right -= 2;
|
|
rect.top += 3;
|
|
if ( enabled )
|
|
XinWindowColorTextForeSet( win, fore_cp.fore_color );
|
|
else
|
|
XinWindowColorTextForeSet( win, ( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
|
|
XinWindowTextOpaqueSet( win, FALSE );
|
|
xi_draw_clipped_text( win, fontp, bd->text, &rect, &rect, attrib, FALSE, 0, -1,
|
|
bd->mnemonic, bd->mnemonic_instance, NULL );
|
|
#if XIWS == XIWS_WM
|
|
NOREF( rule_and_space );
|
|
baseline = rect.top + 8;
|
|
#else
|
|
baseline = rect.top + leading + ascent +
|
|
( rect.bottom - rect.top - leading - ascent - descent ) / 2 - 1;
|
|
#endif
|
|
if ( focus )
|
|
{
|
|
rect.top = baseline - leading - ascent;
|
|
rect.bottom = baseline + descent - 1;
|
|
++rect.left;
|
|
--rect.right;
|
|
XinWindowPenSet( win, &black_cpen );
|
|
xi_draw_dotted_rect( win, &rect );
|
|
}
|
|
break;
|
|
}
|
|
case XIBT_CHECKBOX:
|
|
{
|
|
XinRect cbrct,
|
|
rct2;
|
|
unsigned long attrib;
|
|
XinRect text_rect;
|
|
XinColor color;
|
|
|
|
cbrct = *rct;
|
|
cbrct.bottom -= 4;
|
|
rct2 = cbrct;
|
|
rct2.right = rct2.left + ( rct2.bottom - rct2.top );
|
|
XinWindowDrawModeSet( win, XinDrawModeCopy );
|
|
XinWindowPenSet( win, &hollow_cpen );
|
|
if ( id->back_color && !box_only )
|
|
{
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
xi_draw_rect( win, rct );
|
|
}
|
|
if ( down )
|
|
{
|
|
XinWindowPenSet( win, &fore_cp );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
xi_draw_thick_rect( win, &rct2, 2 );
|
|
}
|
|
else
|
|
xi_draw_3d_rect( win, &rct2, down, 1, 0L, 0L, 0L );
|
|
if ( !enabled )
|
|
fore_cp.fore_color = xi_get_pref( XI_PREF_COLOR_DISABLED );
|
|
if ( checked )
|
|
{
|
|
XinPoint pnt1,
|
|
pnt2;
|
|
|
|
XinWindowPenSet( win, &fore_cp );
|
|
pnt1.h = rct2.left + 2;
|
|
pnt1.v = rct2.bottom - 7;
|
|
xi_move_to( win, pnt1 );
|
|
pnt2.h = pnt1.h;
|
|
pnt2.v = pnt1.v + 5;
|
|
xi_draw_line( win, pnt2 );
|
|
|
|
pnt1.h++;
|
|
pnt1.v--;
|
|
xi_move_to( win, pnt1 );
|
|
pnt2.h++;
|
|
xi_draw_line( win, pnt2 );
|
|
|
|
pnt1.h++;
|
|
pnt1.v = rct2.bottom - 5;
|
|
pnt2 = pnt1;
|
|
pnt2.v += 2;
|
|
|
|
while ( pnt1.v >= ( rct2.top + 3 ) && pnt1.h <= ( rct2.right - 4 ) )
|
|
{
|
|
xi_move_to( win, pnt1 );
|
|
xi_draw_line( win, pnt2 );
|
|
pnt1.h++;
|
|
pnt1.v--;
|
|
pnt2.h++;
|
|
pnt2.v--;
|
|
}
|
|
pnt1.v++;
|
|
xi_move_to( win, pnt1 );
|
|
xi_draw_line( win, pnt2 );
|
|
}
|
|
if ( !box_only )
|
|
{
|
|
XinFont *fontp;
|
|
|
|
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE;
|
|
if ( enabled )
|
|
XinWindowColorTextForeSet( win, fore_color );
|
|
else
|
|
XinWindowColorTextForeSet( win,
|
|
( XinColor ) xi_get_pref( XI_PREF_COLOR_DISABLED ) );
|
|
text_rect = *rct;
|
|
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 2;
|
|
fontp = xi_obj->v.btn->font;
|
|
if ( !fontp )
|
|
fontp = xi_obj->itf->v.itf->font;
|
|
if ( fontp == NULL )
|
|
fontp = xi_get_system_font( );
|
|
color = ( XinColor ) xi_get_pref( XI_PREF_COLOR_CTRL );
|
|
XinWindowColorTextBackSet( win, color );
|
|
XinWindowTextOpaqueSet( win, FALSE );
|
|
XinWindowFontMap( win, fontp );
|
|
xi_draw_clipped_text( win, fontp, bd->text, &text_rect, &text_rect, attrib, FALSE, 0, -1,
|
|
bd->mnemonic, bd->mnemonic_instance, NULL );
|
|
xi_set_clip( win, NULL );
|
|
if ( focus )
|
|
{
|
|
XinPen cpen;
|
|
|
|
cpen = black_cpen;
|
|
XinWindowPenSet( win, &cpen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 4;
|
|
xi_draw_dotted_rect( win, &text_rect );
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
if ( id->back_color )
|
|
{
|
|
XinPen cpen;
|
|
|
|
cpen = black_cpen;
|
|
cpen.fore_color = id->back_color;
|
|
XinWindowPenSet( win, &cpen );
|
|
XinWindowBrushSet( win, &hollow_cbrush );
|
|
text_rect.left = rct2.right + ( rct2.right - rct2.left ) / 4;
|
|
xi_draw_rect( win, &text_rect );
|
|
}
|
|
*/
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_set_fixed_columns */
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
void
|
|
xi_set_fixed_columns( XI_OBJ * list, int new_fixed_count )
|
|
{
|
|
if ( list->type != XIT_LIST )
|
|
XinError( 20031, XinSeverityFatal, 0L );
|
|
lm_set_fixed_columns( list->v.list->lm, new_fixed_count );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_get_fixed_columns */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_get_fixed_columns( XI_OBJ * list )
|
|
{
|
|
if ( list->type != XIT_LIST )
|
|
XinError( 20038, XinSeverityFatal, 0L );
|
|
return lm_get_fixed_columns( list->v.list->lm );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_get_handle */
|
|
/* -------------------------------------------------------------------------*/
|
|
long
|
|
xi_get_handle( XI_OBJ * list, XI_OBJ * child )
|
|
{
|
|
LM_DATA *lm_data;
|
|
|
|
if ( list->type != XIT_LIST )
|
|
return -1L;
|
|
lm_data = ( LM_DATA * ) list->v.list->lm;
|
|
switch ( child->type )
|
|
{
|
|
case XIT_ROW:
|
|
{
|
|
int row = child->v.row;
|
|
|
|
if ( child->v.row_data.is_vert_scrolled )
|
|
return lm_focus_rec_get( lm_data );
|
|
if ( row >= 0 && row < lm_data->nbr_realized_rows )
|
|
return lm_data->recs[row];
|
|
break;
|
|
}
|
|
case XIT_CELL:
|
|
{
|
|
int row;
|
|
|
|
if ( child->v.cell.is_vert_scrolled )
|
|
return lm_focus_rec_get( lm_data );
|
|
row = child->v.cell.row;
|
|
if ( row >= 0 && row < lm_data->nbr_realized_rows )
|
|
return lm_data->recs[row];
|
|
break;
|
|
}
|
|
}
|
|
return -1L;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_field_calc_height_font */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_field_calc_height_font( XinFont * font )
|
|
{
|
|
if ( font == 0 )
|
|
font = xi_get_system_font( );
|
|
return xi_get_fu_height_font( font );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_button_calc_height_font */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_button_calc_height_font( XinFont * font )
|
|
{
|
|
return xi_field_calc_height_font( font );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_field_calc_width_font */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_field_calc_width_font( XinFont * font, char *string )
|
|
{
|
|
int result;
|
|
XinWindow win;
|
|
XinRect rct = {-1000, -1000, -900, -900};
|
|
XinFont *calc_font;
|
|
|
|
if ( font )
|
|
calc_font = font;
|
|
else
|
|
calc_font = xi_get_system_font( );
|
|
{
|
|
XinWindowDef Def;
|
|
|
|
MEMCLEAR( Def );
|
|
Def.type = XinWindowTypeDocument;
|
|
Def.border_style = XinBorderFixed;
|
|
Def.p_rect = &rct;
|
|
Def.title = "";
|
|
win = XinWindowCreate( &Def );
|
|
}
|
|
|
|
XinWindowFontMap( win, calc_font );
|
|
result = XinFontTextWidthGet( calc_font, string, -1 ) + 4;
|
|
XinFontUnmap( calc_font ); /* RGM: Unmap hack */
|
|
XinWindowDestroy( win );
|
|
return result;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_list_def_get_rows */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_list_def_get_rows( XI_OBJ_DEF * list_def )
|
|
{
|
|
int pix_row_spacing,
|
|
height,
|
|
pix_row1_top,
|
|
title_height;
|
|
|
|
if ( list_def->v.list->one_row_list )
|
|
return 1;
|
|
lm_get_vertical_metrics( list_def, &pix_row1_top, &pix_row_spacing, &height,
|
|
&title_height );
|
|
return height / pix_row_spacing;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_list_def_get_height */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_list_def_get_client_height( XI_OBJ_DEF * list_def, int rows )
|
|
{
|
|
int pix_row_spacing,
|
|
height,
|
|
pix_row1_top,
|
|
title_height;
|
|
|
|
lm_get_vertical_metrics( list_def, &pix_row1_top, &pix_row_spacing, &height,
|
|
&title_height );
|
|
return title_height + rows * pix_row_spacing + ( BORDER_WIDTH - RULE_WIDTH_H );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_list_def_get_height */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_list_def_get_outer_height( XI_OBJ_DEF * list_def, int rows )
|
|
{
|
|
int result;
|
|
|
|
result = xi_list_def_get_client_height( list_def, rows );
|
|
return result + ( int ) xi_get_pref( XI_PREF_SB_HEIGHT );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* button_get_horz_padding */
|
|
/* -------------------------------------------------------------------------*/
|
|
static int
|
|
button_get_horz_padding( int type, int height, BOOLEAN packed )
|
|
{
|
|
switch ( type )
|
|
{
|
|
case XIBT_BUTTON:
|
|
case XIBT_BUTTON_CHECKBOX:
|
|
case XIBT_BUTTON_RADIOBTN:
|
|
if ( packed )
|
|
return ( int ) xi_get_pref( XI_PREF_CONTAINER_GRID_WIDTH ) * 2;
|
|
return 6;
|
|
case XIBT_RADIOBTN:
|
|
return height + height / 2 - 6;
|
|
case XIBT_TABBTN:
|
|
return height + 4;
|
|
case XIBT_CHECKBOX:
|
|
return height + height / 2 - 6;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_button_calc_height */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_button_calc_pixel_height( int height )
|
|
{
|
|
return height + 6;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_button_calc_height */
|
|
/* -------------------------------------------------------------------------*/
|
|
int
|
|
xi_button_calc_pixel_width( int width )
|
|
{
|
|
return width + 6;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_button_def_get_width */
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
int
|
|
xi_button_def_get_width( XI_OBJ_DEF * obj_def )
|
|
{
|
|
XinFont *font;
|
|
XinRect rct = {-1000, -1000, -900, -900};
|
|
XinWindow win;
|
|
int width;
|
|
XI_BTN_DEF *button;
|
|
|
|
if ( obj_def->type != XIT_BTN )
|
|
return 0;
|
|
font = xi_def_get_font( obj_def );
|
|
{
|
|
XinWindowDef Def;
|
|
|
|
MEMCLEAR( Def );
|
|
Def.type = XinWindowTypeDocument;
|
|
Def.border_style = XinBorderFixed;
|
|
Def.p_rect = &rct;
|
|
Def.title = "";
|
|
win = XinWindowCreate( &Def );
|
|
}
|
|
XinWindowFontMap( win, font );
|
|
button = obj_def->v.btn;
|
|
width = XinFontTextWidthGet( font, button->text, -1 );
|
|
width += button_get_horz_padding( button->type, xi_get_fu_height_font( font ),
|
|
FALSE );
|
|
XinFontDestroy( font );
|
|
XinWindowDestroy( win );
|
|
return width;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_container_def_get_btn_width */
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
int
|
|
xi_container_def_get_btn_width( XI_OBJ_DEF * obj_def )
|
|
{
|
|
int i;
|
|
XinFont *font;
|
|
XinRect rct = {-1000, -1000, -900, -900};
|
|
XinWindow win;
|
|
int max_width;
|
|
XI_CONTAINER_DEF *container;
|
|
BOOLEAN packed;
|
|
|
|
if ( obj_def->type != XIT_CONTAINER || obj_def->nbr_children <= 0 )
|
|
return 0;
|
|
font = xi_def_get_font( obj_def );
|
|
max_width = 0;
|
|
{
|
|
XinWindowDef Def;
|
|
|
|
MEMCLEAR( Def );
|
|
Def.type = XinWindowTypeDocument;
|
|
Def.border_style = XinBorderFixed;
|
|
Def.p_rect = &rct;
|
|
Def.title = "";
|
|
win = XinWindowCreate( &Def );
|
|
}
|
|
XinWindowFontMap( win, font );
|
|
for ( i = 0; i < obj_def->nbr_children; ++i )
|
|
{
|
|
XI_BTN_DEF *button;
|
|
int width;
|
|
|
|
button = obj_def->children[i]->v.btn;
|
|
width = XinFontTextWidthGet( font, button->text, -1 );
|
|
max_width = max( width, max_width );
|
|
}
|
|
container = obj_def->v.container;
|
|
packed = ( ( container->orientation == XI_GRID_HORIZONTAL
|
|
|| container->orientation == XI_GRID_VERTICAL )
|
|
&& container->packed );
|
|
max_width += button_get_horz_padding( obj_def->children[0]->v.btn->type,
|
|
xi_get_fu_height_font( font ),
|
|
packed );
|
|
XinFontDestroy( font );
|
|
XinWindowDestroy( win );
|
|
return max_width;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_container_def_get_width */
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
int
|
|
xi_container_def_get_width( XI_OBJ_DEF * obj_def )
|
|
{
|
|
XI_CONTAINER_DEF *container;
|
|
|
|
container = obj_def->v.container;
|
|
switch ( container->orientation )
|
|
{
|
|
case XI_STACK_HORIZONTAL:
|
|
{
|
|
int horz_spacing;
|
|
|
|
if ( container->packed )
|
|
horz_spacing = 0;
|
|
else if ( ( horz_spacing = ( int ) xi_get_pref( XI_PREF_HORZ_PIXEL_SPACING ) )
|
|
== 0 )
|
|
{
|
|
XinFont *font;
|
|
|
|
font = xi_def_get_font( obj_def );
|
|
horz_spacing = ( short ) ( ( xi_get_pref( XI_PREF_HORZ_SPACING )
|
|
* xi_get_fu_width_font( font ) ) / XI_FU_MULTIPLE );
|
|
XinFontDestroy( font );
|
|
}
|
|
return xi_container_def_get_btn_width( obj_def ) * obj_def->nbr_children +
|
|
( obj_def->nbr_children - 1 ) * horz_spacing;
|
|
}
|
|
case XI_STACK_VERTICAL:
|
|
return xi_container_def_get_btn_width( obj_def );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_container_def_get_height */
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
int
|
|
xi_container_def_get_height( XI_OBJ_DEF * obj_def )
|
|
{
|
|
XI_CONTAINER_DEF *container;
|
|
XinFont *font;
|
|
int height;
|
|
int vert_spacing;
|
|
int top_offset;
|
|
|
|
if ( obj_def->nbr_children == 0 )
|
|
return 0;
|
|
container = obj_def->v.container;
|
|
font = xi_def_get_font( obj_def );
|
|
height = xi_button_calc_height_font( font );
|
|
XinFontDestroy( font );
|
|
if ( container->orientation == XI_STACK_HORIZONTAL )
|
|
return height;
|
|
if ( container->orientation != XI_STACK_VERTICAL )
|
|
return 0;
|
|
switch ( obj_def->children[0]->v.btn->type )
|
|
{
|
|
case XIBT_BUTTON:
|
|
case XIBT_BUTTON_CHECKBOX:
|
|
case XIBT_BUTTON_RADIOBTN:
|
|
case XIBT_TABBTN:
|
|
if ( container->packed )
|
|
vert_spacing = 0;
|
|
else if ( ( vert_spacing = ( int ) xi_get_pref( XI_PREF_VERT_PIXEL_SPACING ) )
|
|
== 0 )
|
|
vert_spacing = ( int ) ( ( xi_get_pref( XI_PREF_VERT_SPACING )
|
|
* height ) / XI_FU_MULTIPLE );
|
|
top_offset = vert_spacing / 2;
|
|
break;
|
|
case XIBT_CHECKBOX:
|
|
case XIBT_RADIOBTN:
|
|
vert_spacing = 0;
|
|
top_offset = 0;
|
|
break;
|
|
}
|
|
return height * obj_def->nbr_children + vert_spacing
|
|
* ( obj_def->nbr_children - 1 ) + top_offset;
|
|
}
|
|
|
|
|
|
void
|
|
xi_force_focus_cell_visible( XI_OBJ * list )
|
|
{
|
|
int row,
|
|
column;
|
|
BOOLEAN v_scrolled;
|
|
LM_FOCUS_CELL_VISIBLE_FORCE_ARGS args;
|
|
LM_DATA *lmp = ( LM_DATA * ) list->v.list->lm;
|
|
|
|
lm_focus_cell_get( lmp, &row, &column, &v_scrolled );
|
|
MEMCLEAR( args );
|
|
args.lmp = ( LM_DATA * ) list->v.list->lm;
|
|
args.row = row;
|
|
args.column = column;
|
|
args.vert_scrolled = v_scrolled;
|
|
lm_focus_cell_visible_force( &args );
|
|
}
|
|
|
|
BOOLEAN
|
|
xi_cell_data_valid( XI_OBJ * cell )
|
|
{
|
|
XI_OBJ * list = cell->parent;
|
|
LM_DATA *lmp = ( LM_DATA * ) list->v.list->lm;
|
|
|
|
if (lmp->nbr_realized_rows <= cell->v.cell.row ||
|
|
lmp->nbr_columns <= cell->v.cell.column)
|
|
return FALSE;
|
|
return lmp->cell_data[cell->v.cell.row][cell->v.cell.column].valid_data;
|
|
}
|