/* display the scrollbar and handle button events */ #include #include #include #include #include #include "www.h" void DisplayHSlider(); void DisplayVSlider(); extern Display *display; extern int screen; extern unsigned int win_width, win_height; extern int statusHeight; extern int ToolBarHeight; extern long PixelOffset; extern long buf_height; extern int buf_width, PixelIndent; extern RepeatButtonDown; extern unsigned long windowTopShadow, windowBottomShadow, windowShadow, windowColor; int sbar_width = 15; int sy = 20; int sh = 60; int sx = 20; int sw = 60; int px; int py; int ox, oy; int scrolling = 0; int sliding = 0; int uparrow = 0, downarrow = 0; int leftarrow = 0, rightarrow = 0; int vertical; Window win; GC sb_gc; void SetScrollBarWin(Window aWin) { win = aWin; } void SetScrollBarGC(GC aGC) { sb_gc = aGC; } void SetScrollBarVPosition(long offset, long buffer_height) { int h; if (buffer_height > WinHeight) { /* h is pixel height scrollbar can move */ h = WinHeight - 2*(sbar_width - 1) - sh; sy = WinTop + sbar_width - 1 + (h * offset)/(buffer_height - WinHeight); } else sy = WinTop + sbar_width - 1; } void SetScrollBarHPosition(int indent, int buffer_width) { int w; if (buffer_width > WinWidth) { /* w is pixel width scrollbar can move */ w = WinWidth - 2*(sbar_width - 1) - sw; sx = WinLeft + sbar_width - 1 + (w * indent)/(buffer_width - WinWidth); } else sx = WinLeft + sbar_width - 1; } void SetScrollBarHeight(long buffer_height) { int h; double x; h = WinHeight - 2*(sbar_width - 1); if (buffer_height <= WinHeight) sh = h; else { x = ((double)buffer_height)/WinHeight; sh = (int)(0.5 + h/x); /* ensure a minimum size for decent visibility */ if (sh < 6) sh = 6; } } void SetScrollBarWidth(int buffer_width) { int w; double x; w = WinWidth - 2*(sbar_width - 1); if (buffer_width <= WinWidth) sw = w; else { x = ((double)buffer_width)/WinWidth; sw = (int)(0.5 + w/x); /* ensure a minimum size for decent visibility */ if (sw < 6) sw = 6; } } int ScrollButtonDown(int x, int y) { px = x; py = y; sliding = 0; RepeatButtonDown = 0; if (x > WinRight) { scrolling = 1; if (y < WinTop + sbar_width - 1) { uparrow = 1; RepeatButtonDown = 1; MoveUpLine(); return SCROLLBAR; } if (y < sy) { MoveUpPage(); } if (y >= sy && y < sy + sh) { sliding = 1; vertical = 1; oy = y - sy; return SCROLLBAR; } if (y > WinBottom - sbar_width + 1) { downarrow = 1; RepeatButtonDown = 1; MoveDownLine(); return SCROLLBAR; } if (y >= sy + sh) { MoveDownPage(); } } else if (y > WinBottom) { scrolling = 1; if (x < WinLeft + sbar_width - 1) { leftarrow = 1; RepeatButtonDown = 1; MoveLeftLine(); return SCROLLBAR; } if (x < sx) { MoveLeftPage(); } if (x >= sx && x < sx + sw) { sliding = 1; vertical = 0; ox = x - sx; return SCROLLBAR; } if (x > WinRight - sbar_width + 1) { rightarrow = 1; RepeatButtonDown = 1; MoveRightLine(); return SCROLLBAR; } if (x >= sx + sw) { MoveRightPage(); } } return VOID; } void ScrollButtonUp(int x, int y) { px = 0; py = 0; if (sliding) ScrollButtonDrag(x, y); scrolling = 0; sliding = 0; uparrow = downarrow = 0; leftarrow = rightarrow = 0; } /* update/move slider to reflect new position */ void MoveHSlider(int indent, int buffer_width) { int sx1; sx1 = sx; SetScrollBarHPosition(indent, buffer_width); if (sx != sx1) { XSetForeground(display, sb_gc, windowShadow); XFillRectangle(display, win, sb_gc, sx1, WinBottom + 2, sw, sbar_width - 4); DisplayHSlider(); } } /* update/move slider to reflect new position */ void MoveVSlider(long offset, long buffer_height) { int sy1; sy1 = sy; SetScrollBarVPosition(offset, buffer_height); if (sy != sy1) { XSetForeground(display, sb_gc, windowShadow); XFillRectangle(display, win, sb_gc, WinWidth + 2, sy1, sbar_width - 4, sh); DisplayVSlider(); } } void ScrollButtonHDrag(int x, int y) { int x1, w1; px = x; py = y; x1 = WinLeft + sbar_width - 1; if (x - ox < x1) { if (x > x1) ox = x - x1; else { ox = 0; x = x1; } } x1 = WinRight - (sbar_width - 1); if (x - ox + sw > x1) { if (x < x1) ox = x - x1 + sw; else { ox = sw; x = x1; } } if (x - ox > sx) { x1 = sx; w1 = x - ox - x1; } else { x1 = x - ox + sw; w1 = sx + sw - x1; } if (w1 > 0) { XSetForeground(display, sb_gc, windowShadow); XFillRectangle(display, win, sb_gc, x1, WinBottom + 2, w1, sbar_width - 4); } if (sx != x - ox) { sx = x - ox; DisplayHSlider(); SlideHDisplay(sx - WinLeft - sbar_width + 1, WinWidth - 2*(sbar_width - 1)); } } void ScrollButtonVDrag(int x, int y) { int y1, h1; px = x; py = y; y1 = WinTop + sbar_width - 1; if (y - oy < y1) { if (y > y1) oy = y - y1; else { oy = 0; y = y1; } } y1 = WinBottom - (sbar_width - 1); if (y - oy + sh > y1) { if (y < y1) oy = y - y1 + sh; else { oy = sh; y = y1; } } if (y - oy > sy) { y1 = sy; h1 = y - oy - y1; } else { y1 = y - oy + sh; h1 = sy + sh - y1; } if (h1 > 0) { XSetForeground(display, sb_gc, windowShadow); XFillRectangle(display, win, sb_gc, WinRight + 2, y1, sbar_width - 4, h1); } if (sy != y - oy) { sy = y - oy; DisplayVSlider(); SlideVDisplay(sy - WinTop - sbar_width + 1, WinHeight - 2*(sbar_width - 1)); } } void ScrollButtonDrag(int x, int y) { if (sliding) { if (vertical) ScrollButtonVDrag(x, y); else ScrollButtonHDrag(x, y); } } int AtStart(long offset) { long h; h = buf_height - WinHeight; return (h <= 0 || offset == 0); } int AtEnd(long offset) { long h; h = buf_height - WinHeight; return (h <= 0 || offset >= h); } int AtLeft(int indent) { return (indent > 0 ? 0 : 1); } int AtRight(int indent) { return (indent >= buf_width - WinWidth); } void DisplayLeftArrow() { int x, y; XPoint points[3]; x = WinLeft; y = WinBottom; points[0].x = x + sbar_width - 2; points[0].y = y + 2; points[1].x = x + sbar_width - 2; points[1].y = y + sbar_width - 3; points[2].x = x + 2; points[2].y = y + sbar_width/2 + 1; XSetForeground(display, sb_gc, windowColor); XFillPolygon(display, win, sb_gc, points, 3, Convex, CoordModeOrigin); XSetForeground(display, sb_gc, windowBottomShadow); XDrawLines(display, win, sb_gc, points, 3, CoordModeOrigin); points[0].x -= 1; points[0].y += 1; points[1].x -= 1; points[1].y -= 1; points[2].x += 1; XDrawLines(display, win, sb_gc, points, 3, CoordModeOrigin); points[0].x = x + sbar_width - 2; points[0].y = y + 2; points[1].x = x + 2; points[1].y = y + sbar_width/2; XSetForeground(display, sb_gc, windowTopShadow); XDrawLines(display, win, sb_gc, points, 2, CoordModeOrigin); points[0].x -= 1; points[0].y += 1; points[1].x += 3; points[1].y -= 1; XDrawLines(display, win, sb_gc, points, 2, CoordModeOrigin); } void DisplayUpArrow() { int x, y; XPoint points[3]; x = WinRight; y = WinTop; points[0].x = x + 2; points[0].y = y + sbar_width - 2; points[1].x = x + sbar_width - 3; points[1].y = y + sbar_width - 2; points[2].x = x + sbar_width/2 + 1; points[2].y = y + 2; XSetForeground(display, sb_gc, windowColor); XFillPolygon(display, win, sb_gc, points, 3, Convex, CoordModeOrigin); XSetForeground(display, sb_gc, windowBottomShadow); XDrawLines(display, win, sb_gc, points, 3, CoordModeOrigin); points[0].x += 1; points[0].y -= 1; points[1].x -= 1; points[1].y -= 1; points[2].y += 1; XDrawLines(display, win, sb_gc, points, 3, CoordModeOrigin); points[0].x = x + 2; points[0].y = y + sbar_width - 2; points[1].x = x + sbar_width/2; points[1].y = y + 2; XSetForeground(display, sb_gc, windowTopShadow); XDrawLines(display, win, sb_gc, points, 2, CoordModeOrigin); points[0].x += 1; points[0].y -= 1; points[1].x -= 1; points[1].y += 3; XDrawLines(display, win, sb_gc, points, 2, CoordModeOrigin); } void DisplayRightArrow() { int x, y; unsigned int w, h; XPoint points[3]; x = WinLeft; y = WinBottom; w = WinWidth; h = sbar_width; points[0].x = x + w - 3; points[0].y = y + sbar_width/2; points[1].x = x + w - (sbar_width - 1); points[1].y = y + 2; points[2].x = x + w - (sbar_width - 1); points[2].y = y + sbar_width - 3; XSetForeground(display, sb_gc, windowColor); XFillPolygon(display, win, sb_gc, points, 3, Convex, CoordModeOrigin); XSetForeground(display, sb_gc, windowTopShadow); XDrawLines(display, win, sb_gc, points, 3, CoordModeOrigin); points[0].x -= 1; points[0].y -= 1; points[1].x += 1; points[1].y += 1; points[2].x += 1; points[2].y -= 1; XDrawLines(display, win, sb_gc, points, 3, CoordModeOrigin); points[0].x = x + w - 4; points[0].y = y + sbar_width/2 + 1; points[1].x = x + w - (sbar_width - 2); points[1].y = y + sbar_width - 4; XSetForeground(display, sb_gc, windowBottomShadow); XDrawLines(display, win, sb_gc, points, 2, CoordModeOrigin); points[0].x -= 1; points[0].y += 1; points[1].x += 1; points[1].y -= 1; XDrawLines(display, win, sb_gc, points, 2, CoordModeOrigin); } void DisplayDownArrow() { int x, y; unsigned int w, h; XPoint points[3]; x = WinRight; y = WinTop; w = sbar_width; h = WinHeight; points[0].x = x + sbar_width/2; points[0].y = y + h - 3; points[1].x = x + 2; points[1].y = y + h - (sbar_width - 1); points[2].x = x + sbar_width - 3; points[2].y = y + h - (sbar_width - 1); XSetForeground(display, sb_gc, windowColor); XFillPolygon(display, win, sb_gc, points, 3, Convex, CoordModeOrigin); XSetForeground(display, sb_gc, windowTopShadow); XDrawLines(display, win, sb_gc, points, 3, CoordModeOrigin); points[0].x -= 1; points[0].y -= 1; points[1].x += 1; points[1].y += 1; points[2].x -= 1; points[2].y += 1; XDrawLines(display, win, sb_gc, points, 3, CoordModeOrigin); points[0].x = x + sbar_width/2 + 1; points[0].y = y + h - 4; points[1].x = x + sbar_width - 4; points[1].y = y + h - (sbar_width - 2); XSetForeground(display, sb_gc, windowBottomShadow); XDrawLines(display, win, sb_gc, points, 2, CoordModeOrigin); points[0].x += 1; points[0].y -= 1; points[1].x -= 1; points[1].y += 1; XDrawLines(display, win, sb_gc, points, 2, CoordModeOrigin); } void DisplayHSlider() { int x, y; unsigned int w, h; x = WinLeft; y = WinBottom; w = WinHeight; h = sbar_width; y += 2; x = sx; w = sw; h -= 4; XSetForeground(display, sb_gc, windowColor); XFillRectangle(display, win, sb_gc, x+2, y+2, w-4, h-4); XSetForeground(display, sb_gc, windowTopShadow); XFillRectangle(display, win, sb_gc, x, y, w, 1); XFillRectangle(display, win, sb_gc, x, y+1, w-1, 1); XFillRectangle(display, win, sb_gc, x, y, 1, h); XFillRectangle(display, win, sb_gc, x+1, y+1, 1, h-1); XSetForeground(display, sb_gc, windowBottomShadow); XFillRectangle(display, win, sb_gc, x, y+h-1, w, 1); XFillRectangle(display, win, sb_gc, x+1, y+h-2, w-1, 1); XFillRectangle(display, win, sb_gc, x+w-1, y, 1, h); XFillRectangle(display, win, sb_gc, x+w-2, y+1, 1, h-1); } void DisplayVSlider() { int x, y; unsigned int w, h; x = WinRight; y = WinTop; w = sbar_width; h = WinHeight; x += 2; y = sy; h = sh; w -= 4; XSetForeground(display, sb_gc, windowColor); XFillRectangle(display, win, sb_gc, x+2, y+2, w-4, h-4); XSetForeground(display, sb_gc, windowTopShadow); XFillRectangle(display, win, sb_gc, x, y, w, 1); XFillRectangle(display, win, sb_gc, x, y+1, w-1, 1); XFillRectangle(display, win, sb_gc, x, y, 1, h); XFillRectangle(display, win, sb_gc, x+1, y+1, 1, h-1); XSetForeground(display, sb_gc, windowBottomShadow); XFillRectangle(display, win, sb_gc, x, y+h-1, w, 1); XFillRectangle(display, win, sb_gc, x+1, y+h-2, w-1, 1); XFillRectangle(display, win, sb_gc, x+w-1, y, 1, h); XFillRectangle(display, win, sb_gc, x+w-2, y+1, 1, h-1); } void DisplayScrollBar() { int x, y; unsigned int w, h; /* fill-in bottom right corner square */ XSetForeground(display, sb_gc, windowColor); XFillRectangle(display, win, sb_gc, WinRight, WinBottom, sbar_width, sbar_width); x = WinRight; y = WinTop; w = sbar_width; h = WinHeight; /* draw vertical scrollbar background */ XSetForeground(display, sb_gc, windowShadow); XFillRectangle(display, win, sb_gc, x, y, w, h); XSetForeground(display, sb_gc, windowBottomShadow); XFillRectangle(display, win, sb_gc, x, y, w, 1); XFillRectangle(display, win, sb_gc, x, y+1, w-1, 1); XFillRectangle(display, win, sb_gc, x, y, 1, h); XFillRectangle(display, win, sb_gc, x+1, y+1, 1, h-1); XSetForeground(display, sb_gc, windowTopShadow); XFillRectangle(display, win, sb_gc, x, y+h-1, w, 1); XFillRectangle(display, win, sb_gc, x+1, y+h-2, w-1, 1); XFillRectangle(display, win, sb_gc, x+w-1, y, 1, h); XFillRectangle(display, win, sb_gc, x+w-2, y+1, 1, h-1); x = WinLeft; y = WinBottom; w = WinWidth; h = sbar_width; /* draw horizontal scrollbar background */ XSetForeground(display, sb_gc, windowShadow); XFillRectangle(display, win, sb_gc, x, y, w, h); XSetForeground(display, sb_gc, windowBottomShadow); XFillRectangle(display, win, sb_gc, x, y, w, 1); XFillRectangle(display, win, sb_gc, x, y+1, w-1, 1); XFillRectangle(display, win, sb_gc, x, y, 1, h); XFillRectangle(display, win, sb_gc, x+1, y+1, 1, h-1); XSetForeground(display, sb_gc, windowTopShadow); XFillRectangle(display, win, sb_gc, x, y+h-1, w, 1); XFillRectangle(display, win, sb_gc, x+1, y+h-2, w-1, 1); XFillRectangle(display, win, sb_gc, x+w-1, y, 1, h); XFillRectangle(display, win, sb_gc, x+w-2, y+1, 1, h-1); /* draw the sliders */ DisplayHSlider(); DisplayVSlider(); /* draw the arrow buttons */ DisplayUpArrow(); DisplayDownArrow(); DisplayLeftArrow(); DisplayRightArrow(); }