f8c1ec663e
da xi_set_text(XI_OBJ* obj, char* text) a xi_set_text(XI_OBJ* obj, const char* text) git-svn-id: svn://10.65.10.50/branches/R_10_00@23125 c028cbd2-c16b-5b4b-a496-9718f37d4682
1699 lines
44 KiB
C
Executable File
1699 lines
44 KiB
C
Executable File
|
|
/*******************************************************************************
|
|
* Copyright 1991-1996 by ORCA Software, Inc. *
|
|
* *
|
|
* All rights reserved. May not be reproduced or distributed, in printed or *
|
|
* electronic form, without permission of ORCA Software, Inc. May not be *
|
|
* distributed as object code, separately or linked with other object modules, *
|
|
* without permission. *
|
|
*******************************************************************************/
|
|
|
|
#define XI_INTERNAL
|
|
#include "xi.h"
|
|
#include "xitext.h"
|
|
#include "xistx.h"
|
|
#include "xiutils.h"
|
|
#include "xi_int.h"
|
|
#include <limits.h>
|
|
|
|
/* error codes 30100 - 30104 */
|
|
|
|
#if XIWS != XIWS_WM
|
|
#define BORDER_WIDTH 1
|
|
#define BORDER_SPACE 1
|
|
#define DDD_RECT_DEPTH 2
|
|
#else
|
|
#define BORDER_WIDTH_X 8
|
|
#define BORDER_WIDTH_Y 0
|
|
#define BORDER_SPACE_X 0
|
|
#define BORDER_SPACE_Y 0
|
|
#define DDD_RECT_WIDTH 0
|
|
#define CHR_LEFTBRACKET "["
|
|
#define CHR_RIGHTBRACKET "]"
|
|
#endif
|
|
|
|
#define STX_REDRAW_ATR (XI_ATR_VISIBLE | XI_ATR_ENABLED | XI_ATR_RJUST | XI_ATR_PASSWORD)
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
static TXEDIT stx_get_txedit( STX stx );
|
|
static BOOLEAN convert_event_back( EVENT * ep, XinEvent * xiep );
|
|
|
|
#if 0
|
|
static void draw_text_edit_border( STX_DATA * stxp );
|
|
|
|
#endif
|
|
#endif
|
|
|
|
static void
|
|
draw_back_rect( STX_DATA * stxp, XinRect * r )
|
|
{
|
|
XinDrawTools dt;
|
|
|
|
XinWindowDrawToolsNormalGet( &dt );
|
|
dt.pen.width = 1;
|
|
dt.pen.pattern = XinPenHollow;
|
|
dt.brush.pattern = XinBrushSolid;
|
|
if ( stxp->has_focus )
|
|
dt.brush.fore_color = stxp->active_back_color;
|
|
else
|
|
{
|
|
if (stxp->attrib & XI_ATR_ENABLED)
|
|
dt.brush.fore_color = stxp->back_color;
|
|
else
|
|
dt.brush.fore_color = stxp->disabled_back_color;
|
|
}
|
|
dt.draw_mode = XinDrawModeCopy;
|
|
XinWindowDrawToolsSet( stxp->win, &dt );
|
|
|
|
#if XIWS == XIWS_MAC
|
|
if ( stxp->xi_text )
|
|
xi_text_rect_get_adjusted( stxp->xi_text, r );
|
|
#endif
|
|
xi_draw_rect( stxp->win, r );
|
|
}
|
|
|
|
static void
|
|
stx_redraw( STX stx, BOOLEAN update )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
BOOLEAN do_border = FALSE;
|
|
unsigned long tattrib;
|
|
XinRect rct;
|
|
XinColor border_color = 0L;
|
|
|
|
#if XIWS == XIWS_WM
|
|
XinRect r;
|
|
|
|
#endif
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) && stxp->multi_line )
|
|
return;
|
|
#endif
|
|
|
|
rct = stxp->rct;
|
|
if ( update && !xi_XinWindowPaintNeeds( stxp->win, &rct ) )
|
|
return;
|
|
|
|
tattrib = stxp->attrib;
|
|
/* if this field always has a border */
|
|
if ( tattrib & XI_ATR_BORDER )
|
|
{
|
|
do_border = TRUE;
|
|
border_color = stxp->enabled_color;
|
|
}
|
|
/* or if this field has a focus border, and the field has focus */
|
|
if ( tattrib & XI_ATR_FOCUSBORDER )
|
|
{
|
|
do_border = TRUE;
|
|
if ( stxp->has_focus )
|
|
border_color = stxp->active_color;
|
|
else
|
|
{
|
|
border_color = stxp->parent_obj->itf->v.itf->back_color;
|
|
if ( !border_color )
|
|
border_color = XI_COLOR_GRAY;
|
|
}
|
|
}
|
|
/* but if the field is not visible */
|
|
if ( ( tattrib & XI_ATR_VISIBLE ) == 0 )
|
|
do_border = FALSE;
|
|
|
|
XinWindowClipSet( stxp->win, NULL );
|
|
/* draw the border */
|
|
if ( do_border )
|
|
{
|
|
XinDrawTools dt;
|
|
|
|
XinWindowDrawToolsNormalGet( &dt );
|
|
dt.pen.fore_color = border_color;
|
|
dt.pen.width = 1;
|
|
dt.pen.pattern = XinPenSolid;
|
|
dt.brush.pattern = XinBrushHollow;
|
|
dt.brush.fore_color = XI_COLOR_WHITE;
|
|
dt.draw_mode = XinDrawModeCopy;
|
|
XinWindowDrawToolsSet( stxp->win, &dt );
|
|
xi_draw_rect( stxp->win, &rct );
|
|
}
|
|
|
|
/* draw the 3d rectangle */
|
|
if ( stxp->well || stxp->platform )
|
|
{
|
|
XinRect r;
|
|
XinPoint p;
|
|
XinDrawTools dt;
|
|
|
|
r = stxp->rct;
|
|
xi_inflate_rect( &r, -BORDER_WIDTH );
|
|
xi_draw_3d_rect( stxp->win, &r, stxp->well, 2, stxp->hilight_color,
|
|
stxp->back_color, stxp->shadow_color );
|
|
p.h = r.left + 1;
|
|
p.v = r.bottom - 2;
|
|
XinWindowDrawToolsNormalGet( &dt );
|
|
dt.pen.fore_color = stxp->shadow_color;
|
|
if ( !dt.pen.fore_color )
|
|
dt.pen.fore_color = xi_get_pref( XI_PREF_COLOR_CTRL );
|
|
dt.pen.width = 1;
|
|
dt.pen.pattern = XinPenSolid;
|
|
dt.brush.pattern = XinBrushHollow;
|
|
dt.brush.fore_color = XI_COLOR_WHITE;
|
|
dt.draw_mode = XinDrawModeCopy;
|
|
XinWindowDrawToolsSet( stxp->win, &dt );
|
|
xi_move_to( stxp->win, p );
|
|
p.h = r.right - 1;
|
|
xi_draw_line( stxp->win, p );
|
|
p.h -= 1;
|
|
xi_move_to( stxp->win, p );
|
|
p.v = r.top;
|
|
xi_draw_line( stxp->win, p );
|
|
}
|
|
else
|
|
{
|
|
XinRect r;
|
|
|
|
r = stxp->rct;
|
|
xi_inflate_rect( &r, -BORDER_WIDTH );
|
|
draw_back_rect( stxp, &r );
|
|
}
|
|
|
|
if ( stxp->xi_text )
|
|
{
|
|
XinRect r;
|
|
|
|
r = stxp->edit_rect;
|
|
xi_text_prect_set( stxp->xi_text, &r );
|
|
xi_text_clip_set( stxp->xi_text, &r );
|
|
|
|
xi_text_draw( stxp->xi_text, 0L, 0L, update );
|
|
}
|
|
if ( stxp->button &&
|
|
(stxp->no_button_space == XinFlagTrue ||
|
|
(stxp->no_button_space == XinFlagNotSet &&
|
|
( BOOLEAN ) xi_get_pref( XI_PREF_NO_BUTTON_SPACE ) )))
|
|
xi_draw_field_button( stxp->parent_obj );
|
|
}
|
|
|
|
static void
|
|
stx_stop_edit( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
stxp->has_focus = FALSE;
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) && stxp->multi_line )
|
|
{
|
|
XinWindow win;
|
|
|
|
win = stxp->win;
|
|
xi_caret_off( win );
|
|
xi_invalidate_rect( win, &stxp->rct );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if ( stxp->enabled_color != stxp->active_color ||
|
|
stxp->back_color != stxp->active_back_color )
|
|
{
|
|
xi_text_color_fore_set( stxp->xi_text, stxp->enabled_color );
|
|
xi_text_color_back_set( stxp->xi_text, stxp->back_color );
|
|
}
|
|
xi_text_editing_stop( stxp->xi_text );
|
|
stx_redraw( stx, FALSE );
|
|
}
|
|
}
|
|
|
|
STX
|
|
stx_create( XinWindow win, STX_DEF * stx_def, XinRect * field_button )
|
|
{
|
|
STX_DATA *stxp;
|
|
XinRect rct,
|
|
xt_rect;
|
|
int ascent,
|
|
descent,
|
|
leading,
|
|
font_height,
|
|
edit_height,
|
|
inflate;
|
|
XI_OBJ *itf;
|
|
|
|
itf = xi_get_itf( win );
|
|
XinWindowFontMap( win, stx_def->font );
|
|
XinFontMetricsGet( stx_def->font, &leading, &ascent, &descent );
|
|
font_height = ascent + leading + descent;
|
|
stxp = ( STX_DATA * ) xi_tree_malloc( sizeof( STX_DATA ), stx_def->parent );
|
|
stxp->cid = stx_def->cid;
|
|
stxp->win = win;
|
|
stxp->attrib = stx_def->attrib;
|
|
|
|
/* determine the outside rectangle for the edit control */
|
|
edit_height = font_height + 2 * BORDER_WIDTH;
|
|
if ( stx_def->well || stx_def->platform )
|
|
edit_height += 2 * DDD_RECT_DEPTH;
|
|
else
|
|
edit_height += 2 * BORDER_SPACE;
|
|
rct.left = stx_def->pnt.h;
|
|
rct.top = stx_def->pnt.v;
|
|
rct.right = stx_def->pnt.h + stx_def->pixel_width + 2 * BORDER_WIDTH;
|
|
if ( stx_def->well || stx_def->platform )
|
|
rct.right += 2 * DDD_RECT_DEPTH;
|
|
else
|
|
rct.right += 2 * BORDER_SPACE;
|
|
rct.bottom = stx_def->pnt.v + edit_height;
|
|
stxp->rct = rct;
|
|
if ( stx_def->xi_rct.top || stx_def->xi_rct.left ||
|
|
stx_def->xi_rct.bottom || stx_def->xi_rct.right )
|
|
{
|
|
if ( ( stx_def->xi_rct.bottom - stx_def->xi_rct.top ) <= XI_FU_MULTIPLE )
|
|
{
|
|
rct = stx_def->xi_rct;
|
|
xi_fu_to_pu( itf, ( XinPoint * ) & rct, 2 );
|
|
rct.bottom = rct.top + edit_height;
|
|
stxp->rct = rct;
|
|
stxp->multi_line = FALSE;
|
|
}
|
|
else
|
|
{
|
|
rct = stx_def->xi_rct;
|
|
xi_fu_to_pu( xi_get_itf( win ), ( XinPoint * ) & rct, 2 );
|
|
stxp->rct = rct;
|
|
stxp->multi_line = TRUE;
|
|
}
|
|
}
|
|
else
|
|
stxp->multi_line = FALSE;
|
|
|
|
/* determine the actual boundary rect for the editing space. the calculation
|
|
* is the same regardless of whether it is XI_TEXT or TX_EDIT. */
|
|
if ( stx_def->well || stx_def->platform )
|
|
inflate = -( BORDER_WIDTH + DDD_RECT_DEPTH );
|
|
else
|
|
inflate = -( BORDER_WIDTH + BORDER_SPACE );
|
|
xt_rect = stxp->rct;
|
|
xi_inflate_rect( &xt_rect, inflate );
|
|
if ( stx_def->button &&
|
|
(stx_def->no_button_space == XinFlagTrue ||
|
|
(stx_def->no_button_space == XinFlagNotSet &&
|
|
( BOOLEAN ) xi_get_pref( XI_PREF_NO_BUTTON_SPACE ) )))
|
|
{
|
|
int delta;
|
|
|
|
if ( stx_def->platform || stx_def->well )
|
|
{
|
|
stx_def->button_rect.top = xt_rect.top;
|
|
stx_def->button_rect.bottom = xt_rect.bottom;
|
|
}
|
|
else
|
|
{
|
|
stx_def->button_rect.top = stxp->rct.top;
|
|
stx_def->button_rect.bottom = stxp->rct.bottom;
|
|
}
|
|
if (stx_def->button_width > 0)
|
|
delta = stx_def->button_width;
|
|
else
|
|
delta = ( ( stx_def->button_rect.bottom - stx_def->button_rect.top ) );
|
|
if ( stx_def->button_on_left )
|
|
{
|
|
if ( stx_def->platform || stx_def->well )
|
|
{
|
|
stx_def->button_rect.left = xt_rect.left;
|
|
xt_rect.left += delta;
|
|
}
|
|
else
|
|
{
|
|
stx_def->button_rect.left = stxp->rct.left;
|
|
xt_rect.left = stxp->rct.left + delta;
|
|
}
|
|
stx_def->button_rect.right = xt_rect.left;
|
|
}
|
|
else
|
|
{
|
|
if ( stx_def->platform || stx_def->well )
|
|
{
|
|
stx_def->button_rect.right = xt_rect.right;
|
|
xt_rect.right -= delta;
|
|
}
|
|
else
|
|
{
|
|
stx_def->button_rect.right = stxp->rct.right;
|
|
xt_rect.right = stxp->rct.right - delta;
|
|
}
|
|
stx_def->button_rect.left = xt_rect.right;
|
|
}
|
|
*field_button = stx_def->button_rect;
|
|
}
|
|
stxp->edit_rect = xt_rect;
|
|
|
|
stxp->font = stx_def->font;
|
|
stxp->back_color = stx_def->back_color;
|
|
stxp->enabled_color = stx_def->enabled_color;
|
|
stxp->disabled_color = stx_def->disabled_color;
|
|
stxp->active_color = stx_def->active_color;
|
|
stxp->active_back_color = stx_def->active_back_color;
|
|
stxp->disabled_back_color = stx_def->disabled_back_color;
|
|
stxp->hilight_color = stx_def->hilight_color;
|
|
stxp->shadow_color = stx_def->shadow_color;
|
|
stxp->stx_cb = stx_def->stx_cb;
|
|
stxp->text_size = stx_def->text_size;
|
|
stxp->app_data = stx_def->app_data;
|
|
stxp->has_focus = FALSE;
|
|
stxp->well = stx_def->well;
|
|
stxp->platform = stx_def->platform;
|
|
stxp->auto_tab = stx_def->auto_tab;
|
|
stxp->scroll_bar = stx_def->scroll_bar;
|
|
stxp->cr_ok = stx_def->cr_ok;
|
|
stxp->var_len_text = stx_def->var_len_text;
|
|
stxp->parent_obj = stx_def->parent_obj;
|
|
stxp->button = stx_def->button;
|
|
stxp->button_on_left = stx_def->button_on_left;
|
|
stxp->button_rect = stx_def->button_rect;
|
|
stxp->no_button_space = stx_def->no_button_space;
|
|
stxp->button_width = stx_def->button_width;
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) && stxp->multi_line )
|
|
{
|
|
unsigned attrib;
|
|
TXEDIT txt_edit;
|
|
XVT_FNTID xvt_font;
|
|
|
|
attrib = TX_WRAP;
|
|
if ( stxp->attrib & XI_ATR_READONLY )
|
|
attrib |= TX_READONLY;
|
|
attrib |= TX_AUTOHSCROLL | TX_AUTOVSCROLL;
|
|
stxp->txedit = BAD_TXEDIT;
|
|
xvt_font = XinFontXvtConvertBack( stx_def->font );
|
|
txt_edit = xvt_tx_create( ( WINDOW ) win, ( RCT * ) & rct, attrib,
|
|
xvt_font, rct.right - rct.left - 4, INT_MAX );
|
|
stxp->txedit = txt_edit;
|
|
xvt_tx_set_colors( txt_edit, stxp->enabled_color,
|
|
stxp->enabled_color, stxp->back_color );
|
|
xvt_tx_add_par( txt_edit, 0, "" );
|
|
|
|
/* the following line is a hack for ms-windows */
|
|
xi_caret_off( win );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
stxp->xi_text = xi_text_construct( stxp->win,
|
|
stxp->edit_rect.right - stxp->edit_rect.left, stxp->font, ( void * ) stxp,
|
|
stxp->multi_line, stxp->parent_obj->cid, TRUE );
|
|
if ( stxp->attrib & XI_ATR_RJUST )
|
|
xi_text_right_justify_set( stxp->xi_text, TRUE );
|
|
if ( !( stxp->attrib & XI_ATR_VISIBLE ) )
|
|
xi_text_visible_set( stxp->xi_text, FALSE );
|
|
stx_update_colors( ( STX ) stxp );
|
|
xi_text_parent_obj_set( stxp->xi_text, stx_def->parent_obj );
|
|
xi_text_var_len_text_set( stxp->xi_text, stx_def->var_len_text );
|
|
xi_text_buffer_size_set( stxp->xi_text, stxp->text_size );
|
|
xi_text_min_buffer_size_set( stxp->xi_text, stxp->text_size );
|
|
xi_text_scrollbar_set( stxp->xi_text, stxp->scroll_bar );
|
|
xi_text_prect_set( stxp->xi_text, &stxp->edit_rect );
|
|
xi_text_read_only_set( stxp->xi_text, ( stxp->attrib & XI_ATR_READONLY ) != 0 );
|
|
xi_text_password_set( stxp->xi_text, ( stxp->attrib & XI_ATR_PASSWORD ) != 0 );
|
|
xi_text_clip_set( stxp->xi_text, &stxp->edit_rect );
|
|
xi_text_pix_width_and_text_set( stxp->xi_text, "", stxp->edit_rect.right - stxp->edit_rect.left,
|
|
TRUE );
|
|
xi_text_cr_ok_set( stxp->xi_text, stxp->cr_ok );
|
|
}
|
|
return ( ( STX ) ( long ) stxp );
|
|
}
|
|
|
|
void
|
|
stx_set_rect( XinWindow win, STX stx, XinRect *new_rect, XinRect *field_button )
|
|
{
|
|
STX_DATA *stxp;
|
|
XinRect rct,
|
|
xt_rect;
|
|
int ascent,
|
|
descent,
|
|
leading,
|
|
font_height,
|
|
edit_height,
|
|
inflate;
|
|
|
|
XinWindowFontMap( win, xi_text_font_get( stx_xi_text_get( stx ) ) );
|
|
XinFontMetricsGet( xi_text_font_get( stx_xi_text_get( stx ) ),
|
|
&leading, &ascent, &descent );
|
|
font_height = ascent + leading + descent;
|
|
stxp = ( STX_DATA * ) stx;
|
|
|
|
/* determine the outside rectangle for the edit control */
|
|
edit_height = font_height + 2 * BORDER_WIDTH;
|
|
if ( stxp->well || stxp->platform )
|
|
edit_height += 2 * DDD_RECT_DEPTH;
|
|
else
|
|
edit_height += 2 * BORDER_SPACE;
|
|
|
|
if ( ( new_rect->bottom - new_rect->top ) <= XI_FU_MULTIPLE )
|
|
{
|
|
rct = *new_rect;
|
|
rct.bottom = rct.top + edit_height;
|
|
stxp->rct = rct;
|
|
stxp->multi_line = FALSE;
|
|
}
|
|
else
|
|
{
|
|
stxp->rct = *new_rect;
|
|
stxp->multi_line = TRUE;
|
|
}
|
|
|
|
/* determine the actual boundary rect for the editing space. the calculation
|
|
* is the same regardless of whether it is XI_TEXT or TX_EDIT. */
|
|
if ( stxp->well || stxp->platform )
|
|
inflate = -( BORDER_WIDTH + DDD_RECT_DEPTH );
|
|
else
|
|
inflate = -( BORDER_WIDTH + BORDER_SPACE );
|
|
xt_rect = stxp->rct;
|
|
xi_inflate_rect( &xt_rect, inflate );
|
|
if ( stxp->button &&
|
|
(stxp->no_button_space == XinFlagTrue ||
|
|
(stxp->no_button_space == XinFlagNotSet &&
|
|
( BOOLEAN ) xi_get_pref( XI_PREF_NO_BUTTON_SPACE ) )))
|
|
{
|
|
int delta;
|
|
|
|
if ( stxp->platform || stxp->well )
|
|
{
|
|
stxp->button_rect.top = xt_rect.top;
|
|
stxp->button_rect.bottom = xt_rect.bottom;
|
|
}
|
|
else
|
|
{
|
|
stxp->button_rect.top = stxp->rct.top;
|
|
stxp->button_rect.bottom = stxp->rct.bottom;
|
|
}
|
|
if (stxp->button_width > 0)
|
|
delta = stxp->button_width;
|
|
else
|
|
delta = ( ( stxp->button_rect.bottom - stxp->button_rect.top ) );
|
|
if ( stxp->button_on_left )
|
|
{
|
|
if ( stxp->platform || stxp->well )
|
|
{
|
|
stxp->button_rect.left = xt_rect.left;
|
|
xt_rect.left += delta;
|
|
}
|
|
else
|
|
{
|
|
stxp->button_rect.left = stxp->rct.left;
|
|
xt_rect.left = stxp->rct.left + delta;
|
|
}
|
|
stxp->button_rect.right = xt_rect.left;
|
|
}
|
|
else
|
|
{
|
|
if ( stxp->platform || stxp->well )
|
|
{
|
|
stxp->button_rect.right = xt_rect.right;
|
|
xt_rect.right -= delta;
|
|
}
|
|
else
|
|
{
|
|
stxp->button_rect.right = stxp->rct.right;
|
|
xt_rect.right = stxp->rct.right - delta;
|
|
}
|
|
stxp->button_rect.left = xt_rect.right;
|
|
}
|
|
*field_button = stxp->button_rect;
|
|
}
|
|
stxp->edit_rect = xt_rect;
|
|
|
|
xi_text_prect_set( stxp->xi_text, &stxp->edit_rect );
|
|
}
|
|
|
|
void
|
|
stx_delete( STX stx, BOOLEAN destroy_font )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
{
|
|
if ( stxp->use_text_edit )
|
|
{
|
|
xvt_tx_destroy( stxp->txedit );
|
|
xi_invalidate_rect( stxp->win, &stxp->rct );
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if ( stxp->has_focus )
|
|
stx_stop_edit( stx );
|
|
if ( destroy_font )
|
|
XinFontDestroy( stxp->font );
|
|
xi_text_destruct( stxp->xi_text );
|
|
xi_invalidate_rect( stxp->win, &stxp->rct );
|
|
}
|
|
xi_tree_free( ( char * ) stx );
|
|
}
|
|
|
|
void
|
|
stx_destroy_font( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
XinFontDestroy( stxp->font );
|
|
}
|
|
|
|
static void
|
|
stx_start_edit( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
stxp->has_focus = TRUE;
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
{
|
|
xvt_tx_set_active( stxp->txedit );
|
|
xi_invalidate_rect( stxp->win, &stxp->rct );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if ( stxp->enabled_color != stxp->active_color ||
|
|
stxp->back_color != stxp->active_back_color )
|
|
{
|
|
xi_text_color_fore_set( stxp->xi_text, stxp->active_color );
|
|
xi_text_color_back_set( stxp->xi_text, stxp->active_back_color );
|
|
}
|
|
stx_redraw( stx, FALSE );
|
|
xi_text_editing_start( stxp->xi_text );
|
|
if ( stxp->have_mouse )
|
|
{
|
|
if ( ( stxp->attrib & ( XI_ATR_AUTOSELECT | XI_ATR_READONLY ) ) ==
|
|
( XI_ATR_AUTOSELECT | XI_ATR_READONLY ) )
|
|
xi_text_selection_set( stxp->xi_text, 0, SHRT_MAX );
|
|
else if ( ( stxp->attrib & XI_ATR_AUTOSELECT ) && xi_get_pref( XI_PREF_AUTOSEL_ON_MOUSE ) )
|
|
xi_text_selection_set( stxp->xi_text, 0, SHRT_MAX );
|
|
}
|
|
else
|
|
{
|
|
if ( stxp->attrib & XI_ATR_AUTOSELECT )
|
|
xi_text_selection_set( stxp->xi_text, 0, SHRT_MAX );
|
|
else
|
|
if ( stxp->attrib & XI_AGA_ATR_AUTOEND )
|
|
{
|
|
int len = strlen(stxp->xi_text->string);
|
|
xi_text_selection_set( stxp->xi_text, len, len );
|
|
}
|
|
else
|
|
xi_text_selection_set( stxp->xi_text, 0, 0 );
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
stx_focus_set( long stx, BOOLEAN set )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
/* verificare la correttezza
|
|
if ( set == stxp->has_focus )
|
|
XinError( 30101, XinSeverityFatal, 0L );
|
|
*/
|
|
if ( set )
|
|
{
|
|
XI_TEXT *cur_text = xi_text_focus_get( stxp->win );
|
|
|
|
if ( cur_text && xi_text_editing_is( cur_text ) )
|
|
xi_text_editing_stop( cur_text );
|
|
stx_start_edit( stx );
|
|
}
|
|
else
|
|
stx_stop_edit( stx );
|
|
}
|
|
|
|
/*
|
|
do_stx_cb: handles the STX_CB_CHAR, STX_CB_CHANGE, STX_CB_FOCUS cases.
|
|
*/
|
|
static BOOLEAN
|
|
do_stx_cb( STX stx, STX_CB_TYPE cb_reason, XinEvent * ep )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
STX_CB_DATA stx_cb_data;
|
|
|
|
stx_cb_data.stx = stx;
|
|
stx_cb_data.cb_type = cb_reason;
|
|
stx_cb_data.cid = stxp->cid;
|
|
stx_cb_data.win = stxp->win;
|
|
if ( cb_reason == STX_CB_CHAR )
|
|
{
|
|
stx_cb_data.v.chr.ch = ep->v.character.ch;
|
|
stx_cb_data.v.chr.shift = ep->v.character.shift;
|
|
stx_cb_data.v.chr.control = ep->v.character.control;
|
|
stx_cb_data.v.chr.alt = ep->v.character.alt;
|
|
stx_cb_data.v.chr.is_paste = FALSE;
|
|
stx_cb_data.v.chr.refused = FALSE;
|
|
}
|
|
else
|
|
stx_cb_data.v.refused = FALSE;
|
|
( *stxp->stx_cb ) ( &stx_cb_data );
|
|
|
|
/* retval = FALSE if event refused */
|
|
if ( cb_reason == STX_CB_CHAR )
|
|
{
|
|
if ( !stx_cb_data.v.chr.refused )
|
|
ep->v.character.ch = stx_cb_data.v.chr.ch;
|
|
return ( !stx_cb_data.v.chr.refused );
|
|
}
|
|
else
|
|
return ( !stx_cb_data.v.refused );
|
|
}
|
|
|
|
/*
|
|
The parameter gaining_focus is here so that on an XinEventMouseDown, if the
|
|
field is gaining the focus, and XI_PREF_AUTOSEL_ON_MOUSE is TRUE, then
|
|
txt_event knows to select the entire field, not set an insertion point.
|
|
*/
|
|
static BOOLEAN
|
|
send_txt_event( STX stx, XinEvent * ep, BOOLEAN gaining_focus )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
BOOLEAN retval;
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
{
|
|
if ( ep->type != XinEventMenuCommand )
|
|
retval = xi_xvt_tx_event( stxp->win, ep );
|
|
if ( ep->type == XinEventMenuCommand && xi_get_pref( XI_PREF_MULTILINE_QUICK_PASTE ) )
|
|
retval = xi_xvt_tx_event( stxp->win, ep );
|
|
if ( retval )
|
|
{
|
|
( ( XI_OBJ * ) stxp->app_data )->itf->v.itf->chg_flag = TRUE;
|
|
do_stx_cb( stx, STX_CB_CHANGE, ep );
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
BOOLEAN changed;
|
|
|
|
retval = xi_text_event( stxp->xi_text, ep, gaining_focus, &changed );
|
|
|
|
if ( changed )
|
|
{
|
|
( ( XI_OBJ * ) stxp->app_data )->itf->v.itf->chg_flag = TRUE;
|
|
do_stx_cb( stx, STX_CB_CHANGE, ep );
|
|
if ( stxp->auto_tab && ( int ) strlen( xi_text_get( stxp->xi_text ) )
|
|
>= stxp->text_size - 1 )
|
|
{
|
|
XinEvent ev;
|
|
|
|
MEMCLEAR( ev );
|
|
ev.type = XinEventCharacter;
|
|
ev.v.character.ch = '\t';
|
|
xi_event( stxp->win, &ev );
|
|
}
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
/*
|
|
return TRUE if event used, FALSE if event not used.
|
|
*/
|
|
BOOLEAN
|
|
stx_event( STX stx, XinEvent * ep )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
BOOLEAN use_event = TRUE;
|
|
BOOLEAN refused;
|
|
|
|
switch ( ep->type )
|
|
{
|
|
case XinEventResize:
|
|
use_event = FALSE;
|
|
break;
|
|
case XinEventTimer:
|
|
send_txt_event( stx, ep, FALSE );
|
|
use_event = FALSE;
|
|
break;
|
|
case XinEventPaint:
|
|
#if 0
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
{
|
|
if ( ( stxp->attrib & XI_ATR_VISIBLE ) != 0 )
|
|
{
|
|
XinBrush cbrush;
|
|
XinRect r;
|
|
|
|
if ( ep->type == XinEventPaint )
|
|
draw_text_edit_border( stxp );
|
|
cbrush.fore_color = stxp->back_color;
|
|
cbrush.pattern = XinBrushSolid;
|
|
XinWindowBrushSet( stxp->win, &cbrush );
|
|
XinWindowPenSet( stxp->win, &hollow_cpen );
|
|
r = stxp->rct;
|
|
if ( stxp->attrib & XI_ATR_BORDER || stxp->attrib & XI_ATR_FOCUSBORDER )
|
|
xi_inflate_rect( &r, -1 );
|
|
xi_inflate_rect( &r, -2 );
|
|
xi_draw_rect( stxp->win, &r );
|
|
xi_xvt_tx_event( stxp->win, ep );
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
#endif
|
|
{
|
|
if ( ( stxp->attrib & XI_ATR_VISIBLE ) != 0 )
|
|
stx_redraw( stx, TRUE );
|
|
}
|
|
use_event = FALSE;
|
|
break;
|
|
case XinEventMouseDown:
|
|
case XinEventMouseDouble:
|
|
{
|
|
BOOLEAN gaining_focus = FALSE;
|
|
|
|
/* check for focus acquisition */
|
|
if ( xi_pt_in_rect( &stxp->rct, ep->v.mouse.where ) &&
|
|
( stxp->attrib & ( XI_ATR_ENABLED | XI_ATR_VISIBLE ) ) ==
|
|
( XI_ATR_ENABLED | XI_ATR_VISIBLE ) )
|
|
{
|
|
stxp->have_mouse = TRUE;
|
|
if ( !stxp->has_focus )
|
|
{
|
|
if ( !do_stx_cb( stx, STX_CB_FOCUS, ep ) )
|
|
{
|
|
stxp->have_mouse = FALSE;
|
|
break;
|
|
}
|
|
gaining_focus = TRUE;
|
|
}
|
|
/* the stx may have lost the focus, due to a field being disabled, in
|
|
* which case, stxp->xi_text == NULL */
|
|
send_txt_event( stx, ep, gaining_focus );
|
|
if ( stxp->xi_text )
|
|
XinWindowMouseTrap( stxp->win, TRUE );
|
|
if ( ep->type == XinEventMouseDouble )
|
|
do_stx_cb( stx, STX_CB_DBL, ep );
|
|
}
|
|
else
|
|
use_event = FALSE;
|
|
break;
|
|
}
|
|
case XinEventMouseUp:
|
|
if ( stxp->has_focus )
|
|
{
|
|
send_txt_event( stx, ep, FALSE );
|
|
XinWindowMouseRelease( );
|
|
stxp->have_mouse = FALSE;
|
|
}
|
|
break;
|
|
case XinEventMouseMove:
|
|
{
|
|
unsigned long attrib;
|
|
XinRect r;
|
|
|
|
if ( stxp->has_focus )
|
|
send_txt_event( stx, ep, FALSE );
|
|
attrib = stxp->attrib & ( XI_ATR_ENABLED | XI_ATR_VISIBLE );
|
|
r = stxp->edit_rect;
|
|
|
|
#if XIWS == XIWS_MAC || XIWS == XIWS_XM || XIWS == XIWS_WXGTK
|
|
if ( stxp->xi_text )
|
|
xi_text_rect_get_adjusted( stxp->xi_text, &r );
|
|
#endif
|
|
if ( ( attrib != ( XI_ATR_ENABLED | XI_ATR_VISIBLE ) ) ||
|
|
( !xi_pt_in_rect( &r, ep->v.mouse.where ) ) )
|
|
use_event = FALSE;
|
|
break;
|
|
}
|
|
case XinEventCharacter:
|
|
{
|
|
int ch;
|
|
|
|
ch = ep->v.character.ch;
|
|
if ( ch == '\t' || ch == XI_KEY_BTAB || ep->v.character.alt )
|
|
return FALSE;
|
|
if ( stxp->multi_line )
|
|
{
|
|
if ( ch >= ' ' || ch == XI_KEY_CLEAR || ch == XI_KEY_DEL || ch == '\b' )
|
|
{
|
|
refused = do_stx_cb( stx, STX_CB_CHAR, ep );
|
|
/* use_event = FALSE if event refused */
|
|
if ( !refused )
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( ( ch >= ' ' || ch == XI_KEY_CLEAR || ch == XI_KEY_DEL ||
|
|
ch == '\b' ) && ch != XI_KEY_UP && ch != XI_KEY_DOWN )
|
|
{
|
|
refused = do_stx_cb( stx, STX_CB_CHAR, ep );
|
|
/* retval = FALSE if event refused */
|
|
if ( !refused )
|
|
return FALSE;
|
|
}
|
|
}
|
|
use_event = send_txt_event( stx, ep, FALSE );
|
|
break;
|
|
}
|
|
case XinEventDestroy:
|
|
use_event = FALSE;
|
|
break;
|
|
case XinEventMenuCommand:
|
|
use_event = send_txt_event( stx, ep, FALSE );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return use_event;
|
|
}
|
|
|
|
unsigned long
|
|
stx_get_attrib( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
return stxp->attrib;
|
|
}
|
|
|
|
int
|
|
stx_get_cid( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
return stxp->cid;
|
|
}
|
|
|
|
void
|
|
stx_get_sel( STX stx, int *c1, int *c2 )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) && stxp->multi_line )
|
|
{
|
|
int accum_cnt;
|
|
T_PNUM par;
|
|
T_PNUM start_par,
|
|
end_par;
|
|
T_LNUM start_line,
|
|
end_line;
|
|
T_CNUM start_char,
|
|
end_char;
|
|
BOOLEAN ex;
|
|
TXEDIT txed = stxp->txedit;
|
|
|
|
accum_cnt = 0;
|
|
xvt_tx_get_sel( txed, &start_par, &start_line, &start_char,
|
|
&end_par, &end_line, &end_char );
|
|
ex = FALSE;
|
|
for ( par = 0; par <= start_par; par++ )
|
|
{
|
|
T_LNUM nbr_lins,
|
|
lin;
|
|
|
|
nbr_lins = xvt_tx_get_num_par_lines( txed, par );
|
|
for ( lin = 0; lin < nbr_lins; lin++ )
|
|
{
|
|
if ( par == start_par && lin == start_line )
|
|
{
|
|
accum_cnt += start_char;
|
|
ex = TRUE;
|
|
break;
|
|
}
|
|
accum_cnt += xvt_tx_get_num_chars( txed, par, lin );
|
|
}
|
|
if ( ex )
|
|
break;
|
|
accum_cnt += 1; /* add eol at end of paragraph */
|
|
}
|
|
*c1 = accum_cnt;
|
|
if ( start_par == end_par && start_line == end_line &&
|
|
start_char == end_char )
|
|
{
|
|
*c2 = accum_cnt;
|
|
return;
|
|
}
|
|
ex = FALSE;
|
|
for ( par = start_par; par <= end_par; par++ )
|
|
{
|
|
T_LNUM nbr_lins,
|
|
lin;
|
|
|
|
nbr_lins = xvt_tx_get_num_par_lines( txed, par );
|
|
for ( lin = 0; lin < nbr_lins; lin++ )
|
|
{
|
|
if ( par == end_par && lin == end_line )
|
|
{
|
|
accum_cnt += end_char;
|
|
if ( par == start_par && lin == start_line )
|
|
accum_cnt -= start_char;
|
|
ex = TRUE;
|
|
break;
|
|
}
|
|
accum_cnt += xvt_tx_get_num_chars( txed, par, lin );
|
|
if ( par == start_par && lin == start_line )
|
|
accum_cnt -= start_char;
|
|
}
|
|
if ( ex )
|
|
break;
|
|
accum_cnt += 1; /* add eol at end of paragraph */
|
|
}
|
|
*c2 = accum_cnt;
|
|
return;
|
|
}
|
|
#endif
|
|
if ( xi_text_editing_is( stxp->xi_text ) )
|
|
xi_text_selection_get( stxp->xi_text, c1, c2 );
|
|
else
|
|
*c1 = *c2 = 0;
|
|
}
|
|
|
|
XinRect *
|
|
stx_get_rect( STX stx, XinRect * rctp )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
*rctp = stxp->rct;
|
|
return rctp;
|
|
}
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
static void
|
|
tx_get_text( TXEDIT tx, char *string, int string_len )
|
|
{
|
|
char *s;
|
|
int slen,
|
|
cnt,
|
|
nbr_pars;
|
|
unsigned len;
|
|
|
|
slen = 0;
|
|
s = NULL;
|
|
nbr_pars = xvt_tx_get_num_pars( tx );
|
|
for ( cnt = 0; cnt < nbr_pars; ++cnt )
|
|
{
|
|
int nbr_lines,
|
|
cnt2;
|
|
|
|
nbr_lines = xvt_tx_get_num_par_lines( tx, ( short ) cnt );
|
|
for ( cnt2 = 0; cnt2 < nbr_lines; ++cnt2 )
|
|
{
|
|
char *str;
|
|
int old_len;
|
|
|
|
xvt_tx_get_line( tx, ( short ) cnt, A_LOCK, ( short ) cnt2, NULL );
|
|
str = xvt_tx_get_line( tx, ( short ) cnt, A_GET, ( short ) cnt2, &len );
|
|
old_len = slen;
|
|
slen = slen + len;
|
|
if ( s )
|
|
s = ( char * ) xi_tree_realloc( s, slen + 2 );
|
|
else
|
|
s = ( char * ) xi_tree_malloc( slen + 2, NULL );
|
|
|
|
gstrncpy( &s[old_len], str, len );
|
|
}
|
|
slen++;
|
|
#if XIWS == XIWS_MAC
|
|
s[slen - 1] = '\r';
|
|
#else
|
|
s[slen - 1] = '\n';
|
|
#endif
|
|
}
|
|
if ( !slen )
|
|
string[0] = '\0';
|
|
else
|
|
{
|
|
s[slen - 1] = '\0';
|
|
gstrncpy( string, s, string_len );
|
|
string[string_len - 1] = '\0';
|
|
xi_tree_free( s );
|
|
}
|
|
}
|
|
|
|
static int
|
|
tx_get_len( TXEDIT tx )
|
|
{
|
|
int nbr_pars,
|
|
cnt,
|
|
charcnt;
|
|
|
|
charcnt = 0;
|
|
nbr_pars = xvt_tx_get_num_pars( tx );
|
|
for ( cnt = 0; cnt < nbr_pars; ++cnt )
|
|
{
|
|
int nbr_lines,
|
|
cnt2;
|
|
|
|
nbr_lines = xvt_tx_get_num_par_lines( tx, ( short ) cnt );
|
|
for ( cnt2 = 0; cnt2 < nbr_lines; ++cnt2 )
|
|
charcnt += ( xvt_tx_get_num_chars( tx, ( short ) cnt, ( short ) cnt2 ) + 1 );
|
|
}
|
|
return charcnt;
|
|
}
|
|
|
|
#endif
|
|
|
|
char *
|
|
stx_get_text( STX stx, char *s, int len )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
char *b;
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( stxp->multi_line && xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
{
|
|
TXEDIT txed = stxp->txedit;
|
|
|
|
if ( s )
|
|
{
|
|
tx_get_text( txed, s, len );
|
|
b = s;
|
|
}
|
|
else
|
|
{
|
|
int len;
|
|
|
|
len = tx_get_len( txed );
|
|
if ( stxp->buf )
|
|
stxp->buf = ( char * ) xi_tree_realloc( stxp->buf, len );
|
|
else
|
|
stxp->buf = ( char * ) xi_tree_malloc( len, NULL );
|
|
tx_get_text( txed, stxp->buf, len );
|
|
b = stxp->buf;
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
b = xi_text_get( stxp->xi_text );
|
|
}
|
|
if ( s )
|
|
tstrncpy( s, b, len );
|
|
return b;
|
|
}
|
|
|
|
void
|
|
stx_set_bufsize( STX stx, short size )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
xi_text_buffer_size_set( stxp->xi_text, size );
|
|
stxp->text_size = size;
|
|
}
|
|
|
|
void
|
|
stx_set_attrib( STX stx, unsigned long attrib )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
unsigned long do_redraw;
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( stxp->multi_line && xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
{
|
|
TXEDIT txed = stxp->txedit;
|
|
|
|
if ( attrib & XI_ATR_VISIBLE )
|
|
{
|
|
if ( !( stxp->attrib & XI_ATR_VISIBLE ) )
|
|
xvt_tx_resume( txed );
|
|
}
|
|
else
|
|
{
|
|
if ( stxp->attrib & XI_ATR_VISIBLE )
|
|
xvt_tx_suspend( txed );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
do_redraw = ( ( stxp->attrib ^ attrib ) & STX_REDRAW_ATR );
|
|
stxp->attrib = attrib;
|
|
if ( attrib & XI_ATR_ENABLED )
|
|
{
|
|
xi_text_color_fore_set( stxp->xi_text, stxp->enabled_color );
|
|
xi_text_color_back_set( stxp->xi_text, stxp->back_color );
|
|
}
|
|
else
|
|
{
|
|
xi_text_color_fore_set( stxp->xi_text, stxp->disabled_color );
|
|
xi_text_color_back_set( stxp->xi_text, stxp->disabled_back_color );
|
|
}
|
|
xi_text_right_justify_set( stxp->xi_text, (BOOLEAN)( ( stxp->attrib & XI_ATR_RJUST ) != 0 ) );
|
|
xi_text_read_only_set( stxp->xi_text, ( stxp->attrib & XI_ATR_READONLY ) != 0 );
|
|
xi_text_password_set( stxp->xi_text, ( stxp->attrib & XI_ATR_PASSWORD ) != 0 );
|
|
xi_text_visible_set( stxp->xi_text, ( BOOLEAN ) ( ( stxp->attrib & XI_ATR_VISIBLE ) != 0 ) );
|
|
if ( do_redraw )
|
|
xi_invalidate_rect( stxp->win, &( stxp->rct ) );
|
|
}
|
|
|
|
void
|
|
stx_set_focus( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
if ( XinWindowFocusGet( ) != stxp->win )
|
|
{
|
|
XinWindowFocusSet( stxp->win );
|
|
}
|
|
if ( !stxp->has_focus )
|
|
stx_start_edit( stx );
|
|
}
|
|
|
|
void
|
|
stx_set_pos( STX stx, XinPoint p )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
int dh,
|
|
dv,
|
|
inflate;
|
|
XinRect r;
|
|
|
|
dh = p.h - stxp->rct.left;
|
|
dv = p.v - stxp->rct.top;
|
|
|
|
stxp->rct.top += dv;
|
|
stxp->rct.left += dh;
|
|
stxp->rct.bottom += dv;
|
|
stxp->rct.right += dh;
|
|
/* determine the actual boundary rect for the editing space. the calculation
|
|
* is the same regardless of whether it is XI_TEXT or TX_EDIT. */
|
|
if ( stxp->well || stxp->platform )
|
|
inflate = -( BORDER_WIDTH + DDD_RECT_DEPTH );
|
|
else
|
|
inflate = -( BORDER_WIDTH + BORDER_SPACE );
|
|
r = stxp->rct;
|
|
xi_inflate_rect( &r, inflate );
|
|
if ( stxp->button &&
|
|
(stxp->no_button_space == XinFlagTrue ||
|
|
(stxp->no_button_space == XinFlagNotSet &&
|
|
( BOOLEAN ) xi_get_pref( XI_PREF_NO_BUTTON_SPACE ) )))
|
|
{
|
|
if ( stxp->button_on_left )
|
|
r.left += ( stxp->button_rect.right - stxp->button_rect.left );
|
|
else
|
|
r.right -= ( stxp->button_rect.right - stxp->button_rect.left );
|
|
}
|
|
stxp->edit_rect = r;
|
|
xi_text_prect_set( stxp->xi_text, &r );
|
|
}
|
|
|
|
void
|
|
stx_set_sel( STX stx, int c1, int c2 )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( stxp->multi_line && xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
{
|
|
int accum_cnt,
|
|
selidx;
|
|
int sel[2];
|
|
T_PNUM parsel[2],
|
|
par,
|
|
nbr_pars;
|
|
T_LNUM linsel[2],
|
|
lin,
|
|
nbr_lins;
|
|
T_CNUM chrsel[2],
|
|
nbr_chrs;
|
|
TXEDIT txed = stxp->txedit;
|
|
|
|
accum_cnt = 0;
|
|
selidx = 0;
|
|
sel[0] = c1;
|
|
sel[1] = c2;
|
|
nbr_pars = xvt_tx_get_num_pars( txed );
|
|
for ( par = 0; par < nbr_pars; par++ )
|
|
{
|
|
nbr_lins = xvt_tx_get_num_par_lines( txed, par );
|
|
for ( lin = 0; lin < nbr_lins; lin++ )
|
|
{
|
|
nbr_chrs = xvt_tx_get_num_chars( txed, par, lin );
|
|
while ( ( int ) ( accum_cnt + nbr_chrs ) >= sel[selidx] )
|
|
{
|
|
parsel[selidx] = par;
|
|
linsel[selidx] = lin;
|
|
chrsel[selidx] = sel[selidx] - accum_cnt;
|
|
selidx++;
|
|
if ( selidx >= 2 )
|
|
goto set_sel;
|
|
}
|
|
accum_cnt += nbr_chrs;
|
|
}
|
|
accum_cnt += 1; /* add eol at end of paragraph */
|
|
}
|
|
while ( selidx < 2 )
|
|
{
|
|
parsel[selidx] = nbr_pars - 1;
|
|
linsel[selidx] = nbr_lins - 1;
|
|
chrsel[selidx] = nbr_chrs - 1;
|
|
if ( selidx == 1 )
|
|
chrsel[selidx] = nbr_chrs;
|
|
selidx++;
|
|
}
|
|
set_sel:
|
|
xvt_tx_set_sel( txed, parsel[0], linsel[0], chrsel[0],
|
|
parsel[1], linsel[1], chrsel[1] );
|
|
return;
|
|
}
|
|
#endif
|
|
if ( !stxp->has_focus )
|
|
stx_start_edit( stx );
|
|
xi_text_selection_set( stxp->xi_text, c1, c2 );
|
|
}
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
static void
|
|
do_tx_add_par( TXEDIT tx, int limit, char *text )
|
|
{
|
|
char *s,
|
|
*bp,
|
|
*ep;
|
|
int cnt,
|
|
nbr_pars;
|
|
|
|
nbr_pars = xvt_tx_get_num_pars( tx );
|
|
xvt_tx_suspend( tx );
|
|
for ( cnt = 0; cnt < nbr_pars; ++cnt )
|
|
xvt_tx_rem_par( tx, 0 );
|
|
s = ( char * ) xi_tree_malloc( limit + 1, NULL );
|
|
bp = text;
|
|
if ( text[0] == '\0' )
|
|
{
|
|
xvt_tx_add_par( tx, ( unsigned short ) USHRT_MAX, s );
|
|
xvt_tx_resume( tx );
|
|
xi_tree_free( s );
|
|
return;
|
|
}
|
|
while ( TRUE )
|
|
{
|
|
int cnt,
|
|
min_cnt;
|
|
|
|
if ( *bp == '\0' )
|
|
break;
|
|
ep = bp;
|
|
cnt = 0;
|
|
while ( *ep != '\r' && *ep != '\n' && *ep != '\0' )
|
|
{
|
|
++ep;
|
|
++cnt;
|
|
}
|
|
min_cnt = min( limit, cnt );
|
|
gstrncpy( s, bp, min_cnt );
|
|
s[min_cnt] = '\0';
|
|
xvt_tx_add_par( tx, ( unsigned short ) USHRT_MAX, s );
|
|
if ( *ep == '\0' )
|
|
break;
|
|
bp = ep + 1;
|
|
}
|
|
xvt_tx_resume( tx );
|
|
xi_tree_free( s );
|
|
}
|
|
|
|
#endif
|
|
|
|
void
|
|
stx_set_text( STX stx, const char *s )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( stxp->multi_line && xi_get_pref( XI_PREF_USE_TX_SUPPORT ) )
|
|
{
|
|
TXEDIT txed = stxp->txedit;
|
|
|
|
do_tx_add_par( txed, stxp->text_size, s );
|
|
xvt_tx_set_sel( txed, 0, 0, 0, 0, 0, 0 );
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
xi_text_set( stxp->xi_text, s );
|
|
|
|
if ( ( stxp->attrib & XI_ATR_VISIBLE ) != 0
|
|
&& !xi_half_baked( stxp->win ) )
|
|
stx_redraw( stx, FALSE );
|
|
}
|
|
}
|
|
|
|
void
|
|
stx_set_app_data( STX stx, long data )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
stxp->app_data = data;
|
|
}
|
|
|
|
long
|
|
stx_get_app_data( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
return stxp->app_data;
|
|
}
|
|
|
|
XI_TEXT *
|
|
stx_xi_text_get( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
return stxp->xi_text;
|
|
}
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
BOOLEAN
|
|
xi_is_txedit( XI_OBJ * xi_obj )
|
|
{
|
|
if ( stx_get_txedit( xi_obj->v.field->stx ) == BAD_TXEDIT )
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
xi_tx_edit_move( XI_OBJ * xi_obj )
|
|
{
|
|
TXEDIT text_edit;
|
|
XI_ITF_DATA *itf_data;
|
|
XinRect rect;
|
|
XinRect new_rect;
|
|
XinWindow window;
|
|
STX_DATA *stxp;
|
|
|
|
if ( !xi_is_txedit( xi_obj ) )
|
|
return;
|
|
text_edit = stx_get_txedit( xi_obj->v.field->stx );
|
|
( WINDOW ) window = xvt_tx_get_win( text_edit );
|
|
itf_data = xi_obj->itf->v.itf;
|
|
xvt_tx_get_rect( text_edit, ( RCT * ) & rect );
|
|
stxp = ( STX_DATA * ) xi_obj->v.field->stx;
|
|
new_rect = stxp->edit_rect;
|
|
xi_offset_rect( &new_rect, itf_data->delta_x, itf_data->delta_y );
|
|
xvt_tx_move( text_edit, ( RCT * ) & new_rect );
|
|
xi_inflate_rect( &new_rect, 1 );
|
|
xi_invalidate_rect( window, &new_rect );
|
|
xi_inflate_rect( &rect, 1 );
|
|
xi_invalidate_rect( window, &rect );
|
|
}
|
|
|
|
BOOLEAN
|
|
xi_xvt_tx_event( XinWindow win, XinEvent * ep )
|
|
{
|
|
EVENT e;
|
|
|
|
if ( convert_event_back( &e, ep ) )
|
|
return xvt_tx_process_event( ( WINDOW ) win, &e );
|
|
return FALSE;
|
|
}
|
|
|
|
static SCROLL_CONTROL
|
|
convert_what_back( XinScrollBarAction scroll_control )
|
|
{
|
|
switch ( scroll_control )
|
|
{
|
|
case XinScrollBarActionLineUp:
|
|
return SC_LINE_UP;
|
|
case XinScrollBarActionLineDown:
|
|
return SC_LINE_DOWN;
|
|
case XinScrollBarActionPageUp:
|
|
return SC_PAGE_UP;
|
|
case XinScrollBarActionPageDown:
|
|
return SC_PAGE_DOWN;
|
|
case XinScrollBarActionThumb:
|
|
return SC_THUMB;
|
|
case XinScrollBarActionThumbTrack:
|
|
return SC_THUMBTRACK;
|
|
}
|
|
return SC_LINE_UP;
|
|
}
|
|
|
|
static BOOLEAN
|
|
convert_event_back( EVENT * ep, XinEvent * xiep )
|
|
{
|
|
BOOLEAN retval = TRUE;
|
|
|
|
switch ( xiep->type )
|
|
{
|
|
case XinEventCreate:
|
|
ep->type = E_CREATE;
|
|
break;
|
|
case XinEventDestroy:
|
|
ep->type = E_DESTROY;
|
|
break;
|
|
case XinEventFocus:
|
|
ep->type = E_FOCUS;
|
|
ep->v.active = xiep->v.focus.active;
|
|
break;
|
|
case XinEventResize:
|
|
ep->type = E_SIZE;
|
|
ep->v.size.width = xiep->v.resize.width;
|
|
ep->v.size.height = xiep->v.resize.height;
|
|
break;
|
|
case XinEventPaint:
|
|
ep->type = E_UPDATE;
|
|
ep->v.update.rct = *( RCT * ) & xiep->v.paint.rect;
|
|
break;
|
|
case XinEventCloseButton:
|
|
ep->type = E_CLOSE;
|
|
break;
|
|
case XinEventMouseDown:
|
|
ep->type = E_MOUSE_DOWN;
|
|
ep->v.mouse.where.v = xiep->v.mouse.where.v;
|
|
ep->v.mouse.where.h = xiep->v.mouse.where.h;
|
|
ep->v.mouse.shift = xiep->v.mouse.shift;
|
|
ep->v.mouse.control = xiep->v.mouse.control;
|
|
ep->v.mouse.button = xiep->v.mouse.button;
|
|
break;
|
|
case XinEventMouseUp:
|
|
ep->type = E_MOUSE_UP;
|
|
ep->v.mouse.where.v = xiep->v.mouse.where.v;
|
|
ep->v.mouse.where.h = xiep->v.mouse.where.h;
|
|
ep->v.mouse.shift = xiep->v.mouse.shift;
|
|
ep->v.mouse.control = xiep->v.mouse.control;
|
|
ep->v.mouse.button = xiep->v.mouse.button;
|
|
break;
|
|
case XinEventMouseMove:
|
|
ep->type = E_MOUSE_MOVE;
|
|
ep->v.mouse.where.v = xiep->v.mouse.where.v;
|
|
ep->v.mouse.where.h = xiep->v.mouse.where.h;
|
|
ep->v.mouse.shift = xiep->v.mouse.shift;
|
|
ep->v.mouse.control = xiep->v.mouse.control;
|
|
ep->v.mouse.button = xiep->v.mouse.button;
|
|
break;
|
|
case XinEventMouseDouble:
|
|
ep->type = XinEventMouseDouble;
|
|
ep->v.mouse.where.v = xiep->v.mouse.where.v;
|
|
ep->v.mouse.where.h = xiep->v.mouse.where.h;
|
|
ep->v.mouse.shift = xiep->v.mouse.shift;
|
|
ep->v.mouse.control = xiep->v.mouse.control;
|
|
ep->v.mouse.button = xiep->v.mouse.button;
|
|
break;
|
|
case XinEventCharacter:
|
|
ep->type = E_CHAR;
|
|
ep->v.chr.ch = xiep->v.character.ch;
|
|
#if XIWS == XIWS_WM
|
|
/* TODO ep->v.chr.shift and ep->v.chr.control are not set properly for
|
|
* XVT/CH */
|
|
xiep->v.character.shift = FALSE;
|
|
xiep->v.character.control = FALSE;
|
|
#else
|
|
ep->v.chr.shift = xiep->v.character.shift;
|
|
ep->v.chr.control = xiep->v.character.control;
|
|
#endif
|
|
break;
|
|
case XinEventHScroll:
|
|
ep->type = E_HSCROLL;
|
|
ep->v.scroll.pos = xiep->v.scroll.position;
|
|
ep->v.scroll.what = convert_what_back( xiep->v.scroll.action );
|
|
break;
|
|
case XinEventVScroll:
|
|
ep->type = E_VSCROLL;
|
|
ep->v.scroll.pos = xiep->v.scroll.position;
|
|
ep->v.scroll.what = convert_what_back( xiep->v.scroll.action );
|
|
break;
|
|
case XinEventMenuCommand:
|
|
ep->type = E_COMMAND;
|
|
ep->v.cmd.tag = xiep->v.menu_command.tag;
|
|
ep->v.cmd.shift = xiep->v.menu_command.shift;
|
|
ep->v.cmd.control = xiep->v.menu_command.control;
|
|
break;
|
|
case XinEventFont:
|
|
ep->type = E_FONT;
|
|
ep->v.font.font_id = XinFontXvtConvertBack( xiep->v.font.font );
|
|
break;
|
|
case XinEventControl:
|
|
ep->type = E_CONTROL;
|
|
ep->v.ctl.id = xiep->v.control.control_id;
|
|
switch ( xiep->v.control.ctrl_info.type )
|
|
{
|
|
/* non-xvt versions do not need to support buttons, radio buttons,
|
|
* and check boxes */
|
|
case XinWindowTypeButton:
|
|
ep->v.ctl.ci.type = WC_PUSHBUTTON;
|
|
break;
|
|
case XinWindowTypeRadioButton:
|
|
ep->v.ctl.ci.type = WC_RADIOBUTTON;
|
|
break;
|
|
case XinWindowTypeCheckBox:
|
|
ep->v.ctl.ci.type = WC_CHECKBOX;
|
|
break;
|
|
case XinWindowTypeVerticalScrollBar:
|
|
ep->v.ctl.ci.win = ( WINDOW ) xiep->v.control.ctrl_info.win;
|
|
ep->v.ctl.ci.type = WC_HSCROLL;
|
|
ep->v.ctl.ci.v.scroll.what = convert_what_back( xiep->v.control.ctrl_info.v.scroll.action );
|
|
ep->v.ctl.ci.v.scroll.pos = xiep->v.control.ctrl_info.v.scroll.position;
|
|
break;
|
|
case XinWindowTypeHorizontalScrollBar:
|
|
ep->v.ctl.ci.win = ( WINDOW ) xiep->v.control.ctrl_info.win;
|
|
ep->v.ctl.ci.type = WC_HSCROLL;
|
|
ep->v.ctl.ci.v.scroll.what = convert_what_back( xiep->v.control.ctrl_info.v.scroll.action );
|
|
ep->v.ctl.ci.v.scroll.pos = xiep->v.control.ctrl_info.v.scroll.position;
|
|
break;
|
|
}
|
|
break;
|
|
case XinEventTimer:
|
|
ep->type = E_TIMER;
|
|
ep->v.timer.id = xiep->v.timer.id;
|
|
break;
|
|
case XinEventQuit:
|
|
ep->type = E_QUIT;
|
|
ep->v.query = xiep->v.quit.query;
|
|
break;
|
|
case XinEventHelp:
|
|
ep->type = E_HELP;
|
|
ep->v.help.obj = ( WINDOW ) xiep->v.help.obj;
|
|
ep->v.help.tag = xiep->v.help.tag;
|
|
ep->v.help.tid = xiep->v.help.topic_id;
|
|
break;
|
|
case XinEventUser:
|
|
xiep->type = E_USER;
|
|
ep->v.user.id = xiep->v.user.id;
|
|
ep->v.user.ptr = xiep->v.user.ptr;
|
|
break;
|
|
default:
|
|
retval = FALSE;
|
|
break;
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
#if 0
|
|
/*---------------------------------------------------------------------
|
|
function: draw_text_edit_border
|
|
stxptr:
|
|
process:
|
|
---------------------------------------------------------------------*/
|
|
static void
|
|
draw_text_edit_border( STX_DATA * stxp )
|
|
{
|
|
XinRect rct;
|
|
|
|
XinWindowDrawModeSet( stxptr->win, XinDrawModeCopy );
|
|
XinWindowPenSet( stxptr->win, &black_cpen );
|
|
XinWindowBrushSet( stxptr->win, &hollow_cbrush );
|
|
rct = stxptr->rct;
|
|
if ( stxptr->attrib & XI_ATR_BORDER )
|
|
{
|
|
xi_draw_rect( stxptr->win, &rct );
|
|
xi_inflate_rect( &rct, -1 );
|
|
}
|
|
else
|
|
{
|
|
if ( stxptr->attrib & XI_ATR_FOCUSBORDER )
|
|
{
|
|
COLOR pen_color;
|
|
XinPen cpen;
|
|
|
|
if ( stxptr->has_focus )
|
|
{
|
|
pen_color = XI_COLOR_BLACK;
|
|
}
|
|
else
|
|
{
|
|
static XI_OBJ *itf;
|
|
COLOR back_color;
|
|
|
|
itf = xi_get_itf( stxptr->win );
|
|
back_color = itf->v.itf->back_color;
|
|
if ( back_color )
|
|
pen_color = back_color;
|
|
else
|
|
pen_color = xi_get_pref( XI_PREF_COLOR_CTRL );
|
|
}
|
|
cpen.fore_color = pen_color;
|
|
cpen.pattern = XinBrushSolid;
|
|
cpen.width = 1;
|
|
XinWindowPenSet( stxptr->win, &cpen );
|
|
xi_draw_rect( stxptr->win, &rct );
|
|
xi_inflate_rect( &rct, -1 );
|
|
}
|
|
}
|
|
if ( ( ( BOOLEAN ) xi_get_pref( XI_PREF_3D_LOOK ) == FALSE )
|
|
|| ( ( stxptr->well == FALSE ) && ( stxptr->platform == FALSE ) ) )
|
|
return;
|
|
xi_draw_3d_rect( stxptr->win, &rct, stxptr->well, 1, 0L, 0L, 0L );
|
|
}
|
|
|
|
#endif
|
|
|
|
static TXEDIT
|
|
stx_get_txedit( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
return stxp->txedit;
|
|
}
|
|
|
|
#endif
|
|
|
|
BOOLEAN
|
|
stx_cr_is_ok( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
return stxp->cr_ok;
|
|
}
|
|
|
|
void
|
|
stx_update_colors( STX stx )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
|
|
#ifdef XI_USE_TX_SUPPORT
|
|
if ( xi_get_pref( XI_PREF_USE_TX_SUPPORT ) && stxp->multi_line )
|
|
xvt_tx_set_colors( stxp->txedit, stxp->enabled_color,
|
|
stxp->enabled_color, stxp->back_color );
|
|
else
|
|
#endif
|
|
{
|
|
if ( stxp->has_focus )
|
|
{
|
|
xi_text_color_fore_set( stxp->xi_text, stxp->active_color );
|
|
xi_text_color_back_set( stxp->xi_text, stxp->active_back_color );
|
|
}
|
|
else if ( stxp->attrib & XI_ATR_ENABLED )
|
|
{
|
|
xi_text_color_fore_set( stxp->xi_text, stxp->enabled_color );
|
|
xi_text_color_back_set( stxp->xi_text, stxp->back_color );
|
|
}
|
|
else
|
|
{
|
|
xi_text_color_fore_set( stxp->xi_text, stxp->disabled_color );
|
|
xi_text_color_back_set( stxp->xi_text, stxp->disabled_back_color );
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
stx_set_font( STX stx, XinFont* font )
|
|
{
|
|
STX_DATA *stxp = ( STX_DATA * ) stx;
|
|
XinFont* font_copy;
|
|
|
|
XinFontCopy( &font_copy, font );
|
|
|
|
if ( stxp->xi_text != NULL )
|
|
xi_text_font_set( stxp->xi_text, font_copy );
|
|
XinFontDestroy( stxp->font );
|
|
stxp->font = font_copy;
|
|
}
|