Ejemplo n.º 1
0
/*
 * move selection area to visible part of window. argument bToBottom
 * indicates whether to move the line onto the bottom or the top of the
 * window if not visible - this affects the smoothness of scrolling
 * line-by-line.
 */
void
gtab_showsel(HWND hwnd, lpTable ptab, BOOL bToBottom)
{
    int line;
    long change;

    line = gtab_rowtoline(hwnd, ptab, ptab->select.startrow);

    /* move up if last line or not at all visible */
    if ( (line < 0) || line == (ptab->nlines - 1)) {
        change = ptab->select.startrow - ptab->toprow;
        if (bToBottom) {
            /* change to bottom of window. subtract 2 not 1
             * since nlines includes one line that is only
             * partly visible
             */
            change -= (ptab->nlines - 2);
        }
        change -= ptab->hdr.fixedrows;
        gtab_dovscroll(hwnd, ptab, change);
    }
    /* add support for TM_CELL here! */
}
Ejemplo n.º 2
0
/*
 * mark the selected line, if visible, in the style chosen by the
 * client app. This can be TM_SOLID, meaning an inversion of
 * the whole selected area or TM_FOCUS, meaning, inversion of the first
 * cell, and then a dotted focus rectangle for the rest.
 *
 * this function inverts either style, and so will turn the selection
 * both on and off.
 */
void
gtab_invertsel(HWND hwnd, lpTable ptab, HDC hdc_in)
{
	HDC hdc;
	int firstline, lastline;
	long startrow, lastrow, toprow, bottomrow;
	RECT rc;
	int lastcell;



	/* get the selection start and end rows ordered vertically */
	if (ptab->select.nrows == 0) {
	    return;
	} else if (ptab->select.nrows < 0) {
	    startrow = ptab->select.startrow + ptab->select.nrows + 1;
	    lastrow = ptab->select.startrow;
	} else {
	    startrow = ptab->select.startrow;
	    lastrow = ptab->select.startrow + ptab->select.nrows -1;
	}

	/* is selected area (or part of it) visible on screen ?  */
	firstline = gtab_rowtoline(hwnd, ptab, startrow);
	lastline = gtab_rowtoline(hwnd, ptab, lastrow);


	if (firstline < 0) {
	    toprow = gtab_linetorow(hwnd, ptab,
	    		ptab->hdr.fixedselectable ? 0: ptab->hdr.fixedrows);
	    if ((toprow >= startrow)  &&
		(toprow <= lastrow)) {
		    firstline = gtab_rowtoline(hwnd, ptab, toprow);
	    } else {
		return;
	    }
	} else {
	    toprow = 0;
	}


	if (lastline < 0) {
	    bottomrow = gtab_linetorow(hwnd, ptab, ptab->nlines-1);
	    if ((bottomrow <= lastrow) &&
		(bottomrow >=startrow)) {
		    lastline = gtab_rowtoline(hwnd, ptab, bottomrow);
	    } else {
		return;
	    }
	}


	rc.top = ptab->pdata[firstline].linepos.clipstart;
	rc.bottom = ptab->pdata[lastline].linepos.clipend;



	/* selection mode includes a flag TM_FOCUS indicating we should
	 * use a focus rect instead of the traditional inversion for
	 * selections in this table. This interferes with multiple backgrnd
	 * colours less.  However we still do inversion for fixedcols.
	 */

	lastcell = (int)(ptab->select.startcell + ptab->select.ncells - 1);


	/*
	 * invert the whole area for TM_SOLID or just the first
	 * cell for TM_FOCUS
	 */
	rc.left = ptab->pcellpos[ptab->select.startcell].clipstart;
	if (ptab->hdr.selectmode & TM_FOCUS) {
		rc.right = ptab->pcellpos[ptab->select.startcell].clipend;
	}else {
		rc.right = ptab->pcellpos[lastcell].clipend;
	}

	if (hdc_in == NULL) {
		hdc = GetDC(hwnd);
	} else {
		hdc = hdc_in;
	}

	InvertRect(hdc, &rc);

	/*
	 * draw focus rectangle around remaining cells on this line, if there
	 * are any
	 */
	if (ptab->hdr.selectmode & TM_FOCUS) {
		/*
		 * now this is a real fudge. if we are drawing TM_FOCUS
		 * selection, and the real top line is off the top of the
		 * window, then the top of the focus rect will be drawn at
		 * the top of our window. If we then scroll up one line,
		 * a new focus rect will be drawn, but the old top of focus
		 * rect line will still be there as junk on the
		 * screen. To fix this, we have 2 choices: we undo the selection
		 * before every scroll (too slow) or we set the focus rect a little
		 * bigger if the real top line is off-window, so that the top line
		 * is clipped (as it should be). This latter is what we do here
		 */
		if (toprow > startrow) {
		    rc.top--;
		}
		if (ptab->select.ncells > 1) {
			rc.left = ptab->pcellpos[ptab->select.startcell+1].clipstart;
			rc.right = ptab->pcellpos[lastcell].clipend;
			DrawFocusRect(hdc, &rc);
		}
	}

	if (hdc_in == NULL) {
		ReleaseDC(hwnd, hdc);
	}
}
Ejemplo n.º 3
0
/* new rows have been added to the table. adjust the scroll range and
 * position, and redraw the rows if the end of the table is currently
 * visible.
 * rows = the new total row count.
 */
void
gtab_append(
           HWND hwnd,
           lpTable ptab,
           int rows,
           DWORD_PTR id
           )
{
    long oldrows;
    int line, nupdates;
    RECT rc;
    SCROLLINFO si;


    /* change to the new id */
    ptab->hdr.id = id;
    ptab->select.id = id;

    /* update the header, but remember the old nr of rows
     * so we know where to start updating
     */
    oldrows = ptab->hdr.nrows;

    /* check that the new nr of rows is not smaller.
     */
    if (oldrows >= rows) {
        return;
    }

    ptab->hdr.nrows = rows;

    si.cbSize = sizeof(si);
    si.fMask = SIF_PAGE|SIF_RANGE;
    si.nMin = 0;

    /* set the vertical scroll range */
    si.nMax = rows;
    si.nPage = ptab->nlines;
    if (si.nMax < 0) {
        si.nMax = 0;
    }

    /* force the scroll range into 16-bits for win 3.1 */
    ptab->scrollscale = 1;
    while (si.nMax > 32766) {
        ptab->scrollscale *= 16;
        si.nMax /= 16;
        si.nPage /= 16;
    }
    if (!si.nPage)
        si.nPage = 1;

    /* now set the scroll bar range and position */
    SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
    if (si.nMax > 0) {
        SetScrollPos(hwnd, SB_VERT,
                     (int) (ptab->toprow / ptab->scrollscale), TRUE);
    }

    /* calculate which screen lines need to be updated - find what
     * screen line the start of the new section is at
     */
    line = gtab_rowtoline(hwnd, ptab, oldrows);
    if (line == -1) {
        /* not visible -> no more to do */
        return;
    }

    /* how many lines to update - rest of screen or nr of
     * new lines if less than rest of screen
     */
    nupdates = min((ptab->nlines - line), (int)(rows - oldrows));

    /* invalidate the screen line buffers to indicate data
     * needs to be refetch from parent window
     */
    gtab_invallines(hwnd, ptab, line, nupdates);

    /* calculate the region of the screen to be repainted -
     * left and right are same as window. top and bottom
     * need to be calculated from screen line height
     */

    GetClientRect(hwnd, &rc);
    rc.top += line * ptab->rowheight;
    rc.bottom = rc.top + (nupdates * ptab->rowheight);

    /* force a repaint of the updated region */
    InvalidateRect(hwnd, &rc, FALSE);
}