static void GoForward( a_window *wnd, wnd_coord *end, wnd_line_piece *line ) { char ch; ch = line->text[ end->col ]; if( isspace( ch ) || !WndIDChar( wnd, ch ) ) { end->col += GUICharLen( ch ) - 1; return; } for( ;; ) { end->col += GUICharLen( ch ); ch = line->text[end->col]; if( isspace( ch ) || !WndIDChar( wnd, ch ) ) { end->col--; return; } } }
static void GoBackward( a_window *wnd, wnd_coord *start, wnd_line_piece *line ) { char ch; ch = line->text[ start->col ]; if( isspace( ch ) || !WndIDChar( wnd, ch ) ) return; for( ;; ) { if( start->col == 0 ) return; start->col = WndPrevCharCol( line->text, start->col ); ch = line->text[ start->col ]; if( isspace( ch ) || !WndIDChar( wnd, ch ) ) { start->col += GUICharLen( ch ); return; } } }
static void WndDrawCursor( a_window *wnd, wnd_line_piece *line, wnd_row row, int piece ) { const char *p; if( _Is( wnd, WSW_NOT_TO_SCREEN ) ) return; if( _Isnt( wnd, WSW_CHAR_CURSOR ) ) return; if( !line->tabstop ) return; if( wnd->current.row != row ) return; if( wnd->current.piece != piece ) return; if( wnd->current.col < 0 ) return; if( line->length == 0 ) { GUIDrawText( wnd->gui, " ", 1, row, line->indent, WndCursorAttr ); } else if( wnd->current.col < line->length ) { line->indent += GUIGetExtentX( wnd->gui, line->text, wnd->current.col ); p = line->text + wnd->current.col; GUIDrawText( wnd->gui, p, GUICharLen( *p ), row, line->indent, WndCursorAttr ); } }
static bool WndCursorRightCheck( a_window *wnd ) { wnd_line_piece line; int col; bool got; got = WndGetLine( wnd, wnd->current.row, wnd->current.piece, &line ); if( _Isnt( wnd, WSW_CHAR_CURSOR ) || !WndHasCurrent( wnd ) || !got || wnd->current.col + 1 >= line.length ) { return( WndTabRight( wnd, false ) ); } else { WndDirtyCurrChar( wnd ); col = wnd->current.col; wnd->current.col += GUICharLen( line.text[wnd->current.col] ); WndSetCurrCol( wnd ); WndCurrVisible( wnd ); WndDirtyCurrChar( wnd ); return( col != wnd->current.col ); } }
void GUIXDrawText( gui_window *wnd, const char *text, size_t length, gui_coord *in_pos, gui_attr attr, gui_ord extentx, bool draw_extent ) { int vscroll; /* vertical scroll adjust amount */ int hscroll; /* horizontal scroll adjust amount */ size_t my_length; /* actual length of text (may be > length) */ gui_coord my_pos; /* pos in screen coords */ int pos; /* position to draw on VSCREEN */ int col; /* index into string */ gui_coord extent; SAREA area; int width; int frame_adjust; if( attr >= wnd->num_attrs ) { return; } if( !( wnd->style & GUI_VISIBLE ) ) { return; } if( wnd->style & GUI_NOFRAME ) { frame_adjust = 0; } else { frame_adjust = 1; } my_pos.x = in_pos->x; my_pos.y = in_pos->y; GUIScaleToScreenR( &my_pos ); /* adjust for scrolling */ vscroll = 0; if( ( wnd->vgadget != NULL ) && ( !GUI_VSCROLL_EVENTS_SET( wnd ) ) ) { vscroll += wnd->vgadget->pos; } hscroll = 0; if( ( wnd->hgadget != NULL ) && !GUI_HSCROLL_EVENTS_SET( wnd ) ) { hscroll += wnd->hgadget->pos; } if( ( my_pos.y - vscroll + frame_adjust ) < frame_adjust ) { /* row to draw is not visible with vertical scrolling */ return; } if( text != NULL ) { my_length = strlen( text ); if( my_length < length ) { length = my_length; } } else { my_length = 0; } /* if text shows even with scrolling */ if( ( my_pos.x + length ) > hscroll ) { pos = frame_adjust; /* position on VSCREEN */ col = 0; /* index into curr string */ /* start of text in dirty region */ if( ( ( wnd->dirty.col - 1 ) <= ( my_pos.x - hscroll ) ) && ( my_pos.x >= hscroll ) ) { pos += ( my_pos.x - hscroll ); } else { /* start of text to left of dirty region */ pos += wnd->dirty.col - 1; if( my_pos.x < hscroll ) { /* start of text scrolled off screen */ col += ( hscroll - my_pos.x + wnd->dirty.col - 1 ); length -= ( hscroll - my_pos.x + wnd->dirty.col - 1 ); } else { /* start of text visible but to left of dirty region */ col += ( wnd->dirty.col - 1 + hscroll - my_pos.x ); length -= ( wnd->dirty.col - 1 + hscroll - my_pos.x ); } } /* should deal with decreasing length due to text off screen to right */ if( ( length > 0 ) && ( ( col - hscroll ) < ( wnd->dirty.col + wnd->dirty.width ) ) ) { if( ( pos + length ) > ( wnd->dirty.col + wnd->dirty.width ) ) { length = wnd->dirty.col + wnd->dirty.width - pos; } if( length > 0 ) { char *p; const char *cp; for( cp = text; cp < text+col; cp += GUICharLen( *cp ) ) ; if( cp != text + col ) { p = alloca( length ); cp = memcpy( p, text+col, length ); p[0] = ' '; } uivtextput( &wnd->screen, my_pos.y - vscroll + frame_adjust, pos, wnd->colours[attr], cp, length ); } else { length = 0; } } else { length = 0; } } else { pos = -length + 1; /* so (pos+length) will be 1 for drawing extent */ } if( draw_extent ) { if( extentx == GUI_NO_COLUMN ) { /* this is the most that will be covered. It will be adjust for starting position and dirty rect */ extentx = wnd->use.width; } else { /* record total width user wants to cover, adjusting for * portion not visible due to scrolling scrolling */ extent.x = extentx + in_pos->x; GUIScaleToScreenR( &extent ); extentx = extent.x - hscroll; } if( ( pos + length ) <= extentx ) { area.row = my_pos.y - vscroll + frame_adjust; area.height = 1; area.col = pos + length; /* adjust left border for dirty area */ if( area.col < wnd->dirty.col ) { area.col = wnd->dirty.col; } width = extentx - area.col + 1; /* adjust right border for dirty area */ if( ( area.col + width ) > ( wnd->dirty.col + wnd->dirty.width ) ) { width = wnd->dirty.width + wnd->dirty.col - area.col; } if( width > 0 ) { area.width = width; uivfill( &wnd->screen, area, wnd->colours[attr], ' ' ); } } } }
void WndPaintDirt( a_window *wnd ) { int i; wnd_line_piece line; wnd_line_piece next_piece_line; gui_rect rect; wnd_dirt *dirt; gui_coord size; gui_coord half_char; a_window *next; // a_window *last; // last = NULL; for( wnd = WndNext( NULL ); wnd != NULL; wnd = next ) { next = WndNext( wnd ); if( wnd->vscroll_pending != 0 ) { if( wnd->hscroll_pending != -1 ) { _Set( wnd, WSW_REPAINT ); } if( _Is( wnd, WSW_REPAINT ) ) { if( wnd->hscroll_pending != -1 ) { GUIInitHScroll( wnd->gui, wnd->hscroll_pending ); } WndRepaint( wnd ); wnd->hscroll_pending = -1; wnd->vscroll_pending = 0; } else { for( i = 0; i < wnd->title_size; ++i ) { GUIDrawTextExtent( wnd->gui, " ", 1, i, 0, GUI_BACKGROUND, GUI_NO_COLUMN ); } GUIDoVScrollClip( wnd->gui, wnd->vscroll_pending, wnd->title_size, wnd->rows - 1 ); wnd->vscroll_pending = 0; } } if( _Is( wnd, WSW_REPAINT ) ) { _Clr( wnd, WSW_REPAINT ); WndKillCacheLines( wnd ); WndCheckCurrentValid( wnd ); GUIWndDirty( wnd->gui ); if( wnd->max_indent != 0 && wnd->width >= wnd->max_indent ) { GUISetHScroll( wnd->gui, 0 ); wnd->hscroll_pending = -1; GUISetHScrollRange( wnd->gui, wnd->max_indent ); } next = wnd; } else { for( i = 0; i < wnd->dirtyrects; ++i ) { dirt = &wnd->dirty[i]; if( dirt->row < 0 ) continue; if( dirt->row >= wnd->rows ) continue; if( dirt->piece == WND_NO_PIECE ) { if( !WndGetLine( wnd, dirt->row, 0, &line ) ) continue; GUIWndDirtyRow( wnd->gui, dirt->row ); } else { if( !WndGetLine( wnd, dirt->row, dirt->piece, &line ) ) continue; if( line.bitmap ) { GUIGetHotSpotSize( line.text[0], &size ); rect.x = line.indent; rect.y = dirt->row * wnd->max_char.y; rect.width = line.length; rect.height = size.y; } else if( dirt->col != WND_NO_COL ) { if( line.length == 0 ) line.text = " "; rect.x = line.indent; rect.x += GUIGetExtentX(wnd->gui, line.text, dirt->col); rect.y = dirt->row * wnd->max_char.y; rect.width = GUIGetExtentX( wnd->gui, line.text+dirt->col, dirt->end_col-dirt->col+GUICharLen( line.text[dirt->col] ) ); rect.height = wnd->max_char.y; } else if( line.extent == WND_MAX_EXTEND || line.master_tabstop ) { rect.width = 0; rect.height = 0; GUIWndDirtyRow( wnd->gui, dirt->row ); } else { rect.x = line.indent; if( WndGetLine( wnd, dirt->row, dirt->piece+1, &next_piece_line ) ) { if( next_piece_line.indent < line.indent ) { rect.width = WND_APPROX_SIZE; } else { rect.width = next_piece_line.indent - line.indent; } } else { rect.width = WND_APPROX_SIZE; } rect.y = dirt->row * wnd->max_char.y; rect.height = wnd->max_char.y; } /* begin kludge for Kerning problem */ if( rect.width != 0 || rect.height != 0 ) { half_char.x = WndAvgCharX( wnd ) / 2; half_char.y = 0; GUITruncToPixel( &half_char ); if( rect.x < half_char.x ) { rect.width += half_char.x + rect.x; rect.x = 0; } else { rect.x -= half_char.x; rect.width += half_char.x + half_char.x; } GUIWndDirtyRect( wnd->gui, &rect ); } } } } if( wnd->hscroll_pending != -1 ) { GUISetHScroll( wnd->gui, wnd->hscroll_pending ); wnd->hscroll_pending = -1; } wnd->dirtyrects = 0; WndSetThumb( wnd ); } }