3727 lines
91 KiB
C
Executable File
3727 lines
91 KiB
C
Executable File
/*******************************************************************************
|
|
* Copyright 1991-1995 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
|
|
#include "xi.h"
|
|
#include "xitext.h"
|
|
#include "xistx.h"
|
|
#include "xilm.h"
|
|
#include "xiutils.h"
|
|
#include "xvtmenu.h"
|
|
#include "xi_int.h"
|
|
|
|
#if XIWS == MTFWS
|
|
#include <X11/Intrinsic.h>
|
|
#include <Xm/Xm.h>
|
|
#endif
|
|
|
|
#if XIWS == MTFWS
|
|
#include <X11/Xatom.h>
|
|
#include <X11/Intrinsic.h>
|
|
#endif
|
|
|
|
#if XI_IS_CH
|
|
#undef strcmp
|
|
#define strcmp(a, b) strcmp(a, b)
|
|
#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 */
|
|
|
|
/********************************* CONSTANTS *******************************/
|
|
|
|
/********************************* DATA TYPES *******************************/
|
|
|
|
/******************************* STATIC DATA ********************************/
|
|
WINDOW xi_modal_win = NULL_WIN;
|
|
|
|
BOOLEAN xi_false = FALSE;
|
|
|
|
/******************************** FUNCTIONS *********************************/
|
|
|
|
#ifndef NO_PRIMARY_SELECTION
|
|
#if XIWS == MTFWS
|
|
|
|
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;
|
|
WINDOW 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 = xvt_mem_alloc(*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); */
|
|
win = xi_get_window(rp_xi_obj);
|
|
rp_xi_obj = NULL;
|
|
for (p = s; *p != '\0'; ++p)
|
|
{
|
|
EVENT ev;
|
|
|
|
MEMCLEAR(ev);
|
|
ev.type = E_CHAR;
|
|
ev.v.chr.ch = (unsigned char)*p;
|
|
xi_event(win, &ev);
|
|
xvt_dwin_update(win);
|
|
}
|
|
xvt_mem_free(s);
|
|
}
|
|
|
|
|
|
static void
|
|
get_primary_selection(XI_OBJ *itf, WINDOW win)
|
|
{
|
|
Widget widget;
|
|
|
|
rp_xi_obj = itf;
|
|
|
|
/* printf("get_primary_selection: ENTERED, win %d\n", win); */
|
|
|
|
/* request PRIMARY selection */
|
|
widget = (Widget) xvt_vobj_get_attr(win, ATTR_X_WIDGET);
|
|
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++;
|
|
#if XI_IS_CH
|
|
CTOS_IS_CH;
|
|
xi_coalesce_invalidates(itf, TRUE);
|
|
CTOS_END;
|
|
#endif
|
|
(*itf_data->xi_eh)((struct _xi_obj *)itf, xiev);
|
|
#ifdef WINRUNNER
|
|
xir_record(itf, xiev);
|
|
#endif
|
|
if (xi_is_itf(itf))
|
|
{
|
|
#if XI_IS_CH
|
|
CTOS_IS_CH;
|
|
xi_coalesce_invalidates(itf, FALSE);
|
|
CTOS_END;
|
|
#endif
|
|
itf_data->in_callback--;
|
|
if (itf_data->closing)
|
|
{
|
|
itf_data->closing = FALSE;
|
|
xi_close_window_internal(itf);
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static long near
|
|
event_to_longchar(EVENT *ep)
|
|
{
|
|
long c = ep->v.chr.ch;
|
|
|
|
if (ep->v.chr.control)
|
|
c |= XI_MOD_CONTROL;
|
|
if (ep->v.chr.shift)
|
|
c |= XI_MOD_SHIFT;
|
|
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;
|
|
xvt_errmsg_sig_if(!(column->type == XIT_COLUMN), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4, "20010", 20010,
|
|
"Non-column object sent to xi_column_set_pixel_width");
|
|
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((XI_OBJ*)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);
|
|
}
|
|
|
|
void
|
|
xi_hscroll_internal(XI_OBJ *xi_obj, int nbr_lines, int pos)
|
|
{
|
|
XI_OBJ *itf, *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_UNUSED_PREFERENCE))
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
static void
|
|
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, WINDOW win, EVENT *ep)
|
|
{
|
|
XI_ITF_DATA *itf_data;
|
|
XI_OBJ *xi_obj;
|
|
|
|
itf_data = itf->v.itf;
|
|
win = itf_data->xvt_win;
|
|
if ((xi_obj = xi_get_obj(itf, ep->v.ctl.id)) != NULL)
|
|
{
|
|
switch (xi_obj->type)
|
|
{
|
|
case XIT_BTN:
|
|
{
|
|
XI_EVENT xiev;
|
|
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)
|
|
{
|
|
WINDOW front_win = xvt_scr_get_focus_vobj();
|
|
if (win)
|
|
xvt_scr_set_focus_vobj(win);
|
|
xvt_vobj_raise(win);
|
|
if (front_win != win && front_win)
|
|
xvt_scr_set_focus_vobj(front_win);
|
|
xvt_vobj_raise(front_win);
|
|
}
|
|
|
|
break;
|
|
}
|
|
case XIT_LIST:
|
|
{
|
|
switch (ep->v.ctl.ci.v.scroll.what)
|
|
{
|
|
case SC_LINE_UP:
|
|
control_event_scroll(xi_obj, -1, 0, TRUE );
|
|
break;
|
|
case SC_LINE_DOWN:
|
|
control_event_scroll(xi_obj, 1, 0, TRUE );
|
|
break;
|
|
case SC_PAGE_UP:
|
|
control_event_scroll(xi_obj, XI_SCROLL_PGUP, 0, TRUE );
|
|
break;
|
|
case SC_PAGE_DOWN:
|
|
control_event_scroll(xi_obj, XI_SCROLL_PGDOWN, 0, TRUE );
|
|
break;
|
|
case SC_THUMB:
|
|
{
|
|
int percent = ep->v.ctl.ci.v.scroll.pos;
|
|
if (xvt_sbar_get_proportion(ep->v.ctl.ci.win, HVSCROLL)
|
|
+ percent == 100)
|
|
control_event_scroll(xi_obj, XI_SCROLL_LAST, 0, TRUE );
|
|
else
|
|
control_event_scroll(xi_obj, XI_SCROLL_FIRST, percent, TRUE );
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (xi_is_itf(itf) &&
|
|
(xi_obj = xi_get_obj(itf, ep->v.ctl.id - HSCROLL_CID_CONST)) != NULL)
|
|
{
|
|
switch (xi_obj->type)
|
|
{
|
|
case XIT_LIST:
|
|
switch (ep->v.ctl.ci.v.scroll.what)
|
|
{
|
|
case SC_LINE_UP:
|
|
control_event_hscroll(xi_obj, -1, 0);
|
|
break;
|
|
case SC_LINE_DOWN:
|
|
control_event_hscroll(xi_obj, 1, 0);
|
|
break;
|
|
case SC_PAGE_UP:
|
|
control_event_hscroll(xi_obj, XI_SCROLL_PGUP, 0);
|
|
break;
|
|
case SC_PAGE_DOWN:
|
|
control_event_hscroll(xi_obj, XI_SCROLL_PGDOWN, 0);
|
|
break;
|
|
case SC_THUMB:
|
|
{
|
|
int prop;
|
|
int rng1, rng2;
|
|
int pos;
|
|
|
|
prop = xvt_sbar_get_proportion(ep->v.ctl.ci.win, HVSCROLL);
|
|
xvt_sbar_get_range(ep->v.ctl.ci.win, HVSCROLL, &rng1, &rng2);
|
|
pos = (rng2 - rng1 - prop) ?
|
|
(int)(ep->v.ctl.ci.v.scroll.pos * 100L / (rng2 - rng1 - prop)) : 0;
|
|
control_event_hscroll(xi_obj, XI_SCROLL_FIRST, pos);
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_trap_obj(XI_OBJ *xi_obj)
|
|
{
|
|
XI_OBJ *itf;
|
|
XI_ITF_DATA *itf_data;
|
|
|
|
itf = xi_obj->itf;
|
|
itf_data = itf->v.itf;
|
|
itf_data->trap_obj = xi_obj;
|
|
itf_data->trap_explicit = TRUE;
|
|
}
|
|
|
|
static void
|
|
destroy_controls(XI_OBJ *xi_obj)
|
|
{
|
|
XI_OBJ * *objp;
|
|
int i;
|
|
|
|
switch (xi_obj->type)
|
|
{
|
|
case XIT_LIST:
|
|
lm_remove_all_rows( (LM_DATA *) xi_obj->v.list->lm, TRUE );
|
|
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)
|
|
{
|
|
char *p;
|
|
long len;
|
|
|
|
len = e - b;
|
|
buff = xi_get_text(focus_obj, NULL, 0);
|
|
if (xvt_cb_open(TRUE))
|
|
{
|
|
if ((p = xvt_cb_alloc_data(len + 1)) != NULL)
|
|
{
|
|
gstrncpy(p, &buff[b], (int)len);
|
|
p[(int)len] = '\0';
|
|
xvt_cb_put_data(CB_TEXT, NULL, len, (PICTURE)NULL);
|
|
xvt_cb_free_data();
|
|
}
|
|
xvt_cb_close();
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
update_menus(void)
|
|
{
|
|
BOOLEAN paste_enable;
|
|
BOOLEAN cut_or_copy_enable = FALSE;
|
|
XI_OBJ *itf;
|
|
XI_ITF_DATA *itfdata;
|
|
WINDOW win;
|
|
|
|
win = xvt_scr_get_focus_vobj();
|
|
if (win == NULL_WIN || ! xi_is_window(win))
|
|
return;
|
|
itf = xi_get_itf(win);
|
|
itfdata = itf->v.itf;
|
|
if (itfdata->menu_win != NULL_WIN)
|
|
win = itfdata->menu_win;
|
|
if (itfdata->edit_menu)
|
|
{
|
|
XI_OBJ *focus_obj;
|
|
|
|
paste_enable = xvt_cb_has_format(CB_TEXT, NULL);
|
|
xvt_menu_set_item_enabled(win, M_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)
|
|
{
|
|
xvt_menu_set_item_enabled(win, M_EDIT_PASTE, paste_enable);
|
|
itfdata->paste_enable = paste_enable;
|
|
}
|
|
if (cut_or_copy_enable != itfdata->cut_or_copy_enable)
|
|
{
|
|
xvt_menu_set_item_enabled(win, M_EDIT_CUT, cut_or_copy_enable);
|
|
xvt_menu_set_item_enabled(win, M_EDIT_COPY, cut_or_copy_enable);
|
|
xvt_menu_set_item_enabled(win, M_EDIT_CLEAR, cut_or_copy_enable);
|
|
itfdata->cut_or_copy_enable = cut_or_copy_enable;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
do_edit_menu(XI_OBJ *itf, EVENT *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, *column;
|
|
XI_OBJ * *members;
|
|
int col_nbr, nbr_members;
|
|
|
|
list = focus_obj->parent;
|
|
members = xi_get_member_list(list, &nbr_members);
|
|
col_nbr = focus_obj->v.cell.column;
|
|
column = members[col_nbr];
|
|
attrib = xi_get_attrib(column);
|
|
break;
|
|
}
|
|
}
|
|
if (attrib & XI_ATR_EDITMENU)
|
|
{
|
|
int b, e;
|
|
|
|
switch (ep->v.cmd.tag)
|
|
{
|
|
case M_EDIT_CUT:
|
|
copy_to_clip(focus_obj);
|
|
/* fall through */
|
|
case M_EDIT_CLEAR:
|
|
xi_get_sel(focus_obj, &b, &e);
|
|
if (b != e)
|
|
{
|
|
EVENT ev;
|
|
|
|
MEMCLEAR(ev);
|
|
ev.type = E_CHAR;
|
|
ev.v.chr.ch = K_DEL;
|
|
xi_event(xi_get_window(itf), &ev);
|
|
}
|
|
update_menus();
|
|
break;
|
|
case M_EDIT_COPY:
|
|
copy_to_clip(focus_obj);
|
|
update_menus();
|
|
break;
|
|
case M_EDIT_PASTE:
|
|
if (focus_obj->type == XIT_FIELD)
|
|
if (xi_get_txedit(focus_obj) != BAD_TXEDIT)
|
|
if (xi_get_pref(XI_PREF_MULTILINE_QUICK_PASTE))
|
|
break;
|
|
if (xvt_cb_open(FALSE))
|
|
{
|
|
char *p;
|
|
long size;
|
|
|
|
if ((p = xvt_cb_get_data(CB_TEXT, NULL, &size)) != NULL)
|
|
{
|
|
WINDOW win;
|
|
|
|
win = xi_get_window(itf);
|
|
itf->v.itf->pasting = TRUE;
|
|
while ( size-- > 0 )
|
|
{
|
|
EVENT ev;
|
|
|
|
MEMCLEAR(ev);
|
|
ev.type = E_CHAR;
|
|
ev.v.chr.ch = (unsigned char)*p++;
|
|
xi_event(win, &ev);
|
|
xvt_dwin_update(win);
|
|
}
|
|
itf->v.itf->pasting = FALSE;
|
|
}
|
|
xvt_cb_close();
|
|
}
|
|
update_menus();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#define RALEN 32
|
|
#define RCT_TOP 0
|
|
#define RCT_LEFT 1
|
|
#define RCT_BOTTOM 2
|
|
#define RCT_RIGHT 3
|
|
|
|
static BOOLEAN
|
|
bound_rct(RCT *ra, int ra_len, RCT *rct, int which)
|
|
{
|
|
int i;
|
|
BOOLEAN b;
|
|
|
|
switch (which)
|
|
{
|
|
case RCT_TOP:
|
|
{
|
|
for (i = 0; i < ra_len; ++i)
|
|
{
|
|
if (ra->bottom < rct->bottom && ra->bottom >= rct->top)
|
|
rct->top = ra->bottom;
|
|
++ra;
|
|
}
|
|
break;
|
|
}
|
|
case RCT_LEFT:
|
|
{
|
|
for (i = 0; i < ra_len; ++i)
|
|
{
|
|
if (ra->right < rct->right && ra->right >= rct->left)
|
|
rct->left = ra->right;
|
|
++ra;
|
|
}
|
|
break;
|
|
}
|
|
case RCT_BOTTOM:
|
|
{
|
|
for (i = 0; i < ra_len; ++i)
|
|
{
|
|
if (ra->top > rct->top && ra->top <= rct->bottom)
|
|
rct->bottom = ra->top;
|
|
++ra;
|
|
}
|
|
break;
|
|
}
|
|
case RCT_RIGHT:
|
|
{
|
|
for (i = 0; i < ra_len; ++i)
|
|
{
|
|
if (ra->left > rct->left && ra->left <= rct->right)
|
|
rct->right = ra->left;
|
|
++ra;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
b = (rct->top < rct->bottom && rct->left < rct->right);
|
|
return b;
|
|
}
|
|
|
|
|
|
static void
|
|
draw_all_rects(XI_OBJ *itf)
|
|
{
|
|
RCT ra[RALEN];
|
|
RCT rct;
|
|
int list_len, ra_len, i;
|
|
XI_OBJ * *child;
|
|
XI_ITF_DATA *itf_data;
|
|
int cur_delta_x, cur_delta_y;
|
|
|
|
#if XIWS == XOLWS || XIWS == MTFWS
|
|
/* X GRAY SCALE HACK */
|
|
xi_set_xvt_back_color(itf->v.itf->xvt_win, COLOR_WHITE);
|
|
{
|
|
DRAW_CTOOLS ct;
|
|
WINDOW win = itf->v.itf->xvt_win;
|
|
|
|
xi_get_draw_ctools(win, &ct);
|
|
ct.opaque_text = FALSE;
|
|
xi_set_draw_ctools(win, &ct);
|
|
xi_draw_text(win, 0, 0, " ", -1);
|
|
}
|
|
#endif
|
|
|
|
itf_data = itf->v.itf;
|
|
cur_delta_x = itf_data->delta_x;
|
|
cur_delta_y = itf_data->delta_y;
|
|
|
|
list_len = 0;
|
|
for (i = 0, child = itf->children; i < itf->nbr_children; ++i, ++child)
|
|
{
|
|
if ((*child)->type == XIT_LIST && (xi_get_attrib(*child) & XI_ATR_VISIBLE))
|
|
{
|
|
if (list_len < (RALEN - 1))
|
|
{
|
|
xi_get_rect((*child), &ra[list_len]);
|
|
++list_len;
|
|
}
|
|
}
|
|
}
|
|
ra_len = list_len;
|
|
if (list_len)
|
|
{
|
|
int cnt;
|
|
|
|
for (cnt = 0; cnt < list_len; ++cnt)
|
|
{
|
|
RCT lr;
|
|
|
|
lr = ra[cnt];
|
|
|
|
/* do left rect */
|
|
rct.left = 0;
|
|
rct.top = 0;
|
|
rct.bottom = MAXPIX;
|
|
rct.right = lr.left;
|
|
if (bound_rct(ra, ra_len, &rct, RCT_LEFT))
|
|
{
|
|
VRCT_TO_PRCT(&rct);
|
|
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
|
|
}
|
|
|
|
/* do top rect */
|
|
rct.left = 0;
|
|
rct.top = 0;
|
|
rct.bottom = lr.top;
|
|
rct.right = MAXPIX;
|
|
if (bound_rct(ra, ra_len, &rct, RCT_TOP))
|
|
VRCT_TO_PRCT(&rct);
|
|
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
|
|
|
|
/* do right rect */
|
|
rct.left = lr.right;
|
|
rct.top = 0;
|
|
rct.bottom = MAXPIX;
|
|
rct.right = MAXPIX;
|
|
if (bound_rct(ra, ra_len, &rct, RCT_RIGHT))
|
|
VRCT_TO_PRCT(&rct);
|
|
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
|
|
|
|
/* do bottom rect */
|
|
rct.left = 0;
|
|
rct.top = lr.bottom;
|
|
rct.bottom = MAXPIX;
|
|
rct.right = MAXPIX;
|
|
if (bound_rct(ra, ra_len, &rct, RCT_BOTTOM))
|
|
VRCT_TO_PRCT(&rct);
|
|
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rct.top = 0;
|
|
rct.left = 0;
|
|
rct.bottom = MAXPIX;
|
|
rct.right = MAXPIX;
|
|
xvt_dwin_draw_rect(itf_data->xvt_win, &rct);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
draw_background(XI_OBJ *itf)
|
|
{
|
|
XI_ITF_DATA *itf_data = itf->v.itf;
|
|
WINDOW win = itf_data->xvt_win;
|
|
|
|
if (itf_data->back_color)
|
|
{
|
|
DRAW_CTOOLS t;
|
|
CBRUSH cbrush;
|
|
|
|
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
|
|
CBRUSH hollow_cbrush;
|
|
RCT rct;
|
|
|
|
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
|
|
xvt_app_get_default_ctools(&t);
|
|
xvt_dwin_set_draw_ctools(win, &t);
|
|
hollow_cbrush.color = COLOR_WHITE;
|
|
hollow_cbrush.pat = PAT_HOLLOW;
|
|
xvt_dwin_set_cbrush(win, &hollow_cbrush);
|
|
rct.top = 0;
|
|
rct.left = 0;
|
|
rct.bottom = 0;
|
|
rct.right = 0;
|
|
xvt_dwin_draw_rect(win, &rct);
|
|
#endif
|
|
#if XIWS == XOLWS || XIWS == MTFWS
|
|
/* X GRAY SCALE HACK */
|
|
xi_set_xvt_back_color(win, COLOR_WHITE);
|
|
{
|
|
DRAW_CTOOLS ct;
|
|
|
|
xi_get_draw_ctools(win, &ct);
|
|
ct.opaque_text = FALSE;
|
|
xi_set_draw_ctools(win, &ct);
|
|
xi_draw_text(win, 0, 0, " ", -1);
|
|
}
|
|
#endif
|
|
|
|
xvt_app_get_default_ctools(&t);
|
|
xi_set_draw_ctools(win, &t);
|
|
xvt_dwin_set_cpen(win, &hollow_cpen);
|
|
cbrush.pat = PAT_SOLID;
|
|
cbrush.color = itf_data->back_color;
|
|
#if XI_IS_CH
|
|
CTOS_IS_CH;
|
|
xi_fix_color(&cbrush.color);
|
|
CTOS_END;
|
|
#endif
|
|
xvt_dwin_set_cbrush(win, &cbrush);
|
|
xvt_dwin_set_clip(win, NULL);
|
|
draw_all_rects(itf);
|
|
}
|
|
}
|
|
|
|
|
|
static void
|
|
do_post_event(XI_OBJ *itf, EVENT *ep)
|
|
{
|
|
XI_EVENT xiev;
|
|
|
|
if (xi_is_itf(itf))
|
|
{
|
|
/* send XVT event */
|
|
MEMCLEAR(xiev);
|
|
xiev.type = XIE_XVT_POST_EVENT;
|
|
xiev.v.xvte = *ep;
|
|
xiev.refused = FALSE;
|
|
call_cb(itf, &xiev);
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* get_text_ctools */
|
|
/* ------------------------------------------------------------------------ */
|
|
static DRAW_CTOOLS * near
|
|
get_text_ctools(XI_ITF_DATA *itf_data, DRAW_CTOOLS *ct, FONT_OBJ *font)
|
|
{
|
|
xvt_app_get_default_ctools(ct);
|
|
ct->pen.color = ct->fore_color = COLOR_BLACK;
|
|
ct->opaque_text = FALSE;
|
|
if (itf_data->font)
|
|
*font = *itf_data->font;
|
|
else
|
|
*font = xi_sysfont;
|
|
return(ct);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* xi_draw_obj */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void near
|
|
xi_draw_obj(XI_OBJ *xi_obj)
|
|
{
|
|
WINDOW win;
|
|
XI_ITF_DATA *itf_data;
|
|
|
|
itf_data = xi_obj->itf->v.itf;
|
|
win = itf_data->xvt_win;
|
|
switch (xi_obj->type)
|
|
{
|
|
case XIT_TEXT:
|
|
{
|
|
XI_TEXT_DATA *text;
|
|
DRAW_CTOOLS ct;
|
|
FONT_OBJ font;
|
|
|
|
text = xi_obj->v.text;
|
|
get_text_ctools(itf_data, &ct, &font);
|
|
ct.back_color = itf_data->back_color;
|
|
ct.fore_color = COLOR_BLACK;
|
|
if (text->fore_color)
|
|
ct.fore_color = text->fore_color;
|
|
if (text->back_color)
|
|
{
|
|
ct.opaque_text = TRUE;
|
|
ct.back_color = text->back_color;
|
|
}
|
|
xi_set_xvt_font(win, &font, TRUE);
|
|
if (text->font)
|
|
xi_set_xvt_font(win, text->font, FALSE);
|
|
xi_set_draw_ctools(win, &ct);
|
|
if ((text->attrib & XI_ATR_ENABLED))
|
|
xi_set_xvt_fore_color(win, ct.fore_color);
|
|
else
|
|
xi_set_xvt_fore_color( win,
|
|
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
|
|
xi_set_xvt_back_color(win, ct.back_color);
|
|
xi_draw_clipped_text(win, text->text, &text->rct, &text->rct,
|
|
text->attrib | XI_ATR_VCENTER, FALSE, 0, -1);
|
|
break;
|
|
}
|
|
case XIT_LINE:
|
|
{
|
|
XI_LINE_DATA *line;
|
|
PNT pnt1, pnt2;
|
|
|
|
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
|
|
{
|
|
CPEN cpen;
|
|
cpen = black_cpen;
|
|
if (line->fore_color)
|
|
cpen.color = line->fore_color;
|
|
xi_set_cpen(win, &cpen);
|
|
if (line->back_color)
|
|
xi_set_xvt_back_color(win, line->back_color);
|
|
xi_move_to(win, pnt1);
|
|
xi_draw_line(win, pnt2);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case XIT_RECT:
|
|
{
|
|
XI_RECT_DATA *rect;
|
|
RCT rct;
|
|
|
|
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
|
|
{
|
|
CPEN cpen;
|
|
CBRUSH cbrush;
|
|
|
|
cpen = black_cpen;
|
|
if (rect->fore_color)
|
|
cpen.color = rect->fore_color;
|
|
xi_set_cpen(win, &cpen);
|
|
cbrush.pat = PAT_SOLID;
|
|
cbrush.color = COLOR_WHITE;
|
|
if (rect->back_color)
|
|
cbrush.color = rect->back_color;
|
|
xi_set_cbrush(win, &cbrush);
|
|
xi_draw_rect(win, &rct);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* draw_field_button */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void
|
|
draw_field_button(XI_OBJ *xi_obj)
|
|
{
|
|
XI_FIELD_DATA *fd;
|
|
unsigned long attrib;
|
|
STX_DATA *stxd;
|
|
#if XI_IS_NOT_CH
|
|
int x, y;
|
|
RCT cr, r;
|
|
#endif
|
|
WINDOW 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->xvt_win;
|
|
xi_set_draw_mode(win, M_COPY);
|
|
xi_set_clip(win, NULL);
|
|
#if XI_IS_NOT_CH
|
|
CTOS_IS_PM;
|
|
r = fd->btn_rct;
|
|
r.top++;
|
|
r.left++;
|
|
r.bottom--;
|
|
r.right--;
|
|
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
|
|
{
|
|
CBRUSH hollow_cbrush;
|
|
RCT rct;
|
|
DRAW_CTOOLS t;
|
|
|
|
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
|
|
xvt_app_get_default_ctools(&t);
|
|
xvt_dwin_set_draw_ctools(win, &t);
|
|
hollow_cbrush.color = COLOR_WHITE;
|
|
hollow_cbrush.pat = PAT_HOLLOW;
|
|
xvt_dwin_set_cbrush(win, &hollow_cbrush);
|
|
rct.top = 0;
|
|
rct.left = 0;
|
|
rct.bottom = 0;
|
|
rct.right = 0;
|
|
xvt_dwin_draw_rect(win, &rct);
|
|
}
|
|
#endif
|
|
if ((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK))
|
|
{
|
|
const COLOR color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
|
|
const COLOR color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
|
|
const COLOR color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
|
|
|
|
xi_draw_3d_rect(win, &r, fd->down, 2, color_light, color_ctrl, color_dark);
|
|
}
|
|
else
|
|
{
|
|
xi_set_cbrush(win, &white_cbrush);
|
|
xi_set_cpen(win, &hollow_cpen);
|
|
xi_draw_rect(win, &r);
|
|
}
|
|
x = r.left + 3;
|
|
y = r.top + 2;
|
|
cr = r;
|
|
cr.top += 2;
|
|
cr.left += 2;
|
|
cr.bottom -= 2;
|
|
cr.right -= 2;
|
|
xi_set_clip(win, &cr);
|
|
#if XIWS == PMWS
|
|
/* Hack for OS2 - Icons are drawn differenty depending on whether
|
|
opaque_text is set or not in the DRAW_CTOOLS */
|
|
{
|
|
DRAW_CTOOLS ct;
|
|
|
|
xi_get_draw_ctools(win, &ct);
|
|
ct.opaque_text = TRUE;
|
|
ct.back_color = xi_get_pref(XI_PREF_COLOR_CTRL);
|
|
ct.fore_color = COLOR_BLACK;
|
|
xi_set_draw_ctools(win, &ct);
|
|
}
|
|
#endif
|
|
{
|
|
int icon_rid;
|
|
|
|
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, COLOR_BLACK,
|
|
xi_get_pref(XI_PREF_COLOR_CTRL));
|
|
else
|
|
xi_draw_icon( win, x, y, icon_rid, COLOR_BLACK,
|
|
xi_get_pref(XI_PREF_COLOR_CTRL));
|
|
}
|
|
xi_set_clip(win, NULL);
|
|
xi_set_cpen(win, &black_cpen);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
xi_draw_rect(win, &fd->btn_rct);
|
|
CTOS_END;
|
|
#endif
|
|
#if XI_IS_CH
|
|
CTOS_IS_CH;
|
|
NOREF(stxd);
|
|
{
|
|
CBRUSH black_cbrush;
|
|
|
|
black_cbrush = white_cbrush;
|
|
black_cbrush.color = COLOR_BLACK;
|
|
xi_set_clip(win, NULL);
|
|
xi_set_cpen(win, &hollow_cpen);
|
|
xi_set_cbrush(win, &black_cbrush);
|
|
xi_draw_rect(win, &fd->btn_rct);
|
|
}
|
|
CTOS_END;
|
|
#endif
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* field_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void
|
|
field_event(XI_OBJ *xi_obj, EVENT *ep)
|
|
{
|
|
XI_FIELD_DATA *field_data;
|
|
RCT rct;
|
|
#if XIWS == MACWS
|
|
RCT irct;
|
|
WINDOW win;
|
|
#endif
|
|
|
|
field_data = xi_obj->v.field;
|
|
rct = field_data->btn_rct;
|
|
#if XIWS == MACWS
|
|
irct = rct;
|
|
xi_inflate_rect(&irct, -1);
|
|
win = xi_obj->itf->v.itf->xvt_win;
|
|
#endif
|
|
switch (ep->type)
|
|
{
|
|
case E_CHAR:
|
|
{
|
|
long button_key;
|
|
BOOLEAN shift, control;
|
|
|
|
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);
|
|
button_key &= 0xffffffL;
|
|
if (button_key == ep->v.chr.ch &&
|
|
shift == ep->v.chr.shift &&
|
|
control == ep->v.chr.control)
|
|
{
|
|
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 E_UPDATE:
|
|
if (field_data->button)
|
|
draw_field_button(xi_obj);
|
|
break;
|
|
case E_MOUSE_DOWN:
|
|
{
|
|
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 (xvt_rect_has_point(&rct, ep->v.mouse.where))
|
|
{
|
|
field_data->down = TRUE;
|
|
field_data->down_in_btn = TRUE;
|
|
#if XIWS == MACWS
|
|
xi_invalidate_rect(win, &irct);
|
|
#else
|
|
draw_field_button(xi_obj);
|
|
#endif
|
|
xi_set_trap_obj(xi_obj);
|
|
xi_trap_mouse(xi_obj->itf->v.itf->xvt_win);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case E_MOUSE_MOVE:
|
|
if (field_data->button && field_data->down_in_btn)
|
|
{
|
|
if (xvt_rect_has_point(&rct, ep->v.mouse.where) && ! field_data->down)
|
|
{
|
|
field_data->down = TRUE;
|
|
#if XIWS == MACWS
|
|
xi_invalidate_rect(win, &irct);
|
|
#else
|
|
draw_field_button(xi_obj);
|
|
#endif
|
|
}
|
|
if (! xvt_rect_has_point(&rct, ep->v.mouse.where) && field_data->down)
|
|
{
|
|
field_data->down = FALSE;
|
|
#if XIWS == MACWS
|
|
xi_invalidate_rect(win, &irct);
|
|
#else
|
|
draw_field_button(xi_obj);
|
|
#endif
|
|
}
|
|
}
|
|
break;
|
|
case E_MOUSE_UP:
|
|
if (field_data->button && field_data->down_in_btn)
|
|
{
|
|
xi_release_mouse();
|
|
if (field_data->down)
|
|
{
|
|
field_data->down = FALSE;
|
|
#if XIWS == MACWS
|
|
xi_invalidate_rect(win, &irct);
|
|
#else
|
|
draw_field_button(xi_obj);
|
|
#endif
|
|
}
|
|
field_data->down_in_btn = FALSE;
|
|
if (xvt_rect_has_point(&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;
|
|
}
|
|
}
|
|
/* ------------------------------------------------------------------------ */
|
|
/* form_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
static BOOLEAN near
|
|
form_event(XI_OBJ *xi_obj, EVENT *ep)
|
|
{
|
|
BOOLEAN retval = FALSE;
|
|
XI_OBJ *focus_obj = xi_obj->itf->v.itf->focus_obj;
|
|
|
|
switch(ep->type)
|
|
{
|
|
case E_COMMAND:
|
|
/* TODO -- navigation */
|
|
break;
|
|
case E_CHAR:
|
|
{
|
|
long c = event_to_longchar(ep);
|
|
XI_OBJ *next_obj = NULL;
|
|
|
|
/* navigation character event */
|
|
if ( c == '\r' && 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 == K_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 == K_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 == K_DOWN)) ? 1 : 2);
|
|
retval = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return retval;
|
|
}
|
|
/* ------------------------------------------------------------------------ */
|
|
/* invalidate_button_rect */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void near
|
|
invalidate_button_rect(XI_OBJ *xi_obj, XI_BTN_DATA *bd, RCT *rct)
|
|
{
|
|
if ((bd->type == XIBT_BUTTON || bd->type == XIBT_BUTTON_CHECKBOX ||
|
|
bd->type == XIBT_RADIOBTN) && bd->drawable)
|
|
{
|
|
RCT r;
|
|
WINDOW win;
|
|
|
|
r = *rct;
|
|
xi_inflate_rect(&r, -4);
|
|
win = xi_get_window(xi_obj->itf);
|
|
xi_invalidate_rect(win, &r);
|
|
xvt_dwin_update(win);
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* btn_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
static BOOLEAN near
|
|
btn_event(XI_OBJ *xi_obj, EVENT *ep)
|
|
{
|
|
BOOLEAN enabled;
|
|
BOOLEAN visible;
|
|
BOOLEAN focus;
|
|
BOOLEAN dflt;
|
|
BOOLEAN send_to_form = TRUE;
|
|
BOOLEAN ret_val;
|
|
RCT rct;
|
|
unsigned long attrib;
|
|
XI_BTN_DATA *bd;
|
|
|
|
if (! (BOOLEAN)xi_get_pref(XI_PREF_NATIVE_CTRLS))
|
|
{
|
|
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 E_TIMER:
|
|
return FALSE;
|
|
case E_CHAR:
|
|
if (ep->v.chr.ch == ' ' && focus)
|
|
{
|
|
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);
|
|
if (! xi_is_itf(itf))
|
|
send_to_form = FALSE;
|
|
}
|
|
break;
|
|
case E_UPDATE:
|
|
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
|
|
bd->up_icon_rid, bd->disabled_icon_rid, enabled,
|
|
visible, focus, bd->down, dflt, bd->checked, FALSE);
|
|
break;
|
|
case E_MOUSE_DBL:
|
|
if (! xi_get_pref(XI_PREF_DBL_PRESSES_BUTTON))
|
|
break;
|
|
/* else fall through */
|
|
case E_MOUSE_DOWN:
|
|
{
|
|
RCT 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 (xvt_rect_has_point(&hit_rct, ep->v.mouse.where))
|
|
{
|
|
bd->down = TRUE;
|
|
bd->down_in_btn = TRUE;
|
|
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
|
|
bd->up_icon_rid, bd->disabled_icon_rid, enabled,
|
|
visible, focus, bd->down, dflt, bd->checked, FALSE);
|
|
invalidate_button_rect(xi_obj, bd, &rct);
|
|
xi_set_trap_obj(xi_obj);
|
|
xi_trap_mouse(xi_get_window(xi_obj->itf));
|
|
}
|
|
break;
|
|
}
|
|
case E_MOUSE_MOVE:
|
|
if (bd->down_in_btn)
|
|
{
|
|
if (xvt_rect_has_point(&rct, ep->v.mouse.where) && ! bd->down)
|
|
{
|
|
bd->down = TRUE;
|
|
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
|
|
bd->up_icon_rid, bd->disabled_icon_rid,
|
|
enabled, visible, focus, bd->down, dflt,
|
|
bd->checked, FALSE);
|
|
invalidate_button_rect(xi_obj, bd, &rct);
|
|
}
|
|
else if (! xvt_rect_has_point(&rct, ep->v.mouse.where) &&
|
|
bd->down)
|
|
{
|
|
bd->down = FALSE;
|
|
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
|
|
bd->up_icon_rid, bd->disabled_icon_rid,
|
|
enabled, visible, focus, bd->down, dflt,
|
|
bd->checked, FALSE);
|
|
invalidate_button_rect(xi_obj, bd, &rct);
|
|
}
|
|
}
|
|
break;
|
|
case E_MOUSE_UP:
|
|
if (bd->down_in_btn)
|
|
{
|
|
bd->down_in_btn = FALSE;
|
|
if (bd->down)
|
|
{
|
|
bd->down = FALSE;
|
|
xi_draw_button(xi_obj, &rct, bd->text, bd->down_icon_rid,
|
|
bd->up_icon_rid, bd->disabled_icon_rid,
|
|
enabled, visible, focus, bd->down, dflt,
|
|
bd->checked, FALSE);
|
|
invalidate_button_rect(xi_obj, bd, &rct);
|
|
}
|
|
xi_release_mouse();
|
|
if (ep->type == E_MOUSE_UP &&
|
|
xvt_rect_has_point(&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);
|
|
if (! xi_is_itf(itf))
|
|
send_to_form = FALSE;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
ret_val = TRUE;
|
|
if (send_to_form)
|
|
ret_val = form_event(xi_obj, ep);
|
|
return ret_val;
|
|
}
|
|
/* ------------------------------------------------------------------------ */
|
|
/* draw_list_button */
|
|
/* ------------------------------------------------------------------------ */
|
|
#define P_OFFSET 3
|
|
static void
|
|
draw_list_button(WINDOW win, RCT *rct, BOOLEAN down)
|
|
{
|
|
#if XI_IS_NOT_CH
|
|
int x, y, plus_width, plus_height;
|
|
PNT p;
|
|
RCT r;
|
|
BOOLEAN x2;
|
|
|
|
CTOS_IS_PM;
|
|
r = *rct;
|
|
xi_set_cpen(win, &black_cpen);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
xi_draw_rect(win, &r);
|
|
r.top++;
|
|
r.left++;
|
|
r.bottom--;
|
|
r.right--;
|
|
if ((BOOLEAN)xi_get_pref(XI_PREF_3D_LOOK))
|
|
{
|
|
const COLOR color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
|
|
const COLOR color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
|
|
const COLOR color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
|
|
|
|
xi_draw_3d_rect(win, &r, down, 2, color_light, color_ctrl, color_dark);
|
|
}
|
|
else
|
|
{
|
|
xi_set_cbrush(win, &white_cbrush);
|
|
xi_draw_rect(win, &r);
|
|
}
|
|
|
|
p.h = rct->left;
|
|
p.v = rct->top - 1;
|
|
xi_set_cpen(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--;
|
|
xi_set_cpen(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);
|
|
CTOS_END;
|
|
#endif
|
|
NOREF(rct);
|
|
NOREF(down);
|
|
NOREF(win);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* list_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
static void
|
|
list_event(XI_OBJ *xi_obj, EVENT *ep)
|
|
{
|
|
XI_LIST_DATA *list_data;
|
|
RCT 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 E_UPDATE:
|
|
if (list_data->scroll_bar_button)
|
|
draw_list_button(lmp->win, &rct, list_data->down);
|
|
break;
|
|
case E_MOUSE_DOWN:
|
|
if (list_data->scroll_bar_button)
|
|
{
|
|
if (xvt_rect_has_point(&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);
|
|
xi_trap_mouse(xi_obj->itf->v.itf->xvt_win);
|
|
}
|
|
}
|
|
break;
|
|
case E_MOUSE_MOVE:
|
|
if (list_data->scroll_bar_button && list_data->down_in_btn)
|
|
{
|
|
if (xvt_rect_has_point(&rct, ep->v.mouse.where) && ! list_data->down)
|
|
{
|
|
list_data->down = TRUE;
|
|
draw_list_button(lmp->win, &rct, TRUE);
|
|
}
|
|
if (! xvt_rect_has_point(&rct, ep->v.mouse.where) && list_data->down)
|
|
{
|
|
list_data->down = FALSE;
|
|
draw_list_button(lmp->win, &rct, FALSE);
|
|
}
|
|
}
|
|
break;
|
|
case E_MOUSE_UP:
|
|
if (list_data->scroll_bar_button && list_data->down_in_btn)
|
|
{
|
|
xi_release_mouse();
|
|
if (list_data->down)
|
|
{
|
|
list_data->down = FALSE;
|
|
draw_list_button(lmp->win, &rct, FALSE);
|
|
}
|
|
list_data->down_in_btn = FALSE;
|
|
if (xvt_rect_has_point(&rct, ep->v.mouse.where))
|
|
{
|
|
XI_EVENT xiev;
|
|
XI_OBJ *itf;
|
|
|
|
MEMCLEAR(xiev);
|
|
xiev.type = XIE_BUTTON;
|
|
xiev.v.xi_obj = xi_obj;
|
|
itf = xi_obj->itf;
|
|
call_cb(itf, &xiev);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* itf_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
static BOOLEAN near
|
|
itf_event(XI_OBJ *xi_obj, EVENT *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 E_COMMAND:
|
|
/* TODO -- navigation */
|
|
break;
|
|
case E_CHAR:
|
|
{
|
|
long c = event_to_longchar(ep);
|
|
XI_OBJ *next_obj = NULL;
|
|
|
|
xvt_errmsg_sig_if(!(focus_obj->itf == xi_obj), NULL_WIN,
|
|
SEV_FATAL, ERR_ASSERT_4, "20030", 20030,
|
|
"Internal focus error");
|
|
|
|
/* 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')
|
|
{
|
|
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 (next_obj != NULL)
|
|
{
|
|
xi_move_focus_internal(next_obj, TRUE, FALSE, 0);
|
|
retval = TRUE;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return(retval);
|
|
}
|
|
|
|
|
|
/* ------------------------------------------------------------------------ */
|
|
/* xi_send_event */
|
|
/* ------------------------------------------------------------------------ */
|
|
|
|
static int
|
|
xi_send_event(XI_OBJ *xi_obj, EVENT *ep, BOOLEAN do_subtree)
|
|
{
|
|
int n;
|
|
XI_OBJ * *objlist;
|
|
BOOLEAN send_to_parent = FALSE;
|
|
int retval = 0;
|
|
|
|
switch(xi_obj->type)
|
|
{
|
|
case XIT_RECT:
|
|
case XIT_TEXT:
|
|
case XIT_LINE:
|
|
if (ep->type == E_UPDATE)
|
|
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 == E_CHAR && 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(xi_obj->v.list->lm, ep);
|
|
send_to_parent = FALSE;
|
|
do_subtree = FALSE;
|
|
}
|
|
else
|
|
{
|
|
list_event(xi_obj, ep);
|
|
retval = lm_event(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;
|
|
|
|
/* 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 (retval)
|
|
{
|
|
return retval;
|
|
}
|
|
}
|
|
}
|
|
if (send_to_parent)
|
|
{
|
|
retval = xi_send_event(xi_obj->parent, ep, FALSE);
|
|
return retval;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
void
|
|
xi_event(WINDOW win, EVENT *ep)
|
|
{
|
|
XI_OBJ *itf;
|
|
XI_EVENT xiev;
|
|
XI_ITF_DATA *itf_data;
|
|
BOOLEAN retval;
|
|
CURSOR new_cursor;
|
|
|
|
if (win == NULL_WIN)
|
|
win = xvt_scr_get_focus_vobj();
|
|
if (win == NULL_WIN || ((itf = xi_get_itf(win)) == NULL))
|
|
return;
|
|
itf_data = itf->v.itf;
|
|
|
|
/* send XVT event */
|
|
MEMCLEAR(xiev);
|
|
xiev.type = XIE_XVT_EVENT;
|
|
xiev.v.xvte = *ep;
|
|
xiev.refused = FALSE;
|
|
if (!call_cb(itf, &xiev))
|
|
return;
|
|
if (xiev.refused)
|
|
return;
|
|
|
|
*ep = xiev.v.xvte;
|
|
|
|
if (ep->type == E_MOUSE_UP)
|
|
xi_release_mouse();
|
|
|
|
if (! xi_eh(win, ep))
|
|
return;
|
|
if (ep->type == E_UPDATE)
|
|
xi_dequeue();
|
|
|
|
#if (XIWS == PMWS) || (XIWS == MTFWS) || (XIWS == XOLWS) || (XIWS == WMWS) || (XIWS == GRWS) || (XIWS == MACWS)
|
|
#if (XIWS == MACWS)
|
|
if (xi_modal_win && ep->type == E_FOCUS && (! ep->v.active) && win == xi_modal_win)
|
|
{
|
|
xvt_scr_set_focus_vobj(xi_modal_win);
|
|
xvt_vobj_raise(xi_modal_win);
|
|
}
|
|
#else
|
|
if (xi_modal_win && ep->type == E_FOCUS && ep->v.active && win != xi_modal_win)
|
|
{
|
|
xvt_scr_set_focus_vobj(xi_modal_win);
|
|
xvt_vobj_raise(xi_modal_win);
|
|
}
|
|
#endif
|
|
if (xi_modal_win && win != xi_modal_win && xvt_vobj_get_parent(win) != xi_modal_win && ep->type != E_UPDATE && ep->type != E_TIMER)
|
|
return;
|
|
#endif
|
|
|
|
|
|
MEMCLEAR(xiev);
|
|
switch (ep->type)
|
|
{
|
|
case E_TIMER:
|
|
{
|
|
xi_send_event(itf, ep, TRUE);
|
|
break;
|
|
}
|
|
case E_UPDATE:
|
|
{
|
|
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 E_MOUSE_DOWN:
|
|
case E_MOUSE_DBL:
|
|
{
|
|
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 E_CHAR:
|
|
#if XIWS == WINWS
|
|
if (ep->v.chr.ch == '\t' && ep->v.chr.shift)
|
|
/* ignore bogus shift-tab from XVT */
|
|
break;
|
|
#endif
|
|
#if XVT_OS != XVT_OS_CTOS
|
|
#if XIWS == WMWS
|
|
/* TODO ep->v.chr.shift and ep->v.chr.control are not set properly for XVT/CH */
|
|
ep->v.chr.shift = FALSE;
|
|
ep->v.chr.control = FALSE;
|
|
#endif
|
|
#endif
|
|
if (ep->v.chr.ch == K_BTAB)
|
|
ep->v.chr.shift = FALSE;
|
|
if (itf_data->focus_obj != NULL)
|
|
xi_send_event(itf_data->focus_obj, ep, FALSE);
|
|
update_menus();
|
|
break;
|
|
case E_SIZE:
|
|
xi_send_event(itf, ep, TRUE);
|
|
break;
|
|
case E_MOUSE_UP:
|
|
#ifndef NO_PRIMARY_SELECTION
|
|
#if XIWS == MTFWS
|
|
if (ep->v.mouse.button == 2)
|
|
get_primary_selection(itf, win);
|
|
#endif
|
|
#endif
|
|
itf_data->mouse_is_down = FALSE;
|
|
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 E_MOUSE_MOVE:
|
|
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 = CURSOR_ARROW;
|
|
break;
|
|
case 1:
|
|
new_cursor = CURSOR_IBEAM;
|
|
break;
|
|
case 2:
|
|
new_cursor =
|
|
(CURSOR)xi_get_pref(XI_PREF_SIZE_CURSOR_RID);
|
|
break;
|
|
case 3:
|
|
new_cursor =
|
|
(CURSOR)xi_get_pref(XI_PREF_HAND_CURSOR_RID);
|
|
break;
|
|
case 4:
|
|
new_cursor = CURSOR_CROSS;
|
|
break;
|
|
case 5:
|
|
new_cursor = CURSOR_ARROW;
|
|
break;
|
|
case 6:
|
|
new_cursor =
|
|
(CURSOR)xi_get_pref(XI_PREF_VSIZE_CURSOR_RID);
|
|
break;
|
|
}
|
|
if (itf_data->cursor != new_cursor)
|
|
{
|
|
#if XI_IS_NOT_CH
|
|
CTOS_IS_PM;
|
|
xvt_win_set_cursor(itf_data->xvt_win, new_cursor);
|
|
CTOS_END;
|
|
#endif
|
|
itf_data->cursor = new_cursor;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case E_COMMAND:
|
|
{
|
|
WINDOW win;
|
|
|
|
xiev.v.cmd.tag = ep->v.cmd.tag;
|
|
xiev.v.cmd.shift = ep->v.cmd.shift;
|
|
xiev.v.cmd.control = ep->v.cmd.control;
|
|
xiev.type = XIE_COMMAND;
|
|
win = itf_data->xvt_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 E_ACTIVATE:
|
|
update_menus();
|
|
break;
|
|
case E_KILL_WINDOW:
|
|
{
|
|
XI_ITF_DATA *itf_data;
|
|
int i;
|
|
destroy_controls(itf);
|
|
xvt_tx_process_event(win, ep);
|
|
xiev.type = XIE_CLEANUP;
|
|
xiev.v.xi_obj = itf;
|
|
call_cb(itf, &xiev);
|
|
xi_remove_window_from_list(win);
|
|
|
|
itf_data = itf->v.itf;
|
|
for (i = 0; i < itf_data->nbr_font_ids; ++i)
|
|
xvt_font_destroy(itf_data->font_ids[i]);
|
|
|
|
/* free the whole interface tree */
|
|
xi_tree_free((char *)itf);
|
|
break;
|
|
}
|
|
case E_CLOSE:
|
|
xiev.type = XIE_CLOSE;
|
|
xiev.v.xi_obj = itf;
|
|
call_cb(itf, &xiev);
|
|
if (!xiev.refused)
|
|
xi_close_window_internal(itf);
|
|
break;
|
|
case E_QUIT:
|
|
if (ep->v.query)
|
|
xvt_app_allow_quit();
|
|
else
|
|
xi_terminate();
|
|
break;
|
|
case E_HSCROLL:
|
|
case E_VSCROLL:
|
|
/* handle E_HSCROLL, etc if list is using window scroll bars */
|
|
break;
|
|
case E_CONTROL:
|
|
control_event(itf, win, ep);
|
|
update_menus();
|
|
break;
|
|
}
|
|
|
|
if (ep->type == E_UPDATE)
|
|
{
|
|
/* send XVT event */
|
|
MEMCLEAR(xiev);
|
|
xiev.type = XIE_UPDATE;
|
|
xiev.v.xvte = *ep;
|
|
xiev.refused = FALSE;
|
|
call_cb(itf, &xiev);
|
|
xvt_dwin_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:
|
|
default:
|
|
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4, "20018", 20018,
|
|
"Invalid object passed to xi_get_attrib");
|
|
}
|
|
return 0L;
|
|
}
|
|
|
|
XI_OBJ *
|
|
xi_get_focus(XI_OBJ *itf)
|
|
{
|
|
WINDOW win;
|
|
|
|
if (itf != NULL)
|
|
return(itf->v.itf->focus_obj);
|
|
else if ((win = xvt_scr_get_focus_vobj()) == NULL_WIN)
|
|
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)
|
|
{
|
|
xvt_errmsg_sig_if(!(xi_obj->type == XIT_LIST), NULL_WIN,
|
|
SEV_FATAL, ERR_ASSERT_4, "20020", 20020,
|
|
"Non-list object passed to xi_get_list_info");
|
|
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:
|
|
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);
|
|
}
|
|
xvt_errmsg_sig_if(!(!(BOOLEAN)xi_get_pref(XI_PREF_ASSERT_ON_NULL_CID)),
|
|
NULL_WIN, SEV_FATAL, ERR_ASSERT_4,"30207", 30207,
|
|
"xi_get_obj: Invalid cid");
|
|
return(NULL);
|
|
}
|
|
|
|
RCT *
|
|
xi_get_rect(XI_OBJ *xi_obj, RCT *rctp)
|
|
{
|
|
return xi_get_rect_internal(xi_obj, rctp, NULL, NULL);
|
|
}
|
|
|
|
RCT *
|
|
xi_get_rect_internal(XI_OBJ *xi_obj, RCT *rctp, RCT *old_win_rct, RCT *new_win_rct)
|
|
{
|
|
XI_OBJ * *objp;
|
|
RCT 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:
|
|
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
|
|
xi_get_enclosing_rect(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;
|
|
RCT 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:
|
|
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20021", 20021,
|
|
"xi_get_rect: Invalid XI_OBJ_TYPE in tree");
|
|
}
|
|
return(rctp);
|
|
}
|
|
|
|
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
|
|
&& !focus_obj->v.cell.is_vert_scrolled );
|
|
/* 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:
|
|
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:
|
|
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4, "20022", 20022,
|
|
"Invalid object passed to xi_get_sel");
|
|
break;
|
|
}
|
|
}
|
|
|
|
TXEDIT
|
|
xi_get_txedit(XI_OBJ *xi_obj)
|
|
{
|
|
return stx_get_txedit(xi_obj->v.field->stx);
|
|
}
|
|
|
|
char* xi_get_text(XI_OBJ *xi_obj, char *s, int len)
|
|
{
|
|
static char buf[100];
|
|
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:
|
|
xvt_vobj_get_title(xi_obj->v.itf->xvt_win, buf, sizeof(buf));
|
|
b = buf;
|
|
break;
|
|
case XIT_ROW:
|
|
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4, "20023", 20023,
|
|
"xi_get_text not implemented for XIT_ROW");
|
|
case XIT_BTN:
|
|
b = xi_obj->v.btn->text;
|
|
break;
|
|
case XIT_FIELD:
|
|
b = stx_get_text(xi_obj->v.field->stx, s, len);
|
|
break;
|
|
case XIT_TEXT:
|
|
{
|
|
XI_TEXT_DATA *text_data;
|
|
|
|
text_data = xi_obj->v.text;
|
|
b = text_data->text;
|
|
}
|
|
break;
|
|
case XIT_LIST:
|
|
case XIT_GROUP:
|
|
case XIT_FORM:
|
|
if (s)
|
|
*s = '\0';
|
|
break;
|
|
}
|
|
if (s && b)
|
|
tgstrncpy(s, b, len);
|
|
return b;
|
|
}
|
|
|
|
WINDOW
|
|
xi_get_window(XI_OBJ *xi_obj)
|
|
{
|
|
return(xi_obj->itf->v.itf->xvt_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, COLOR color, unsigned long attrib, int row_height)
|
|
{
|
|
LM_SCROLL_ARG arg;
|
|
|
|
xvt_errmsg_sig_if(!(xi_obj->type == XIT_LIST), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20024",
|
|
20024, "Invalidate object passed to xi_scroll_rec");
|
|
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;
|
|
|
|
xvt_errmsg_sig_if(!(xi_obj->type == XIT_LIST), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20037",
|
|
20037, "Invalidate object passed to xi_scroll_internal");
|
|
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;
|
|
|
|
xvt_errmsg_sig_if(!(xi_obj->type == XIT_ROW), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20025",
|
|
20025, "Invalidate object passed to xi_delete_row");
|
|
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;
|
|
|
|
xvt_errmsg_sig_if(!(list->type == XIT_LIST), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20026",
|
|
20026, "Invalidate object passed to xi_insert_row");
|
|
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, COLOR color)
|
|
{
|
|
RCT 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 far *lmp = LMP(xi_obj->parent->v.list->lm);
|
|
int idx = xi_obj->v.cell.row;
|
|
int idx2 = xi_obj->v.cell.column;
|
|
BOOLEAN do_redraw = (lmp->cell_data[idx][idx2].color != color);
|
|
|
|
lm_set_color( xi_obj->parent->v.list->lm, LM_CELL, xi_obj->v.cell.row,
|
|
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled, color,
|
|
FALSE);
|
|
if (do_redraw)
|
|
{
|
|
xi_get_rect(xi_obj, &rct);
|
|
xi_invalidate_rect(xi_get_window(xi_obj->itf), &rct);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_attrib(XI_OBJ *xi_obj, unsigned long attrib)
|
|
{
|
|
int n;
|
|
XI_OBJ * *objlist;
|
|
unsigned long attrib_diff;
|
|
WINDOW win = xi_obj->itf->v.itf->xvt_win;
|
|
|
|
attrib_diff = xi_get_attrib(xi_obj) ^ attrib;
|
|
switch(xi_obj->type)
|
|
{
|
|
case XIT_BTN:
|
|
if (! (BOOLEAN)xi_get_pref(XI_PREF_NATIVE_CTRLS))
|
|
{
|
|
XI_BTN_DATA *bd;
|
|
RCT 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)
|
|
{
|
|
WINDOW btn_win;
|
|
|
|
btn_win = xi_obj->v.btn->btnctl;
|
|
xvt_vobj_set_visible(btn_win, (BOOLEAN)((attrib & XI_ATR_VISIBLE)
|
|
!= 0));
|
|
xi_invalidate_rect(win, &xi_obj->v.btn->rct);
|
|
}
|
|
if (attrib_diff & XI_ATR_ENABLED)
|
|
xvt_vobj_set_enabled(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:
|
|
{
|
|
RCT 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:
|
|
{
|
|
RCT 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)
|
|
{
|
|
xvt_vobj_set_visible(ld->sb_win, (BOOLEAN)((attrib & XI_ATR_VISIBLE) != 0));
|
|
xvt_vobj_set_enabled(ld->sb_win, (BOOLEAN)((attrib & XI_ATR_ENABLED) != 0));
|
|
}
|
|
if (ld->hsb_win)
|
|
{
|
|
xvt_vobj_set_visible(ld->hsb_win, (BOOLEAN)((attrib & XI_ATR_VISIBLE) != 0));
|
|
xvt_vobj_set_enabled(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:
|
|
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20027", 20027,
|
|
"Invalid object passed to xi_set_attrib");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_bufsize(XI_OBJ *xi_obj, int size)
|
|
{
|
|
XI_OBJ * *objp;
|
|
int i;
|
|
|
|
switch(xi_obj->type)
|
|
{
|
|
case XIT_FIELD:
|
|
stx_set_bufsize(xi_obj->v.field->stx, (short)size);
|
|
break;
|
|
case XIT_COLUMN:
|
|
lm_set_buf_size(xi_obj->parent->v.list->lm, LM_COLUMN,
|
|
xi_obj_to_idx(xi_obj), size);
|
|
break;
|
|
case XIT_LIST:
|
|
case XIT_FORM:
|
|
objp = xi_obj->children;
|
|
for (i = xi_obj->nbr_children; i > 0; i--, objp++)
|
|
xi_set_bufsize(*objp, size);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void xi_set_sel(XI_OBJ *xi_obj, int selstart, int selstop)
|
|
{
|
|
switch(xi_obj->type)
|
|
{
|
|
case XIT_CELL:
|
|
xi_set_focus(xi_obj);
|
|
lm_set_sel( xi_obj->parent->v.list->lm, xi_obj->v.cell.row,
|
|
xi_obj->v.cell.column, xi_obj->v.cell.is_vert_scrolled,
|
|
selstart, selstop);
|
|
break;
|
|
case XIT_FIELD:
|
|
xi_set_focus(xi_obj);
|
|
stx_set_sel(xi_obj->v.field->stx, selstart, selstop);
|
|
break;
|
|
case XIT_BTN:
|
|
case XIT_FORM:
|
|
case XIT_GROUP:
|
|
case XIT_TEXT:
|
|
case XIT_COLUMN:
|
|
case XIT_ITF:
|
|
case XIT_LIST:
|
|
case XIT_ROW:
|
|
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20028", 20028,
|
|
"Invalid object passed to xi_set_sel");
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_set_text(XI_OBJ *xi_obj, char *s)
|
|
{
|
|
char *buf;
|
|
size_t buf_size = 256;
|
|
BOOLEAN ddd;
|
|
|
|
if ( xi_obj == xi_obj->itf->v.itf->focus_obj )
|
|
xi_obj->itf->v.itf->chg_flag = FALSE;
|
|
buf = xvt_mem_alloc(buf_size);
|
|
xi_get_text(xi_obj, buf, buf_size);
|
|
if (! strcmp(s, buf))
|
|
{
|
|
xvt_mem_free(buf);
|
|
return;
|
|
}
|
|
xvt_mem_free(buf);
|
|
ddd = ! (BOOLEAN)xi_get_pref(XI_PREF_NATIVE_CTRLS);
|
|
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->xvt_win, &btn->rct);
|
|
}
|
|
else
|
|
xvt_vobj_set_title(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:
|
|
{
|
|
/*
|
|
RCT 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->xvt_win, &rct);
|
|
*/
|
|
break;
|
|
}
|
|
case XIT_ITF:
|
|
xvt_vobj_set_title(xi_obj->v.itf->xvt_win, s);
|
|
break;
|
|
case XIT_ROW:
|
|
xvt_errmsg_sig_if(!(xi_false), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20029", 20029,
|
|
"xi_set_text not implemented for XIT_ROW");
|
|
case XIT_TEXT:
|
|
{
|
|
XI_TEXT_DATA *text_data;
|
|
RCT 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->xvt_win, &rct);
|
|
}
|
|
break;
|
|
}
|
|
case XIT_GROUP:
|
|
case XIT_FORM:
|
|
case XIT_LIST:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void
|
|
xi_draw_button(XI_OBJ *xi_obj, RCT *rct, char *text,
|
|
int down_icon_rid, int up_icon_rid, int disabled_icon_rid,
|
|
BOOLEAN enabled, BOOLEAN visible, BOOLEAN focus, BOOLEAN down, BOOLEAN dflt,
|
|
BOOLEAN checked, BOOLEAN box_only)
|
|
{
|
|
XI_BTN_DATA *bd;
|
|
COLOR fore_color;
|
|
CPEN fore_cp;
|
|
WINDOW win;
|
|
XI_OBJ *itf;
|
|
XI_ITF_DATA *id;
|
|
COLOR color_light = 0L;
|
|
COLOR color_ctrl = 0L;
|
|
COLOR color_dark = 0L;
|
|
|
|
if (! visible)
|
|
return;
|
|
itf = xi_obj->itf;
|
|
id = itf->v.itf;
|
|
if (id->half_baked)
|
|
return;
|
|
win = xi_get_window(itf);
|
|
xvt_dwin_set_clip( win, NULL );
|
|
bd = xi_obj->v.btn;
|
|
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_color = COLOR_BLACK;
|
|
fore_cp = black_cpen;
|
|
if (bd->fore_color)
|
|
{
|
|
fore_cp.color = bd->fore_color;
|
|
fore_color = bd->fore_color;
|
|
}
|
|
switch (bd->type)
|
|
{
|
|
case XIBT_BUTTON:
|
|
case XIBT_BUTTON_CHECKBOX:
|
|
case XIBT_BUTTON_RADIOBTN:
|
|
{
|
|
int grid_width;
|
|
RCT r;
|
|
|
|
r = *rct;
|
|
if (xi_obj->v.btn->packed == TRUE)
|
|
{
|
|
grid_width = (int)xi_get_pref(XI_PREF_CONTAINER_GRID_WIDTH);
|
|
xi_inflate_rect(&r, -grid_width);
|
|
}
|
|
else
|
|
{
|
|
XI_BTN_TYPE bt;
|
|
|
|
bt = xi_obj->v.btn->type;
|
|
if (bt == XIBT_BUTTON || bt == XIBT_BUTTON_CHECKBOX ||
|
|
bt == XIBT_BUTTON_RADIOBTN)
|
|
xi_inflate_rect(&r, -3);
|
|
}
|
|
xi_set_draw_mode(win, M_COPY);
|
|
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
|
|
{
|
|
CBRUSH hollow_cbrush;
|
|
RCT rct;
|
|
DRAW_CTOOLS t;
|
|
|
|
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
|
|
xvt_app_get_default_ctools(&t);
|
|
xvt_dwin_set_draw_ctools(win, &t);
|
|
hollow_cbrush.color = COLOR_WHITE;
|
|
hollow_cbrush.pat = PAT_HOLLOW;
|
|
xvt_dwin_set_cbrush(win, &hollow_cbrush);
|
|
rct.top = 0;
|
|
rct.left = 0;
|
|
rct.bottom = 0;
|
|
rct.right = 0;
|
|
xvt_dwin_draw_rect(win, &rct);
|
|
}
|
|
#endif
|
|
xi_draw_3d_rect(win, &r, (BOOLEAN)(down || bd->checked), 2, color_light, color_ctrl, color_dark);
|
|
if (up_icon_rid)
|
|
{
|
|
int x, y;
|
|
RCT r2;
|
|
|
|
x = r.left + 2 + bd->icon_x;
|
|
y = r.top + 2 + bd->icon_y;
|
|
r2 = r;
|
|
xi_inflate_rect(&r2, -2);
|
|
xi_set_clip(win, &r2);
|
|
if (down)
|
|
xi_draw_icon(win, x, y + 1, down_icon_rid, COLOR_BLACK, color_ctrl);
|
|
else
|
|
{
|
|
if (enabled || ! disabled_icon_rid)
|
|
xi_draw_icon(win, x, y, up_icon_rid, COLOR_BLACK, color_ctrl);
|
|
else
|
|
xi_draw_icon(win, x, y, disabled_icon_rid, COLOR_BLACK, color_ctrl);
|
|
}
|
|
xi_set_clip(win, NULL);
|
|
}
|
|
else
|
|
{
|
|
unsigned long attrib;
|
|
RCT text_rect;
|
|
// COLOR color;
|
|
FONT_OBJ* fontp;
|
|
|
|
attrib = XI_ATR_VCENTER | XI_ATR_HCENTER | XI_ATR_VISIBLE;
|
|
if (enabled)
|
|
xi_set_xvt_fore_color(win, fore_color);
|
|
else
|
|
xi_set_xvt_fore_color( win,
|
|
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
|
|
text_rect = r;
|
|
if (down)
|
|
text_rect.top += 2;
|
|
fontp = xi_obj->itf->v.itf->font;
|
|
if (fontp)
|
|
xi_set_xvt_font(win, fontp, FALSE);
|
|
else
|
|
xi_set_xvt_font(win, &xi_sysfont, FALSE);
|
|
xi_set_xvt_back_color(win, color_ctrl);
|
|
xi_draw_clipped_text(win, text, &text_rect, &text_rect, attrib, FALSE, 0, -1);
|
|
}
|
|
if ((focus) || (xi_obj->v.btn->packed))
|
|
{
|
|
int width;
|
|
RCT rct2;
|
|
|
|
width = (xi_obj->v.btn->packed) ? grid_width : 2;
|
|
rct2 = r;
|
|
rct2.top -= width;
|
|
rct2.left -= width;
|
|
rct2.bottom += width;
|
|
rct2.right += width;
|
|
xi_set_cpen(win, &black_cpen);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
xi_draw_thick_rect(win, &rct2, width);
|
|
}
|
|
else
|
|
{
|
|
RCT rct2;
|
|
CPEN cpen;
|
|
|
|
rct2 = r;
|
|
rct2.top--;
|
|
rct2.left--;
|
|
rct2.bottom++;
|
|
rct2.right++;
|
|
xi_set_cpen(win, &black_cpen);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
xi_draw_rect(win, &rct2);
|
|
rct2.top--;
|
|
rct2.left--;
|
|
rct2.bottom++;
|
|
rct2.right++;
|
|
if (id->back_color)
|
|
{
|
|
cpen = black_cpen;
|
|
cpen.color = id->back_color;
|
|
xi_set_cpen(win, &cpen);
|
|
xi_draw_rect(win, &rct2);
|
|
}
|
|
if (dflt)
|
|
{
|
|
rct2.top--;
|
|
rct2.left--;
|
|
rct2.bottom++;
|
|
rct2.right++;
|
|
xi_set_cpen(win, &black_cpen);
|
|
xi_draw_rect(win, &rct2);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case XIBT_RADIOBTN:
|
|
{
|
|
RCT rbrct, rct2;
|
|
unsigned long attrib;
|
|
RCT text_rect;
|
|
COLOR color;
|
|
|
|
rbrct = *rct;
|
|
rbrct.bottom -= 4;
|
|
rct2 = rbrct;
|
|
rct2.right = rct2.left + (rct2.bottom - rct2.top);
|
|
xi_set_draw_mode(win, M_COPY);
|
|
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
|
|
{
|
|
CBRUSH hollow_cbrush;
|
|
RCT rct;
|
|
DRAW_CTOOLS t;
|
|
|
|
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
|
|
xvt_app_get_default_ctools(&t);
|
|
xvt_dwin_set_draw_ctools(win, &t);
|
|
hollow_cbrush.color = COLOR_WHITE;
|
|
hollow_cbrush.pat = PAT_HOLLOW;
|
|
xvt_dwin_set_cbrush(win, &hollow_cbrush);
|
|
rct.top = 0;
|
|
rct.left = 0;
|
|
rct.bottom = 0;
|
|
rct.right = 0;
|
|
xvt_dwin_draw_rect(win, &rct);
|
|
}
|
|
#endif
|
|
xi_draw_3d_diamond(win, &rct2, checked, down, down ? 2 : 1,
|
|
down ? bd->fore_color : 0L);
|
|
if (checked)
|
|
{
|
|
RCT 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)
|
|
{
|
|
CPEN cpen;
|
|
FONT_OBJ *fontp;
|
|
|
|
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE;
|
|
if (enabled)
|
|
xi_set_xvt_fore_color(win, fore_color);
|
|
else
|
|
xi_set_xvt_fore_color( win,
|
|
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
|
|
text_rect = *rct;
|
|
text_rect.left = rct2.right + (rct2.right - rct2.left) / 2;
|
|
fontp = xi_obj->itf->v.itf->font;
|
|
if (fontp)
|
|
xi_set_xvt_font(win, fontp, FALSE);
|
|
else
|
|
xi_set_xvt_font(win, &xi_sysfont, FALSE);
|
|
color = (COLOR)xi_get_pref(XI_PREF_COLOR_CTRL);
|
|
xi_set_xvt_back_color(win, color);
|
|
xi_draw_clipped_text(win, text, &text_rect, &text_rect, attrib, FALSE, 0, -1);
|
|
if (focus)
|
|
{
|
|
cpen = black_cpen;
|
|
cpen.pat = PAT_RUBBER;
|
|
xi_set_cpen(win, &cpen);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
text_rect.left = rct2.right + (rct2.right - rct2.left) / 4;
|
|
xi_draw_rect(win, &text_rect);
|
|
}
|
|
else
|
|
{
|
|
if (id->back_color)
|
|
{
|
|
cpen = black_cpen;
|
|
cpen.color = id->back_color;
|
|
xi_set_cpen(win, &cpen);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
text_rect.left = rct2.right + (rct2.right - rct2.left) / 4;
|
|
xi_draw_rect(win, &text_rect);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case XIBT_TABBTN:
|
|
{
|
|
RCT tbrct;
|
|
unsigned long attrib;
|
|
CPEN line_cpen;
|
|
PNT p;
|
|
COLOR color;
|
|
CPEN cpen;
|
|
int leading, ascent, descent, height, width, hdiff, vdiff;
|
|
RCT r;
|
|
char s[100];
|
|
FONT_OBJ *fontp;
|
|
|
|
tbrct = *rct;
|
|
height = tbrct.bottom - tbrct.top;
|
|
xi_set_draw_mode(win, M_COPY);
|
|
line_cpen = black_cpen;
|
|
|
|
/* Draw background color, one line at a time */
|
|
line_cpen.color = xi_get_pref( XI_PREF_COLOR_CTRL );
|
|
xi_set_cpen(win, &line_cpen);
|
|
for ( hdiff = 1, vdiff = height / 2; hdiff < height; hdiff++ )
|
|
{
|
|
p.h = tbrct.left + vdiff;
|
|
p.v = tbrct.top + hdiff;
|
|
xi_move_to( win, p );
|
|
p.h = tbrct.right - vdiff;
|
|
xi_draw_line( win, p );
|
|
if ( hdiff % 2 )
|
|
vdiff--;
|
|
}
|
|
|
|
/* Draw bottom line, adjust color if checked. */
|
|
if (checked)
|
|
line_cpen.color = xi_get_pref(XI_PREF_COLOR_CTRL);
|
|
else
|
|
line_cpen.color = xi_get_pref( XI_PREF_COLOR_LIGHT );
|
|
xi_set_cpen(win, &line_cpen);
|
|
p.h = tbrct.left + 1;
|
|
p.v = tbrct.bottom;
|
|
xi_move_to(win, p);
|
|
p.h = tbrct.right - 1;
|
|
xi_draw_line(win, p);
|
|
|
|
line_cpen.color = xi_get_pref(XI_PREF_COLOR_LIGHT);
|
|
xi_set_cpen(win, &line_cpen);
|
|
|
|
/* Draw left, slanted line */
|
|
p.h = tbrct.left;
|
|
p.v = tbrct.bottom;
|
|
xi_move_to(win, p);
|
|
p.h = tbrct.left + height / 2;
|
|
p.v = tbrct.top;
|
|
xi_draw_line(win, p);
|
|
|
|
/* Draw top line */
|
|
xi_move_to(win, p);
|
|
p.h = tbrct.right - height / 2;
|
|
p.v = tbrct.top;
|
|
xi_draw_line(win, p);
|
|
|
|
/* Draw right, slanted line */
|
|
line_cpen.color = xi_get_pref(XI_PREF_COLOR_DARK);
|
|
xi_set_cpen(win, &line_cpen);
|
|
p.v = tbrct.top + 1;
|
|
xi_move_to(win, p);
|
|
p.h = tbrct.right;
|
|
p.v = tbrct.bottom;
|
|
xi_draw_line(win, p);
|
|
|
|
/* Draw text */
|
|
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE | XI_ATR_HCENTER;
|
|
if (enabled)
|
|
xi_set_xvt_fore_color(win, fore_color);
|
|
else
|
|
xi_set_xvt_fore_color( win,
|
|
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
|
|
fontp = xi_obj->itf->v.itf->font;
|
|
if ( !fontp )
|
|
fontp = &xi_sysfont;
|
|
if ( checked )
|
|
{
|
|
XVT_FNTID font_id = xvt_font_create();
|
|
xvt_font_copy( font_id, *fontp, (unsigned long)XVT_FA_ALL );
|
|
xvt_font_set_style( font_id, XVT_FS_BOLD );
|
|
xvt_dwin_set_font( win, font_id );
|
|
xvt_font_destroy( font_id );
|
|
} else
|
|
xi_set_xvt_font(win, fontp, FALSE);
|
|
|
|
{
|
|
DRAW_CTOOLS ct;
|
|
xi_get_draw_ctools(win, &ct);
|
|
ct.opaque_text = FALSE;
|
|
xi_set_draw_ctools(win, &ct);
|
|
}
|
|
|
|
xi_draw_clipped_text(win, text, &tbrct, &tbrct, attrib, FALSE, 0, -1);
|
|
|
|
/* Draw focus line, or erase focus line */
|
|
if (focus)
|
|
{
|
|
cpen = black_cpen;
|
|
cpen.pat = PAT_RUBBER;
|
|
}
|
|
else
|
|
{
|
|
cpen = black_cpen;
|
|
cpen.color = xi_get_pref( XI_PREF_COLOR_CTRL );
|
|
}
|
|
xi_get_font_metrics(win, &leading, &ascent, &descent);
|
|
height = leading + ascent + descent;
|
|
gstrncpy(s, text, sizeof(s));
|
|
s[sizeof(s) - 1] = '\0';
|
|
width = xi_xvt_get_text_width(win, s, -1);
|
|
vdiff = (tbrct.bottom - tbrct.top - height) / 2 - 1;
|
|
hdiff = (tbrct.right - tbrct.left - width) / 2 - 2;
|
|
r = tbrct;
|
|
r.top += vdiff;
|
|
#if XIWS != GRWS
|
|
r.top++;
|
|
#endif
|
|
r.bottom -= vdiff;
|
|
r.left += hdiff;
|
|
r.right -= hdiff;
|
|
xi_set_cpen(win, &cpen);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
xi_draw_rect(win, &r);
|
|
break;
|
|
}
|
|
case XIBT_CHECKBOX:
|
|
{
|
|
RCT cbrct, rct2;
|
|
unsigned long attrib;
|
|
RCT text_rect;
|
|
COLOR color;
|
|
|
|
cbrct = *rct;
|
|
cbrct.bottom -= 4;
|
|
rct2 = cbrct;
|
|
rct2.right = rct2.left + (rct2.bottom - rct2.top);
|
|
xi_set_draw_mode(win, M_COPY);
|
|
#if (XIWS == PMWS) && (XVT_OS != XVT_OS_CTOS)
|
|
{
|
|
CBRUSH hollow_cbrush;
|
|
RCT rct;
|
|
DRAW_CTOOLS t;
|
|
|
|
/* Bad bug with XVT/PM, needs this before can draw COLOR_LTGRAY */
|
|
xvt_app_get_default_ctools(&t);
|
|
xvt_dwin_set_draw_ctools(win, &t);
|
|
hollow_cbrush.color = COLOR_WHITE;
|
|
hollow_cbrush.pat = PAT_HOLLOW;
|
|
xvt_dwin_set_cbrush(win, &hollow_cbrush);
|
|
rct.top = 0;
|
|
rct.left = 0;
|
|
rct.bottom = 0;
|
|
rct.right = 0;
|
|
xvt_dwin_draw_rect(win, &rct);
|
|
}
|
|
#endif
|
|
if (down)
|
|
{
|
|
xi_set_cpen(win, &fore_cp);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
xi_draw_thick_rect(win, &rct2, 2);
|
|
}
|
|
else
|
|
xi_draw_3d_rect(win, &rct2, down, 1, 0L, 0L, 0L);
|
|
if (! enabled)
|
|
fore_cp.color = xi_get_pref(XI_PREF_COLOR_DISABLED);
|
|
if (checked)
|
|
{
|
|
PNT pnt1, pnt2;
|
|
|
|
xi_set_cpen(win, &fore_cp);
|
|
pnt1.h = rct2.left + 2;
|
|
pnt1.v = rct2.bottom - 7;
|
|
xi_move_to(win, pnt1);
|
|
pnt2.h = pnt1.h;
|
|
pnt2.v = pnt1.v + 5;
|
|
xi_draw_line(win, pnt2);
|
|
|
|
pnt1.h++;
|
|
pnt1.v--;
|
|
xi_move_to(win, pnt1);
|
|
pnt2.h++;
|
|
xi_draw_line(win, pnt2);
|
|
|
|
pnt1.h++;
|
|
pnt1.v = rct2.bottom - 5;
|
|
pnt2 = pnt1;
|
|
pnt2.v += 2;
|
|
|
|
while (pnt1.v >= (rct2.top + 3) && pnt1.h <= (rct2.right - 4))
|
|
{
|
|
xi_move_to(win, pnt1);
|
|
xi_draw_line(win, pnt2);
|
|
pnt1.h++;
|
|
pnt1.v--;
|
|
pnt2.h++;
|
|
pnt2.v--;
|
|
}
|
|
pnt1.v++;
|
|
xi_move_to(win, pnt1);
|
|
xi_draw_line(win, pnt2);
|
|
}
|
|
if (! box_only)
|
|
{
|
|
FONT_OBJ *fontp;
|
|
|
|
attrib = XI_ATR_VCENTER | XI_ATR_VISIBLE;
|
|
if (enabled)
|
|
xi_set_xvt_fore_color(win, fore_color);
|
|
else
|
|
xi_set_xvt_fore_color( win,
|
|
(COLOR)xi_get_pref(XI_PREF_COLOR_DISABLED) );
|
|
text_rect = *rct;
|
|
text_rect.left = rct2.right + (rct2.right - rct2.left) / 2;
|
|
fontp = xi_obj->itf->v.itf->font;
|
|
if (fontp)
|
|
xi_set_xvt_font(win, fontp, FALSE);
|
|
else
|
|
xi_set_xvt_font(win, &xi_sysfont, FALSE);
|
|
color = (COLOR)xi_get_pref(XI_PREF_COLOR_CTRL);
|
|
xi_set_xvt_back_color(win, color);
|
|
xi_draw_clipped_text(win, text, &text_rect, &text_rect, attrib, FALSE, 0, -1);
|
|
if (focus)
|
|
{
|
|
CPEN cpen;
|
|
|
|
cpen = black_cpen;
|
|
cpen.pat = PAT_RUBBER;
|
|
xi_set_cpen(win, &cpen);
|
|
xi_set_cbrush(win, &hollow_cbrush);
|
|
text_rect.left = rct2.right + (rct2.right - rct2.left) / 4;
|
|
xi_draw_rect(win, &text_rect);
|
|
}
|
|
else
|
|
{
|
|
if (id->back_color)
|
|
{
|
|
CPEN cpen;
|
|
|
|
cpen = black_cpen;
|
|
cpen.color = id->back_color;
|
|
xi_set_cpen(win, &cpen);
|
|
xi_set_cbrush(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 )
|
|
{
|
|
xvt_errmsg_sig_if(!(list->type == XIT_LIST), NULL_WIN,
|
|
SEV_FATAL, ERR_ASSERT_4, "20031", 20031,
|
|
"Non-list object sent to xi_set_fixed_columns");
|
|
lm_set_fixed_columns( list->v.list->lm, new_fixed_count );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_get_fixed_columns */
|
|
/* -------------------------------------------------------------------------*/
|
|
int xi_get_fixed_columns( XI_OBJ* list )
|
|
{
|
|
xvt_errmsg_sig_if(!( list->type == XIT_LIST), NULL_WIN, SEV_FATAL,
|
|
ERR_ASSERT_4,"20038", 20038,
|
|
"Non-list object sent to xi_get_fixed_columns");
|
|
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 ( 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_data->focus_rec;
|
|
row = child->v.cell.row;
|
|
if ( row >= 0 && row < lm_data->nbr_realized_rows)
|
|
return lm_data->recs[row];
|
|
break;
|
|
}
|
|
}
|
|
return -1L;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_field_calc_height_font_id */
|
|
/* -------------------------------------------------------------------------*/
|
|
int xi_field_calc_height_font_id( XVT_FNTID font )
|
|
{
|
|
if (font == 0)
|
|
font = xi_sysfont;
|
|
return xi_get_fu_height_font( &font );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_button_calc_height_font_id */
|
|
/* -------------------------------------------------------------------------*/
|
|
int xi_button_calc_height_font_id( XVT_FNTID font )
|
|
{
|
|
return xi_field_calc_height_font_id( font );
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_field_calc_width_font_id */
|
|
/* -------------------------------------------------------------------------*/
|
|
int xi_field_calc_width_font_id( XVT_FNTID font, char* string )
|
|
{
|
|
WINDOW win;
|
|
XI_RCT rct = {-1000,-1000,-900,-900};
|
|
int result;
|
|
|
|
if (font == 0)
|
|
font = xi_sysfont;
|
|
win = xi_new_child_window(&rct, "", W_DOC, FALSE, FALSE, FALSE, FALSE,
|
|
FALSE, FALSE, NULL_WIN, 0L, 0, 0L, FALSE, FALSE, 0);
|
|
xvt_dwin_set_font(win, font);
|
|
result = xvt_dwin_get_text_width( win, string, -1 ) + 4;
|
|
xvt_vobj_destroy(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 )
|
|
{
|
|
FONT_OBJ* font;
|
|
XI_RCT rct = {-1000,-1000,-900,-900};
|
|
WINDOW win;
|
|
int width;
|
|
XI_BTN_DEF* button;
|
|
|
|
if ( obj_def->type != XIT_BTN)
|
|
return 0;
|
|
font = xi_def_get_font( obj_def );
|
|
win = xi_new_child_window(&rct, "", W_DOC, FALSE, FALSE, FALSE, FALSE,
|
|
FALSE, FALSE, NULL_WIN, 0L, 0, 0L, FALSE, FALSE, 0);
|
|
xvt_dwin_set_font(win, *font);
|
|
button = obj_def->v.btn;
|
|
width = xvt_dwin_get_text_width( win, button->text, -1 );
|
|
xvt_vobj_destroy( win );
|
|
width += button_get_horz_padding( button->type, xi_get_fu_height_font( font ),
|
|
FALSE );
|
|
return width;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_container_def_get_btn_width */
|
|
/* -------------------------------------------------------------------------*/
|
|
|
|
int xi_container_def_get_btn_width( XI_OBJ_DEF* obj_def )
|
|
{
|
|
int i;
|
|
FONT_OBJ* font;
|
|
XI_RCT rct = {-1000,-1000,-900,-900};
|
|
WINDOW 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;
|
|
win = xi_new_child_window(&rct, "", W_DOC, FALSE, FALSE, FALSE, FALSE,
|
|
FALSE, FALSE, NULL_WIN, 0L, 0, 0L, FALSE, FALSE, 0);
|
|
xvt_dwin_set_font(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 = xvt_dwin_get_text_width( win, button->text, -1 );
|
|
max_width = max( width, max_width );
|
|
}
|
|
xvt_vobj_destroy( win );
|
|
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 );
|
|
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)
|
|
{
|
|
FONT_OBJ* 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);
|
|
}
|
|
return xi_container_def_get_btn_width( obj_def ) * obj_def->nbr_children +
|
|
(obj_def->nbr_children - 1) * horz_spacing;
|
|
}
|
|
case XI_STACK_VERTICAL:
|
|
return xi_container_def_get_btn_width( obj_def );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* -------------------------------------------------------------------------*/
|
|
/* xi_container_def_get_height */
|
|
/* -------------------------------------------------------------------------*/
|
|
int xi_container_def_get_height( XI_OBJ_DEF* obj_def )
|
|
{
|
|
XI_CONTAINER_DEF* container;
|
|
FONT_OBJ* 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_id( *font );
|
|
if (container->orientation == XI_STACK_HORIZONTAL)
|
|
return height;
|
|
if (container->orientation != XI_STACK_VERTICAL)
|
|
return 0;
|
|
switch (obj_def->children[0]->v.btn->type)
|
|
{
|
|
case XIBT_BUTTON:
|
|
case XIBT_BUTTON_CHECKBOX:
|
|
case XIBT_BUTTON_RADIOBTN:
|
|
case XIBT_TABBTN:
|
|
if (container->packed)
|
|
vert_spacing = 0;
|
|
else if ((vert_spacing = (int)xi_get_pref( XI_PREF_VERT_PIXEL_SPACING))
|
|
== 0)
|
|
vert_spacing = (int)((xi_get_pref(XI_PREF_VERT_SPACING)
|
|
* height ) / XI_FU_MULTIPLE );
|
|
top_offset = vert_spacing / 2;
|
|
break;
|
|
case XIBT_CHECKBOX:
|
|
case XIBT_RADIOBTN:
|
|
vert_spacing = 0;
|
|
top_offset = 0;
|
|
break;
|
|
}
|
|
return height * obj_def->nbr_children + vert_spacing
|
|
* (obj_def->nbr_children - 1) + top_offset;
|
|
}
|
|
|