예제 #1
0
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;
        }
    }
}
예제 #2
0
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;
        }
    }
}
예제 #3
0
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 );
    }
}
예제 #4
0
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 );
    }
}
예제 #5
0
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], ' ' );
            }
        }
    }
}
예제 #6
0
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 );
    }
}