Files correlati : xi.dll Ricompilazione Demo : [ ] Commento : Resi meno profondi i bottoni dei listbox/querybox git-svn-id: svn://10.65.10.50/trunk@17309 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			4888 lines
		
	
	
		
			149 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			4888 lines
		
	
	
		
			149 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 "xilm.h"
 | |
| #include "xilmst.h"
 | |
| #include "xiutils.h"
 | |
| #include "xidisply.h"
 | |
| #include <limits.h>
 | |
| 
 | |
| static XinDrawTools lm_normal_ctools;
 | |
| 
 | |
| #define LM_COL_ATTR(lm, col) (LMP(lm)->lm_column_data[col]->attrib)
 | |
| #define LM_REDRAW_COL_ATR (LM_COL_ATR_ENABLED | LM_COL_ATR_RJUST |   LM_COL_ATR_PASSWORD | LM_COL_ATR_SELECTED)
 | |
| #define LM_REDRAW_ROW_ATR (LM_ROW_ATR_ENABLED | LM_ROW_ATR_SELECTED)
 | |
| 
 | |
| #define LM_REDRAW_CELL_ATR (LM_CELL_ATR_SELECTED | LM_CELL_ATR_RJUST | LM_CELL_ATR_HCENTER)
 | |
| #define SELECT_CELLS_OFFSET 1
 | |
| 
 | |
| typedef struct
 | |
| {
 | |
|   BOOLEAN XinWindowPaintNeeds;
 | |
|   XinRect rct;
 | |
|   XinRect prct;
 | |
| } ROW_INFO;
 | |
| 
 | |
| static XinBrush lm_white_cbrush;
 | |
| static XinPen lm_black_cpen;
 | |
| static BOOLEAN lm_tools_inited = FALSE;
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_draw_clipped_text
 | |
| lmp:        current lmp
 | |
| s:          string
 | |
| bound_rctp:
 | |
| clip_rctp:
 | |
| attrib:
 | |
| set_the_cpen:
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| lm_draw_clipped_text( LM_DATA * lmp, char *s, XinRect * bound_rctp,
 | |
|               XinRect * clip_rctp, unsigned long attrib, BOOLEAN set_the_cpen,
 | |
|                       BOOLEAN adj_v )
 | |
| {
 | |
|   XinRect br,
 | |
|   cr;
 | |
|   BOOLEAN left,
 | |
|   right;
 | |
| 
 | |
|   br = *bound_rctp;
 | |
|   br.left += lmp->rct.left;
 | |
|   br.right += lmp->rct.left;
 | |
| 
 | |
|   if ( adj_v )
 | |
|   {
 | |
|     lm_adj_v( lmp, br.top );
 | |
|     lm_adj_v( lmp, br.bottom );
 | |
|   }
 | |
| 
 | |
|   left = lm_adj_h( lmp, &br.left );
 | |
|   right = lm_adj_h( lmp, &br.right );
 | |
|   if ( !left && !right )
 | |
|     return;
 | |
|   xi_rect_intersect( &cr, &br, clip_rctp );
 | |
|   xi_draw_clipped_text( lmp->win, lmp->cur_font, s, &br, &cr, attrib,
 | |
|                         set_the_cpen, 0, -1, '\0', 0, NULL );
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_draw_rect
 | |
| lmp:        current lmp
 | |
| rctp:       rectangle to draw
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| lm_draw_rect( LM_DATA * lmp, XinRect * rctp, BOOLEAN adj_v )
 | |
| {
 | |
|   XinRect r;
 | |
|   BOOLEAN leftb,
 | |
|   rightb;
 | |
| 
 | |
|   r = *rctp;
 | |
|   r.left += lmp->rct.left;
 | |
|   if ( r.right != SHRT_MAX )
 | |
|     r.right += lmp->rct.left;
 | |
| 
 | |
|   if ( adj_v )
 | |
|   {
 | |
|     lm_adj_v( lmp, r.top );
 | |
|     lm_adj_v( lmp, r.bottom );
 | |
|   }
 | |
| 
 | |
|   leftb = lm_adj_h( lmp, &r.left );
 | |
|   if ( r.right == SHRT_MAX )
 | |
|     rightb = TRUE;
 | |
|   else
 | |
|     rightb = lm_adj_h( lmp, &r.right );
 | |
|   if ( !leftb && !rightb )
 | |
|     return;
 | |
|   xi_draw_rect( lmp->win, &r );
 | |
| }
 | |
| 
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_draw_icon
 | |
| lmp:        current lmp
 | |
| left:       h position
 | |
| top:        v position
 | |
| icon_rid:   resource id
 | |
| vir_clip:   virtual clip rectangle
 | |
| phys_rct:
 | |
| fore_color: desired colors if icons
 | |
| back_color:
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| lm_draw_icon( LM_DATA * lmp, int left, int top, int icon_rid, XI_BITMAP * bitmap,
 | |
|               XinRect * vir_clip, XinRect * phys_rct, BOOLEAN adj_v,
 | |
|               XinColor fore_color, XinColor back_color )
 | |
| {
 | |
|   XinRect crct,
 | |
|   r;
 | |
|   short sleft;
 | |
|   BOOLEAN leftb,
 | |
|   rightb;
 | |
| 
 | |
|   left += lmp->rct.left;
 | |
|   r = *phys_rct;
 | |
| 
 | |
|   r.left += lmp->rct.left;
 | |
|   r.right += lmp->rct.left;
 | |
| 
 | |
|   if ( adj_v )
 | |
|   {
 | |
|     lm_adj_v( lmp, r.top );
 | |
|     lm_adj_v( lmp, r.bottom );
 | |
|   }
 | |
| 
 | |
|   leftb = lm_adj_h( lmp, &r.left );
 | |
|   rightb = lm_adj_h( lmp, &r.right );
 | |
|   if ( !leftb && !rightb )
 | |
|     return;
 | |
|   if ( adj_v )
 | |
|     lm_adj_v( lmp, top );
 | |
|   if ( xi_rect_intersect( &crct, &r, vir_clip ) )
 | |
|   {
 | |
|     xi_set_clip( lmp->win, &crct );
 | |
|     sleft = left;
 | |
|     if ( lm_adj_h( lmp, &sleft ) )
 | |
|     {
 | |
|       if ( bitmap != NULL )
 | |
|         xi_bitmap_draw( bitmap, lmp->win, &r, &crct, FALSE );
 | |
|       else
 | |
|         xi_draw_icon( lmp->win, sleft, top, icon_rid, fore_color, back_color );
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_draw_3d_rect
 | |
| lmp:        current lmp
 | |
| rctp:       rectangle
 | |
| well:       or platform
 | |
| depth:      in pixels
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| lm_draw_3d_rect( LM_DATA * lmp, XinRect * rctp, BOOLEAN well, int depth, BOOLEAN adj_v )
 | |
| {
 | |
|   XinRect r;
 | |
|   BOOLEAN left,
 | |
|   right;
 | |
|   const XinColor color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
 | |
|   const XinColor color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
 | |
|   const XinColor color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
 | |
| 
 | |
|   r = *rctp;
 | |
| 
 | |
|   r.left += lmp->rct.left;
 | |
|   r.right += lmp->rct.left;
 | |
| 
 | |
|   if ( adj_v )
 | |
|   {
 | |
|     lm_adj_v( lmp, r.top );
 | |
|     lm_adj_v( lmp, r.bottom );
 | |
|   }
 | |
| 
 | |
|   left = lm_adj_h( lmp, &r.left );
 | |
|   right = lm_adj_h( lmp, &r.right );
 | |
|   if ( !left && !right )
 | |
|     return;
 | |
|   xi_draw_3d_rect( lmp->win, &r, well, depth, color_light, color_ctrl, color_dark);
 | |
| }
 | |
| 
 | |
| /*********** draw column headings ***********/
 | |
| static void
 | |
| draw_column_headings( LM_DATA * lmp, XinRect * actual_rct )
 | |
| {
 | |
|   XinWindow win = lmp->win;
 | |
|   LM lm = ( LM ) lmp;
 | |
|   XinRect clip_rct;
 | |
| 
 | |
|   clip_rct = *actual_rct;
 | |
|   if ( !lmp->update_cells_only )
 | |
|   {
 | |
|     if ( !( lmp->update_rows_at_top + lmp->update_rows_at_bottom ) )
 | |
|     {
 | |
|       if ( !lmp->no_heading )
 | |
|       {
 | |
|         int col;
 | |
| 
 | |
|         if ( lmp->nbr_columns == 0 )
 | |
|         {
 | |
|           XinRect hr;
 | |
|           XinBrush cb;
 | |
| 
 | |
|           hr.top = lmp->pix_top + BORDER_WIDTH;
 | |
|           hr.bottom = lmp->pix_hdr_bottom + BORDER_WIDTH;
 | |
|           hr.left = lmp->rct.left;
 | |
|           hr.right = lmp->rct.right;
 | |
|           XinWindowPenSet( win, &hollow_cpen );
 | |
|           cb = white_cbrush;
 | |
|           cb.fore_color = lmp->white_space_color;
 | |
|           XinWindowBrushSet( win, &cb );
 | |
|           XinWindowDrawModeSet( win, XinDrawModeCopy );
 | |
|           xi_set_clip( win, actual_rct );
 | |
|           xi_draw_rect( win, &hr );
 | |
|         }
 | |
|         for ( col = 0; col < lmp->nbr_columns; col++ )
 | |
|         {
 | |
|           XinRect heading_rct,
 | |
|           cell_rct;
 | |
|           LM_COLUMN_DATA *col_data;
 | |
|           unsigned long attrib;
 | |
| 
 | |
|           col_data = lmp->lm_column_data[col];
 | |
|           if ( col_data->suppress_update_heading )
 | |
|             continue;
 | |
| 
 | |
|           lm_get_cell_rect( &heading_rct, lm, 1, col, FALSE, FALSE );
 | |
|           heading_rct.top = lmp->pix_top + BORDER_WIDTH;
 | |
| #if XIWS == XIWS_WM
 | |
|           heading_rct.bottom = lmp->pix_hdr_bottom - VPIX_PER_CH;
 | |
|           lm_get_cell_rect( &cell_rct, lm, 1, col, TRUE, FALSE );
 | |
|           cell_rct.top = lmp->rct.top + VPIX_PER_CH;
 | |
| #else
 | |
|           heading_rct.bottom = lmp->pix_hdr_bottom;
 | |
|           lm_get_cell_rect( &cell_rct, lm, 1, col, TRUE, FALSE );
 | |
|           cell_rct.top = lmp->rct.top + 2 * BORDER_WIDTH;
 | |
| #endif
 | |
|           cell_rct.bottom = lmp->pix_hdr_bottom;
 | |
|           XinWindowPenSet( win, &hollow_cpen );
 | |
|           XinWindowBrushSet( win, &white_cbrush );
 | |
|           XinWindowDrawModeSet( win, XinDrawModeCopy );
 | |
|           xi_set_clip( win, actual_rct );
 | |
|           if ( col_data->font )
 | |
|             lmp->cur_font = col_data->font;
 | |
|           else
 | |
|             lmp->cur_font = lmp->font;
 | |
| 
 | |
|           if ( col_data->heading_well || col_data->heading_platform )
 | |
|           {
 | |
|             XinColor fore_color,
 | |
|             back_color;
 | |
| 
 | |
|             lm_draw_3d_rect( lmp, &heading_rct,
 | |
|                             ( BOOLEAN ) ( COLUMN_IS_SELECTED( lm, col )
 | |
|                                           || COLUMN_IS_PUSHED( lm, col ) ?
 | |
|                                           !col_data->heading_well :
 | |
|                                           col_data->heading_well ),
 | |
|                             2, FALSE );
 | |
|             /* Adjust for exact drawable area */
 | |
|             cell_rct.left++;
 | |
|             cell_rct.right--;
 | |
|             cell_rct.top++;
 | |
|             cell_rct.bottom = heading_rct.bottom - 2 + BORDER_WIDTH;
 | |
|             if ( COLUMN_IS_ENABLED( lm, col ) )
 | |
|             {
 | |
|               if ( LIST_IS_ENABLED( lmp ) )
 | |
|                 fore_color = lmp->enabled_color;
 | |
|               else
 | |
|                 fore_color = lmp->disabled_color;
 | |
|               back_color = lmp->back_color;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               fore_color = lmp->disabled_color;
 | |
|               back_color = lmp->disabled_back_color;
 | |
|             }
 | |
|             if ( col_data->heading_well || col_data->heading_platform )
 | |
|               back_color = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
 | |
|             XinWindowColorTextForeSet( win, fore_color );
 | |
|             XinWindowColorTextBackSet( win, back_color );
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             XinColor fore_color;
 | |
| 
 | |
|             if ( COLUMN_IS_ENABLED( lm, col ) )
 | |
|             {
 | |
|               if ( LIST_IS_ENABLED( lmp ) )
 | |
|                 fore_color = lmp->enabled_color;
 | |
|               else
 | |
|                 fore_color = lmp->disabled_color;
 | |
|               XinWindowColorTextForeSet( win, fore_color );
 | |
|               XinWindowColorTextBackSet( win, lmp->back_color );
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               fore_color = lmp->disabled_color;
 | |
|               XinWindowColorTextForeSet( win, fore_color );
 | |
|               XinWindowColorTextBackSet( win, lmp->disabled_back_color );
 | |
|             }
 | |
|             if ( COLUMN_IS_SELECTED( lm, col ) )
 | |
|             {
 | |
|               XinBrush cb;
 | |
| 
 | |
|               cb = white_cbrush;
 | |
|               cb.fore_color = fore_color;
 | |
|               XinWindowBrushSet( win, &cb );
 | |
|               XinWindowColorTextForeSet( win, XI_COLOR_WHITE );
 | |
|             }
 | |
|             lm_draw_rect( lmp, &heading_rct, FALSE );
 | |
|             /* Adjust for exact drawable area */
 | |
|             cell_rct.left--;
 | |
|             cell_rct.right++;
 | |
|             cell_rct.top--;
 | |
|             cell_rct.bottom++;
 | |
|           }
 | |
|           attrib = ( ( LM_COL_ATTR( lm, col ) | XI_ATR_VISIBLE ) &
 | |
|                     ~XI_ATR_PASSWORD ) |
 | |
|                   ( lmp->min_heading_height ? XI_ATR_VCENTER : 0 );
 | |
|           if ( col_data->center_heading )
 | |
|           {
 | |
|             attrib |= XI_ATR_HCENTER;
 | |
|             attrib &= ~XI_ATR_RJUST;
 | |
|           }
 | |
|           clip_rct.top = cell_rct.top;
 | |
|           clip_rct.bottom = cell_rct.bottom;
 | |
|           if ( col_data->icon_mode == XIM_ICON_HAS_PRIORITY
 | |
|               || col_data->icon_mode == XIM_TEXT_AND_BITMAP_OVERLAP )
 | |
|           {
 | |
|             if ( col_data->icon_rid || col_data->bitmap != NULL )
 | |
|             {
 | |
|               XinColor fore_color,
 | |
|               back_color;
 | |
| 
 | |
|               if ( COLUMN_IS_ENABLED( lm, col ) )
 | |
|               {
 | |
|                 if ( LIST_IS_ENABLED( lmp ) )
 | |
|                   fore_color = lmp->enabled_color;
 | |
|                 else
 | |
|                   fore_color = lmp->disabled_color;
 | |
|                 back_color = lmp->back_color;
 | |
|               }
 | |
|               else
 | |
|               {
 | |
|                 fore_color = lmp->disabled_color;
 | |
|                 back_color = lmp->disabled_back_color;
 | |
|               }
 | |
|               if ( col_data->heading_well || col_data->heading_platform )
 | |
|                 back_color = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
 | |
|               {
 | |
|                 XinRect temp_rct = cell_rct;
 | |
| 
 | |
|                 temp_rct.top--;
 | |
|                 temp_rct.left--;
 | |
|                 temp_rct.right++;
 | |
|                 temp_rct.bottom--;
 | |
|                 if ( col_data->heading_well || col_data->heading_platform )
 | |
|                   temp_rct.bottom--;
 | |
|                 clip_rct.top--;
 | |
|                 lm_draw_icon( lmp, temp_rct.left + col_data->icon_x,
 | |
|                           temp_rct.top + col_data->icon_y, col_data->icon_rid,
 | |
|                               col_data->bitmap, &clip_rct, &temp_rct, FALSE,
 | |
|                               fore_color, back_color );
 | |
|                 clip_rct.top++;
 | |
|               }
 | |
|             }
 | |
|             if ( col_data->icon_mode == XIM_TEXT_AND_BITMAP_OVERLAP
 | |
|                 || ( col_data->icon_rid == 0 && col_data->bitmap == NULL ) )
 | |
|             {
 | |
|               char *ch;
 | |
|               int lines;
 | |
| 
 | |
|               ch = col_data->heading_text;
 | |
|               lines = 1;
 | |
|               while ( *ch != '\0' )
 | |
|               {
 | |
|                 if ( *ch == '\n' )
 | |
|                   ++lines;
 | |
|                 ++ch;
 | |
|               }
 | |
|               XinWindowTextOpaqueSet( lmp->win, FALSE );
 | |
|               if ( lines == 1 )
 | |
|               {
 | |
|                 lm_draw_clipped_text( lmp, col_data->heading_text, &cell_rct,
 | |
|                                       &clip_rct,
 | |
|                                       attrib, TRUE, FALSE );
 | |
|               }
 | |
|               else
 | |
|               {
 | |
|                 char *s;
 | |
|                 char *first_char;
 | |
|                 char *ch;
 | |
|                 BOOLEAN bk = FALSE;
 | |
|                 int leading,
 | |
|                 ascent,
 | |
|                 descent;
 | |
| 
 | |
|                 s = XinMemoryAlloc( strlen( col_data->heading_text ) + 1 );
 | |
|                 strcpy( s, col_data->heading_text );
 | |
|                 ch = s;
 | |
|                 first_char = ch;
 | |
|                 XinFontMetricsGet( lmp->cur_font, &leading, &ascent, &descent );
 | |
|                 cell_rct.top +=
 | |
|                         ( cell_rct.bottom - cell_rct.top -
 | |
|                           ( leading + ascent + descent ) * lines ) / 2;
 | |
|                 cell_rct.bottom = cell_rct.top + leading + ascent + descent;
 | |
|                 while ( TRUE )
 | |
|                 {
 | |
|                   while ( *ch != '\n' && *ch != '\0' )
 | |
|                     ++ch;
 | |
|                   if ( *ch == '\0' )
 | |
|                     bk = TRUE;
 | |
|                   *ch = 0;
 | |
|                   lm_draw_clipped_text( lmp, first_char, &cell_rct,
 | |
|                                         &clip_rct,
 | |
|                                       attrib & ~XI_ATR_VCENTER, TRUE, FALSE );
 | |
|                   if ( bk )
 | |
|                     break;
 | |
|                   cell_rct.top += ( leading + ascent + descent );
 | |
|                   cell_rct.bottom += ( leading + ascent + descent );
 | |
|                   ++ch;
 | |
|                   first_char = ch;
 | |
|                 }
 | |
|                 XinMemoryFree( s );
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|           if ( col_data->icon_mode == XIM_TEXT_WITH_ICON_ON_LEFT
 | |
|               || col_data->icon_mode == XIM_TEXT_WITH_ICON_ON_RIGHT )
 | |
|           {                     /* Draw both text and icon, even if the icon is
 | |
|                                 * currently zero. */
 | |
|             XinColor fore_color,
 | |
|             back_color;
 | |
|             char *ch;
 | |
|             int lines;
 | |
|             short bitmap_width;
 | |
|             short bitmap_height;
 | |
| 
 | |
|             if ( col_data->icon_rid || col_data->bitmap != NULL )
 | |
|             {
 | |
|               if ( col_data->bitmap != NULL )
 | |
|                 xi_bitmap_size_get( col_data->bitmap, &bitmap_width, &bitmap_height );
 | |
|               if ( COLUMN_IS_ENABLED( lm, col ) )
 | |
|               {
 | |
|                 if ( LIST_IS_ENABLED( lmp ) )
 | |
|                   fore_color = lmp->enabled_color;
 | |
|                 else
 | |
|                   fore_color = lmp->disabled_color;
 | |
|                 back_color = lmp->back_color;
 | |
|               }
 | |
|               else
 | |
|               {
 | |
|                 fore_color = lmp->disabled_color;
 | |
|                 back_color = lmp->disabled_back_color;
 | |
|               }
 | |
|               if ( col_data->heading_well || col_data->heading_platform )
 | |
|                 back_color = xi_get_pref( XI_PREF_COLOR_CTRL );
 | |
|               {
 | |
|                 XinRect temp_rct = cell_rct;
 | |
| 
 | |
|                 if ( col_data->icon_mode == XIM_TEXT_WITH_ICON_ON_LEFT )
 | |
|                 {
 | |
|                   temp_rct.left = cell_rct.left - 1;
 | |
|                   if ( col_data->bitmap != NULL )
 | |
|                     temp_rct.right = temp_rct.left + bitmap_width;
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                   if ( col_data->bitmap != NULL )
 | |
|                   {
 | |
|                     temp_rct.left = cell_rct.right - bitmap_width;
 | |
|                     temp_rct.right = temp_rct.left + bitmap_width;
 | |
|                   }
 | |
|                   else
 | |
|                     temp_rct.left = cell_rct.right - 32;
 | |
|                   if ( temp_rct.left < cell_rct.left - 1 )
 | |
|                     temp_rct.left = cell_rct.left - 1;
 | |
|                 }
 | |
|                 temp_rct.top--;
 | |
|                 temp_rct.bottom--;
 | |
|                 if ( col_data->heading_well || col_data->heading_platform )
 | |
|                   temp_rct.bottom--;
 | |
|                 clip_rct.top--;
 | |
|                 lm_draw_icon( lmp, temp_rct.left, temp_rct.top, col_data->icon_rid,
 | |
|                               col_data->bitmap, &clip_rct, &temp_rct, FALSE,
 | |
|                               fore_color, back_color );
 | |
|                 clip_rct.top++;
 | |
|               }
 | |
|             }
 | |
|             if ( col_data->icon_mode == XIM_TEXT_WITH_ICON_ON_LEFT )
 | |
|             {
 | |
|               if ( col_data->bitmap != NULL )
 | |
|                 cell_rct.left += bitmap_width;
 | |
|               else
 | |
|                 cell_rct.left += 32;
 | |
|               if ( cell_rct.left > cell_rct.right )
 | |
|                 cell_rct.left = cell_rct.right;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               if ( col_data->bitmap != NULL )
 | |
|                 cell_rct.right -= bitmap_width;
 | |
|               else
 | |
|                 cell_rct.right -= 32;
 | |
|               if ( cell_rct.right < cell_rct.left )
 | |
|                 cell_rct.right = cell_rct.left;
 | |
|             }
 | |
|             ch = col_data->heading_text;
 | |
|             lines = 1;
 | |
|             while ( *ch != '\0' )
 | |
|             {
 | |
|               if ( *ch == '\n' )
 | |
|                 ++lines;
 | |
|               ++ch;
 | |
|             }
 | |
|             XinWindowTextOpaqueSet( lmp->win, FALSE );
 | |
|             if ( lines == 1 )
 | |
|             {
 | |
|               lm_draw_clipped_text( lmp, col_data->heading_text, &cell_rct,
 | |
|                                     &clip_rct,
 | |
|                                     attrib, TRUE, FALSE );
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               char *s;
 | |
|               char *first_char;
 | |
|               char *ch;
 | |
|               BOOLEAN bk = FALSE;
 | |
|               int leading,
 | |
|               ascent,
 | |
|               descent;
 | |
| 
 | |
|               s = XinMemoryAlloc( strlen( col_data->heading_text ) + 1 );
 | |
|               strcpy( s, col_data->heading_text );
 | |
|               ch = s;
 | |
|               first_char = ch;
 | |
|               XinFontMetricsGet( lmp->cur_font, &leading, &ascent, &descent );
 | |
|               cell_rct.top +=
 | |
|                       ( cell_rct.bottom - cell_rct.top -
 | |
|                         ( leading + ascent + descent ) * lines ) / 2;
 | |
|               cell_rct.bottom = cell_rct.top + leading + ascent + descent;
 | |
|               while ( TRUE )
 | |
|               {
 | |
|                 while ( *ch != '\n' && *ch != '\0' )
 | |
|                   ++ch;
 | |
|                 if ( *ch == '\0' )
 | |
|                   bk = TRUE;
 | |
|                 *ch = 0;
 | |
|                 lm_draw_clipped_text( lmp, first_char, &cell_rct,
 | |
|                                       &clip_rct,
 | |
|                                       attrib & ~XI_ATR_VCENTER, TRUE, FALSE );
 | |
|                 if ( bk )
 | |
|                   break;
 | |
|                 cell_rct.top += ( leading + ascent + descent );
 | |
|                 cell_rct.bottom += ( leading + ascent + descent );
 | |
|                 ++ch;
 | |
|                 first_char = ch;
 | |
|               }
 | |
|               XinMemoryFree( s );
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| 
 | |
| /*********** draw cells ***********/
 | |
| static void
 | |
| draw_cells( LM_DATA * lmp, BOOLEAN update )
 | |
| {
 | |
|   int first_row;
 | |
|   int last_row;
 | |
| 
 | |
|   first_row = lmp->first_fully_vis;
 | |
|   if ( first_row < 0 )
 | |
|     first_row = 0;
 | |
|   last_row = min( lmp->last_fully_vis + 1, lmp->nbr_realized_rows - 1 );
 | |
|   if ( last_row < 0 )
 | |
|     return;
 | |
|   draw_cell_range( lmp, first_row, last_row, 0, lmp->nbr_columns - 1, update );
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------*/
 | |
| /* draw_other_rectangles                                                   */
 | |
| /*-------------------------------------------------------------------------*/
 | |
| static void
 | |
| draw_other_rectangles( LM_DATA * lmp, XinRect * actual_rct )
 | |
| {
 | |
|   XinWindow win = lmp->win;
 | |
|   XinRect lmp_rct,
 | |
|   vr,
 | |
|   hr;
 | |
|   int i,
 | |
|   actual_r,
 | |
|   hrule_h;
 | |
|   XinBrush cbrush;
 | |
|   XI_LIST_DATA *list_data;
 | |
|   XI_OBJ *list_obj;
 | |
| 
 | |
|   lmp_rct = lmp->rct;
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = lmp->rct.left + lmp->pixel_width + 2 * BORDER_WIDTH;
 | |
|   else
 | |
|     actual_r = lmp->rct.right;
 | |
|   list_obj = lmp->list_obj;
 | |
|   list_data = list_obj->v.list;
 | |
|   hrule_h = actual_r;
 | |
| 
 | |
|   /*********** Graphical: border at right of last column ***********/
 | |
|   /*********** Graphical: rectangle around entire list ***********/
 | |
|   /*********** Graphical: rectangle at bottom of list ***********/
 | |
|   /* NOTE: GRAPHICAL SYSTEMS ONLY, HERE.  CH is in beginning of draw_lm */
 | |
| #if XIWS != XIWS_WM
 | |
|   xi_set_clip( win, actual_rct );
 | |
|   XinWindowPenSet( win, &black_cpen );
 | |
|   XinWindowDrawModeSet( win, XinDrawModeCopy );
 | |
|   if ( lmp->pixel_width )
 | |
|   {
 | |
|     XinPoint p,
 | |
|     p2;
 | |
|     int width;
 | |
| 
 | |
|     p.h = lmp->rct.right - 1 - lmp->rct.left;
 | |
|     p.v = lmp_rct.top;
 | |
|     p2 = p;
 | |
|     p2.v = min( lmp_rct.bottom, lmp->rrr_bottom + lmp->rrr_offset + lmp->mlr.top );
 | |
|     width = BORDER_WIDTH;
 | |
|     XinWindowPenSet( win, &black_cpen );
 | |
|     if ( !lmp->no_vert_lines && lmp->nbr_columns != 0 )
 | |
|     {                           /* Only draw this line if there are actually
 | |
|                                 * columns */
 | |
|       WIDTHLOOP( i, width )
 | |
|       {
 | |
|         lm_move_to( lmp, p, FALSE, TRUE );
 | |
|         lm_draw_line( lmp, p2, FALSE, TRUE );
 | |
|         --p.h;
 | |
|         --p2.h;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     {
 | |
|       XinRect r;
 | |
| 
 | |
|       r = lmp->rct;
 | |
|       r.left = lmp->rct.right - lmp->rct.left;
 | |
|       r.right = SHRT_MAX;
 | |
|       if ( lmp->no_vert_lines )
 | |
|         r.left -= BORDER_WIDTH;
 | |
|       XinWindowPenSet( win, &hollow_cpen );
 | |
|       cbrush.pattern = XinBrushSolid;
 | |
|       cbrush.fore_color = lmp->white_space_color;
 | |
|       XinWindowBrushSet( win, &cbrush );
 | |
|       xi_set_clip( win, actual_rct );
 | |
| 
 | |
|       lm_draw_rect( lmp, &r, FALSE );
 | |
|     }
 | |
| 
 | |
|     /* draw border around entire list */
 | |
|     lmp_rct.right = actual_r;
 | |
|     {
 | |
|       XinRect r;
 | |
|       XinBrush cb;
 | |
| 
 | |
|       r = lmp->rct;
 | |
|       if ( list_data->sb_win )
 | |
|       {
 | |
|         xi_get_sb_rect( list_obj, &vr );
 | |
|         /* add one, so that one pixel of the double border will overlap one
 | |
|         * pixel of the scroll bar. */
 | |
|         r.right = vr.right + 1;
 | |
|       }
 | |
|       else if ( list_data->hsb_win )
 | |
|         r.right = r.left + lmp->pixel_width + 2 * BORDER_WIDTH;
 | |
|       xi_get_hsb_rect( list_obj, &hr );
 | |
|       r.bottom = hr.bottom + 1;
 | |
|       XinWindowBrushSet( win, &hollow_cbrush );
 | |
|       XinWindowPenSet( win, &black_cpen );
 | |
|       xi_set_clip( win, NULL );
 | |
|       xi_draw_rect( win, &r );
 | |
|       xi_inflate_rect( &r, -1 );
 | |
|       xi_draw_rect( win, &r );
 | |
| 
 | |
|       cb = white_cbrush;
 | |
|       cb.fore_color = lmp->white_space_color;
 | |
|       XinWindowBrushSet( win, &cb );
 | |
|       XinWindowPenSet( win, &hollow_cpen );
 | |
|       r.left += 1;
 | |
|       r.top = lmp->rct.bottom;
 | |
|       r.right -= 1;
 | |
|       r.bottom -= 1;
 | |
|       xi_draw_rect( win, &r );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* RGM: Changed this rectangle to stop at the top of the horizontal scroll
 | |
|   * bar instead of the bottom. The bottom area is drawn just above. Was this
 | |
|   * rectangle supposed to draw both? If so, it is drawing over the line at the
 | |
|   * bottom of the list, when there are fixed columns. */
 | |
|   {                             /* rectangle at bottom of list */
 | |
|     XinRect r;
 | |
|     XinRect hsb_rect;
 | |
| 
 | |
|     xi_get_hsb_rect( lmp->list_obj, &hsb_rect );
 | |
|     cbrush.pattern = XinBrushSolid;
 | |
|     cbrush.fore_color = lmp->white_space_color;
 | |
|     XinWindowBrushSet( win, &cbrush );
 | |
|     r = lmp->mlr;
 | |
|     r.top = lmp->rrr_bottom + lmp->rrr_offset + lmp->mlr.top;
 | |
|     r.top = min( r.top, hsb_rect.top );
 | |
|     r.bottom = hsb_rect.top;
 | |
|     r.right = lmp->rct.right;
 | |
|     if ( lmp->pixel_width )
 | |
|       r.right = lmp->rct.left + lmp->pixel_width + 2;
 | |
|     xi_draw_rect( win, &r );
 | |
|   }
 | |
| 
 | |
|   /* border around entire list */
 | |
|   if ( !( lmp->update_rows_at_top + lmp->update_rows_at_bottom ) )
 | |
|   {
 | |
|     XinWindowPenSet( win, &black_cpen );
 | |
|     XinWindowBrushSet( win, &hollow_cbrush );
 | |
|     XinWindowDrawModeSet( win, XinDrawModeCopy );
 | |
|     xi_set_clip( win, NULL );
 | |
|     lmp_rct = lmp->rct;
 | |
|     if ( lmp->pixel_width )
 | |
|       lmp_rct.right = hrule_h;
 | |
|     WIDTHLOOP( i, BORDER_WIDTH )
 | |
|     {
 | |
|       xi_draw_rect( win, &lmp_rct );
 | |
|       xi_inflate_rect( &lmp_rct, -1 );
 | |
|     }
 | |
|   }
 | |
| 
 | |
| #endif
 | |
| #if XIWS == XIWS_WM
 | |
|   xi_set_clip( win, actual_rct );
 | |
|   XinWindowPenSet( win, &black_cpen );
 | |
|   XinWindowDrawModeSet( win, XinDrawModeCopy );
 | |
|   if ( lmp->pixel_width )
 | |
|   {
 | |
|     XinRect r;
 | |
|     XinPoint p1,
 | |
|     p2;
 | |
| 
 | |
|     r = lmp->rct;
 | |
|     r.left = lmp->rct.right - lmp->rct.left + BORDER_WIDTH;
 | |
|     r.top += BORDER_WIDTH;
 | |
|     r.right = 9999;
 | |
|     XinWindowPenSet( win, &hollow_cpen );
 | |
|     cbrush.pat = XinPatternSolid;
 | |
|     cbrush.color = lmp->white_space_color;
 | |
|     XinWindowPaintBrushSet( win, &cbrush );
 | |
|     xi_set_clip( win, actual_rct );
 | |
|     lm_draw_rect( lmp, &r, FALSE );
 | |
| 
 | |
|     XinWindowPenSet( win, &black_cpen );
 | |
|     p1.h = r.left;
 | |
|     p1.v = lmp->rct.top;
 | |
|     p2.h = r.left;
 | |
|     p2.v = r.bottom;
 | |
|     lm_move_to( lmp, p1, FALSE, TRUE );
 | |
|     lm_draw_line( lmp, p2, FALSE, TRUE );
 | |
| 
 | |
|   }
 | |
| 
 | |
|   {                             /* rectangle at bottom of list */
 | |
|     XinRect r;
 | |
| 
 | |
|     cbrush.pat = XinPatternSolid;
 | |
|     cbrush.color = lmp->white_space_color;
 | |
|     XinWindowPaintBrushSet( win, &cbrush );
 | |
|     XinWindowPenSet( win, &hollow_cpen );
 | |
|     r = lmp->mlr;
 | |
|     r.left += BORDER_WIDTH;
 | |
|     r.top = lmp->rrr_bottom + lmp->rrr_offset + lmp->mlr.top;
 | |
|     r.right = lmp->rct.right;
 | |
|     if ( lmp->pixel_width )
 | |
|       r.right = lmp->rct.left + 2 * lmp->pixel_width;
 | |
|     if ( r.top < r.bottom )
 | |
|       xi_draw_rect( win, &r );
 | |
|   }
 | |
| #endif
 | |
|   lmp->update_rows_at_top = 0;
 | |
|   lmp->update_rows_at_bottom = 0;
 | |
|   lmp->update_cells_only = FALSE;
 | |
| }
 | |
| 
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_size_hit_test
 | |
| lm:         current lm
 | |
| ep:         xvt event
 | |
| columnp:    column, to be filled in
 | |
| returns:    FALSE if hit test did not fall on place where column could be sized.
 | |
| -------------------------------------------------------------------------*/
 | |
| static BOOLEAN
 | |
| lm_size_hit_test( LM lm, XinEvent * ep, int *columnp )
 | |
| {
 | |
|   int column,
 | |
|   temp,
 | |
|   col_offset;
 | |
|   LM_DATA *lmp = LMP( lm );
 | |
|   XinPoint where;
 | |
| 
 | |
|   col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | |
|   where = ep->v.mouse.where;
 | |
|   if ( where.h < 0 )
 | |
|     return FALSE;
 | |
|   if ( lmp->pixel_width && ( where.h > ( lmp->pixel_width + lmp->delta_x )
 | |
|                             + 2 * BORDER_WIDTH ) )
 | |
|     return FALSE;
 | |
|   if ( where.v > lmp->pix_top && where.v < lmp->pix_row1_top )
 | |
|   {
 | |
|     for ( column = 0; column < lmp->nbr_columns; column++ )
 | |
|     {
 | |
|       LM_COLUMN_DATA *column_data;
 | |
| 
 | |
|       if ( column >= lmp->fixed_columns && column < lmp->first_vis )
 | |
|         continue;
 | |
|       column_data = lmp->lm_column_data[column];
 | |
|       temp = column_data->x_pix_pos +
 | |
|               col_offset +
 | |
|               column_data->pix_width;
 | |
|       if ( where.h >= temp &&
 | |
|           where.h < temp + col_offset * 2 + RULE_WIDTH_V )
 | |
|       {
 | |
|         *columnp = column;
 | |
|         return TRUE;
 | |
|       }
 | |
|     }
 | |
|     return FALSE;
 | |
|   }
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| static void
 | |
| draw_cell_text( LM_DATA * lmp, LM_CELL_DATA * cell_data, LM_COLUMN_DATA * column_data,
 | |
|                 int row, int col, int col_offset, int leading, int ascent,
 | |
|     int descent, XinColor fore_color, XinColor back_color, BOOLEAN set_clip )
 | |
| {
 | |
|   XinRect rct;
 | |
|   unsigned long attrib,
 | |
|   cell_attrib;
 | |
|   char *s;
 | |
|   int len,
 | |
|   baseline,
 | |
|   wid;
 | |
|   XinWindow win = lmp->win;
 | |
| 
 | |
|   if ( lm_focus_cell_has( lmp, row, col, FALSE ) && !cell_data->button_full_cell )
 | |
|     return;
 | |
| 
 | |
|   cell_attrib = cell_data->attrib &
 | |
|           ( XI_ATR_HCENTER | XI_ATR_RJUST );
 | |
|   attrib = LM_COL_ATTR( lmp, col ) | XI_ATR_VISIBLE |
 | |
|           ( lmp->min_cell_height ? XI_ATR_VCENTER : 0 );
 | |
|   if ( cell_attrib )
 | |
|   {
 | |
|     attrib &= ~( XI_ATR_HCENTER | XI_ATR_RJUST );
 | |
|     attrib |= cell_attrib;
 | |
|   }
 | |
|   if ( cell_data->button_full_cell )
 | |
|     attrib = attrib | XI_ATR_HCENTER | XI_ATR_VCENTER;
 | |
|   lm_xi_text_prect_get( lmp, column_data, cell_data, row, col, col_offset, leading,
 | |
|                         ascent, descent, &rct );
 | |
|   xi_text_prect_set( cell_data->xi_text, &rct );
 | |
|   if ( column_data->wrap_text )
 | |
|   {
 | |
|     XinRect mlr = lmp->mlr;
 | |
| 
 | |
|     if ( lmp->pixel_width )
 | |
|       mlr.right = mlr.left + lmp->pixel_width + BORDER_WIDTH;
 | |
|     xi_text_max_lines_to_draw_set( cell_data->xi_text, lmp->max_lines_in_cell );
 | |
|     xi_text_draw( cell_data->xi_text, fore_color, back_color, FALSE );
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if ( set_clip )
 | |
|     {
 | |
|       XinRect mlr = lmp->mlr;
 | |
|       XinRect cell_rct;
 | |
| 
 | |
|       if ( lmp->pixel_width )
 | |
|         mlr.right = mlr.left + lmp->pixel_width + BORDER_WIDTH;
 | |
|       cell_rct = rct;
 | |
|       if ( cell_data->button_full_cell )
 | |
|       {
 | |
|         xi_inflate_rect( &cell_rct, -2 );
 | |
|       }
 | |
|       xi_rect_intersect( &cell_rct, &mlr, &cell_rct );
 | |
|       xi_set_clip( win, &cell_rct );
 | |
|     }
 | |
|     s = xi_get_text_string( xi_text_get( cell_data->xi_text ), LM_COL_ATTR( lmp, col ) );
 | |
|     len = strlen( s );
 | |
| #if XIWS == XIWS_WM
 | |
|     baseline = rct.top + 8;
 | |
| #else
 | |
|     if ( attrib & XI_ATR_VCENTER )
 | |
|       baseline = rct.top + leading + ascent +
 | |
|               ( rct.bottom - rct.top - leading - ascent - descent ) / 2 - 1;
 | |
|     else
 | |
|       baseline = rct.top + leading + ascent;
 | |
| #endif
 | |
|     if ( attrib & XI_ATR_RJUST )
 | |
|     {
 | |
|       XinWindowFontMap( win, lmp->cur_font );
 | |
|       wid = XinFontTextWidthGet( lmp->cur_font, s, -1 );
 | |
|       xi_draw_text( win, lmp->cur_font, rct.right - wid, baseline, s, len );
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       if ( attrib & XI_ATR_HCENTER )
 | |
|       {
 | |
|         int x;
 | |
| 
 | |
|         wid = XinFontTextWidthGet( lmp->cur_font, s, len );
 | |
|         x = ( rct.left + rct.right ) / 2 - wid / 2;
 | |
|         if ( x < rct.left )
 | |
|           x = rct.left;
 | |
|         xi_draw_text( win, lmp->cur_font, x, baseline, s, len );
 | |
|       }
 | |
|       else
 | |
|         xi_draw_text( win, lmp->cur_font, rct.left, baseline, s, len );
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   redraw_cell_button
 | |
| lmp:        current lmp
 | |
| row:
 | |
| col:                 0
 | |
| clip_rct:   clip rectangle
 | |
| down:       if TRUE, then button is depressed
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| redraw_cell_button( LM_DATA * lmp, int row, int col, XinRect * clip_rct,
 | |
|                     BOOLEAN down, BOOLEAN clear_button )
 | |
| {
 | |
|   XinRect r,
 | |
|   outer_rct,
 | |
|   col_rct,
 | |
|   clip_rect;
 | |
|   int cell_btn_icon_x,
 | |
|   cell_btn_icon_y;
 | |
|   LM_CELL_DATA *cell_data;
 | |
|   BOOLEAN button_on_left;
 | |
|   BOOLEAN button_full_cell;
 | |
|   int button_icon_rid;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
|   XinPoint p;
 | |
|   XinDrawTools ct;
 | |
|   XinRect actual_rct;
 | |
|   int actual_r;
 | |
| 
 | |
|   actual_rct = lmp->rct;
 | |
| #if XIWS != XIWS_WM
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = lmp->rct.left + lmp->pixel_width + 2 * BORDER_WIDTH;
 | |
|   else
 | |
|     actual_r = lmp->rct.right;
 | |
|   actual_rct.right = actual_r - BORDER_WIDTH;
 | |
| #else
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = lmp->rct.left + lmp->pixel_width;
 | |
|   else
 | |
|     actual_r = lmp->rct.right;
 | |
|   actual_rct.right = actual_r;
 | |
| #endif
 | |
|   column_data = lmp->lm_column_data[col];
 | |
|   col_rct.left = column_data->x_pix_pos;
 | |
|   col_rct.right = col_rct.left + column_data->pix_width +
 | |
|           2 * ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | |
|   col_rct.top = clip_rct->top;
 | |
|   col_rct.bottom = clip_rct->bottom;
 | |
|   cell_data = &lmp->cell_data[row][col];
 | |
|   button_on_left = cell_data->button_on_left;
 | |
|   button_full_cell = cell_data->button_full_cell;
 | |
|   button_icon_rid = cell_data->button_icon_rid;
 | |
|   lm_get_cell_rect( &outer_rct, ( LM ) lmp, row, col, FALSE, FALSE );
 | |
|   r = outer_rct;
 | |
|   xi_inflate_rect( &r, 1 );
 | |
|   if ( !button_full_cell )
 | |
|   {
 | |
|     if ( button_on_left )
 | |
|     {
 | |
|       r.right = r.left + lmp->pix_row_spacing;
 | |
|       p.h = r.right - 1;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       r.left = r.right - lmp->pix_row_spacing;
 | |
|       p.h = r.left;
 | |
|     }
 | |
|   }
 | |
|   XinWindowPenSet( lmp->win, &black_cpen );
 | |
|   XinWindowDrawModeSet( lmp->win, XinDrawModeCopy );
 | |
|   clip_rect = col_rct;
 | |
|   clip_rect.left += lmp->rct.left;
 | |
|   clip_rect.right += lmp->rct.left;
 | |
| 
 | |
|   lm_adj_h( lmp, &clip_rect.left );
 | |
|   lm_adj_h( lmp, &clip_rect.right );
 | |
|   xi_rect_intersect( &clip_rect, &clip_rect, &lmp->mlr );
 | |
|   xi_rect_intersect( &clip_rect, &clip_rect, &actual_rct );
 | |
|   xi_set_clip( lmp->win, &clip_rect );
 | |
|   if ( clear_button )
 | |
|   {
 | |
|     if ( lmp->no_horz_lines )
 | |
|     {
 | |
|       /* if there is a button below, then decrement r.bottom */
 | |
|       int nr;
 | |
|       LM_CELL_DATA *row_below_cell_data;
 | |
| 
 | |
|       nr = row;
 | |
|       row_below_cell_data = &lmp->cell_data[nr + 1][col];
 | |
|       if ( row < lmp->nbr_realized_rows - 1 &&
 | |
|           row_below_cell_data->button &&
 | |
|           row_below_cell_data->button_on_left == lmp->cell_data[nr][col].button_on_left &&
 | |
|           row_below_cell_data->button_full_cell == lmp->cell_data[nr][col].button_full_cell &&
 | |
|           ( !row_below_cell_data->button_on_focus ) )
 | |
|         r.bottom--;
 | |
| 
 | |
|       XinWindowPenSet( lmp->win, &hollow_cpen );
 | |
|       XinWindowBrushSet( lmp->win, &white_cbrush );
 | |
|       lm_draw_rect( lmp, &r, TRUE );
 | |
|     }
 | |
|     return;
 | |
|   }
 | |
|   if ( lmp->no_horz_lines || lmp->no_vert_lines )
 | |
|     lm_draw_rect( lmp, &r, TRUE );
 | |
|   else
 | |
|   {
 | |
|     p.v = r.top;
 | |
|     lm_move_to( lmp, p, TRUE, TRUE );
 | |
|     p.v = r.bottom;
 | |
|     lm_draw_line( lmp, p, TRUE, TRUE );
 | |
|   }
 | |
|   xi_inflate_rect( &r, -1 );
 | |
|   lm_draw_3d_rect( lmp, &r, down, 2, TRUE );
 | |
|   xi_inflate_rect( &r, -2 );
 | |
|   
 | |
|   // Guy was here: le icone vanno centrate nel bottone
 | |
|   // cell_btn_icon_x = ( int ) xi_get_pref( XI_PREF_CELL_BTN_ICON_X );
 | |
|   // cell_btn_icon_y = ( int ) xi_get_pref( XI_PREF_CELL_BTN_ICON_Y );
 | |
|   cell_btn_icon_x = (r.right-r.left)/2 - 16;
 | |
|   cell_btn_icon_y = (r.bottom-r.top)/2 - 16;
 | |
|   
 | |
|   r.left = max( r.left, col_rct.left );
 | |
|   r.right = min( r.right, col_rct.right );
 | |
|   XinWindowDrawToolsGet( lmp->win, &ct );
 | |
|   ct.text_fore_color = lmp->enabled_color;
 | |
|   ct.text_back_color = aga_get_pref( AGA_PREF_BTN_COLOR_CTRL );
 | |
|   ct.opaque_text = FALSE;
 | |
|   if ( lmp->row_colors[row] )
 | |
|     ct.text_fore_color = lmp->row_colors[row];
 | |
|   if ( cell_data->color )
 | |
|     ct.text_fore_color = cell_data->color;
 | |
|   XinWindowDrawToolsSet( lmp->win, &ct );
 | |
|   if ( !button_full_cell )
 | |
|   {
 | |
|     lm_draw_icon( lmp, r.left + cell_btn_icon_x, r.top + cell_btn_icon_y + down,
 | |
|                   button_icon_rid ? button_icon_rid : ( int ) xi_get_pref( XI_PREF_COMBO_ICON ),
 | |
|                   cell_data->button_bitmap, clip_rct, &r, TRUE, XI_COLOR_BLACK,
 | |
|                   aga_get_pref( AGA_PREF_BTN_COLOR_CTRL ) );
 | |
|   }
 | |
|   else if ( button_full_cell && ( cell_data->icon_rid || cell_data->bitmap != NULL ) )
 | |
|   {
 | |
|     lm_draw_icon( lmp, r.left, r.top, cell_data->icon_rid, cell_data->bitmap,
 | |
|                   clip_rct, &r, TRUE, XI_COLOR_BLACK, aga_get_pref( AGA_PREF_BTN_COLOR_CTRL ) );
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     LM_CELL_DATA *cell_data;
 | |
|     int col_offset;
 | |
|     int leading,
 | |
|     ascent,
 | |
|     descent;
 | |
| 
 | |
|     cell_data = &lmp->cell_data[row][col];
 | |
|     col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | |
|     XinFontMetricsGet( lmp->cur_font, &leading, &ascent, &descent );
 | |
|     draw_cell_text( lmp, cell_data, column_data,
 | |
|                     row, col, col_offset, leading, ascent,
 | |
|                     descent, 0L, 0L, TRUE );
 | |
|     if ( lm_focus_cell_has( lmp, row, col, FALSE ) )
 | |
|     {
 | |
|       XinRect mlr = lmp->mlr;
 | |
|       XinRect cell_rct,
 | |
|       clip_rct,
 | |
|       text_rct;
 | |
|       int baseline;
 | |
| 
 | |
|       if ( lmp->pixel_width )
 | |
|         mlr.right = mlr.left + lmp->pixel_width + BORDER_WIDTH;
 | |
|       lm_xi_text_prect_get( lmp, column_data, cell_data, row, col, col_offset, leading,
 | |
|                             ascent, descent, &cell_rct );
 | |
|       xi_rect_intersect( &clip_rct, &mlr, &cell_rct );
 | |
|       xi_set_clip( lmp->win, &clip_rct );
 | |
| #if XIWS == XIWS_WM
 | |
|       baseline = cell_rct.top + 8;
 | |
| #else
 | |
|       baseline = cell_rct.top + leading + ascent +
 | |
|               ( cell_rct.bottom - cell_rct.top - leading - ascent - descent ) / 2 - 1;
 | |
| #endif
 | |
|       text_rct = cell_rct;
 | |
|       text_rct.top = baseline - leading - ascent - 2;
 | |
|       text_rct.top = max( text_rct.top, ( cell_rct.top ) );
 | |
|       text_rct.bottom = baseline + descent + 2;
 | |
|       text_rct.bottom = min( text_rct.bottom, ( cell_rct.bottom - 2 ) );
 | |
|       XinWindowPenSet( lmp->win, &black_cpen );
 | |
|       XinWindowDrawModeSet( lmp->win, XinDrawModeCopy );
 | |
|       xi_draw_dotted_rect( lmp->win, &text_rct );
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| static void
 | |
| draw_cell_buttons( LM_DATA * lmp, ROW_INFO * row_info, int first_row, int last_row,
 | |
|                   BOOLEAN in_update_event )
 | |
| {
 | |
|   int col,
 | |
|   row;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
|   ROW_INFO *ri;
 | |
| 
 | |
|   NOREF( in_update_event );
 | |
|   /* draw exception rectangles - draw enabled, not selected cells */
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
| 
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       XinRect mr;
 | |
|       BOOLEAN button;
 | |
|       BOOLEAN button_on_focus;
 | |
|       BOOLEAN button_full_cell;
 | |
|       LM_CELL_DATA *cell_data;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       mr = lmp->mlr;
 | |
|       if ( lmp->pixel_width )
 | |
|         mr.right = lmp->rct.left + lmp->pixel_width + BORDER_WIDTH;
 | |
|       cell_data = &lmp->cell_data[row][col];
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       button = cell_data->button;
 | |
|       button_on_focus = cell_data->button_on_focus;
 | |
|       button_full_cell = cell_data->button_full_cell;
 | |
|       if ( lmp->button_on_cell_focus )
 | |
|       {
 | |
|         if ( ( button && !button_on_focus ) ||
 | |
|             ( button && button_full_cell ) ||
 | |
|             ( button && button_on_focus &&
 | |
|               lm_focus_cell_has( lmp, row, col, FALSE ) ) )
 | |
|           redraw_cell_button( lmp, row, col, &mr, FALSE, FALSE );
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         if ( ( button && !button_on_focus ) ||
 | |
|             ( button && button_full_cell ) ||
 | |
|             ( button && button_on_focus &&
 | |
|               lm_row_has_focus( lmp, row, FALSE ) ) )
 | |
|           redraw_cell_button( lmp, row, col, &mr, FALSE, FALSE );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_XinWindowPaintNeeds
 | |
| lmp:        current lmp
 | |
| rctp:       rectangle to test
 | |
| adj_h:      adjust h
 | |
| adj_v:      adjust v
 | |
| returns:    TRUE if rectangle needs update
 | |
| -------------------------------------------------------------------------*/
 | |
| static BOOLEAN
 | |
| lm_XinWindowPaintNeeds( LM_DATA * lmp, XinRect * rctp, BOOLEAN adj_h, BOOLEAN adj_v )
 | |
| {
 | |
|   XinRect r;
 | |
| 
 | |
|   r = *rctp;
 | |
|   if ( adj_h )
 | |
|   {
 | |
|     r.left += lmp->rct.left;
 | |
|     r.right += lmp->rct.left;
 | |
|   }
 | |
| 
 | |
|   if ( adj_v )
 | |
|   {
 | |
|     lm_adj_v( lmp, r.top );
 | |
|     lm_adj_v( lmp, r.bottom );
 | |
|   }
 | |
| 
 | |
|   if ( adj_h )
 | |
|   {
 | |
|     BOOLEAN leftb,
 | |
|     rightb;
 | |
| 
 | |
|     leftb = lm_adj_h( lmp, &r.left );
 | |
|     rightb = lm_adj_h( lmp, &r.right );
 | |
|     if ( !leftb && !rightb )
 | |
|       return FALSE;
 | |
|   }
 | |
|   xi_offset_rect( &r, -lmp->list_obj->itf->v.itf->delta_x,
 | |
|                   -lmp->list_obj->itf->v.itf->delta_y );
 | |
|   return XinWindowPaintNeeds( lmp->win, &r );
 | |
| }
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| /*  calc_col_XinWindowPaintNeeds                                               */
 | |
| /* ------------------------------------------------------------------------- */
 | |
| static void
 | |
| calc_col_XinWindowPaintNeeds( LM_DATA * lmp, int first_col, int last_col,
 | |
|                               BOOLEAN update )
 | |
| {
 | |
|   int col;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
| 
 | |
| #if XIWS == XIWS_WM
 | |
|   NOREF( update );
 | |
| #endif
 | |
| 
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|     lmp->lm_column_data[col]->XinWindowPaintNeeds = FALSE;
 | |
|   for ( col = first_col; col <= last_col; ++col )
 | |
|   {
 | |
|     XinRect rct;
 | |
|     BOOLEAN rightb,
 | |
|     leftb;
 | |
| 
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( column_data->suppress_update_cells )
 | |
|       continue;
 | |
|     rct.left = lmp->rct.left + column_data->x_pix_pos;
 | |
|     rct.right = rct.left + column_data->pix_width +
 | |
|             2 * ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | |
|     rct.top = lmp->rct.top;
 | |
|     rct.bottom = lmp->rct.bottom;
 | |
|     column_data->column_rct = rct;
 | |
| #if XIWS != XIWS_WM
 | |
|     leftb = lm_adj_h( lmp, &rct.left );
 | |
|     rightb = lm_adj_h( lmp, &rct.right );
 | |
|     column_data->prct = rct;
 | |
|     if ( !leftb && !rightb )
 | |
|       column_data->XinWindowPaintNeeds = FALSE;
 | |
|     else
 | |
|     {
 | |
|       if ( update )
 | |
|       {
 | |
|         if ( xi_XinWindowPaintNeeds( lmp->win, &column_data->prct ) )
 | |
|           column_data->XinWindowPaintNeeds = TRUE;
 | |
|         else
 | |
|           column_data->XinWindowPaintNeeds = FALSE;
 | |
|       }
 | |
|       else
 | |
|         column_data->XinWindowPaintNeeds = TRUE;
 | |
|     }
 | |
| #else
 | |
|     leftb = lm_adj_h( lmp, &rct.left );
 | |
|     rightb = lm_adj_h( lmp, &rct.right );
 | |
|     column_data->prct = rct;
 | |
|     if ( !leftb && !rightb )
 | |
|       column_data->XinWindowPaintNeeds = FALSE;
 | |
|     else
 | |
|       column_data->XinWindowPaintNeeds = TRUE;
 | |
| #endif
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*********** draw row rules ***********/
 | |
| static void
 | |
| draw_row_rules( LM_DATA * lmp, int first_row_to_draw, int last_row_to_draw, BOOLEAN update )
 | |
| {
 | |
|   int r2,
 | |
|   first_row,
 | |
|   last_row;
 | |
|   int row,
 | |
|   actual_r,
 | |
|   hrule_h,
 | |
|   col;
 | |
|   XinPoint p;
 | |
|   XinRect r;
 | |
|   XinRect actual_rct = lmp->mlr;
 | |
| 
 | |
| #if XIWS != XIWS_WM
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = actual_rct.left + lmp->pixel_width;
 | |
|   else
 | |
|     actual_r = lmp->rct.right;
 | |
|   actual_rct.right = actual_r;
 | |
| #else
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = lmp->rct.left + lmp->pixel_width;
 | |
|   else
 | |
|     actual_r = lmp->rct.right;
 | |
|   actual_rct.right = actual_r;
 | |
| #endif
 | |
|   hrule_h = actual_r;
 | |
|   xi_set_clip( lmp->win, &actual_rct );
 | |
| 
 | |
|   if ( lmp->no_horz_lines )
 | |
|   {
 | |
|     XinPen back_cpen;
 | |
| 
 | |
|     back_cpen = black_cpen;
 | |
|     back_cpen.fore_color = lmp->back_color;
 | |
|     XinWindowPenSet( lmp->win, &back_cpen );
 | |
|   }
 | |
|   else
 | |
|   {
 | |
| #if XIWS != XIWS_WM
 | |
|     XinPen back_cpen;
 | |
| 
 | |
|     back_cpen = black_cpen;
 | |
|     back_cpen.fore_color = lmp->rule_color;
 | |
|     XinWindowPenSet( lmp->win, &back_cpen );
 | |
| #else
 | |
|     XinWindowPenSet( lmp->win, &black_cpen );
 | |
| #endif
 | |
|   }
 | |
|   r2 = lmp->rct.right - lmp->delta_x;
 | |
|   r2 = min( r2, hrule_h );
 | |
|   if ( r2 < hrule_h && lmp->no_vert_lines )
 | |
|     r2 -= 2;
 | |
| 
 | |
|   first_row = max( 0, lmp->first_fully_vis - 1 );
 | |
|   last_row = min( lmp->nbr_realized_rows, lmp->last_fully_vis + 1 );
 | |
| 
 | |
|   if ( lmp->update_rows_at_top )
 | |
|   {
 | |
|     XinRect row_rct;
 | |
|     int old_last_row = last_row;
 | |
| 
 | |
|     last_row = min( last_row, first_row + lmp->update_rows_at_top + 1 );
 | |
|     lm_get_row_rect( &row_rct, ( LM ) lmp, last_row );
 | |
|     row_rct.bottom = lmp->mlr.bottom - lmp->mlr.top;
 | |
|     if ( update && lm_XinWindowPaintNeeds( lmp, &row_rct, FALSE, TRUE ) )
 | |
|       last_row = old_last_row;
 | |
|   }
 | |
|   if ( lmp->update_rows_at_bottom )
 | |
|   {
 | |
|     XinRect row_rct;
 | |
|     int old_first_row = first_row;
 | |
| 
 | |
|     first_row = max( first_row, lmp->last_fully_vis - lmp->update_rows_at_bottom );
 | |
|     lm_get_row_rect( &row_rct, ( LM ) lmp, first_row );
 | |
|     row_rct.top = 0;
 | |
|     if ( update && lm_XinWindowPaintNeeds( lmp, &row_rct, FALSE, TRUE ) )
 | |
|       first_row = old_first_row;
 | |
|   }
 | |
| 
 | |
|   if ( first_row_to_draw != -1 )
 | |
|   {
 | |
|     first_row = max( first_row_to_draw - 1, first_row );
 | |
|     last_row = min( last_row_to_draw + 1, last_row );
 | |
|   }
 | |
| 
 | |
|   if ( lmp->no_horz_lines && !lmp->no_vert_lines )
 | |
|   {                             /* Draw between the vertical lines */
 | |
|     for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|       if ( !lmp->lm_column_data[col]->suppress_update_cells )
 | |
|       {
 | |
|         lm_get_rect( ( LM ) lmp, LM_COLUMN, col, &r );
 | |
|         if ( lmp->pixel_width != 0 && r.left > lmp->pixel_width )
 | |
|           break;
 | |
|         for ( row = first_row; row < last_row; row++ )
 | |
|         {
 | |
|           p.h = r.left;
 | |
|           p.v = lmp->pix_offsets[row] + lmp->pix_heights[row] - 1;
 | |
|           lm_move_to( lmp, p, TRUE, FALSE );
 | |
|           p.h = r.right;
 | |
|           lm_draw_line( lmp, p, TRUE, FALSE );
 | |
|         }
 | |
|       }
 | |
|   }
 | |
|   else
 | |
|   {                             /* Draw single lines all the way across the
 | |
|                                 * list */
 | |
|     r = lmp->rct;
 | |
|     for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|       if ( !lmp->lm_column_data[col]->suppress_update_cells )
 | |
|         break;
 | |
|     if ( col )
 | |
|       r.left = lmp->lm_column_data[col]->x_pix_pos;
 | |
| 
 | |
|     for ( row = first_row; row < last_row; ++row )
 | |
|     {
 | |
|       p.h = r.left;
 | |
|       p.v = lmp->pix_offsets[row] + lmp->pix_heights[row] - 1;
 | |
|       lm_move_to( lmp, p, TRUE, FALSE );
 | |
|       p.h = r2;
 | |
|       lm_draw_line( lmp, p, TRUE, FALSE );
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| static void
 | |
| draw_background_rects( LM_DATA * lmp, XinWindow win, ROW_INFO * row_info,
 | |
|                       int first_row, int last_row )
 | |
| {
 | |
|   XinColor last_brush_color;
 | |
|   int col,
 | |
|   row;
 | |
|   int focus_row,
 | |
|   focus_column;
 | |
|   BOOLEAN v_scrolled;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
|   ROW_INFO *ri;
 | |
|   extern XinPen hollow_cpen;
 | |
|   BOOLEAN list_has_focus;
 | |
| 
 | |
|   list_has_focus = lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | |
| 
 | |
|   /* draw exception rectangles - draw enabled, not selected cells */
 | |
|   last_brush_color = 0xFFFFFFFFL;       /* this is a value that will never be
 | |
|                                         * used for an actual color, so that
 | |
|                                         * the background color will be set
 | |
|                                         * properly the first time through */
 | |
|   XinWindowPenSet( win, &hollow_cpen );
 | |
|   XinWindowDrawModeSet( win, XinDrawModeCopy );
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       XinColor brush_color;
 | |
|       LM_CELL_DATA *cell_data = &lmp->cell_data[row][col];
 | |
|       BOOLEAN do_draw;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       if ( list_has_focus && !v_scrolled && col == focus_column && row == focus_row )
 | |
|         continue;
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       do_draw = lm_focus_cell_has( lmp, row, col, FALSE );
 | |
|       if ( ( CELL_IS_ENABLED( lmp, row, col ) ) && !( CELL_IS_SELECTED( lmp, row, col ) ) )
 | |
|         do_draw = TRUE;
 | |
|       if ( do_draw )
 | |
|       {
 | |
|         XinRect rct;
 | |
| 
 | |
|         brush_color = lmp->back_color;
 | |
|         if ( cell_data->back_color )
 | |
|           brush_color = cell_data->back_color;
 | |
| /*
 | |
| TO OPTIMIZE BACKGROUND DRAWING, USE NEXT TWO LINES
 | |
|                   if (brush_color == lmp->back_color)
 | |
|                         continue;
 | |
| */
 | |
|         if ( brush_color != last_brush_color )
 | |
|         {
 | |
|           XinBrush cbrush;
 | |
| 
 | |
|           cbrush.fore_color = brush_color;
 | |
|           cbrush.pattern = XinBrushSolid;
 | |
|           XinWindowBrushSet( win, &cbrush );
 | |
|         }
 | |
|         rct = column_data->prct;
 | |
|         rct.top = ri->prct.top;
 | |
|         rct.bottom = ri->prct.bottom;
 | |
|         xi_draw_rect( win, &rct );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* draw exception rectangles - draw disabled, not selected cells */
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
| 
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       XinColor brush_color;
 | |
|       LM_CELL_DATA *cell_data = &lmp->cell_data[row][col];
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       if ( list_has_focus && !v_scrolled && col == focus_column && row == focus_row )
 | |
|         continue;
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       if ( !( CELL_IS_ENABLED( lmp, row, col ) ) && !( CELL_IS_SELECTED( lmp, row, col ) ) )
 | |
|       {
 | |
|         XinRect rct;
 | |
| 
 | |
|         brush_color = lmp->disabled_back_color;
 | |
| /*
 | |
| TO OPTIMIZE BACKGROUND DRAWING, USE NEXT TWO LINES
 | |
|                   if (brush_color == lmp->back_color)
 | |
|                         continue;
 | |
| */
 | |
|         if ( brush_color != last_brush_color )
 | |
|         {
 | |
|           XinBrush cbrush;
 | |
| 
 | |
|           cbrush.fore_color = brush_color;
 | |
|           cbrush.pattern = XinBrushSolid;
 | |
|           XinWindowBrushSet( win, &cbrush );
 | |
|         }
 | |
|         rct = column_data->prct;
 | |
|         rct.top = ri->prct.top;
 | |
|         rct.bottom = ri->prct.bottom;
 | |
|         xi_draw_rect( win, &rct );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* draw exception rectangles - draw selected cells */
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
| 
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       XinColor brush_color;
 | |
|       LM_CELL_DATA *cell_data = &lmp->cell_data[row][col];
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       if ( list_has_focus && !v_scrolled && col == focus_column && row == focus_row )
 | |
|         continue;
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       if ( CELL_IS_SELECTED( lmp, row, col ) && !lm_focus_cell_has( lmp, row, col, FALSE ) )
 | |
|       {
 | |
|         XinRect rct;
 | |
| 
 | |
|         if ( CELL_IS_ENABLED( lmp, row, col ) )
 | |
|         {
 | |
|           brush_color = lmp->enabled_color;
 | |
|           if ( lmp->row_colors[row] )
 | |
|             brush_color = lmp->row_colors[row];
 | |
|           if ( cell_data->color )
 | |
|             brush_color = cell_data->color;
 | |
|         }
 | |
|         else
 | |
|           brush_color = lmp->disabled_color;
 | |
|         if ( cell_data->back_color && lmp->retain_back_color_on_select )
 | |
|           brush_color = cell_data->back_color;
 | |
| /*
 | |
| TO OPTIMIZE BACKGROUND DRAWING, USE NEXT TWO LINES
 | |
|                   if (brush_color == lmp->back_color)
 | |
|                         continue;
 | |
| */
 | |
|         if ( brush_color != last_brush_color )
 | |
|         {
 | |
|           XinBrush cbrush;
 | |
| 
 | |
|           cbrush.fore_color = brush_color;
 | |
|           cbrush.pattern = XinBrushSolid;
 | |
|           XinWindowBrushSet( win, &cbrush );
 | |
|         }
 | |
|         rct = column_data->prct;
 | |
|         rct.top = ri->prct.top;
 | |
|         rct.bottom = ri->prct.bottom;
 | |
|         xi_draw_rect( win, &rct );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
| #if XIWS != XIWS_WM
 | |
|   /* draw 3d rectangles */
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
| 
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       XinRect rct;
 | |
|       LM_CELL_DATA *cell_data = &lmp->cell_data[row][col];
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       if ( list_has_focus && !v_scrolled && col == focus_column && row == focus_row )
 | |
|         continue;
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
| 
 | |
|       rct = column_data->prct;
 | |
|       rct.top = ri->prct.top;
 | |
|       rct.bottom = ri->prct.bottom;
 | |
|       if ( column_data->column_well || column_data->column_platform )
 | |
|       {
 | |
|         const XinColor color_light = aga_get_pref(AGA_PREF_BTN_COLOR_LIGHT);
 | |
|         const XinColor color_ctrl = aga_get_pref(AGA_PREF_BTN_COLOR_CTRL);
 | |
|         const XinColor color_dark = aga_get_pref(AGA_PREF_BTN_COLOR_DARK);
 | |
| 
 | |
|         xi_draw_3d_rect( win, &rct, ( BOOLEAN ) ( CELL_IS_SELECTED( lmp, row, col ) ? !column_data->column_well :
 | |
|                                   column_data->column_well ), 2, color_light, color_ctrl, color_dark );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| #else
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
| 
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       XinColor brush_color;
 | |
|       LM_CELL_DATA *cell_data = &lmp->cell_data[row][col];
 | |
|       BOOLEAN do_draw;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       if ( list_has_focus && !v_scrolled && col == focus_column && row == focus_row )
 | |
|         continue;
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       do_draw = lm_focus_cell_has( lmp, row, col, FALSE );
 | |
|       if ( ( CELL_IS_ENABLED( lmp, row, col ) ) && !( CELL_IS_SELECTED( lmp, row, col ) ) )
 | |
|         do_draw = TRUE;
 | |
|       if ( do_draw )
 | |
|       {
 | |
|         if ( column_data->column_well || column_data->column_platform )
 | |
|         {
 | |
|           XinRect rct;
 | |
| 
 | |
|           brush_color = lmp->back_color;
 | |
|           if ( cell_data->back_color )
 | |
|             brush_color = cell_data->back_color;
 | |
|           if ( brush_color != last_brush_color )
 | |
|           {
 | |
|             XinBrush cbrush;
 | |
| 
 | |
|             cbrush.color = brush_color;
 | |
|             cbrush.pat = XinPatternSolid;
 | |
|             XinWindowPaintBrushSet( win, &cbrush );
 | |
|           }
 | |
|           rct = column_data->prct;
 | |
|           rct.top = ri->prct.top;
 | |
|           rct.bottom = ri->prct.bottom;
 | |
|           xi_draw_rect( win, &rct );
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| #endif
 | |
|   if ( list_has_focus && !v_scrolled && focus_row >= first_row && focus_row <= last_row )
 | |
|   {
 | |
|     XinColor brush_color;
 | |
|     LM_CELL_DATA *cell_data = &lmp->cell_data[focus_row][focus_column];
 | |
|     XinBrush cbrush;
 | |
|     XinRect rct,
 | |
|     row_rect;
 | |
| 
 | |
|     column_data = lmp->lm_column_data[focus_column];
 | |
|     if ( column_data->XinWindowPaintNeeds )
 | |
|     {
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, focus_row, focus_column, FALSE );
 | |
|       brush_color = lmp->active_back_color; // Big brained XI put here lmp->back_color!
 | |
|       if ( cell_data->back_color )
 | |
|         brush_color = cell_data->back_color;
 | |
| 
 | |
|       cbrush.fore_color = brush_color;
 | |
|       cbrush.pattern = XinBrushSolid;
 | |
|       XinWindowBrushSet( win, &cbrush );
 | |
|       rct = column_data->prct;
 | |
|       lm_get_row_rect( &row_rect, ( LM ) lmp, focus_row );
 | |
| #if XIWS != XIWS_WM
 | |
|       row_rect.bottom--;
 | |
|       if ( row_rect.bottom < row_rect.top )
 | |
|         row_rect.bottom = row_rect.top;
 | |
| #endif
 | |
|       lm_adj_v( lmp, row_rect.top );
 | |
|       lm_adj_v( lmp, row_rect.bottom );
 | |
|       rct.top = row_rect.top;
 | |
|       rct.bottom = row_rect.bottom;
 | |
| #if XIWS == XIWS_MAC || XIWS == XIWS_XM  || XIWS == XIWS_WXGTK
 | |
|       if ( cell_data->xi_text )
 | |
|         xi_text_rect_get_adjusted( cell_data->xi_text, &rct );
 | |
| #endif
 | |
|       xi_draw_rect( win, &rct );
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| static void
 | |
| draw_cell_icons( LM_DATA * lmp, XinWindow win, ROW_INFO * row_info,
 | |
|                 int first_row, int last_row )
 | |
| {
 | |
|   int col,
 | |
|   row;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
|   ROW_INFO *ri;
 | |
|   XinDrawTools ct;
 | |
|   XinColor last_fore_color,
 | |
|   last_back_color;
 | |
| 
 | |
|   XinWindowDrawToolsGet( win, &ct );
 | |
|   ct.text_fore_color = lmp->enabled_color;
 | |
|   ct.text_back_color = lmp->back_color;
 | |
|   ct.opaque_text = TRUE;
 | |
|   XinWindowDrawToolsSet( win, &ct );
 | |
|   last_back_color = 0L;
 | |
|   last_fore_color = 0L;
 | |
|   /* draw cell icons */
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
| 
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       XinRect rct;
 | |
|       LM_CELL_DATA *cell_data = &lmp->cell_data[row][col];
 | |
|       XinColor fore_color,
 | |
|       back_color;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       rct = column_data->prct;
 | |
|       rct.top = ri->rct.top;
 | |
|       rct.bottom = ri->rct.bottom;
 | |
|       lm_adj_v( lmp, rct.top );
 | |
|       lm_adj_v( lmp, rct.bottom );
 | |
|       {
 | |
|         XinRect mlr = lmp->mlr;
 | |
| 
 | |
|         if ( lmp->pixel_width )
 | |
|           mlr.right = mlr.left + lmp->pixel_width + BORDER_WIDTH;
 | |
|         xi_rect_intersect( &mlr, &mlr, &rct );
 | |
|         xi_set_clip( win, &mlr );
 | |
|       }
 | |
|       fore_color = ct.text_fore_color;
 | |
|       back_color = ct.text_back_color;
 | |
|       if ( lmp->row_colors[row] )
 | |
|         fore_color = lmp->row_colors[row];
 | |
|       if ( cell_data->color )
 | |
|         fore_color = cell_data->color;
 | |
|       if ( cell_data->back_color )
 | |
|       {
 | |
|         back_color = cell_data->back_color;
 | |
|       }
 | |
|       if ( cell_data->bitmap != NULL && !cell_data->button_full_cell )
 | |
|       {
 | |
|         if ( lmp->no_horz_lines )
 | |
|           rct.bottom++;
 | |
|         if ( lmp->no_vert_lines )
 | |
|           rct.right++;
 | |
|         xi_bitmap_draw( cell_data->bitmap, win, &rct, &rct, FALSE );
 | |
|         continue;
 | |
|       }
 | |
|       if ( !cell_data->icon_rid )
 | |
|         continue;
 | |
|       if ( cell_data->button_full_cell )
 | |
|         continue;
 | |
|       if ( fore_color != last_fore_color || back_color != last_back_color )
 | |
|         xi_draw_icon( win, rct.left, rct.top, cell_data->icon_rid, fore_color, back_color );
 | |
|       else
 | |
|         xi_draw_icon( win, rct.left, rct.top, cell_data->icon_rid, 0L, 0L );
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| static void
 | |
| get_cell_color( LM_DATA * lmp, LM_CELL_DATA * cell_data, LM_COLUMN_DATA * column_data,
 | |
|                 int row, int col, XinColor * color, XinColor * back_color )
 | |
| {
 | |
|   BOOLEAN list_enabled,
 | |
|   col_enabled,
 | |
|   enabled;
 | |
|   XinColor temp_color;
 | |
| 
 | |
|   list_enabled = ( lmp->attrib & XI_ATR_ENABLED ) != 0;
 | |
|   col_enabled = ( lmp->lm_column_data[col]->attrib & XI_ATR_ENABLED ) != 0;
 | |
|   enabled = list_enabled && col_enabled;
 | |
|   if ( CELL_IS_SELECTED( lmp, row, col ) )
 | |
|   {
 | |
|     XinColor enabled_back_color,
 | |
|     enabled_color;
 | |
|     XinColor disabled_back_color,
 | |
|     disabled_color;
 | |
| 
 | |
|     /* determine enabled_back_color */
 | |
|     enabled_back_color = lmp->back_color;
 | |
|     if ( cell_data->back_color )
 | |
|       enabled_back_color = cell_data->back_color;
 | |
| 
 | |
|     /* determine enabled_color */
 | |
|     enabled_color = lmp->enabled_color;
 | |
|     temp_color = lmp->row_colors[row];
 | |
|     if ( temp_color )
 | |
|       enabled_color = temp_color;
 | |
|     if ( cell_data->color )
 | |
|       enabled_color = cell_data->color;
 | |
| 
 | |
|     /* determine disabled colors */
 | |
|     disabled_back_color = lmp->disabled_back_color;
 | |
|     disabled_color = lmp->disabled_color;
 | |
| 
 | |
|     if ( enabled )
 | |
|     {
 | |
|       if ( lmp->retain_back_color_on_select && cell_data->back_color )
 | |
|       {
 | |
|         *color = enabled_color;
 | |
|         *back_color = enabled_back_color;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         *color = enabled_back_color;
 | |
|         *back_color = enabled_color;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       *color = disabled_back_color;
 | |
|       *back_color = disabled_color;
 | |
|     }
 | |
| 
 | |
|     if ( column_data->column_well || column_data->column_platform )
 | |
|       *color = lmp->enabled_color;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     if ( enabled )
 | |
|     {
 | |
|       *color = lmp->enabled_color;
 | |
|       temp_color = lmp->row_colors[row];
 | |
|       if ( temp_color )
 | |
|         *color = temp_color;
 | |
|       if ( cell_data->color )
 | |
|         *color = cell_data->color;
 | |
|       *back_color = lmp->back_color;
 | |
|       if ( cell_data->back_color )
 | |
|         *back_color = cell_data->back_color;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       *color = lmp->disabled_color;
 | |
|       *back_color = lmp->disabled_back_color;
 | |
|     }
 | |
|   }
 | |
|   if ( column_data->wrap_text && !cell_data->back_color
 | |
|       && ( column_data->column_platform || column_data->column_well ) )
 | |
|     *back_color = xi_get_pref( XI_PREF_COLOR_CTRL );
 | |
|   else if ( *color == XI_COLOR_BLACK )
 | |
|     *color = 0L;
 | |
| }
 | |
| 
 | |
| static void
 | |
| draw_all_cell_text( LM_DATA * lmp, XinWindow win, ROW_INFO * row_info,
 | |
|             int col_offset, int first_row, int last_row, XinRect * list_rect,
 | |
|                     BOOLEAN in_update_event )
 | |
| {
 | |
|   XinDrawTools ctools;
 | |
|   int row,
 | |
|   col;
 | |
|   ROW_INFO *ri;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
|   int leading,
 | |
|   ascent,
 | |
|   descent;
 | |
|   BOOLEAN have_last_font;
 | |
|   BOOLEAN have_set_height = FALSE;
 | |
|   XinFont *last_font;
 | |
| 
 | |
|   ctools = lm_normal_ctools;
 | |
| 
 | |
|   /* the following two lines must come before the XinWindowFontSet, because in
 | |
|   * R3, setting the draw ctools also sets the font. */
 | |
|   ctools.text_fore_color = XI_COLOR_BLACK;
 | |
| #if XIWS == XIWS_WM
 | |
|   ctools.BackColor = lmp->back_color;
 | |
| #endif
 | |
|   XinWindowDrawToolsSet( win, &ctools );
 | |
| 
 | |
|   lmp->cur_font = lmp->font;
 | |
|   XinFontMetricsGet( lmp->cur_font, &leading, &ascent, &descent );
 | |
| 
 | |
| /*
 | |
| draw:
 | |
| font: default
 | |
| wrapped: no
 | |
| color: black
 | |
| 
 | |
| one of the slowest operations is setting colors, therefore we only draw text
 | |
| of the most common color.  after this loop, we draw text of other colors.
 | |
| because this loop draws most of the cells, don't set any colors within
 | |
| this loop.
 | |
| 
 | |
| color is set to black just above.
 | |
| */
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     int col_offset;
 | |
|     XinRect clip_rect,
 | |
|     rect;
 | |
| 
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
| 
 | |
|     if ( column_data->wrap_text )
 | |
|       continue;
 | |
|     rect = column_data->prct;
 | |
|     col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | |
|     rect.left += col_offset;
 | |
|     rect.right -= col_offset;
 | |
|     if ( !xi_rect_intersect( &clip_rect, &rect, list_rect ) )
 | |
|       continue;
 | |
|     xi_set_clip( win, &clip_rect );
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       LM_CELL_DATA *cell_data;
 | |
|       XinColor color,
 | |
|       back_color;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       cell_data = &lmp->cell_data[row][col];
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       if ( cell_data->font )
 | |
|         continue;
 | |
|       if ( cell_data->icon_rid || cell_data->bitmap != NULL )
 | |
|         continue;
 | |
|       if ( cell_data->button_full_cell )
 | |
|         continue;
 | |
|       if ( lmp->set_heights[row] )
 | |
|       {
 | |
|         have_set_height = TRUE;
 | |
|         continue;
 | |
|       }
 | |
|       get_cell_color( lmp, cell_data, column_data, row, col, &color, &back_color );
 | |
|       if ( color )
 | |
|         continue;
 | |
|       draw_cell_text( lmp, cell_data, column_data,
 | |
|                       row, col, col_offset, leading, ascent,
 | |
|                       descent, color, back_color, FALSE );
 | |
|     }
 | |
|   }
 | |
| 
 | |
| /*
 | |
| draw:
 | |
| font: default
 | |
| wrapped: no
 | |
| color: not black
 | |
| */
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     XinRect clip_rect;
 | |
| 
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
|     if ( column_data->wrap_text )
 | |
|       continue;
 | |
|     if ( !xi_rect_intersect( &clip_rect, &column_data->prct, list_rect ) )
 | |
|       continue;
 | |
|     xi_set_clip( win, &clip_rect );
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       LM_CELL_DATA *cell_data;
 | |
|       XinColor color,
 | |
|       back_color;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       cell_data = &lmp->cell_data[row][col];
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       if ( cell_data->font )
 | |
|         continue;
 | |
|       if ( cell_data->icon_rid || cell_data->bitmap != NULL )
 | |
|         continue;
 | |
|       if ( cell_data->button_full_cell )
 | |
|         continue;
 | |
|       if ( lmp->set_heights[row] )
 | |
|       {
 | |
|         have_set_height = TRUE;
 | |
|         continue;
 | |
|       }
 | |
|       get_cell_color( lmp, cell_data, column_data, row, col, &color, &back_color );
 | |
|       if ( !color )
 | |
|         continue;
 | |
|       XinWindowColorTextForeSet( win, color );
 | |
| #if XIWS == XIWS_WM
 | |
|       XinWindowColorTextBackSet( win, lmp->enabled_color );
 | |
| #endif
 | |
|       draw_cell_text( lmp, cell_data, column_data, row, col, col_offset,
 | |
|                       leading, ascent, descent, color, back_color, FALSE );
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 
 | |
| /*
 | |
| draw:
 | |
| font: default
 | |
| wrapped: yes
 | |
| color: black
 | |
| 
 | |
| this needs to be a separate loop from above, because this loop sets the
 | |
| clipping region for each cell, and the above loop sets the clipping region
 | |
| for each column.
 | |
| */
 | |
|   XinWindowColorTextForeSet( win, XI_COLOR_BLACK );
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
|     if ( !column_data->wrap_text && !have_set_height )
 | |
|       continue;
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       LM_CELL_DATA *cell_data;
 | |
|       XinColor color,
 | |
|       back_color;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       if ( lmp->row_colors[row] )
 | |
|         continue;
 | |
|       cell_data = &lmp->cell_data[row][col];
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       if ( cell_data->font )
 | |
|         continue;
 | |
|       if ( cell_data->icon_rid || cell_data->bitmap != NULL )
 | |
|         continue;
 | |
|       if ( cell_data->button_full_cell )
 | |
|         continue;
 | |
|       if ( !column_data->wrap_text && !lmp->set_heights[row] )
 | |
|         continue;
 | |
|       get_cell_color( lmp, cell_data, column_data, row, col, &color, &back_color );
 | |
|       if ( color )
 | |
|         continue;
 | |
|       draw_cell_text( lmp, cell_data, column_data,
 | |
|                       row, col, col_offset, leading, ascent,
 | |
|                       descent, color, back_color, TRUE );
 | |
|     }
 | |
|   }
 | |
| 
 | |
| /*
 | |
| draw:
 | |
| font: default
 | |
| wrapped: yes
 | |
| color: not black
 | |
| 
 | |
| this needs to be a separate loop from above, because this loop sets the
 | |
| colors for each cell, and the above loop only draws black.
 | |
| */
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
|     if ( !column_data->wrap_text && !have_set_height )
 | |
|       continue;
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       LM_CELL_DATA *cell_data;
 | |
|       XinColor color,
 | |
|       back_color;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       cell_data = &lmp->cell_data[row][col];
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       if ( cell_data->font )
 | |
|         continue;
 | |
|       if ( cell_data->icon_rid || cell_data->bitmap != NULL )
 | |
|         continue;
 | |
|       if ( cell_data->button_full_cell )
 | |
|         continue;
 | |
|       if ( !column_data->wrap_text && !lmp->set_heights[row] )
 | |
|         continue;
 | |
|       get_cell_color( lmp, cell_data, column_data, row, col, &color, &back_color );
 | |
|       if ( !color )
 | |
|         continue;
 | |
|       XinWindowColorTextForeSet( win, color );
 | |
|       draw_cell_text( lmp, cell_data, column_data,
 | |
|                       row, col, col_offset, leading, ascent,
 | |
|                       descent, color, back_color, TRUE );
 | |
|     }
 | |
|   }
 | |
| 
 | |
| /*
 | |
| draw:
 | |
| font: not default
 | |
| wrapped: either yes or no
 | |
| color: any
 | |
| 
 | |
| draw all of the rest of the text
 | |
| */
 | |
|   have_last_font = FALSE;
 | |
|   last_font = NULL;
 | |
|   for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[col];
 | |
|     if ( !column_data->XinWindowPaintNeeds )
 | |
|       continue;
 | |
|     for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|     {
 | |
|       LM_CELL_DATA *cell_data;
 | |
|       XinColor color,
 | |
|       back_color;
 | |
|       BOOLEAN need_to_set;
 | |
| 
 | |
|       if ( !ri->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       cell_data = &lmp->cell_data[row][col];
 | |
|       if ( !cell_data->valid_data )
 | |
|         do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       if ( !cell_data->font )
 | |
|         continue;
 | |
|       if ( cell_data->icon_rid || cell_data->bitmap != NULL )
 | |
|         continue;
 | |
|       if ( cell_data->button_full_cell )
 | |
|         continue;
 | |
|       need_to_set = FALSE;
 | |
|       if ( !have_last_font )
 | |
|         need_to_set = TRUE;
 | |
|       if ( have_last_font && !font_compare( last_font, cell_data->font ) )
 | |
|         need_to_set = TRUE;
 | |
|       if ( need_to_set )
 | |
|       {
 | |
|         int char_width;
 | |
| 
 | |
|         lmp->cur_font = cell_data->font;
 | |
|         xi_get_font_metrics_font( cell_data->font, &leading, &ascent,
 | |
|                                   &descent, &char_width );
 | |
|         last_font = cell_data->font;
 | |
|         have_last_font = TRUE;
 | |
|       }
 | |
|       get_cell_color( lmp, cell_data, column_data, row, col, &color, &back_color );
 | |
|       XinWindowColorTextForeSet( win, color );
 | |
| 
 | |
|       draw_cell_text( lmp, cell_data, column_data,
 | |
|                       row, col, col_offset, leading, ascent,
 | |
|                       descent, color, back_color, TRUE );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if ( lm_focus_list_has( lmp ) )
 | |
|   {
 | |
|     int focus_row,
 | |
|     focus_column;
 | |
|     BOOLEAN v_scrolled;
 | |
| 
 | |
|     if ( lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled ) )
 | |
|       if ( lm_focus_cell_has( lmp, focus_row, focus_column, v_scrolled ) )
 | |
|         set_focus_cell_rct( lmp, focus_row, focus_column, in_update_event );
 | |
|   }
 | |
| }
 | |
| 
 | |
| #if XIWS != XIWS_WM
 | |
| static void
 | |
| draw_row_focus_border( LM_DATA * lmp, ROW_INFO * row_info, int first_row, int last_row )
 | |
| {
 | |
|   int col,
 | |
|   row;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
|   ROW_INFO *ri;
 | |
|   XinPen color_cpen;
 | |
|   XinPen rule_cpen;
 | |
|   BOOLEAN last_was_rule = TRUE;
 | |
|   XinRect mr;
 | |
| 
 | |
|   if ( !lmp->row_focus_border )
 | |
|     return;
 | |
|   color_cpen.width = 1;
 | |
|   color_cpen.fore_color = lmp->row_focus_border_color;
 | |
|   color_cpen.pattern = XinPenSolid;
 | |
|   if ( lmp->no_horz_lines )
 | |
|   {
 | |
|     rule_cpen = black_cpen;
 | |
|     rule_cpen.fore_color = lmp->back_color;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     rule_cpen.width = 1;
 | |
|     rule_cpen.fore_color = lmp->rule_color;
 | |
|     rule_cpen.pattern = XinPenSolid;
 | |
|   }
 | |
|   XinWindowPenSet( lmp->win, &rule_cpen );
 | |
|   {
 | |
|     mr = lmp->mlr;
 | |
|     if ( lmp->pixel_width )
 | |
|       mr.right = mr.left + lmp->pixel_width + BORDER_WIDTH;
 | |
|     xi_set_clip( lmp->win, &mr );
 | |
|   }
 | |
|   for ( row = first_row, ri = &row_info[first_row]; row <= last_row; ++row, ++ri )
 | |
|   {
 | |
|     XinRect rct;
 | |
|     XinPoint p;
 | |
|     XinWindow win = lmp->win;
 | |
|     BOOLEAN row_has_focus = lm_row_has_focus( lmp, row, FALSE );
 | |
| 
 | |
|     if ( !ri->XinWindowPaintNeeds )
 | |
|       continue;
 | |
|     if ( row_has_focus )
 | |
|     {
 | |
|       if ( last_was_rule )
 | |
|       {
 | |
|         XinWindowPenSet( lmp->win, &color_cpen );
 | |
|         last_was_rule = FALSE;
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       if ( !last_was_rule )
 | |
|       {
 | |
|         XinWindowPenSet( lmp->win, &rule_cpen );
 | |
|         last_was_rule = TRUE;
 | |
|       }
 | |
|     }
 | |
|     for ( col = 0; col < lmp->nbr_columns; ++col )
 | |
|     {
 | |
|       column_data = lmp->lm_column_data[col];
 | |
|       if ( !column_data->XinWindowPaintNeeds )
 | |
|         continue;
 | |
|       rct = column_data->prct;
 | |
|       rct.top = ri->prct.top;
 | |
|       rct.bottom = ri->prct.bottom;
 | |
| 
 | |
|       /* draw top line */
 | |
|       p.h = rct.left;
 | |
|       p.v = rct.top - 1;
 | |
|       xi_move_to( win, p );
 | |
|       p.h = rct.right;
 | |
|       xi_draw_line( win, p );
 | |
| 
 | |
|       if ( row_has_focus )
 | |
|       {
 | |
|         /* draw next line down */
 | |
|         p.v++;
 | |
|         p.h = rct.left;
 | |
|         xi_move_to( win, p );
 | |
|         p.h = rct.right;
 | |
|         xi_draw_line( win, p );
 | |
|       }
 | |
| 
 | |
|       /* draw bottom line */
 | |
|       p.h = rct.left;
 | |
|       p.v = rct.bottom;
 | |
|       xi_move_to( win, p );
 | |
|       p.h = rct.right;
 | |
|       xi_draw_line( win, p );
 | |
| 
 | |
|       if ( row_has_focus )
 | |
|       {
 | |
|         /* draw line above bottom line */
 | |
|         p.v--;
 | |
|         p.h = rct.left;
 | |
|         xi_move_to( win, p );
 | |
|         p.h = rct.right;
 | |
|         xi_draw_line( win, p );
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| /*  draw_cell_focus_border                                                   */
 | |
| /* ------------------------------------------------------------------------- */
 | |
| static void
 | |
| draw_cell_focus_border( LM_DATA * lmp )
 | |
| {
 | |
|   XinColor border_color;
 | |
|   XinRect rct,
 | |
|   row_rect;
 | |
|   XinDrawTools dt;
 | |
|   int focus_row,
 | |
|   focus_column;
 | |
|   BOOLEAN v_scrolled;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
| 
 | |
|   if ( !lm_focus_list_has( lmp ) )
 | |
|     return;
 | |
|   lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | |
|   if (v_scrolled)
 | |
|     return;
 | |
|   column_data = lmp->lm_column_data[focus_column];
 | |
|   if ( !( column_data->attrib & XI_ATR_FOCUSBORDER ) )
 | |
|     return;
 | |
|   rct = column_data->prct;
 | |
|   lm_get_row_rect( &row_rect, ( LM ) lmp, focus_row );
 | |
| #if XIWS != XIWS_WM
 | |
|   row_rect.bottom--;
 | |
|   if ( row_rect.bottom < row_rect.top )
 | |
|     row_rect.bottom = row_rect.top;
 | |
| #endif
 | |
|   lm_adj_v( lmp, row_rect.top );
 | |
|   lm_adj_v( lmp, row_rect.bottom );
 | |
|   rct.top = row_rect.top;
 | |
|   rct.bottom = row_rect.bottom;
 | |
|   border_color = lmp->enabled_color;
 | |
| 
 | |
|   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( lmp->win, &dt );
 | |
|   xi_draw_rect( lmp->win, &rct );
 | |
| }
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| /*  draw_cell_block                                                          */
 | |
| /* ------------------------------------------------------------------------- */
 | |
| static void
 | |
| draw_cell_block( LM_DATA * lmp, int first_row, int last_row,
 | |
|                 ROW_INFO * row_info, BOOLEAN in_update_event )
 | |
| {
 | |
|   XinWindow win = lmp->win;
 | |
|   XinRect actual_rct = lmp->mlr;
 | |
|   int actual_r;
 | |
|   int col_offset;
 | |
| 
 | |
|   col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | |
| 
 | |
| #if XIWS != XIWS_WM
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = lmp->mlr.left + lmp->pixel_width;
 | |
|   else
 | |
|     actual_r = lmp->mlr.right;
 | |
|   actual_rct.right = actual_r;
 | |
| #else
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = lmp->mlr.left + lmp->pixel_width;
 | |
|   else
 | |
|     actual_r = lmp->mlr.right;
 | |
|   actual_rct.right = actual_r;
 | |
| #endif
 | |
| 
 | |
|   xi_set_clip( win, &actual_rct );
 | |
| 
 | |
|   /* draw backgrounds of cells */
 | |
|   draw_background_rects( lmp, win, row_info, first_row, last_row );
 | |
| 
 | |
|   /* draw all of the text in the cells */
 | |
|   draw_all_cell_text( lmp, win, row_info, col_offset, first_row, last_row,
 | |
|                       &actual_rct, in_update_event );
 | |
| 
 | |
|   /* draw cell buttons */
 | |
|   draw_cell_buttons( lmp, row_info, first_row, last_row, in_update_event );
 | |
| 
 | |
| #if XIWS != XIWS_WM
 | |
|   draw_row_rules( lmp, first_row, last_row, FALSE );
 | |
| #endif
 | |
| 
 | |
|   draw_cell_icons( lmp, win, row_info, first_row, last_row );
 | |
| 
 | |
| #if XIWS != XIWS_WM
 | |
|   draw_row_focus_border( lmp, row_info, first_row, last_row );
 | |
| #endif
 | |
|   draw_cell_focus_border( lmp );
 | |
| }
 | |
| 
 | |
| /* ------------------------------------------------------------------------- */
 | |
| /*  draw_cell_range                                                          */
 | |
| /* ------------------------------------------------------------------------- */
 | |
| void
 | |
| draw_cell_range( LM_DATA * lmp, int first_row, int last_row,
 | |
|                 int first_col, int last_col,
 | |
|                 BOOLEAN in_event_update )
 | |
| {
 | |
|   int row,
 | |
|   col;
 | |
|   ROW_INFO *row_info;
 | |
|   ROW_INFO *row_ptr;
 | |
| 
 | |
|   if ( lmp->list_obj->nbr_children <= 0 )
 | |
|     return;
 | |
|   if ( xi_get_attrib( lmp->list_obj ) & XI_ATR_VISIBLE )
 | |
|   {
 | |
|     row_info = ( ROW_INFO * ) XinMemoryAlloc( sizeof( ROW_INFO ) * ( last_row + 1 ) );
 | |
|     for ( row = first_row, row_ptr = row_info + first_row; row <= last_row;
 | |
|           ++row, ++row_ptr )
 | |
|     {
 | |
|       lm_get_row_rect( &row_ptr->rct, ( LM ) lmp, row );
 | |
|       /* don't need to test for the rule, it is drawn elsewhere */
 | |
| #if XIWS != XIWS_WM
 | |
|       row_ptr->rct.bottom--;
 | |
|       if ( row_ptr->rct.bottom < row_ptr->rct.top )
 | |
|         row_ptr->rct.bottom = row_ptr->rct.top;
 | |
| #endif
 | |
|       row_ptr->prct = row_ptr->rct;
 | |
|       lm_adj_v( lmp, row_ptr->prct.top );
 | |
|       lm_adj_v( lmp, row_ptr->prct.bottom );
 | |
|       if ( in_event_update )
 | |
|       {
 | |
|         if ( lm_XinWindowPaintNeeds( lmp, &row_ptr->rct, FALSE, TRUE ) )
 | |
|           row_ptr->XinWindowPaintNeeds = TRUE;
 | |
|         else
 | |
|           row_ptr->XinWindowPaintNeeds = FALSE;
 | |
|       }
 | |
|       else
 | |
|         row_ptr->XinWindowPaintNeeds = TRUE;
 | |
|     }
 | |
| 
 | |
|     /* force cell requests for visible cells - makes it draw nicer */
 | |
|     /* This used to be for columns with suppress_update_cells, but now applies to all */
 | |
|     /* Used to have the following line as a condition for the "for" loop: */
 | |
|     /* if ( lmp->lm_column_data[col]->suppress_update_cells ) */
 | |
|     for ( row = first_row; row <= last_row; ++row )
 | |
|     {
 | |
| 	    for ( col = first_col; col <= last_col; ++col )
 | |
| 		  {
 | |
|         LM_CELL_DATA *cell_data;
 | |
| 
 | |
|         cell_data = &( lmp->cell_data[row][col] );
 | |
|         if ( !cell_data->valid_data )
 | |
|           do_lm_cb_text( lmp, row, col, FALSE );
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     /* determine which columns need to be updated */
 | |
|     calc_col_XinWindowPaintNeeds( lmp, first_col, last_col, in_event_update );
 | |
| 
 | |
|     /* at this point, we should never need to call lm_XinWindowPaintNeeds again
 | |
|     * in this function or any called functions. */
 | |
|     draw_cell_block( lmp, first_row, last_row, row_info, in_event_update );
 | |
|     XinMemoryFree( ( char * ) row_info );
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_cell_btn_event
 | |
| lmp:        current lmp
 | |
| ep:         xvt event
 | |
| oevp:       xvt event, without virtual coordinate conversion
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| lm_cell_btn_event( LM_DATA * lmp, XinEvent * ep, XinEvent * oevp )
 | |
| {
 | |
|   XinRect mr;
 | |
|   int hit_test_value,
 | |
|   row,
 | |
|   col;
 | |
| 
 | |
|   mr = lmp->mlr;
 | |
|   if ( lmp->pixel_width )
 | |
|     mr.right = lmp->rct.left + lmp->pixel_width + BORDER_WIDTH;
 | |
| 
 | |
|   hit_test_value = lm_hit_test( ( LM ) lmp, ep, oevp, &row, &col, NULL, NULL, NULL );
 | |
| 
 | |
|   switch ( ep->type )
 | |
|   {
 | |
|     case XinEventMouseDown:
 | |
|     case XinEventMouseDouble:
 | |
|       lmp->down_in_btn = TRUE;
 | |
|       lmp->btn_down = TRUE;
 | |
|       lmp->btn_down_row = row;
 | |
|       lmp->btn_down_col = col;
 | |
|       XinWindowMouseTrap( lmp->win, TRUE );
 | |
|       xi_set_trap_obj( lmp->list_obj );
 | |
|       redraw_cell_button( lmp, row, col, &mr, lmp->btn_down, FALSE );
 | |
|       break;
 | |
|     case XinEventMouseMove:
 | |
|       {
 | |
|         BOOLEAN last = lmp->btn_down;
 | |
| 
 | |
|         if ( hit_test_value != 5 || row != lmp->btn_down_row || col != lmp->btn_down_col )
 | |
|           lmp->btn_down = FALSE;
 | |
|         else
 | |
|           lmp->btn_down = TRUE;
 | |
|         if ( last != lmp->btn_down )
 | |
|         {
 | |
|           redraw_cell_button( lmp, lmp->btn_down_row, lmp->btn_down_col, &mr,
 | |
|                               lmp->btn_down, FALSE );
 | |
|           last = lmp->btn_down;
 | |
|         }
 | |
|         break;
 | |
|       }
 | |
|     case XinEventMouseUp:
 | |
|       {
 | |
|         BOOLEAN clear_button;
 | |
| 
 | |
|         {
 | |
|           int focus_row,
 | |
|           focus_col;
 | |
|           BOOLEAN is_vert_scrolled;
 | |
| 
 | |
|           lm_focus_cell_get( lmp, &focus_row, &focus_col, &is_vert_scrolled );
 | |
|           clear_button = ( lmp->btn_down_row != focus_row );
 | |
|         }
 | |
|         if ( lmp->btn_down && !clear_button )
 | |
|           redraw_cell_button( lmp, lmp->btn_down_row, lmp->btn_down_col, &mr,
 | |
|                               FALSE, FALSE );
 | |
|         lmp->btn_down = FALSE;
 | |
|         lmp->down_in_btn = FALSE;
 | |
|         if ( hit_test_value == 5 && row == lmp->btn_down_row && col == lmp->btn_down_col )
 | |
|           do_lm_cb( ( LM ) lmp, LM_CB_CELL_BTN, row, col, ep, NULL, 0 );
 | |
|         else if ( clear_button )
 | |
|           redraw_cell( ( LM ) lmp, lmp->btn_down_row, lmp->btn_down_col, FALSE );
 | |
|         break;
 | |
|       }
 | |
|     default:
 | |
|       break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   get_select_column
 | |
| -------------------------------------------------------------------------*/
 | |
| static int
 | |
| get_select_column( LM_DATA * lmp )
 | |
| {
 | |
|   int col;
 | |
| 
 | |
|   for ( col = 0; col < lmp->nbr_columns; col++ )
 | |
|     if ( LM_COL_ATTR( ( LM ) lmp, col ) & XI_ATR_SELECTABLE )
 | |
|       return col;
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   find_selection
 | |
| -------------------------------------------------------------------------*/
 | |
| static int
 | |
| find_selection( LM_DATA * lmp )
 | |
| {
 | |
|   int row_num;
 | |
| 
 | |
|   for ( row_num = 0; row_num < lmp->nbr_realized_rows; row_num++ )
 | |
|     if ( lm_get_attrib( ( LM ) lmp, LM_ROW, row_num, 0, FALSE )
 | |
|         & LM_ROW_ATR_SELECTED )
 | |
|       return row_num;
 | |
|   return -1;
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_set_attrib
 | |
| lm:         current lm
 | |
| lm_part:    must be LM_LIST, LM_COLUMN, LM_ROW, or LM_CELL
 | |
| idx:        if LM_LIST, not used
 | |
|                 if LM_COLUMN, column number
 | |
|                 if LM_ROW, row number
 | |
|                 if LM_CELL, row number
 | |
| idx2:       if LM_LIST, not used
 | |
|                 if LM_COLUMN, not used
 | |
|                 if LM_ROW, not used
 | |
|                 if LM_CELL, column number
 | |
| attrib:     attribute to set
 | |
| half_baked: if set, don't redraw
 | |
| -------------------------------------------------------------------------*/
 | |
| void
 | |
| lm_set_attrib( LM lm, LM_PART lm_part, int idx, int idx2,
 | |
|               BOOLEAN v_scrolled, unsigned long attrib, int half_baked )
 | |
| {
 | |
|   unsigned long do_redraw;
 | |
|   LM_DATA *lmp = LMP( lm );
 | |
|   int focus_row,
 | |
|   focus_column;
 | |
| 
 | |
|   switch ( lm_part )
 | |
|   {
 | |
|     case LM_LIST:
 | |
|       {
 | |
|         XinRect r;
 | |
| 
 | |
|         lmp->attrib = attrib;
 | |
|         xi_get_rect( lmp->list_obj, &r );
 | |
|         r.right += 10;
 | |
|         r.bottom += 4;
 | |
|         xi_invalidate_rect( lmp->win, &r );
 | |
|         break;
 | |
|       }
 | |
|     case LM_COLUMN:
 | |
|       {
 | |
|         LM_COLUMN_DATA *column_data;
 | |
|         XinRect rct;
 | |
| 
 | |
|         column_data = lmp->lm_column_data[idx];
 | |
|         do_redraw = ( ( column_data->attrib ^ attrib ) & LM_REDRAW_COL_ATR );
 | |
|         if ( ( column_data->attrib ^ attrib )
 | |
|             & ( LM_COL_ATR_PASSWORD | LM_COL_ATR_READONLY ) )
 | |
|         {
 | |
|           int row;
 | |
| 
 | |
|           for ( row = 0; row < lmp->nbr_realized_rows; row++ )
 | |
|           {
 | |
|             LM_CELL_DATA *cell_data = &lmp->cell_data[row][idx];
 | |
| 
 | |
|             if ( cell_data->xi_text )
 | |
|             {
 | |
|               xi_text_password_set( cell_data->xi_text,
 | |
|                                     ( attrib & LM_COL_ATR_PASSWORD ) != 0 );
 | |
|               xi_text_read_only_set( cell_data->xi_text,
 | |
|                                     ( attrib & LM_COL_ATR_READONLY ) != 0 );
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|         column_data->attrib = attrib;
 | |
|         if ( do_redraw )
 | |
|         {
 | |
|           BOOLEAN is_vert_scrolled;
 | |
| 
 | |
|           lm_get_rect( lm, LM_COLUMN, idx, &rct );
 | |
|           xi_invalidate_rect( lmp->win, &rct );
 | |
|           if ( lm_focus_cell_get( lmp, &focus_row, &focus_column, &is_vert_scrolled ) )
 | |
|             if ( ( !is_vert_scrolled ) && ( focus_column == idx ) && lm_focus_state_get( lmp ) != LM_FOCUS_VISIBLE )
 | |
|               set_focus_cell_rct( lmp, focus_row, focus_column, FALSE );
 | |
|         }
 | |
|         break;
 | |
|       }
 | |
|     case LM_ROW:
 | |
|       {
 | |
|         unsigned long old_attrib;
 | |
| 
 | |
|         do_redraw = ( ( lmp->row_attribs[idx] ^ attrib ) & LM_REDRAW_ROW_ATR );
 | |
|         old_attrib = lmp->row_attribs[idx];
 | |
|         if ( lmp->single_select && ( attrib & XI_ATR_SELECTED ) )
 | |
|         {
 | |
|           int old_row;
 | |
| 
 | |
|           old_row = find_selection( lmp );
 | |
|           if ( old_row != -1 && old_row != idx )
 | |
|             lm_set_attrib( lm, LM_ROW, old_row, 0, FALSE,
 | |
|                           lmp->row_attribs[old_row] & ~XI_ATR_SELECTED,
 | |
|                           half_baked );
 | |
|         }
 | |
|         lmp->row_attribs[idx] = attrib;
 | |
|         if ( !half_baked && do_redraw )
 | |
|         {
 | |
|           if ( ( old_attrib & XI_ATR_SELECTED ) != ( attrib & XI_ATR_SELECTED ) )
 | |
|           {
 | |
|             BOOLEAN is_vert_scrolled;
 | |
| 
 | |
|             lm_redraw_row( lmp, idx, FALSE );
 | |
|             if ( lm_focus_cell_get( lmp, &focus_row, &focus_column, &is_vert_scrolled ) )
 | |
|               if ( ( !is_vert_scrolled ) && ( focus_row == idx ) && lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | |
|                 set_focus_cell_rct( lmp, focus_row, focus_column, FALSE );
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             XinRect r;
 | |
| 
 | |
|             lm_get_row_rect( &r, lm, idx );
 | |
|             xi_set_clip( lmp->win, NULL );
 | |
|             lm_invalidate_rect( lmp, &r, FALSE );
 | |
|           }
 | |
|         }
 | |
|         break;
 | |
|       }
 | |
|     case LM_CELL:
 | |
|       {
 | |
|         unsigned long old_attrib;
 | |
|         LM_CELL_DATA *cell_data;
 | |
| 
 | |
|         cell_data = &lmp->cell_data[idx][idx2];
 | |
|         if ( !cell_data->valid_data )
 | |
|           return;
 | |
|         if ( v_scrolled )
 | |
|         {
 | |
|           /* TODO this could be called with a v_scrolled cell when the focus is
 | |
|           * not really there.  unlikely, but could happen. */
 | |
|           lm_focus_cell_attrib_set( lmp, attrib );
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           old_attrib = lmp->cell_data[idx][idx2].attrib;
 | |
|           do_redraw = ( ( old_attrib ^ attrib ) & LM_REDRAW_CELL_ATR );
 | |
|           cell_data->attrib = attrib;
 | |
|           if ( !half_baked && do_redraw )
 | |
|           {
 | |
|             BOOLEAN is_vert_scrolled;
 | |
| 
 | |
|             redraw_cell( lm, idx, idx2, FALSE );
 | |
|             if ( lm_focus_cell_get( lmp, &focus_row, &focus_column, &is_vert_scrolled ) )
 | |
|               if ( ( !is_vert_scrolled ) && ( focus_row == idx ) && ( focus_column == idx2 )
 | |
|                   && lm_focus_state_get( lmp ) != LM_FOCUS_VISIBLE )
 | |
|                 set_focus_cell_rct( lmp, focus_row, focus_column, FALSE );
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   select_row
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| select_row( LM lm, int row, int column, BOOLEAN dbl_click )
 | |
| {
 | |
|   unsigned long attrib;
 | |
|   LM_CB_DATA lm_cb_data;
 | |
|   XI_OBJ *old_itf;
 | |
|   int old_row;
 | |
|   LM_DATA *lmp = LMP( lm );
 | |
| 
 | |
|   old_row = find_selection( lmp );
 | |
|   if ( old_row != row && old_row != -1 )
 | |
|   {
 | |
|     attrib = lm_get_attrib( lm, LM_ROW, old_row, 0, FALSE );
 | |
|     attrib &= ~LM_ROW_ATR_SELECTED;
 | |
|     lm_set_attrib( lm, LM_ROW, old_row, 0, FALSE, attrib, FALSE );
 | |
|   }
 | |
|   attrib = lm_get_attrib( lm, LM_ROW, row, 0, FALSE );
 | |
|   attrib |= LM_ROW_ATR_SELECTED;
 | |
|   lm_cb_data.lm = lm;
 | |
|   lm_cb_data.cb_type = LM_CB_SELECT;
 | |
|   lm_cb_data.cid = lmp->cid;
 | |
|   lm_cb_data.win = lmp->win;
 | |
|   lm_cb_data.row = ( unsigned char ) row;
 | |
|   if ( column == -1 )
 | |
|     column = ( unsigned char ) get_select_column( lmp );
 | |
|   lm_cb_data.column = column;
 | |
|   lm_cb_data.v.select.selected = TRUE;
 | |
|   lm_cb_data.v.select.dbl_click = dbl_click;
 | |
|   lm_cb_data.v.select.shift = FALSE;
 | |
|   lm_cb_data.v.select.control = FALSE;
 | |
|   old_itf = lmp->itf_obj;
 | |
|   ( *lmp->lm_cb ) ( &lm_cb_data );
 | |
|   if ( xi_is_itf( old_itf ) )
 | |
|     if ( !lm_cb_data.v.select.refused && old_row != row )
 | |
|       lm_set_attrib( lm, LM_ROW, row, 0, FALSE, attrib, FALSE );
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   send_select_event
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| send_select_event( LM lm, int row, int column, XinEvent * ep, unsigned long attrib )
 | |
| {
 | |
|   LM_CB_DATA lm_cb_data;
 | |
|   XI_OBJ *old_itf;
 | |
|   LM_DATA *lmp = LMP( lm );
 | |
| 
 | |
|   if ( ep->type == XinEventMouseDouble )
 | |
|     attrib |= LM_ROW_ATR_SELECTED;
 | |
|   else
 | |
|   {
 | |
|     if ( attrib & LM_ROW_ATR_SELECTED )
 | |
|       attrib &= ~LM_ROW_ATR_SELECTED;
 | |
|     else
 | |
|       attrib |= LM_ROW_ATR_SELECTED;
 | |
|   }
 | |
|   lm_cb_data.lm = lm;
 | |
|   lm_cb_data.cb_type = LM_CB_SELECT;
 | |
|   lm_cb_data.cid = lmp->cid;
 | |
|   lm_cb_data.win = lmp->win;
 | |
|   lm_cb_data.row = ( unsigned char ) row;
 | |
|   lm_cb_data.column = ( unsigned char ) column;
 | |
|   lm_cb_data.v.select.selected = ( ( attrib & LM_ROW_ATR_SELECTED ) != 0 );
 | |
|   lm_cb_data.v.select.dbl_click = ( ep->type == XinEventMouseDouble );
 | |
|   lm_cb_data.v.select.shift = ep->v.mouse.shift;
 | |
|   lm_cb_data.v.select.control = ep->v.mouse.control;
 | |
|   old_itf = lmp->itf_obj;
 | |
|   ( *lmp->lm_cb ) ( &lm_cb_data );
 | |
|   if ( xi_is_itf( old_itf ) )
 | |
|     if ( !lm_cb_data.v.select.refused )
 | |
|       lm_set_attrib( lm, LM_ROW, row, 0, FALSE, attrib, FALSE );
 | |
| }
 | |
| 
 | |
| /*********** draw border around entire list ***********/
 | |
| static void
 | |
| draw_list_rect( LM_DATA * lmp, XinRect * vr, XinRect * hr )
 | |
| {
 | |
|   XinRect r;
 | |
|   XI_OBJ *list_obj = lmp->list_obj;
 | |
|   XI_LIST_DATA *list_data = list_obj->v.list;
 | |
| 
 | |
|   r = lmp->rct;
 | |
|   if ( list_data->sb_win )
 | |
|     r.right = vr->right;
 | |
|   else
 | |
|     r.right += BORDER_WIDTH;
 | |
|   if ( list_data->hsb_win )
 | |
|     r.bottom = hr->bottom;
 | |
|   xi_draw_rect( lmp->win, &r );
 | |
| }
 | |
| 
 | |
| /*********** draw heading rules ***********/
 | |
| static void
 | |
| draw_heading_rules( LM_DATA * lmp, int hrule_h )
 | |
| {
 | |
|   if ( !( lmp->update_rows_at_top + lmp->update_rows_at_bottom ) )
 | |
|   {
 | |
|     if ( !lmp->no_heading )
 | |
|     {
 | |
|       int i;
 | |
|       XinPoint p;
 | |
| 
 | |
| #if XIWS != XIWS_WM
 | |
|       int r2;
 | |
|       XinWindow win = lmp->win;
 | |
| 
 | |
| #endif
 | |
| 
 | |
| #if XIWS == XIWS_WM
 | |
|       /* heading rule, Release 3.0 */
 | |
|       p.h = lmp->rct.left;
 | |
|       p.v = lmp->pix_hdr_bottom;
 | |
|       xi_move_to( lmp->win, p );
 | |
|       p.h = hrule_h - VPIX_PER_CH;
 | |
|       xi_draw_line( lmp->win, p );
 | |
| #endif
 | |
| #if XIWS != XIWS_WM
 | |
|       r2 = lmp->rct.right - lmp->delta_x;
 | |
|       if ( lmp->nbr_columns == 0 )
 | |
|         r2 -= 2 * BORDER_WIDTH;
 | |
|       r2 = min( r2, hrule_h );
 | |
|       WIDTHLOOP( i, BORDER_WIDTH )
 | |
|       {
 | |
|         p.h = lmp->rct.left;
 | |
|         p.v = lmp->pix_row1_top - BORDER_WIDTH + i;
 | |
|         xi_move_to( win, p );
 | |
|         p.h = r2;
 | |
|         xi_draw_line( win, p );
 | |
|       }
 | |
| #endif
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*********** draw column rules ***********/
 | |
| static void
 | |
| draw_column_rules( LM_DATA * lmp )
 | |
| {
 | |
|   LM_COLUMN_DATA **lmcd;
 | |
|   int col;
 | |
|   XinPoint p;
 | |
| 
 | |
| #if XIWS == XIWS_WM
 | |
|   XinPoint from_p;
 | |
| 
 | |
| #endif
 | |
| 
 | |
|   if ( lmp->no_vert_lines )
 | |
|   {
 | |
|     XinPen back_cpen;
 | |
| 
 | |
|     back_cpen = black_cpen;
 | |
|     back_cpen.fore_color = lmp->back_color;
 | |
|     XinWindowPenSet( lmp->win, &back_cpen );
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     XinPen back_cpen;
 | |
| 
 | |
|     back_cpen = black_cpen;
 | |
|     back_cpen.fore_color = lmp->rule_color;
 | |
|     XinWindowPenSet( lmp->win, &back_cpen );
 | |
|   }
 | |
|   for ( col = 1, lmcd = &lmp->lm_column_data[1]; col < lmp->nbr_columns; col++, ++lmcd )
 | |
|   {
 | |
|     p.h = ( *lmcd )->x_pix_pos - RULE_WIDTH_V;
 | |
| #if XIWS == XIWS_WM
 | |
|     p.v = lmp->pix_top;
 | |
|     lm_move_to( lmp, p, FALSE, TRUE );
 | |
|     p.v = lmp->mlr.bottom - VPIX_PER_CH;
 | |
|     lm_draw_line( lmp, p, FALSE, TRUE );
 | |
| #endif
 | |
| #if XIWS != XIWS_WM
 | |
|     /* if RULE_WIDTH_V were used, this is where it would be used */
 | |
|     p.v = lmp->rct.top;
 | |
|     lm_move_to( lmp, p, FALSE, TRUE );
 | |
|     p.v = min( lmp->rct.bottom, lmp->rrr_bottom + lmp->rrr_offset + lmp->mlr.top );
 | |
|     lm_draw_line( lmp, p, FALSE, TRUE );
 | |
| #endif
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| lm:         current lm
 | |
| update:     if TRUE, draw_lm is being called due to an XinEventPaint event
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| draw_lm( LM lm, BOOLEAN update )
 | |
| {
 | |
|   int hrule_h,
 | |
|   actual_r,
 | |
|   idx;
 | |
|   XinRect lmp_rct,
 | |
|   actual_rct,
 | |
|   clip_rct;
 | |
|   XinRect hr,
 | |
|   vr;
 | |
|   XI_OBJ *list_obj;
 | |
|   XI_LIST_DATA *list_data;
 | |
|   LM_DATA *lmp = LMP( lm );
 | |
|   XinWindow win = lmp->win;
 | |
|   XinBrush back_cbrush;
 | |
| 
 | |
| #if XIWS != XIWS_WM
 | |
|   XinRect urct;
 | |
| 
 | |
| #else
 | |
|   XinBrush lm_cbrush;
 | |
|   XinPoint from_p;
 | |
| 
 | |
| /***********************************************************************/
 | |
| /* set up variables for drawing */
 | |
|   c_xd = C_XD;
 | |
|   c_xu = C_XU;
 | |
|   c_v = C_V;
 | |
|   c_xx = C_XX;
 | |
| #endif
 | |
|   if ( !( lmp->attrib & LM_ATR_VISIBLE ) )
 | |
|   {
 | |
|     lmp->update_rows_at_top = 0;
 | |
|     lmp->update_rows_at_bottom = 0;
 | |
|     return;
 | |
|   }
 | |
|   list_obj = lmp->list_obj;
 | |
|   list_data = list_obj->v.list;
 | |
|   lmp_rct = lmp->rct;
 | |
|   actual_rct = lmp_rct;
 | |
| #if XIWS != XIWS_WM
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = lmp->rct.left + lmp->pixel_width + 2 * BORDER_WIDTH;
 | |
|   else
 | |
|     actual_r = lmp->rct.right;
 | |
|   actual_rct.right = actual_r - BORDER_WIDTH;
 | |
| #else
 | |
|   if ( lmp->pixel_width )
 | |
|     actual_r = lmp->rct.left + lmp->pixel_width;
 | |
|   else
 | |
|     actual_r = lmp->rct.right + 8;
 | |
|   actual_rct.right = actual_r;
 | |
| #endif
 | |
|   hrule_h = actual_r;
 | |
|   if ( lmp->pixel_width )
 | |
|     lmp_rct.right = hrule_h;
 | |
|   urct = lmp_rct;
 | |
|   if ( list_data->sb_win )
 | |
|   {
 | |
|     if ( list_data->have_sb_rct )
 | |
|       vr = list_data->sb_rct;
 | |
|     else
 | |
|       xi_get_sb_rect( list_obj, &vr );
 | |
|     urct.right = vr.right;
 | |
|   }
 | |
|   if ( list_data->hsb_win )
 | |
|   {
 | |
|     if ( list_data->have_hsb_rct )
 | |
|       hr = list_data->hsb_rct;
 | |
|     else
 | |
|       xi_get_hsb_rect( list_obj, &hr );
 | |
|     urct.bottom = hr.bottom;
 | |
|   }
 | |
| #if XIWS != XIWS_WM
 | |
|   if ( update && !xi_XinWindowPaintNeeds( win, &urct ) )
 | |
|   {
 | |
|     lmp->update_rows_at_top = 0;
 | |
|     lmp->update_rows_at_bottom = 0;
 | |
|     return;
 | |
|   }
 | |
| #endif
 | |
|   lmp_rct = lmp->rct;
 | |
|   if ( lmp->nbr_realized_rows )
 | |
|   {
 | |
|     idx = lmp->nbr_realized_rows - 1;
 | |
|     lmp->rrr_bottom = lmp->pix_offsets[idx] + lmp->pix_heights[idx];
 | |
|   }
 | |
|   else
 | |
|     lmp->rrr_bottom = 0;
 | |
|   if ( !lm_tools_inited )
 | |
|   {
 | |
|     lm_white_cbrush.fore_color = XI_COLOR_WHITE;
 | |
|     lm_white_cbrush.pattern = XinBrushSolid;
 | |
|     lm_black_cpen.width = 1;
 | |
|     lm_black_cpen.fore_color = XI_COLOR_BLACK;
 | |
|     lm_black_cpen.pattern = XinPenSolid;
 | |
|     XinWindowDrawToolsNormalGet( &lm_normal_ctools );
 | |
|     lm_tools_inited = TRUE; // Added by Guy :-(
 | |
|   }
 | |
| 
 | |
|   /***********************************************************************/
 | |
|   /* draw anything other than in the cell region */
 | |
|   /* prior to this, there are no calls for drawing */
 | |
| 
 | |
|   back_cbrush = lm_white_cbrush;
 | |
| /*
 | |
| TO OPTIMIZE BACKGROUND DRAWING, USE THE FOLLOWING LINE, AND DON'T SET TO HOLLOW
 | |
|   back_cbrush.color = lmp->back_color;
 | |
| */
 | |
| #if XIWS != XIWS_WM
 | |
|   back_cbrush.pattern = XinBrushHollow;
 | |
| #endif
 | |
|   XinWindowBrushSet( win, &back_cbrush );
 | |
|   XinWindowPenSet( win, &lm_black_cpen );
 | |
|   clip_rct = actual_rct;
 | |
| #if XIWS == XIWS_WM
 | |
|   if ( list_data->hsb_win )
 | |
|     clip_rct.bottom += 8;
 | |
|   clip_rct.right += 8;
 | |
| #endif
 | |
|   xi_set_clip( win, &clip_rct );
 | |
|   XinWindowDrawModeSet( win, XinDrawModeCopy );
 | |
| 
 | |
|   /* XinBrush: white_cbrush XinDrawPen:   black_cpen CLIP:   actual_rct */
 | |
| 
 | |
|   /*********** draw the rectangle around the list ***********/
 | |
|   draw_list_rect( lmp, &vr, &hr );
 | |
| 
 | |
| #if XIWS == XIWS_WM
 | |
|   xi_set_clip( win, &actual_rct );
 | |
| #endif
 | |
| 
 | |
|   /*********** draw the rules between the heading and the cells ***********/
 | |
|   if ( !lmp->update_cells_only )
 | |
|     draw_heading_rules( lmp, hrule_h );
 | |
| 
 | |
|   /*********** draw column rules ***********/
 | |
|   draw_column_rules( lmp );
 | |
| 
 | |
|   /* XinBrush: white_cbrush XinDrawPen:   black_cpen OR back_color cpen CLIP:
 | |
|   * actual_rct */
 | |
| 
 | |
|   /*********** draw column headings ***********/
 | |
|   if ( !lmp->update_cells_only )
 | |
|     draw_column_headings( lmp, &actual_rct );
 | |
|   xi_set_clip( win, NULL );
 | |
| 
 | |
|   /*********** draw text in cells ***********/
 | |
|   draw_cells( lmp, update );
 | |
| 
 | |
|   draw_other_rectangles( lmp, &actual_rct );
 | |
| 
 | |
|   xi_set_clip( win, NULL );
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:       send_cell_event
 | |
| lm:             current lm
 | |
| ep:             xvt event
 | |
| gaining_focus:  if TRUE, the edit control is gaining focus as this function is called
 | |
| returns:        TRUE if the event was used
 | |
| -------------------------------------------------------------------------*/
 | |
| static BOOLEAN
 | |
| send_cell_event( LM lm, XinEvent * ep, BOOLEAN gaining_focus, BOOLEAN send_to_txt )
 | |
| {
 | |
|   BOOLEAN retval = FALSE;
 | |
|   int ch;
 | |
|   LM_DATA *lmp = LMP( lm );
 | |
| 
 | |
|   if ( lm_focus_state_get( lmp ) != LM_FOCUS_VISIBLE )
 | |
|     return FALSE;
 | |
|   if ( ep->type == XinEventCharacter )
 | |
|   {
 | |
|     if ( ep->v.character.alt )
 | |
|       return FALSE;
 | |
|     ch = ep->v.character.ch;
 | |
|     if ( ( ch >= ' ' || ch == XI_KEY_CLEAR || ch == XI_KEY_DEL || ch == '\b'
 | |
|           || ch == '\r' || ch == '\n' )
 | |
|         && ch != XI_KEY_BTAB && ch != XI_KEY_UP && ch != XI_KEY_DOWN &&
 | |
|         (!(lmp->attrib & LM_ATR_NAVIGATE) || ( ch != XI_KEY_LEFT && ch != XI_KEY_RIGHT)))
 | |
|     {
 | |
|       int focus_row,
 | |
|       focus_column;
 | |
|       BOOLEAN v_scrolled;
 | |
| 
 | |
|       lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | |
|       retval = do_lm_cb( lm, LM_CB_CHAR, focus_row, focus_column, ep, NULL, 0 );
 | |
|       /* retval = FALSE if event refused */
 | |
|       if ( !retval )
 | |
|         return FALSE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if ( send_to_txt )
 | |
|   {
 | |
|     LM_CELL_DATA *cell_data;
 | |
|     int focus_row,
 | |
|     focus_column;
 | |
|     BOOLEAN v_scrolled;
 | |
|     BOOLEAN changed = FALSE;
 | |
| 
 | |
|     lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | |
|     cell_data = &lmp->cell_data[focus_row][focus_column];
 | |
|     if ( cell_data->button_full_cell && ep->type == XinEventCharacter )
 | |
|     {
 | |
|       ch = ep->v.character.ch;
 | |
|       if ( ch == ' ' || ch == '\r' || ch == '\n' )
 | |
|       {
 | |
|         do_lm_cb( ( LM ) lmp, LM_CB_CELL_BTN, focus_row, focus_column, ep, NULL, 0 );
 | |
|       }
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       retval = xi_text_event( cell_data->xi_text, ep, gaining_focus, &changed );
 | |
|       if ( changed )
 | |
|       {
 | |
|         LM_COLUMN_DATA *lm_column_data;
 | |
| 
 | |
|         lm_column_data = lmp->lm_column_data[focus_column];
 | |
|         retval = do_lm_cb( lm, LM_CB_CHANGE, focus_row, focus_column, ep, NULL, 0 );
 | |
|         if ( lm_column_data->auto_tab
 | |
|             && ( int ) strlen( xi_text_get( cell_data->xi_text ) )
 | |
|             >= lm_column_data->text_size - 1 )
 | |
|         {
 | |
|           XinEvent ev;
 | |
| 
 | |
|           MEMCLEAR( ev );
 | |
|           ev.type = XinEventCharacter;
 | |
|           ev.v.character.ch = '\t';
 | |
|           xi_event( lmp->win, &ev );
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return retval;
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_vsize_hit_test
 | |
| lm:         current lm
 | |
| ep:         xvt event
 | |
| rowp:       row, to be filled in
 | |
| columnp:    column, to be filled in
 | |
| returns:    FALSE if hit test did not fall on place where column could be vertically sized.
 | |
| -------------------------------------------------------------------------*/
 | |
| static BOOLEAN
 | |
| lm_vsize_hit_test( LM_DATA * lmp, XinEvent * ep, int *rowp, int *columnp )
 | |
| {
 | |
|   int i,
 | |
|   n,
 | |
|   v;
 | |
|   int *pix_offsetsp;
 | |
|   int *pix_heightsp;
 | |
| 
 | |
|   if ( lmp->lm_column_data[*columnp]->size_rows )
 | |
|   {
 | |
|     v = ep->v.mouse.where.v - lmp->rrr_offset - lmp->mlr.top;
 | |
|     for ( i = 0,
 | |
|           pix_offsetsp = &lmp->pix_offsets[i],
 | |
|           pix_heightsp = &lmp->pix_heights[i];
 | |
|           i < lmp->nbr_realized_rows;
 | |
|           ++i, ++pix_offsetsp, ++pix_heightsp )
 | |
|     {
 | |
|       n = *pix_offsetsp + *pix_heightsp;
 | |
|       if ( v >= n - 3 && v <= n + 1 )
 | |
|       {
 | |
|         *rowp = i;
 | |
|         return TRUE;
 | |
|       }
 | |
|     }
 | |
|     return FALSE;
 | |
|   }
 | |
|   else
 | |
|     return FALSE;
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   rubber_y
 | |
| lmp:        current lmp
 | |
| y:          draw a rubber line at position y
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| rubber_y( LM_DATA * lmp, int y )
 | |
| {
 | |
| #if XIWS != XIWS_WM
 | |
|   int left,
 | |
|   right;
 | |
|   XinDrawTools new_ctools;
 | |
|   XinPoint pnt;
 | |
|   XinWindow win = lmp->win;
 | |
| 
 | |
|   left = lmp->mlr.left;
 | |
|   right = lmp->mlr.right;
 | |
|   if ( lmp->pixel_width )
 | |
|     right = left + lmp->pixel_width + BORDER_WIDTH;
 | |
|   XinWindowDrawToolsNormalGet( &new_ctools );
 | |
|   XinWindowDrawToolsSet( win, &new_ctools );
 | |
|   XinWindowPenSet( win, &rubber_cpen );
 | |
|   XinWindowDrawModeSet( win, XinDrawModeXor );
 | |
|   xi_set_clip( win, NULL );
 | |
|   pnt.h = left;
 | |
|   pnt.v = y;
 | |
|   lm_move_to( lmp, pnt, TRUE, FALSE );
 | |
|   pnt.h = right;
 | |
|   lm_draw_line( lmp, pnt, TRUE, FALSE );
 | |
| #else
 | |
|   NOREF( lmp );
 | |
|   NOREF( y );
 | |
| #endif
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   calc_y
 | |
| lmp:        current lmp
 | |
| ep:         xvt event
 | |
| returns:    Calculates and returns the Y pixel position of the rubber band line.
 | |
|                 Used only when sizing rows.
 | |
| -------------------------------------------------------------------------*/
 | |
| static int
 | |
| calc_y( LM_DATA * lmp, XinEvent * ep )
 | |
| {
 | |
|   int row = lmp->row_being_sized;
 | |
|   int temp;
 | |
|   int min_height_in_pix = 4;
 | |
|   int v;
 | |
| 
 | |
|   v = min( lmp->mlr.bottom, ep->v.mouse.where.v ) - lmp->rrr_offset - lmp->mlr.top;
 | |
|   temp = lmp->pix_offsets[row] + min_height_in_pix;
 | |
|   temp = max( v, temp );
 | |
|   return temp;
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_vsize_event
 | |
| lmp:        current lmp
 | |
| ep:         xvt event
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| lm_vsize_event( LM_DATA * lmp, XinEvent * ep )
 | |
| {
 | |
|   int y;
 | |
| 
 | |
|   switch ( ep->type )
 | |
|   {
 | |
|     case XinEventMouseDown:
 | |
|     case XinEventMouseDouble:
 | |
|       y = calc_y( lmp, ep );
 | |
|       lmp->last_y = y;
 | |
|       rubber_y( lmp, y );
 | |
|       break;
 | |
|     case XinEventMouseMove:
 | |
|       y = calc_y( lmp, ep );
 | |
|       rubber_y( lmp, lmp->last_y );
 | |
|       lmp->last_y = y;
 | |
|       rubber_y( lmp, y );
 | |
|       break;
 | |
|     case XinEventMouseUp:
 | |
|       {
 | |
|         int delta,
 | |
|         row;
 | |
|         XI_OBJ row_obj;
 | |
| 
 | |
|         row = lmp->row_being_sized;
 | |
|         y = calc_y( lmp, ep );
 | |
|         rubber_y( lmp, lmp->last_y );
 | |
|         delta = y - lmp->pix_offsets[row] + 1;
 | |
|         XI_MAKE_ROW( &row_obj, lmp->list_obj, row );
 | |
|         if ( do_lm_cb( ( LM ) lmp, LM_CB_ROW_SIZE, row, 0, NULL, NULL, delta ) )
 | |
|         {
 | |
|           xi_set_row_height( &row_obj, delta );
 | |
|           calculate_pix_offsets( lmp, FALSE );
 | |
|         }
 | |
|         lm_focus_cell_visible_attempt( lmp );
 | |
|         break;
 | |
|       }
 | |
|     default:
 | |
|       break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:       lm_select_cells_hit_test
 | |
| lmp:            current lmp
 | |
| ep:             xvt event
 | |
| rowp:           row number, to be filled in
 | |
| columnp:        column number, to be filled in
 | |
| on_disabled:    if TRUE, then the hit was on a disabled column
 | |
| returns:        TRUE if there was a hit
 | |
| -------------------------------------------------------------------------*/
 | |
| static BOOLEAN
 | |
| lm_select_cells_hit_test( LM_DATA * lmp, XinEvent * ep, int *rowp,
 | |
|                           int *columnp, BOOLEAN * on_disabled )
 | |
| {
 | |
|   int delta_top,
 | |
|   column,
 | |
|   col_offset,
 | |
|   last_vis,
 | |
|   row,
 | |
|   idx;
 | |
|   LM_COLUMN_DATA *column_data;
 | |
|   BOOLEAN retval;
 | |
|   BOOLEAN inv_v,
 | |
|   inv_h;                       /* if set to TRUE, then invalid v or invalid h */
 | |
| 
 | |
|   retval = TRUE;
 | |
|   if ( columnp )
 | |
|     *columnp = 0;
 | |
|   if ( on_disabled )
 | |
|     *on_disabled = FALSE;
 | |
|   inv_v = FALSE;
 | |
|   inv_h = FALSE;
 | |
|   last_vis = lmp->last_vis;
 | |
|   delta_top = ep->v.mouse.where.v - lmp->mlr.top - lmp->rrr_offset;
 | |
| 
 | |
|   /* If list has no columns */
 | |
|   if ( lmp->nbr_columns <= 0 )
 | |
|     return FALSE;
 | |
| 
 | |
|   /* If mouse is above the top of the first row */
 | |
|   if ( ep->v.mouse.where.v < lmp->pix_row1_top - RULE_WIDTH_V -
 | |
|       RULE_Y_OFFSET_TOP )
 | |
|   {
 | |
|     if ( rowp )
 | |
|       *rowp = 0;
 | |
|     retval = FALSE;
 | |
|     inv_v = TRUE;
 | |
|   }
 | |
| 
 | |
|   /* if mouse is below the bottom of the list, or if the mouse is below the
 | |
|   * bottom of the last row if there are fewer rows than can be displayed in
 | |
|   * the list */
 | |
|   idx = lmp->nbr_realized_rows - 1;
 | |
|   if ( ep->v.mouse.where.v >= lmp->mlr.bottom ||
 | |
|       delta_top > lmp->pix_offsets[idx] + lmp->pix_heights[idx] )
 | |
|   {
 | |
|     if ( rowp )
 | |
|       *rowp = lmp->nbr_realized_rows;
 | |
|     retval = FALSE;
 | |
|     inv_v = TRUE;
 | |
|   }
 | |
| 
 | |
|   /* if mouse is to the right of the list, or if the mouse is to the right of
 | |
|   * the rightmost column */
 | |
|   column_data = lmp->lm_column_data[lmp->nbr_columns - 1];
 | |
|   if ( ( ep->v.mouse.where.h >= ( lmp->rct.right - lmp->rct.left ) ) ||
 | |
|       ( ep->v.mouse.where.h >= ( column_data->x_pix_pos + column_data->pix_width ) ) )
 | |
|   {
 | |
|     if ( columnp )
 | |
|       *columnp = last_vis + 1;
 | |
|     retval = FALSE;
 | |
|     inv_h = TRUE;
 | |
|   }
 | |
| 
 | |
|   /* if mouse has a valid y coordinate */
 | |
|   if ( !inv_v )
 | |
|   {
 | |
| 
 | |
|     if ( rowp )
 | |
|       *rowp = 0;
 | |
|     retval = FALSE;
 | |
|     for ( row = 0; row < lmp->nbr_realized_rows; ++row )
 | |
|     {
 | |
|       int pix_offset,
 | |
|       pix_height;
 | |
| 
 | |
|       pix_offset = lmp->pix_offsets[row];
 | |
|       pix_height = lmp->pix_heights[row];
 | |
|       if ( delta_top >= pix_offset - SELECT_CELLS_OFFSET - 2
 | |
|           && delta_top <= pix_offset + SELECT_CELLS_OFFSET )
 | |
|       {
 | |
|         if ( rowp )
 | |
|           *rowp = row;
 | |
|         if ( !inv_h )
 | |
|           retval = TRUE;
 | |
|         break;
 | |
|       }
 | |
|       if ( delta_top >= ( pix_offset + pix_height ) - SELECT_CELLS_OFFSET - 2
 | |
|           && delta_top <= ( pix_offset + pix_height ) + SELECT_CELLS_OFFSET )
 | |
|       {
 | |
|         if ( rowp )
 | |
|           *rowp = row + 1;
 | |
|         if ( !inv_h )
 | |
|           retval = TRUE;
 | |
|         break;
 | |
|       }
 | |
|       if ( delta_top >= pix_offset &&
 | |
|           delta_top <= pix_offset + pix_height )
 | |
|       {
 | |
|         if ( rowp )
 | |
|           *rowp = row;
 | |
|       }
 | |
|     }
 | |
|     if ( rowp && !retval && *rowp < lmp->down_row )
 | |
|       ++* rowp;
 | |
|   }
 | |
| 
 | |
|   /* if mouse has a valid x coordinate */
 | |
|   if ( !inv_h )
 | |
|   {
 | |
|     column_data = lmp->lm_column_data[0];
 | |
|     col_offset = ( int ) xi_get_pref( XI_PREF_COLUMN_OFFSET );
 | |
|     if ( ( ( !( column_data->attrib & XI_ATR_ENABLED ) || lmp->down_on_disabled ) &&
 | |
|           ( !( column_data->attrib & XI_ATR_SELECTABLE ) ) ) &&
 | |
|         ( ( ep->v.mouse.where.h >= column_data->x_pix_pos ) &&
 | |
|           ( ep->v.mouse.where.h < ( column_data->x_pix_pos + column_data->pix_width ) ) ) )
 | |
|     {
 | |
|       if ( columnp )
 | |
|         *columnp = 0;
 | |
|       if ( on_disabled )
 | |
|         *on_disabled = TRUE;
 | |
|     }
 | |
|     else if ( ( ep->v.mouse.where.h >= column_data->x_pix_pos ) &&
 | |
|           ( ep->v.mouse.where.h < ( column_data->x_pix_pos + col_offset ) ) )
 | |
|     {
 | |
|       if ( columnp )
 | |
|         *columnp = 0;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       BOOLEAN found = FALSE;
 | |
|       int last_col;
 | |
| 
 | |
|       last_col = -1;
 | |
|       for ( column = 0; column < lmp->nbr_columns; column++ )
 | |
|       {
 | |
|         int temp;
 | |
| 
 | |
|         column_data = lmp->lm_column_data[column];
 | |
|         if ( ( ( !( column_data->attrib & XI_ATR_ENABLED ) || lmp->down_on_disabled ) &&
 | |
|               ( !( column_data->attrib & XI_ATR_SELECTABLE ) ) ) &&
 | |
|             ( ( ep->v.mouse.where.h >= column_data->x_pix_pos ) &&
 | |
|               ( ep->v.mouse.where.h <
 | |
|                 ( column_data->x_pix_pos + column_data->pix_width ) ) ) )
 | |
|         {
 | |
|           if ( columnp )
 | |
|             *columnp = column;
 | |
|           if ( on_disabled )
 | |
|             *on_disabled = TRUE;
 | |
|           found = TRUE;
 | |
|           break;
 | |
|         }
 | |
|         temp = column_data->x_pix_pos +
 | |
|                 col_offset +
 | |
|                 column_data->pix_width - SELECT_CELLS_OFFSET;
 | |
|         if ( ep->v.mouse.where.h >= temp &&
 | |
|             ep->v.mouse.where.h < ( temp + col_offset * 2
 | |
|                                     + 2 * SELECT_CELLS_OFFSET
 | |
|                                     + RULE_WIDTH_V ) )
 | |
|         {
 | |
|           if ( columnp )
 | |
|             *columnp = column + 1;
 | |
|           found = TRUE;
 | |
|           break;
 | |
|         }
 | |
|         if ( ep->v.mouse.where.h >= temp )
 | |
|           last_col = column;
 | |
|       }
 | |
|       if ( !found )
 | |
|       {
 | |
|         retval = FALSE;
 | |
|         if ( columnp )
 | |
|         {
 | |
|           if ( ( last_col + 1 ) < lmp->down_column )
 | |
|             *columnp = last_col + 2;
 | |
|           else
 | |
|             *columnp = last_col + 1;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   /* If v is not invalid, and if h is not invalid, and if the column is valid,
 | |
|   * then if the column is enabled, then the hit test must be within a range of
 | |
|   * the rules. If the column is not enabled, then the hit test may be anywhere
 | |
|   * within the cell. */
 | |
|   if ( !inv_v )
 | |
|   {
 | |
|     BOOLEAN enabled_col = FALSE;
 | |
| 
 | |
|     if ( columnp && !inv_h )
 | |
|     {
 | |
|       if ( *columnp >= lmp->nbr_columns )
 | |
|         enabled_col = FALSE;
 | |
|       else
 | |
|         enabled_col = ( lmp->lm_column_data[*columnp]->attrib & XI_ATR_ENABLED &&
 | |
|                         !lmp->down_on_disabled );
 | |
|       if ( enabled_col )
 | |
|       {
 | |
|         delta_top = ep->v.mouse.where.v - lmp->mlr.top - lmp->rrr_offset;
 | |
|         retval = FALSE;
 | |
|         for ( row = 0; row < lmp->nbr_realized_rows; ++row )
 | |
|         {
 | |
|           int pix_offset,
 | |
|           pix_height;
 | |
| 
 | |
|           pix_offset = lmp->pix_offsets[row];
 | |
|           pix_height = lmp->pix_heights[row];
 | |
|           if ( delta_top >= pix_offset - SELECT_CELLS_OFFSET - 2
 | |
|               && delta_top <= pix_offset + SELECT_CELLS_OFFSET )
 | |
|           {
 | |
|             if ( rowp )
 | |
|               *rowp = row;
 | |
|             retval = TRUE;
 | |
|             break;
 | |
|           }
 | |
|           if ( delta_top >= ( pix_offset + pix_height ) - SELECT_CELLS_OFFSET - 2
 | |
|           && delta_top <= ( pix_offset + pix_height ) + SELECT_CELLS_OFFSET )
 | |
|           {
 | |
|             if ( rowp )
 | |
|               *rowp = row + 1;
 | |
|             retval = TRUE;
 | |
|             break;
 | |
|           }
 | |
|         }
 | |
|         return retval;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   return retval;
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   invert_selection
 | |
| lmp:        current lmp
 | |
| r:          row
 | |
| c:          column
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| invert_selection( LM_DATA * lmp, int r, int c, BOOLEAN v_scrolled )
 | |
| {
 | |
|   unsigned long attrib;
 | |
| 
 | |
|   attrib = lm_get_attrib( ( LM ) lmp, LM_CELL, r, c, v_scrolled );
 | |
|   if ( attrib & LM_CELL_ATR_SELECTED )
 | |
|     lm_set_attrib( ( LM ) lmp, LM_CELL, r, c, v_scrolled,
 | |
|                   attrib & ~LM_CELL_ATR_SELECTED, FALSE );
 | |
|   else
 | |
|     lm_set_attrib( ( LM ) lmp, LM_CELL, r, c, v_scrolled,
 | |
|                   attrib | LM_CELL_ATR_SELECTED, FALSE );
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   in_rct
 | |
| rct:        rectangle
 | |
| r:          row
 | |
| c:          column
 | |
| returns:    TRUE if c and r are in rct
 | |
| -------------------------------------------------------------------------*/
 | |
| static BOOLEAN
 | |
| in_rct( XinRect * rct, int r, int c )
 | |
| {
 | |
|   if ( c >= rct->left && c < rct->right && r >= rct->top && r < rct->bottom )
 | |
|     return TRUE;
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_select_cell_event
 | |
| lmp:        current lmp
 | |
| ep:         xvt event
 | |
| -------------------------------------------------------------------------*/
 | |
| static void
 | |
| lm_select_cell_event( LM_DATA * lmp, XinEvent * ep )
 | |
| {
 | |
|   int row,
 | |
|   column;
 | |
| 
 | |
|   switch ( ep->type )
 | |
|   {
 | |
|     case XinEventMouseDown:
 | |
|     case XinEventMouseDouble:
 | |
|       if ( !ep->v.mouse.shift )
 | |
|       {
 | |
|         int r,
 | |
|         c;
 | |
| 
 | |
|         for ( r = 0; r < lmp->nbr_realized_rows; ++r )
 | |
|           for ( c = 0; c < lmp->nbr_columns; ++c )
 | |
|           {
 | |
|             unsigned long attrib;
 | |
| 
 | |
|             attrib = lm_get_attrib( ( LM ) lmp, LM_CELL, r, c, FALSE );
 | |
|             if ( attrib & LM_CELL_ATR_SELECTED )
 | |
|               lm_set_attrib( ( LM ) lmp, LM_CELL, r, c, FALSE,
 | |
|                             attrib & ~LM_CELL_ATR_SELECTED, FALSE );
 | |
|           }
 | |
|       }
 | |
|       break;
 | |
|     case XinEventMouseMove:
 | |
|     case XinEventMouseUp:
 | |
|       {
 | |
|         int last_cur_row,
 | |
|         last_cur_column,
 | |
|         r,
 | |
|         c,
 | |
|         down_row,
 | |
|         down_column;
 | |
|         XinRect old_rct,
 | |
|         new_rct,
 | |
|         enclosing_rct;
 | |
| 
 | |
|         lm_select_cells_hit_test( lmp, ep, &row, &column, NULL );
 | |
|         last_cur_row = lmp->cur_row;
 | |
|         last_cur_column = lmp->cur_column;
 | |
|         down_row = lmp->down_row;
 | |
|         down_column = lmp->down_column;
 | |
|         if ( lmp->down_on_disabled )
 | |
|         {
 | |
|           if ( ep->type == XinEventMouseUp )
 | |
|             lmp->down_on_disabled = FALSE;
 | |
|           if ( row >= lmp->down_row )
 | |
|             lmp->cur_row = row + 1;
 | |
|           else
 | |
|             lmp->cur_row = row;
 | |
|           if ( column >= lmp->down_column )
 | |
|             lmp->cur_column = column + 1;
 | |
|           else
 | |
|             lmp->cur_column = column;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           lmp->cur_row = row;
 | |
|           lmp->cur_column = column;
 | |
|         }
 | |
|         if ( lmp->cur_row == last_cur_row && lmp->cur_column == last_cur_column &&
 | |
|             ( ep->type == XinEventMouseMove || ep->type == XinEventMouseUp ) )
 | |
|           break;
 | |
|         old_rct.left = min( down_column, last_cur_column );
 | |
|         old_rct.right = max( down_column, last_cur_column );
 | |
|         old_rct.top = min( down_row, last_cur_row );
 | |
|         old_rct.bottom = max( down_row, last_cur_row );
 | |
|         new_rct.left = min( down_column, lmp->cur_column );
 | |
|         new_rct.right = max( down_column, lmp->cur_column );
 | |
|         new_rct.top = min( down_row, lmp->cur_row );
 | |
|         new_rct.bottom = max( down_row, lmp->cur_row );
 | |
|         enclosing_rct.top = min( old_rct.top, new_rct.top );
 | |
|         enclosing_rct.bottom = max( old_rct.bottom, new_rct.bottom );
 | |
|         enclosing_rct.left = min( old_rct.left, new_rct.left );
 | |
|         enclosing_rct.right = max( old_rct.right, new_rct.right );
 | |
|         for ( c = enclosing_rct.left; c <= enclosing_rct.right; ++c )
 | |
|         {
 | |
|           for ( r = enclosing_rct.top; r <= enclosing_rct.bottom; ++r )
 | |
|           {
 | |
|             if ( ( in_rct( &old_rct, r, c ) &&
 | |
|                   in_rct( &new_rct, r, c ) ) ||
 | |
|                 ( !in_rct( &old_rct, r, c ) &&
 | |
|                   !in_rct( &new_rct, r, c ) ) )
 | |
|               continue;
 | |
|             if ( r >= lmp->nbr_realized_rows || c >= lmp->nbr_columns ||
 | |
|                 r < 0 || c < 0 )
 | |
|               continue;
 | |
|             invert_selection( lmp, r, c, FALSE );
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*-------------------------------------------------------------------------
 | |
| function:   lm_event
 | |
| lm:         current lm
 | |
| ep:         xvt event
 | |
| return:     TRUE if event is consumed
 | |
| -------------------------------------------------------------------------*/
 | |
| #define DRAG_MARGIN 5
 | |
| 
 | |
| int
 | |
| lm_event( XI_OBJ * itf, LM lm, XinEvent * ep )
 | |
| {
 | |
|   int row,
 | |
|   column;
 | |
|   LM_DATA *lmp = LMP( lm );
 | |
|   BOOLEAN send_event = FALSE;
 | |
|   int retval = 1;
 | |
|   XinEvent oevt;
 | |
|   BOOLEAN ep_needs_restore = FALSE;
 | |
| 
 | |
|   oevt = *ep;
 | |
|   switch ( ep->type )
 | |
|   {
 | |
|     case XinEventMouseDown:
 | |
|     case XinEventMouseDouble:
 | |
|     case XinEventMouseMove:
 | |
|     case XinEventMouseUp:
 | |
|       {
 | |
|         XinRect rct;
 | |
| 
 | |
|         if ( lmp->attrib & XI_ATR_VISIBLE )
 | |
|         {
 | |
|           /* COORDINATE CONVERSION changes horizontal coordinates - moves mouse
 | |
|           * to the right - increases where.h if where.h is > lmp->vir_left, so
 | |
|           * that where.h is in the correct virtual horizontal space - also
 | |
|           * makes where.h be relative to the list, not the window. */
 | |
|           lm_get_rect( lm, LM_LIST, 0, &rct );
 | |
|           if ( xi_pt_in_rect( &rct, ep->v.mouse.where ) ||
 | |
|           lmp->selecting_cells || lmp->sizing_column || lmp->moving_column ||
 | |
|               lmp->down_in_btn || lmp->selecting_text || lmp->sizing_row ||
 | |
|               lmp->dragging_row || lmp->down_in_heading )
 | |
|           {
 | |
|             if ( ep->type == XinEventMouseDown )
 | |
|             {
 | |
|               if ( ep->v.mouse.where.h >= lmp->vir_left )
 | |
|                 lmp->down_in_hscrolling = TRUE;
 | |
|               else
 | |
|                 lmp->down_in_hscrolling = FALSE;
 | |
|             }
 | |
|             if ( !lmp->sizing_column )
 | |
|             {
 | |
|               if ( ( lmp->pixel_width && ( ep->v.mouse.where.h >= lmp->vir_left ) ) )
 | |
|               {
 | |
|                 ep->v.mouse.where.h += lmp->delta_x;
 | |
|                 lmp->in_hscrolling = TRUE;
 | |
|               }
 | |
|               else
 | |
|                 lmp->in_hscrolling = FALSE;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               if ( lmp->down_in_hscrolling )
 | |
|                 ep->v.mouse.where.h += lmp->delta_x;
 | |
|             }
 | |
|             ep->v.mouse.where.h -= lmp->rct.left;
 | |
|             ep_needs_restore = TRUE;
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             *ep = oevt;
 | |
|             return FALSE;
 | |
|           }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           *ep = oevt;
 | |
|           return FALSE;
 | |
|         }
 | |
|         break;
 | |
|       }
 | |
|     default:
 | |
|       break;
 | |
|   }
 | |
|   switch ( ep->type )
 | |
|   {
 | |
|     case XinEventPaint:
 | |
|       /* the following code sends the event directly on to redraw_cell if text
 | |
|       * is being scrolled in a text object. This speeds horizontal scrolling.
 | |
|       * see also lm_text_scrolling. */
 | |
|       if ( lmp->text_scrolling )
 | |
|       {
 | |
|         int row,
 | |
|         col;
 | |
|         BOOLEAN v_scrolled;
 | |
| 
 | |
|         lm_focus_cell_get( lmp, &row, &col, &v_scrolled );
 | |
|         draw_cell_range( lmp, row, row, col, col, FALSE );
 | |
|         if ( lm_focus_state_get( lmp ) != LM_FOCUS_VISIBLE )
 | |
|           send_cell_event( lm, &oevt, FALSE, TRUE );
 | |
|         lmp->text_scrolling = FALSE;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         draw_lm( lm, TRUE );
 | |
|         /* if ( lm_focus_state_get(lmp) != LM_FOCUS_VISIBLE ) */
 | |
|         send_cell_event( lm, &oevt, FALSE, TRUE );
 | |
|       }
 | |
|       retval = 0;
 | |
|       break;
 | |
|     case XinEventResize:
 | |
|       {
 | |
|         int new_height,
 | |
|         new_width;
 | |
|         XinRect hr,
 | |
|         vr,
 | |
|         cr;
 | |
|         XI_OBJ *list_obj;
 | |
| 
 | |
|         if ( lmp->resize_with_window )
 | |
|         {
 | |
|           XinRect rct,
 | |
|           wrct;
 | |
|           BOOLEAN replace_focus = FALSE;
 | |
| 
 | |
|           list_obj = lmp->list_obj;
 | |
|           if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | |
|             lm_focus_cell_invis_make( lmp );
 | |
|           else
 | |
|           {
 | |
|             if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | |
|             {
 | |
|               XI_OBJ *focus_obj = xi_get_focus(list_obj->itf);
 | |
|               if (focus_obj->type == XIT_CELL && focus_obj->parent == list_obj)
 | |
|                 replace_focus = TRUE;
 | |
|               if ( !xi_move_focus( list_obj->itf ) )
 | |
|               {
 | |
|                 retval = 0;
 | |
|                 break;
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|           xi_get_hsb_rect( list_obj, &hr );
 | |
|           xi_get_sb_rect( list_obj, &vr );
 | |
|           XinWindowRectGet( lmp->win, &cr );
 | |
|           new_height = cr.bottom - lmp->pix_top;
 | |
|           new_width = cr.right - lmp->rct.left;
 | |
|           xi_set_list_size( list_obj, new_height, new_width );
 | |
|           if ( ( BOOLEAN ) xi_get_pref( XI_PREF_LIMIT_MIN_WIN_SIZE ) )
 | |
|           {
 | |
|             xi_get_rect( list_obj, &rct );
 | |
|             if ( abs( rct.bottom - cr.bottom ) > 4 ||
 | |
|                 abs( rct.right - cr.right ) > 4 )
 | |
|             {
 | |
|               wrct = cr;
 | |
|               wrct.bottom = max( rct.bottom, cr.bottom );
 | |
|               wrct.right = max( rct.right, cr.right );
 | |
|               if ( wrct.bottom != cr.bottom || wrct.right != cr.right )
 | |
|               {
 | |
|                 XinWindowPointsTranslate( lmp->win, XinWindowParentGet( lmp->win ), ( XinPoint * ) & wrct, 2 );
 | |
|                 XinWindowRectSet( lmp->win, &wrct );
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|           if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | |
|             lm_focus_cell_visible_attempt( lmp );
 | |
|           else if (replace_focus)
 | |
|             xi_move_focus( list_obj );
 | |
|         }
 | |
|         retval = 0;
 | |
|         break;
 | |
|       }
 | |
|     case XinEventMouseDown:
 | |
|     case XinEventMouseDouble:
 | |
|       {
 | |
|         int hit_test_value;
 | |
|         BOOLEAN is_vis,
 | |
|         is_hit,
 | |
|         is_part_vis;
 | |
| 
 | |
|         if ( ep->v.mouse.button > 0 )
 | |
|           break;
 | |
| 
 | |
|         if ( lmp->single_select && lmp->position_by_typing_cid > 0 && lmp->position_by_typing_buf != NULL )
 | |
|           lmp->position_by_typing_buf[0] = '\0';
 | |
| 
 | |
|         hit_test_value = lm_hit_test( lm, ep, &oevt, &row, &column, &is_vis, &is_hit, &is_part_vis );
 | |
|         /* The row scrolled during the XinEventMouseDown */
 | |
|         if ( is_part_vis && ep->type == XinEventMouseDouble )
 | |
|           --row;
 | |
|         if ( is_part_vis && ep->type != XinEventMouseDouble )
 | |
|         {
 | |
|           XinEvent lep;
 | |
|           LM_SCROLL_ARG lm_scroll_arg;
 | |
|           static BOOLEAN in_here = FALSE;
 | |
| 
 | |
|           if ( in_here )
 | |
|             return FALSE;
 | |
|           MEMCLEAR( lm_scroll_arg );
 | |
|           lm_scroll_arg.lm = lm;
 | |
|           lm_scroll_arg.nbr_lines = 1;
 | |
|           /* lm_scroll_arg.percent = 0; lm_scroll_arg.same_cell = 0;
 | |
|           * lm_scroll_arg.rec = 0L; lm_scroll_arg.have_rec = FALSE;
 | |
|           * lm_scroll_arg.color = 0L; lm_scroll_arg.attrib = 0L;
 | |
|           * lm_scroll_arg.row_height = 0; lm_scroll_arg.rec_at_top = FALSE; */
 | |
| 
 | |
|           lm_focus_cell_invis_make( lmp );
 | |
|           calculate_pix_offsets( lmp, TRUE );
 | |
|           lm_make_rrr_room_pix( lmp, 0, FALSE );
 | |
|           lm_focus_cell_visible_attempt( lmp );
 | |
| 
 | |
|           lm_scroll( &lm_scroll_arg );
 | |
|           lep = oevt;
 | |
|           lep.v.mouse.where.v -= lm_scroll_arg.pixels_scrolled;
 | |
|           in_here = TRUE;
 | |
|           lm_event( itf, lm, &lep );
 | |
|           in_here = FALSE;
 | |
|           return TRUE;
 | |
|         }
 | |
|         if ( is_hit )
 | |
|         {
 | |
|           if ( lm_vsize_hit_test( lmp, ep, &row, &column ) )
 | |
|           {
 | |
|             XI_OBJ *itf,
 | |
|             *list;
 | |
| 
 | |
|             itf = lmp->itf_obj;
 | |
|             list = lmp->list_obj;
 | |
|             if ( list && xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | |
|             {
 | |
|               lm_focus_cell_invis_make( lmp );
 | |
|               xi_set_trap_obj( list );
 | |
|               lmp->row_being_sized = row;
 | |
|               lmp->sizing_row = TRUE;
 | |
|               XinWindowMouseTrap( lmp->win, TRUE );
 | |
|               lm_vsize_event( lmp, ep );
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               if ( list && xi_move_focus( itf ) )
 | |
|               {
 | |
|                 xi_set_trap_obj( list );
 | |
|                 lmp->row_being_sized = row;
 | |
|                 lmp->sizing_row = TRUE;
 | |
|                 XinWindowMouseTrap( lmp->win, TRUE );
 | |
|                 lm_vsize_event( lmp, ep );
 | |
|               }
 | |
|             }
 | |
|             break;
 | |
|           }
 | |
| 
 | |
|         }
 | |
| 
 | |
|         if ( lmp->select_cells )
 | |
|         {
 | |
|           int row,
 | |
|           column;
 | |
|           BOOLEAN on_disabled;
 | |
| 
 | |
|           if ( lm_select_cells_hit_test( lmp, ep, &row, &column, &on_disabled ) )
 | |
|           {
 | |
|             XI_OBJ *list;
 | |
| 
 | |
|             list = lmp->list_obj;
 | |
|             xi_set_trap_obj( list );
 | |
|             lmp->selecting_cells = TRUE;
 | |
|             lmp->down_row = row;
 | |
|             lmp->cur_row = row;
 | |
|             lmp->down_column = column;
 | |
|             lmp->cur_column = column;
 | |
|             lmp->down_on_disabled = on_disabled;
 | |
|             lm_select_cell_event( lmp, ep );
 | |
|             XinWindowMouseTrap( lmp->win, TRUE );
 | |
|             if ( on_disabled )
 | |
|             {
 | |
|               invert_selection( lmp, row, column, FALSE );
 | |
|               lmp->cur_row = row + 1;
 | |
|               lmp->cur_column = column + 1;
 | |
|             }
 | |
|             break;
 | |
|           }
 | |
|         }
 | |
| 
 | |
|         /* check for cell button hit */
 | |
|         if ( hit_test_value == 5 )
 | |
|           if ( LIST_IS_ENABLED( lm ) )
 | |
|             lm_cell_btn_event( lmp, ep, &oevt );
 | |
| 
 | |
|         /* check for focus acquisition */
 | |
|         if ( hit_test_value == 1 )
 | |
|         {
 | |
|           if ( row == -1 )
 | |
|           {
 | |
|             if ( LIST_IS_ENABLED( lm ) &&
 | |
|                 COLUMN_IS_SELECTABLE( lm, column ) &&
 | |
|                 ( ep->type == XinEventMouseDouble ||
 | |
|                   ( ep->type == XinEventMouseDown && !
 | |
|                     lmp->movable_columns && !xi_get_pref( XI_PREF_SINGLE_CLICK_COL_SELECT ) )
 | |
|                     ) )
 | |
|             {
 | |
|               unsigned long attrib;
 | |
|               LM_CB_DATA lm_cb_data;
 | |
| 
 | |
|               attrib = lm_get_attrib( lm, LM_COLUMN, column, 0, FALSE );
 | |
|               if ( ep->type == XinEventMouseDouble && !lmp->movable_columns )
 | |
|                 attrib |= LM_COL_ATR_SELECTED;
 | |
|               else
 | |
|               {
 | |
|                 if ( attrib & LM_COL_ATR_SELECTED )
 | |
|                   attrib &= ~LM_COL_ATR_SELECTED;
 | |
|                 else
 | |
|                   attrib |= LM_COL_ATR_SELECTED;
 | |
|               }
 | |
|               lm_cb_data.lm = lm;
 | |
|               lm_cb_data.cb_type = LM_CB_SELECT;
 | |
|               lm_cb_data.cid = lmp->cid;
 | |
|               lm_cb_data.win = lmp->win;
 | |
|               lm_cb_data.row = ( unsigned char ) 255;
 | |
|               lm_cb_data.column = ( unsigned char ) column;
 | |
|               lm_cb_data.v.select.selected =
 | |
|                       ( ( attrib & LM_COL_ATR_SELECTED ) != 0 );
 | |
|               lm_cb_data.v.select.dbl_click =
 | |
|                       ( ep->type == XinEventMouseDouble );
 | |
|               lm_cb_data.v.select.shift = ep->v.mouse.shift;
 | |
|               lm_cb_data.v.select.control = ep->v.mouse.control;
 | |
|               ( *lmp->lm_cb ) ( &lm_cb_data );
 | |
|               if ( !lm_cb_data.v.select.refused )
 | |
|                 lm_set_attrib( lm, LM_COLUMN, column, 0, FALSE, attrib,
 | |
|                               FALSE );
 | |
|             }
 | |
|             else if ( LIST_IS_ENABLED( lm ) &&
 | |
|                       COLUMN_IS_SELECTABLE( lm, column ) &&
 | |
|                       ( ep->type == XinEventMouseDouble ||
 | |
|                         ( ep->type == XinEventMouseDown &&
 | |
|                           !lmp->movable_columns && xi_get_pref( XI_PREF_SINGLE_CLICK_COL_SELECT ) )
 | |
|                         ) )
 | |
|             {                   /* Select on the mouse up if the mouse is still
 | |
|                                 * in the heading. */
 | |
|               XinRect rct;
 | |
| 
 | |
|               lmp->down_in_heading = TRUE;
 | |
|               lmp->column_being_moved = column;
 | |
|               lmp->down_pt = ep->v.mouse.where;
 | |
|               lmp->lm_column_data[column]->pushed = TRUE;
 | |
|               xi_set_trap_obj( lmp->list_obj );
 | |
|               XinWindowMouseTrap( lmp->win, TRUE );
 | |
|               lm_get_rect( lm, LM_COLUMN, column, &rct );
 | |
|               draw_column_headings( lmp, &rct );
 | |
|             }
 | |
| 
 | |
|             if ( LIST_IS_ENABLED( lm ) && COLUMN_IS_SELECTABLE( lm, column ) &&
 | |
|                 ep->type == XinEventMouseDown && lmp->movable_columns &&
 | |
|                 xi_get_pref( XI_PREF_SINGLE_CLICK_COL_SELECT ) )
 | |
|             {
 | |
|               /* If the mouse doesn't move much, we will select on the up.  If
 | |
|               * it does move, we will do a column move. */
 | |
|               XinRect rct;
 | |
| 
 | |
|               lmp->down_in_heading = TRUE;
 | |
|               lmp->column_being_moved = column;
 | |
|               lmp->down_pt = ep->v.mouse.where;
 | |
|               lmp->lm_column_data[column]->pushed = TRUE;
 | |
|               xi_set_trap_obj( lmp->list_obj );
 | |
|               XinWindowMouseTrap( lmp->win, TRUE );
 | |
|               lm_get_rect( lm, LM_COLUMN, column, &rct );
 | |
|               draw_column_headings( lmp, &rct );
 | |
|             }
 | |
|             else if ( LIST_IS_ENABLED( lm ) &&
 | |
|                       ( ep->type == XinEventMouseDown ||
 | |
|                         ( ep->type == XinEventMouseDouble &&
 | |
|                           !COLUMN_IS_SELECTABLE( lm, column ) ) ) &&
 | |
|                       lmp->movable_columns )
 | |
|             {
 | |
|               XI_OBJ *itf,
 | |
|               *list;
 | |
| 
 | |
|               itf = lmp->itf_obj;
 | |
|               list = lmp->list_obj;
 | |
|               if ( list && xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | |
|               {
 | |
|                 lm_focus_cell_invis_make( lmp );
 | |
|                 xi_set_trap_obj( list );
 | |
|                 lmp->column_being_moved = column;
 | |
|                 lmp->moving_column = TRUE;
 | |
|                 XinWindowMouseTrap( lmp->win, TRUE );
 | |
|                 lm_move_event( lmp, ep );
 | |
|               }
 | |
|               else
 | |
|               {
 | |
|                 if ( list && xi_move_focus( itf ) )
 | |
|                 {
 | |
|                   xi_set_trap_obj( list );
 | |
|                   lmp->column_being_moved = column;
 | |
|                   lmp->moving_column = TRUE;
 | |
|                   XinWindowMouseTrap( lmp->win, TRUE );
 | |
|                   lm_move_event( lmp, ep );
 | |
|                 }
 | |
|               }
 | |
|             }
 | |
|             break;
 | |
|           }
 | |
| 
 | |
|           if ( CELL_IS_SELECTABLE( lm, row, column ) )
 | |
|           {
 | |
|             lmp->down_pt = ep->v.mouse.where;
 | |
|             lmp->rec_being_moved = lmp->recs[row];
 | |
|             lmp->drag_row_height = lmp->pix_heights[row];
 | |
|             lmp->down_in_row = TRUE;
 | |
|             xi_set_trap_obj( lmp->list_obj );
 | |
|             if ( lmp->single_select )
 | |
|             {
 | |
|               lmp->list_obj->v.list->in_select_process = TRUE;
 | |
|               xi_move_focus( lmp->list_obj );
 | |
|               select_row( lm, row, column, ( BOOLEAN ) ( ep->type == XinEventMouseDouble ) );
 | |
|               if ( xi_is_itf( itf ) )
 | |
|                 lmp->list_obj->v.list->in_select_process = FALSE;
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               unsigned long attrib;
 | |
|               attrib = lm_get_attrib( lm, LM_ROW, row, 0, FALSE );
 | |
|               if ( lmp->drag_and_drop_rows && ( attrib & LM_ROW_ATR_SELECTED ) != 0
 | |
|                   && !ep->v.mouse.shift )
 | |
|               {
 | |
|                 lmp->delay_select = TRUE;
 | |
|                 lmp->delay_row = row;
 | |
|                 lmp->delay_column = column;
 | |
|                 lmp->delay_dbl = (ep->type == XinEventMouseDouble);
 | |
|               }
 | |
|               else
 | |
|                 send_select_event( lm, row, column, ep, attrib );
 | |
|             }
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             BOOLEAN gaining_focus = FALSE;
 | |
|             LM_CELL_DATA *cell_data = &lmp->cell_data[row][column];
 | |
| 
 | |
|             if ( !is_vis )
 | |
|               break;
 | |
| 
 | |
|             if ( !cell_data->icon_rid && cell_data->bitmap == NULL &&
 | |
|                 !cell_data->button_full_cell )
 | |
|             {
 | |
|               /* set this flag here, not later! */
 | |
|               lmp->have_mouse = TRUE;
 | |
| 
 | |
|               if ( lm_focus_state_get( lmp ) == LM_FOCUS_NOWHERE )
 | |
|               {
 | |
|                 send_event = do_lm_cb( lm, LM_CB_FOCUS, row, column,
 | |
|                                       NULL, NULL, 0 );
 | |
|                 gaining_focus = TRUE;
 | |
|               }
 | |
|               else
 | |
|               {
 | |
|                 if ( !lm_focus_cell_has( lmp, row, column, FALSE ) )
 | |
|                 {
 | |
|                   send_event = do_lm_cb( lm, LM_CB_FOCUS, row, column, NULL, NULL, 0 );
 | |
|                   /* send_event = FALSE if refused */
 | |
| 
 | |
|                   gaining_focus = send_event;
 | |
|                 }
 | |
|                 else
 | |
|                   send_event = TRUE;
 | |
|               }
 | |
|               if ( send_event )
 | |
|               {
 | |
|                 int focus_row,
 | |
|                 focus_column;
 | |
|                 BOOLEAN v_scrolled;
 | |
| 
 | |
|                 lm_focus_cell_get( lmp, &focus_row, &focus_column, &v_scrolled );
 | |
|                 if ( ( lmp->lm_column_data[focus_column]->attrib
 | |
|                       & LM_COL_ATR_AUTOSELECT )
 | |
|                     && xi_get_pref( XI_PREF_AUTOSEL_ON_MOUSE )
 | |
|                     && gaining_focus )
 | |
|                   ;
 | |
|                 else
 | |
|                 {
 | |
|                   XinWindowMouseTrap( lmp->win, TRUE );
 | |
|                   lmp->selecting_text = TRUE;
 | |
|                   send_cell_event( lm, &oevt, gaining_focus, TRUE );
 | |
|                 }
 | |
|               }
 | |
|               else
 | |
|                 lmp->have_mouse = FALSE;
 | |
|               if ( ep->type == XinEventMouseDouble )
 | |
|                 do_lm_cb( lm, LM_CB_DBL, row, column, NULL, NULL, 0 );
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           if ( LIST_IS_ENABLED( lm ) &&
 | |
|               lmp->sizable_columns &&
 | |
|               lm_size_hit_test( lm, ep, &column ) )
 | |
|           {
 | |
|             XI_OBJ *itf,
 | |
|             *list;
 | |
| 
 | |
|             itf = lmp->itf_obj;
 | |
|             list = lmp->list_obj;
 | |
|             if ( list && xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | |
|             {
 | |
|               lm_focus_cell_invis_make( lmp );
 | |
|               xi_set_trap_obj( list );
 | |
|               lmp->column_being_sized = column;
 | |
|               lmp->sizing_column = TRUE;
 | |
|               XinWindowMouseTrap( lmp->win, TRUE );
 | |
|               lm_size_event( lmp, ep );
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|               if ( list && xi_move_focus( itf ) )
 | |
|               {
 | |
|                 xi_set_trap_obj( list );
 | |
|                 lmp->column_being_sized = column;
 | |
|                 lmp->sizing_column = TRUE;
 | |
|                 XinWindowMouseTrap( lmp->win, TRUE );
 | |
|                 lm_size_event( lmp, ep );
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|           else
 | |
|             retval = 0;
 | |
|         }
 | |
|         break;
 | |
|       }
 | |
|     case XinEventMouseUp:
 | |
|       lmp->down_in_row = FALSE;
 | |
|       if ( lmp->single_select && lmp->position_by_typing_cid > 0 && lmp->position_by_typing_buf != NULL )
 | |
|         lmp->position_by_typing_buf[0] = '\0';
 | |
|       if ( lmp->selecting_cells )
 | |
|       {
 | |
|         LM_CB_DATA lm_cb_data;
 | |
| 
 | |
|         lm_select_cell_event( lmp, ep );
 | |
|         XinWindowMouseRelease(  );
 | |
|         lmp->selecting_cells = FALSE;
 | |
|         lmp->down_row = 0;
 | |
|         lmp->down_column = 0;
 | |
|         lm_cb_data.lm = lm;
 | |
|         lm_cb_data.cb_type = LM_CB_SELECT;
 | |
|         lm_cb_data.cid = lmp->cid;
 | |
|         lm_cb_data.win = lmp->win;
 | |
|         lm_cb_data.row = ( unsigned char ) 255;
 | |
|         lm_cb_data.column = ( unsigned char ) 255;
 | |
|         lm_cb_data.v.select.selected = TRUE;
 | |
|         lm_cb_data.v.select.dbl_click = FALSE;
 | |
|         lm_cb_data.v.select.shift = ep->v.mouse.shift;
 | |
|         lm_cb_data.v.select.control = ep->v.mouse.control;
 | |
|         ( *lmp->lm_cb ) ( &lm_cb_data );
 | |
|       }
 | |
|       if ( lmp->sizing_column )
 | |
|       {
 | |
|         lm_size_event( lmp, ep );
 | |
|         XinWindowMouseRelease(  );
 | |
|         lmp->sizing_column = FALSE;
 | |
|         lmp->column_being_sized = 0;
 | |
|         break;
 | |
|       }
 | |
|       if ( lmp->sizing_row )
 | |
|       {
 | |
|         lm_vsize_event( lmp, ep );
 | |
|         XinWindowMouseRelease(  );
 | |
|         lmp->sizing_row = FALSE;
 | |
|         lmp->row_being_sized = 0;
 | |
|         break;
 | |
|       }
 | |
|       if ( lmp->moving_column )
 | |
|       {
 | |
|         lm_move_event( lmp, ep );
 | |
|         XinWindowMouseRelease(  );
 | |
|         lmp->moving_column = FALSE;
 | |
|         lmp->column_being_moved = 0;
 | |
|         break;
 | |
|       }
 | |
|       if ( lmp->down_in_btn )
 | |
|       {
 | |
|         lm_cell_btn_event( lmp, ep, &oevt );
 | |
|         XinWindowMouseRelease(  );
 | |
|         lmp->down_in_btn = FALSE;
 | |
|         lmp->btn_down = FALSE;
 | |
|         break;
 | |
|       }
 | |
|       if ( lmp->dragging_row )
 | |
|       {
 | |
|         lm_drag_row_event( itf, lmp, ep, &oevt );
 | |
|         XinWindowMouseRelease(  );
 | |
|         lmp->dragging_row = FALSE;
 | |
|         break;
 | |
|       }
 | |
|       if ( lmp->delay_select )
 | |
|       {
 | |
|         unsigned long attrib = lm_get_attrib( lm, LM_ROW, lmp->delay_row, 0, FALSE );
 | |
| 
 | |
|         lmp->delay_select = FALSE;
 | |
|         if (lmp->delay_dbl)
 | |
|         {
 | |
|           XinEvent ev;
 | |
|           MEMCLEAR( ev );
 | |
|           ev.type = XinEventMouseDouble;
 | |
|           lmp->delay_dbl = FALSE;
 | |
|           send_select_event( lm, lmp->delay_row, lmp->delay_column, &ev, attrib );
 | |
|         }
 | |
|         else
 | |
|           send_select_event( lm, lmp->delay_row, lmp->delay_column, ep, attrib );
 | |
|         break;
 | |
|       }
 | |
|       if ( lmp->down_in_heading )
 | |
|       {
 | |
|         /* If the mouse is still in the heading, select the col. */
 | |
|         int hit_test_value;
 | |
|         BOOLEAN is_vis,
 | |
|         is_hit,
 | |
|         is_part_vis;
 | |
|         unsigned long attrib;
 | |
|         LM_CB_DATA lm_cb_data;
 | |
| 
 | |
|         lmp->lm_column_data[lmp->column_being_moved]->pushed = FALSE;
 | |
|         hit_test_value = lm_hit_test( lm, ep, &oevt, &row, &column, &is_vis,
 | |
|                                       &is_hit, &is_part_vis );
 | |
|         if ( hit_test_value == 1 && row == -1 && column == lmp->column_being_moved )
 | |
|         {
 | |
|           attrib = lm_get_attrib( lm, LM_COLUMN, column, 0, FALSE );
 | |
|           if ( attrib & LM_COL_ATR_SELECTED )
 | |
|             attrib &= ~LM_COL_ATR_SELECTED;
 | |
|           else
 | |
|             attrib |= LM_COL_ATR_SELECTED;
 | |
|           lm_cb_data.lm = lm;
 | |
|           lm_cb_data.cb_type = LM_CB_SELECT;
 | |
|           lm_cb_data.cid = lmp->cid;
 | |
|           lm_cb_data.win = lmp->win;
 | |
|           lm_cb_data.row = ( unsigned char ) 255;
 | |
|           lm_cb_data.column = ( unsigned char ) lmp->column_being_moved;
 | |
|           lm_cb_data.v.select.selected =
 | |
|                   ( ( attrib & LM_COL_ATR_SELECTED ) != 0 );
 | |
|           lm_cb_data.v.select.dbl_click = FALSE;
 | |
|           lm_cb_data.v.select.shift = ep->v.mouse.shift;
 | |
|           lm_cb_data.v.select.control = ep->v.mouse.control;
 | |
|           ( *lmp->lm_cb ) ( &lm_cb_data );
 | |
|           if ( !lm_cb_data.v.select.refused )
 | |
|             lm_set_attrib( lm, LM_COLUMN, column, 0, FALSE, attrib,
 | |
|                           FALSE );
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           XinRect rct;
 | |
| 
 | |
|           lm_get_rect( lm, LM_COLUMN, lmp->column_being_moved, &rct );
 | |
|           draw_column_headings( lmp, &rct );
 | |
|         }
 | |
|         XinWindowMouseRelease(  );
 | |
|         lmp->down_in_heading = FALSE;
 | |
|         lmp->column_being_moved = 0;
 | |
|         break;
 | |
|       }
 | |
|       if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | |
|       {
 | |
|         send_cell_event( lm, &oevt, FALSE, TRUE );
 | |
|         lmp->selecting_text = FALSE;
 | |
|         XinWindowMouseRelease(  );
 | |
|         lmp->have_mouse = FALSE;
 | |
|         break;
 | |
|       }
 | |
|       break;
 | |
|     case XinEventMouseMove:
 | |
|       {
 | |
|         BOOLEAN is_vis,
 | |
|         is_hit,
 | |
|         is_part_vis;
 | |
| 
 | |
|         if ( !( lmp->attrib & XI_ATR_VISIBLE ) )
 | |
|         {
 | |
|           retval = FALSE;
 | |
|           break;
 | |
|         }
 | |
|         if ( lmp->selecting_cells )
 | |
|         {
 | |
|           lm_select_cell_event( lmp, ep );
 | |
|           break;
 | |
|         }
 | |
|         if ( lmp->sizing_column )
 | |
|         {
 | |
|           lm_size_event( lmp, ep );
 | |
|           break;
 | |
|         }
 | |
|         if ( lmp->sizing_row )
 | |
|         {
 | |
|           lm_vsize_event( lmp, ep );
 | |
|           break;
 | |
|         }
 | |
|         if ( lmp->moving_column )
 | |
|         {
 | |
|           lm_move_event( lmp, ep );
 | |
|           break;
 | |
|         }
 | |
|         if ( lmp->down_in_btn )
 | |
|         {
 | |
|           lm_cell_btn_event( lmp, ep, &oevt );
 | |
|           break;
 | |
|         }
 | |
|         if ( lmp->dragging_row )
 | |
|         {
 | |
|           lm_drag_row_event( itf, lmp, ep, &oevt );
 | |
|           break;
 | |
|         }
 | |
|         if ( lmp->down_in_row && lmp->drag_and_drop_rows
 | |
|             && ( ep->v.mouse.where.v > lmp->down_pt.v + DRAG_MARGIN
 | |
|                   || ep->v.mouse.where.v < lmp->down_pt.v - DRAG_MARGIN
 | |
|                   || ep->v.mouse.where.h > lmp->down_pt.h + DRAG_MARGIN
 | |
|                   || ep->v.mouse.where.h < lmp->down_pt.h - DRAG_MARGIN ) )
 | |
|         {                       /* start row dragging */
 | |
|           lmp->down_in_row = FALSE;
 | |
|           lmp->delay_select = FALSE;
 | |
|           XinWindowMouseTrap( lmp->win, TRUE );
 | |
|           lm_drag_row_event( itf, lmp, ep, &oevt );
 | |
|         }
 | |
|         if ( lmp->down_in_heading && lmp->movable_columns
 | |
|             && ( ep->v.mouse.where.v > lmp->down_pt.v + DRAG_MARGIN
 | |
|                   || ep->v.mouse.where.v < lmp->down_pt.v - DRAG_MARGIN
 | |
|                   || ep->v.mouse.where.h > lmp->down_pt.h + DRAG_MARGIN
 | |
|                   || ep->v.mouse.where.h < lmp->down_pt.h - DRAG_MARGIN ) )
 | |
|         {
 | |
|           /* The user moved far enough to switch to moving the column. */
 | |
|           XI_OBJ *itf,
 | |
|           *list;
 | |
|           XinPoint where;
 | |
|           XinRect rct;
 | |
| 
 | |
|           lmp->down_in_heading = FALSE;
 | |
|           lmp->lm_column_data[lmp->column_being_moved]->pushed = FALSE;
 | |
|           lm_get_rect( lm, LM_COLUMN, lmp->column_being_moved, &rct );
 | |
|           draw_column_headings( lmp, &rct );
 | |
|           itf = lmp->itf_obj;
 | |
|           list = lmp->list_obj;
 | |
|           if ( list && xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED ) )
 | |
|           {
 | |
|             lm_focus_cell_invis_make( lmp );
 | |
|             lmp->moving_column = TRUE;
 | |
|             ep->type = XinEventMouseDown;
 | |
|             where = ep->v.mouse.where;
 | |
|             ep->v.mouse.where = lmp->down_pt;
 | |
|             lm_move_event( lmp, ep );
 | |
|             ep->type = XinEventMouseMove;
 | |
|             ep->v.mouse.where = where;
 | |
|             lm_move_event( lmp, ep );
 | |
|           }
 | |
|           else
 | |
|           {
 | |
|             if ( list && xi_move_focus( itf ) )
 | |
|             {
 | |
|               lmp->moving_column = TRUE;
 | |
|               ep->type = XinEventMouseDown;
 | |
|               where = ep->v.mouse.where;
 | |
|               ep->v.mouse.where = lmp->down_pt;
 | |
|               lm_move_event( lmp, ep );
 | |
|               ep->type = XinEventMouseMove;
 | |
|               ep->v.mouse.where = where;
 | |
|               lm_move_event( lmp, ep );
 | |
|             }
 | |
|             else
 | |
|               lmp->column_being_moved = 0;
 | |
|           }
 | |
|           break;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           int hit_test_value;
 | |
|           BOOLEAN is_vis,
 | |
|           is_hit,
 | |
|           is_part_vis;
 | |
| 
 | |
|           hit_test_value = lm_hit_test( lm, ep, &oevt, &row, &column, &is_vis,
 | |
|                                         &is_hit, &is_part_vis );
 | |
|           if ( lmp->down_in_heading && !lmp->movable_columns &&
 | |
|               lmp->lm_column_data[lmp->column_being_moved]->pushed == TRUE &&
 | |
|               ( hit_test_value != 1 || row != -1 || column != lmp->column_being_moved ) )
 | |
|           {
 | |
|             XinRect rct;
 | |
| 
 | |
|             lmp->lm_column_data[lmp->column_being_moved]->pushed = FALSE;
 | |
|             lm_get_rect( lm, LM_COLUMN, lmp->column_being_moved, &rct );
 | |
|             draw_column_headings( lmp, &rct );
 | |
|           }
 | |
|           else if ( lmp->down_in_heading && !lmp->movable_columns &&
 | |
|               lmp->lm_column_data[lmp->column_being_moved]->pushed == FALSE &&
 | |
|                     ( hit_test_value == 1 && row == -1 && column == lmp->column_being_moved ) )
 | |
|           {
 | |
|             XinRect rct;
 | |
| 
 | |
|             lmp->lm_column_data[lmp->column_being_moved]->pushed = TRUE;
 | |
|             lm_get_rect( lm, LM_COLUMN, lmp->column_being_moved, &rct );
 | |
|             draw_column_headings( lmp, &rct );
 | |
|           }
 | |
|         }
 | |
|         if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | |
|           send_cell_event( lm, &oevt, FALSE, TRUE );
 | |
|         retval = lm_hit_test( lm, ep, &oevt, &row, &column, &is_vis, &is_hit, &is_part_vis );
 | |
|         if ( is_part_vis )
 | |
|         {
 | |
|           unsigned long attrib;
 | |
| 
 | |
|           attrib = lmp->lm_column_data[column]->attrib;
 | |
|           if ( attrib & XI_ATR_SELECTABLE )
 | |
|             return 0;
 | |
|           if ( !retval )
 | |
|             retval = 1;
 | |
|           return retval;
 | |
|         }
 | |
|         if ( is_hit )
 | |
|         {
 | |
|           if ( LIST_IS_ENABLED( lm ) &&
 | |
|               lm_vsize_hit_test( lmp, ep, &row, &column ) )
 | |
|           {
 | |
|             *ep = oevt;
 | |
|             return 6;
 | |
|           }
 | |
|         }
 | |
|         if ( LIST_IS_ENABLED( lm ) &&
 | |
|             lmp->select_cells &&
 | |
|             lm_select_cells_hit_test( lmp, ep, NULL, NULL, NULL ) )
 | |
|         {
 | |
|           *ep = oevt;
 | |
|           return 4;
 | |
|         }
 | |
|         if ( LIST_IS_ENABLED( lm ) &&
 | |
|             lmp->sizable_columns &&
 | |
|             lm_size_hit_test( lm, ep, &column ) )
 | |
|         {
 | |
|           *ep = oevt;
 | |
|           return 2;
 | |
|         }
 | |
|         if ( retval )
 | |
|         {
 | |
|           if ( !is_vis )
 | |
|           {
 | |
|             *ep = oevt;
 | |
|             return 5;
 | |
|           }
 | |
|           if ( CELL_IS_SELECTABLE( lm, row, column ) )
 | |
|             retval = 5;
 | |
|           if ( row == -1 )
 | |
|             retval = 5;
 | |
|           if ( row >= 0 && ( lmp->cell_data[row][column].icon_rid
 | |
|                             || lmp->cell_data[row][column].bitmap != NULL ) )
 | |
|             retval = 5;
 | |
|           if ( row >= 0 && lmp->cell_data[row][column].button_full_cell )
 | |
|             retval = 5;
 | |
|           if ( LIST_IS_ENABLED( lm ) &&
 | |
|               lmp->movable_columns &&
 | |
|               lm_hit_test( lm, ep, &oevt, &row, &column, NULL, NULL, NULL ) )
 | |
|             if ( row == -1 )
 | |
|               retval = 3;
 | |
|         }
 | |
|         break;
 | |
|       }
 | |
|     case XinEventCharacter:
 | |
|       if ( xi_get_pref( XI_PREF_KEEP_FOCUS_FIXED )
 | |
|           && ep->v.character.ch != XI_KEY_NEXT
 | |
|           && ep->v.character.ch != XI_KEY_PREV )
 | |
|       {
 | |
|         int row,
 | |
|         column;
 | |
|         BOOLEAN v_scrolled;
 | |
|         LM_FOCUS_CELL_VISIBLE_FORCE_ARGS args;
 | |
| 
 | |
|         lm_focus_cell_get( lmp, &row, &column, &v_scrolled );
 | |
|         MEMCLEAR( args );
 | |
|         args.lmp = lmp;
 | |
|         args.row = row;
 | |
|         args.column = column;
 | |
|         args.vert_scrolled = v_scrolled;
 | |
|         lm_focus_cell_visible_force( &args );
 | |
|       }
 | |
|       {
 | |
|         long button_key;
 | |
|         BOOLEAN shift,
 | |
|         control,
 | |
|         alt;
 | |
|         int focus_row,
 | |
|         focus_column;
 | |
|         BOOLEAN h_scrolled;
 | |
| 
 | |
|         button_key = xi_get_pref( XI_PREF_BUTTON_KEY );
 | |
|         shift = ( BOOLEAN ) ( ( button_key & XI_MOD_SHIFT ) != 0 );
 | |
|         control = ( BOOLEAN ) ( ( button_key & XI_MOD_CONTROL ) != 0 );
 | |
|         alt = ( BOOLEAN ) ( ( button_key & XI_MOD_ALT ) != 0 );
 | |
|         button_key &= 0xffffffL;
 | |
|         if ( button_key == ep->v.character.ch &&
 | |
|             shift == ep->v.character.shift &&
 | |
|             control == ep->v.character.control &&
 | |
|             alt == ep->v.character.alt )
 | |
|         {
 | |
|           if ( lm_focus_cell_get( lmp, &focus_row, &focus_column, &h_scrolled )
 | |
|               && lmp->cell_data[focus_row][focus_column].button )
 | |
|             do_lm_cb( ( LM ) lmp, LM_CB_CELL_BTN, focus_row, focus_column, ep, NULL, 0 );
 | |
|           return FALSE;
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       if ( lmp->single_select )
 | |
|       {
 | |
|         BOOLEAN clear_buffer = TRUE;
 | |
|         switch ( ep->v.character.ch )
 | |
|         {
 | |
|           case XI_KEY_UP:
 | |
|             {
 | |
|               int cur_row = find_selection( lmp );
 | |
| 
 | |
|               if ( cur_row == -1 )
 | |
|                 cur_row = 0;
 | |
|               else
 | |
|               {
 | |
|                 if ( cur_row == 0 )
 | |
|                   xi_scroll( lmp->list_obj, -1 );
 | |
|                 else
 | |
|                   cur_row--;
 | |
|               }
 | |
|               select_row( lm, cur_row, -1, FALSE );
 | |
|               break;
 | |
|             }
 | |
|           case XI_KEY_DOWN:
 | |
|             {
 | |
|               int cur_row = find_selection( lmp );
 | |
| 
 | |
|               if ( cur_row == -1 )
 | |
|                 cur_row = 0;
 | |
|               else
 | |
|               {
 | |
|                 if ( cur_row == lmp->last_fully_vis )
 | |
|                   xi_scroll( lmp->list_obj, 1 );
 | |
|                 else
 | |
|                   cur_row++;
 | |
|               }
 | |
|               select_row( lm, cur_row, -1, FALSE );
 | |
|               break;
 | |
|             }
 | |
|           case XI_KEY_PREV:
 | |
|             xi_scroll( lmp->list_obj, XI_SCROLL_PGUP );
 | |
|             select_row( lm, lmp->last_fully_vis, -1, FALSE );
 | |
|             break;
 | |
|           case XI_KEY_NEXT:
 | |
|             xi_scroll( lmp->list_obj, XI_SCROLL_PGDOWN );
 | |
|             select_row( lm, 0, -1, FALSE );
 | |
|             break;
 | |
|           case XI_KEY_HOME:
 | |
|           case XI_KEY_LHOME:
 | |
|             xi_scroll( lmp->list_obj, XI_SCROLL_FIRST );
 | |
|             select_row( lm, 0, -1, FALSE );
 | |
|             break;
 | |
|           case XI_KEY_END:
 | |
|           case XI_KEY_LEND:
 | |
|             xi_scroll( lmp->list_obj, XI_SCROLL_LAST );
 | |
|             select_row( lm, lmp->last_fully_vis, -1, FALSE );
 | |
|             break;
 | |
|           case '\r':
 | |
|           case ' ':
 | |
|           case '\n':
 | |
|             row = find_selection( lmp );
 | |
|             select_row( lm, row, -1, TRUE );
 | |
|             clear_buffer = FALSE;
 | |
| #if 0
 | |
|             if ( row != -1 )
 | |
|             {
 | |
|               LM_CB_DATA lm_cb_data;
 | |
| 
 | |
|               lm_cb_data.lm = lm;
 | |
|               lm_cb_data.cb_type = LM_CB_SELECT;
 | |
|               lm_cb_data.cid = lmp->cid;
 | |
|               lm_cb_data.win = lmp->win;
 | |
|               lm_cb_data.row = ( unsigned char ) row;
 | |
|               lm_cb_data.column = ( unsigned char ) get_select_column( lmp );
 | |
|               lm_cb_data.v.select.selected = TRUE;
 | |
|               lm_cb_data.v.select.dbl_click = TRUE;
 | |
|               lm_cb_data.v.select.shift = FALSE;
 | |
|               lm_cb_data.v.select.control = FALSE;
 | |
|               ( *lmp->lm_cb ) ( &lm_cb_data );
 | |
|             }
 | |
| #endif
 | |
|             break;
 | |
|           default:
 | |
|             if ( lmp->position_by_typing_cid > 0 )
 | |
|             {
 | |
|               int len, old_len;
 | |
|               if (lmp->position_by_typing_buf == NULL)
 | |
|               {
 | |
|                 lmp->position_by_typing_buf = (char *)xi_tree_malloc( 100 * sizeof(char), lmp->list_obj );
 | |
|                 memset( lmp->position_by_typing_buf, '\0', 100 * sizeof( char ) );
 | |
|               }
 | |
|               len = old_len = strlen( lmp->position_by_typing_buf );
 | |
|               if (ep->v.character.ch == '\b')
 | |
|               {
 | |
|                 if (len > 0)
 | |
|                 {
 | |
|                   lmp->position_by_typing_buf[len-1] = '\0';
 | |
|                   len--;
 | |
|                 }
 | |
|               } else {
 | |
|                 lmp->position_by_typing_buf[len] = (char)(toupper(ep->v.character.ch));
 | |
|                 lmp->position_by_typing_buf[len+1] = '\0';
 | |
|                 len++;
 | |
|               }
 | |
|               /* Find the row that matches the buffer and scroll to it. */
 | |
|               if (len == 0)
 | |
|                 xi_scroll( lmp->list_obj, XI_SCROLL_FIRST );
 | |
|               else {
 | |
|                 BOOLEAN use_allocate_free = FALSE;
 | |
|                 BOOLEAN do_first = FALSE;     /* Should we send an XIE_GET_FIRST the first time thru the loop? */
 | |
|                 BOOLEAN done_first = FALSE;   /* have we been thru the loop at least once? */
 | |
|                 BOOLEAN do_get = TRUE; /* Should we send an XIE_GET_? at all? */
 | |
|                 BOOLEAN found = FALSE;
 | |
|                 BOOLEAN right_row = FALSE;
 | |
|                 int comp_len;
 | |
|                 int comp_result;
 | |
|                 long spec_rec, data_rec = 0L, swap_rec, start_rec = 0L;
 | |
|                 XI_EVENT xiev;
 | |
|                 char text_buffer[200];
 | |
|                 int col_nbr;
 | |
| 
 | |
|                 {
 | |
|                   int nbr_cols;
 | |
|                   XI_OBJ **col;
 | |
|                   col_nbr = 0;
 | |
|                   col = xi_get_member_list( lmp->list_obj, & nbr_cols );
 | |
|                   while (nbr_cols)
 | |
|                   {
 | |
|                     if ((*col)->cid == lmp->position_by_typing_cid)
 | |
|                       break;
 | |
|                     col_nbr++;
 | |
|                     nbr_cols--;
 | |
|                     col++;
 | |
|                   }
 | |
|                   if (!nbr_cols)
 | |
|                     return FALSE;
 | |
|                 }
 | |
|                 MEMCLEAR( xiev );
 | |
|                 /* We need two handles, which we will alternate between spec and data_rec. */
 | |
|                 xiev.type = XIE_REC_ALLOCATE;
 | |
|                 xiev.v.rec_allocate.list = lmp->list_obj;
 | |
|                 (itf->v.itf->xi_eh) ( itf, &xiev );
 | |
|                 if ( xiev.refused )
 | |
|                   return FALSE;
 | |
|                 spec_rec = xiev.v.rec_allocate.record;
 | |
|                 if (spec_rec != 0)
 | |
|                 {
 | |
|                   use_allocate_free = TRUE;
 | |
|                   (itf->v.itf->xi_eh) ( itf, &xiev );
 | |
|                   if ( xiev.refused )
 | |
|                     return FALSE;
 | |
|                   data_rec = xiev.v.rec_allocate.record;
 | |
|                 }
 | |
| 
 | |
|                 if (old_len > len || len  == 1)
 | |
|                   do_first = TRUE;
 | |
| 
 | |
|                 while (!found)
 | |
|                 {
 | |
|                   MEMCLEAR( xiev );
 | |
|                   xiev.v.rec_request.list = lmp->list_obj;
 | |
|                   if (use_allocate_free)
 | |
|                     xiev.v.rec_request.data_rec = data_rec;
 | |
|                   if (!done_first)
 | |
|                   {
 | |
|                     if (do_first)
 | |
|                       xiev.type = XIE_GET_FIRST;
 | |
|                     else {
 | |
|                       int row = find_selection( lmp );
 | |
|                       if (row != -1)
 | |
|                       {
 | |
|                         xiev.type = XIE_GET_NEXT;
 | |
|                         start_rec = lmp->recs[row];
 | |
|                         do_get = FALSE; /* We have the record.  Don't send an XIE_GET_? */
 | |
|                       } else
 | |
|                         xiev.type = XIE_GET_FIRST;
 | |
|                     }
 | |
|                   } else {
 | |
|                     xiev.type = XIE_GET_NEXT;
 | |
|                     xiev.v.rec_request.spec_rec = spec_rec;
 | |
|                   }
 | |
|                   if (do_get)
 | |
|                   {
 | |
|                     (itf->v.itf->xi_eh) ( itf, &xiev );
 | |
|                     if ( xiev.refused )
 | |
|                       break;
 | |
|                   }
 | |
|                   done_first = TRUE;
 | |
|                   if (use_allocate_free)
 | |
|                   {
 | |
|                     swap_rec = data_rec;
 | |
|                     data_rec = spec_rec;
 | |
|                     spec_rec = swap_rec;
 | |
|                   } else
 | |
|                     spec_rec = xiev.v.rec_request.data_rec;
 | |
|                   MEMCLEAR( xiev );
 | |
|                   xiev.type = XIE_CELL_REQUEST;
 | |
|                   xiev.v.cell_request.list = lmp->list_obj;
 | |
|                   xiev.v.cell_request.s = text_buffer;
 | |
|                   xiev.v.cell_request.len = 200;
 | |
|                   if (do_get)
 | |
|                     xiev.v.cell_request.rec = spec_rec;
 | |
|                   else
 | |
|                     xiev.v.cell_request.rec = start_rec;
 | |
|                   xiev.v.cell_request.col_nbr = col_nbr;
 | |
|                   (itf->v.itf->xi_eh) ( itf, &xiev );
 | |
|                   comp_len = len;
 | |
|                   if (xiev.v.cell_request.len < comp_len)
 | |
|                     comp_len = xiev.v.cell_request.len;
 | |
|                   {
 | |
|                     int i = 0;
 | |
|                     for (; i < comp_len; i++)
 | |
|                       xiev.v.cell_request.s[i] = toupper( xiev.v.cell_request.s[i] );
 | |
|                   }
 | |
|                   comp_result = strncmp(lmp->position_by_typing_buf, xiev.v.cell_request.s, comp_len);
 | |
|                   if (comp_result == 0) {
 | |
|                     found = TRUE;
 | |
|                     right_row = TRUE;
 | |
|                   } else if (comp_result < 0) {
 | |
|                     found = TRUE;
 | |
|                     right_row = FALSE;
 | |
|                     do_get = TRUE;
 | |
|                   } else
 | |
|                     do_get = TRUE;
 | |
|                 }
 | |
|                 if (right_row)
 | |
|                 {
 | |
|                   int i;
 | |
|                   long test_rec;
 | |
|                   if (do_get)
 | |
|                     test_rec = spec_rec;
 | |
|                   else
 | |
|                     test_rec = start_rec;
 | |
| 
 | |
|                   for (i = 0; i < lmp->nbr_realized_rows; i++)
 | |
|                     if (lmp->recs[i] == test_rec)
 | |
|                       break;
 | |
|                   if (i >= lmp->nbr_realized_rows)
 | |
|                   {
 | |
|                     XI_SCROLL_RECORD_ARG arg;
 | |
|                     MEMCLEAR( arg );
 | |
|                     arg.xi_obj = lmp->list_obj;
 | |
|                     if (do_get)
 | |
|                       arg.record = spec_rec;
 | |
|                     else
 | |
|                       arg.record = start_rec;
 | |
|                     arg.rec_at_top = TRUE;
 | |
|                     xi_scroll_record( &arg );
 | |
|                     for (i = 0; i < lmp->nbr_realized_rows; i++)
 | |
|                       if (lmp->recs[i] == test_rec)
 | |
|                         break;
 | |
|                   }
 | |
|                   if (i < lmp->nbr_realized_rows)
 | |
|                   {
 | |
|                     long attrib;
 | |
|               attrib = lm_get_attrib( lm, LM_ROW, i, 0, FALSE );
 | |
|               if ( !(attrib & LM_ROW_ATR_SELECTED) )
 | |
|               select_row( lm, i, -1, FALSE );
 | |
|             }
 | |
|           } else {
 | |
|             XinBeep();
 | |
|             lmp->position_by_typing_buf[len-1] = '\0';
 | |
|                 }
 | |
|                 if (use_allocate_free)
 | |
|                 {
 | |
|                   MEMCLEAR( xiev );
 | |
|                   xiev.type = XIE_REC_FREE;
 | |
|                   xiev.v.rec_free.list = lmp->list_obj;
 | |
|                   xiev.v.rec_free.record = data_rec;
 | |
|                   (itf->v.itf->xi_eh) ( itf, &xiev );
 | |
|                   if (!right_row || !do_get)
 | |
|                   {
 | |
|                     xiev.v.rec_free.record = spec_rec;
 | |
|                     (itf->v.itf->xi_eh) ( itf, &xiev );
 | |
|                   }
 | |
|                 }
 | |
|               }
 | |
|               clear_buffer = FALSE;
 | |
|             } else
 | |
|               return FALSE;
 | |
|         }
 | |
|         if (clear_buffer && lmp->position_by_typing_buf != NULL)
 | |
|           lmp->position_by_typing_buf[0] = '\0';
 | |
|         return TRUE;
 | |
|       }
 | |
| 
 | |
|       if ( !lmp->sizing_row )
 | |
|       {
 | |
|         BOOLEAN nav_ret = FALSE;
 | |
| 
 | |
|         if ( !lmp->itf_obj->v.itf->pasting )
 | |
|           nav_ret = ( BOOLEAN ) navigate_char_event( lm, ep );
 | |
|         if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | |
|         {
 | |
|           int ch = ep->v.character.ch;
 | |
|           retval = send_cell_event( lm, ep, FALSE, ( BOOLEAN ) ( !nav_ret ) );
 | |
|           /* If the high-level application wants to do its own autotabbing, it
 | |
|           * will change the character to a tab, so we need to process that
 | |
|           * here. */
 | |
|           if ( ep->v.character.ch != ch )
 | |
|             nav_ret = ( BOOLEAN ) navigate_char_event( lm, ep );
 | |
|         }
 | |
|         else
 | |
|           retval = FALSE;
 | |
|       }
 | |
|       break;
 | |
|     case XinEventDestroy:
 | |
|       retval = 0;
 | |
|       break;
 | |
|     case XinEventTimer:
 | |
|     case XinEventMenuCommand:
 | |
|       if ( lm_focus_state_get( lmp ) == LM_FOCUS_VISIBLE )
 | |
|         retval = send_cell_event( lm, ep, FALSE, TRUE );
 | |
|       break;
 | |
|     default:
 | |
|       break;
 | |
|   }
 | |
|   if ( ep_needs_restore )
 | |
|     *ep = oevt;
 | |
|   return ( retval );
 | |
| }
 |