f8c1ec663e
da xi_set_text(XI_OBJ* obj, char* text) a xi_set_text(XI_OBJ* obj, const char* text) git-svn-id: svn://10.65.10.50/branches/R_10_00@23125 c028cbd2-c16b-5b4b-a496-9718f37d4682
4443 lines
124 KiB
C
Executable File
4443 lines
124 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;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
default:
|
||
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;
|
||
}
|
||
default:
|
||
break;
|
||
}
|
||
break;
|
||
default:
|
||
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;
|
||
default:
|
||
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;
|
||
}
|
||
default:
|
||
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 1 // #ifdef XVAGA
|
||
if ( b == e )
|
||
{
|
||
e++;
|
||
xi_set_sel( focus_obj, b, e );
|
||
}
|
||
#endif
|
||
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;
|
||
}
|
||
}
|
||
/* Che programmatore cazzone!
|
||
while ( size-- > 0 )
|
||
{
|
||
XinEvent ev;
|
||
|
||
MEMCLEAR( ev );
|
||
ev.type = XinEventCharacter;
|
||
ev.v.character.ch = ( unsigned char ) *p++;
|
||
xi_event( win, &ev );
|
||
XinWindowPaintForce( win );
|
||
}
|
||
*/
|
||
if (size) // Molto meglio cosi!
|
||
{
|
||
XinEvent ev;
|
||
MEMCLEAR( ev );
|
||
ev.type = XinEventCharacter;
|
||
while ( size-- > 0 )
|
||
{
|
||
ev.v.character.ch = ( unsigned char ) *p++;
|
||
xi_event( win, &ev );
|
||
}
|
||
}
|
||
|
||
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 = black_cpen;
|
||
XinBrush cbrush = white_cbrush;
|
||
|
||
if ( rect->fore_color )
|
||
cpen.fore_color = rect->fore_color;
|
||
if ( rect->back_color )
|
||
cbrush.fore_color = rect->back_color;
|
||
|
||
XinWindowBrushSet( win, &cbrush );
|
||
|
||
if ( rect->ridge )
|
||
{
|
||
XinWindowPenSet( win, &hollow_cpen );
|
||
xi_draw_rect( win, &rct );
|
||
XinWindowPenSet( win, &cpen );
|
||
xi_draw_roundrect( win, &rct, 4, 4 );
|
||
}
|
||
else
|
||
{
|
||
XinWindowPenSet( win, &cpen );
|
||
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);
|
||
const int button_depth = 1;
|
||
|
||
#if XIWS != XIWS_WM
|
||
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;
|
||
xi_inflate_rect( &r, -1 );
|
||
|
||
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
|
||
xi_draw_shaded_rect(win, &r, fd->down, button_depth, color_light, color_ctrl, color_dark);
|
||
else
|
||
{
|
||
XinWindowBrushSet( win, &white_cbrush );
|
||
XinWindowPenSet( win, &hollow_cpen );
|
||
xi_draw_rect( win, &r );
|
||
}
|
||
|
||
cr = r;
|
||
xi_inflate_rect( &cr, -button_depth );
|
||
xi_set_clip( win, &cr );
|
||
if ( fd->button_bitmap != NULL )
|
||
xi_bitmap_draw( fd->button_bitmap, win, &cr, &cr, FALSE );
|
||
else
|
||
{
|
||
XinColor color = ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) ? color_ctrl : xi_get_pref( XI_PREF_COLOR_CTRL );
|
||
// Guy was here: center icon in button
|
||
int x = (r.left+r.right-XinMetricGet(XinMetricIconWidth))/2; // x = r.left + 3;
|
||
int y = (r.top+r.bottom-XinMetricGet(XinMetricIconHeight))/2; // y = r.top + 2;
|
||
|
||
int 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;
|
||
default:
|
||
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)
|
||
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;
|
||
default:
|
||
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 );
|
||
xi_inflate_rect(&r, -1);
|
||
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_shaded_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;
|
||
default:
|
||
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;
|
||
default:
|
||
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;
|
||
default:
|
||
new_cursor = XI_CURSOR_ARROW;
|
||
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;
|
||
}
|
||
default:
|
||
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 = 0L;
|
||
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;
|
||
default:
|
||
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;
|
||
default:
|
||
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;
|
||
}
|
||
default:
|
||
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;
|
||
default:
|
||
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;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
void
|
||
xi_set_text( XI_OBJ * xi_obj, const char *s )
|
||
{
|
||
BOOLEAN ddd;
|
||
BOOLEAN do_compare = TRUE;
|
||
|
||
if ( xi_obj == xi_obj->itf->v.itf->focus_obj )
|
||
xi_obj->itf->v.itf->chg_flag = FALSE;
|
||
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)
|
||
{
|
||
const size_t buf_size = 256;
|
||
char *buf = (char*)XinMemoryAlloc( buf_size );
|
||
int cmp = 0;
|
||
xi_get_text( xi_obj, buf, buf_size );
|
||
cmp = strcmp( s, buf );
|
||
XinMemoryFree( buf );
|
||
if (!cmp)
|
||
return;
|
||
}
|
||
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;
|
||
default:
|
||
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 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 )
|
||
{
|
||
int 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, -1 ); // Was -3
|
||
}
|
||
XinWindowDrawModeSet( win, XinDrawModeCopy );
|
||
|
||
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
|
||
xi_draw_shaded_rect( win, &r, ( BOOLEAN ) ( down || bd->checked ), 2, color_light, color_ctrl, color_dark );
|
||
else
|
||
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 || bd->checked) // Guy added bd->checked
|
||
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;
|
||
text_rect.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( );
|
||
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
|
||
{
|
||
if ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) )
|
||
xi_draw_shaded_rect( win, &rct2, down, 1, 0L, 0L, 0L );
|
||
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 );
|
||
|
||
/* Sarebbe bello ma ... non <20> trasparente
|
||
XinRect rct3 = rct2;
|
||
xi_inflate_rect(&rct3, -2);
|
||
xi_draw_checkmark(win, &rct3);
|
||
*/
|
||
}
|
||
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;
|
||
}
|
||
default:
|
||
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 );
|
||
default:
|
||
break;
|
||
}
|
||
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;
|
||
default:
|
||
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;
|
||
}
|