summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsf-exg <sf-exg>2014-05-30 19:44:11 +0000
committersf-exg <sf-exg>2014-05-30 19:44:11 +0000
commitb26c396de00dd55b9ac1368c3ef02d8f61390712 (patch)
tree31a62557722c15ccf6f03ac970f63cfaf69949dc /src
parenta00d7e3d734e6c86c3a0b45bf841ee8eb332f41f (diff)
Fix height and position of the stippled area in next scrollbar, patch by totto.
Diffstat (limited to 'src')
-rw-r--r--src/scrollbar-next.C313
-rw-r--r--src/scrollbar.h214
2 files changed, 527 insertions, 0 deletions
diff --git a/src/scrollbar-next.C b/src/scrollbar-next.C
new file mode 100644
index 0000000..2d9db7b
--- /dev/null
+++ b/src/scrollbar-next.C
@@ -0,0 +1,313 @@
+/*----------------------------------------------------------------------*
+ * File: scrollbar-next.C
+ *----------------------------------------------------------------------*
+ *
+ * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA>
+ * Copyright (c) 1998 Alfredo K. Kojima <kojima@windowmaker.org>
+ * - N*XTstep like scrollbars
+ * Copyright (c) 1999-2001 Geoff Wing <gcw@pobox.com>
+ * Copyright (c) 2004-2006 Marc Lehmann <schmorp@schmorp.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *----------------------------------------------------------------------*/
+
+#include "../config.h" /* NECESSARY */
+#include "rxvt.h" /* NECESSARY */
+
+/*----------------------------------------------------------------------*/
+#if defined(NEXT_SCROLLBAR)
+
+#define n_stp_width 8
+#define n_stp_height 2
+const unsigned char n_stp_bits[] = { 0x55, 0xaa };
+
+/*
+ * N*XTSTEP like scrollbar - written by Alfredo K. Kojima
+ */
+#define SCROLLER_DIMPLE_WIDTH 6
+#define SCROLLER_DIMPLE_HEIGHT 6
+#define ARROW_WIDTH 13
+#define ARROW_HEIGHT 13
+
+const char *const SCROLLER_DIMPLE[] =
+ {
+ ".%###.",
+ "%#%%%%",
+ "#%%...",
+ "#%.. ",
+ "#%. ",
+ ".%. ."
+ };
+const char *const SCROLLER_ARROW_UP[] =
+ {
+ ".............",
+ ".............",
+ "......%......",
+ "......#......",
+ ".....%#%.....",
+ ".....###.....",
+ "....%###%....",
+ "....#####....",
+ "...%#####%...",
+ "...#######...",
+ "..%#######%..",
+ ".............",
+ "............."
+ };
+const char *const SCROLLER_ARROW_DOWN[] =
+ {
+ ".............",
+ ".............",
+ "..%#######%..",
+ "...#######...",
+ "...%#####%...",
+ "....#####....",
+ "....%###%....",
+ ".....###.....",
+ ".....%#%.....",
+ "......#......",
+ "......%......",
+ ".............",
+ "............."
+ };
+const char *const HI_SCROLLER_ARROW_UP[] =
+ {
+ " ",
+ " ",
+ " % ",
+ " % ",
+ " %%% ",
+ " %%% ",
+ " %%%%% ",
+ " %%%%% ",
+ " %%%%%%% ",
+ " %%%%%%% ",
+ " %%%%%%%%% ",
+ " ",
+ " "
+ };
+const char *const HI_SCROLLER_ARROW_DOWN[] =
+ {
+ " ",
+ " ",
+ " %%%%%%%%% ",
+ " %%%%%%% ",
+ " %%%%%%% ",
+ " %%%%% ",
+ " %%%%% ",
+ " %%% ",
+ " %%% ",
+ " % ",
+ " % ",
+ " ",
+ " "
+ };
+
+static Pixmap
+renderPixmap (scrollBar_t *sb, const char *const *data, int width, int height)
+{
+ char a;
+ int x, y;
+ Pixmap d;
+ GC pointcolour;
+
+ d = XCreatePixmap (sb->term->dpy, sb->win, width, height, sb->term->depth);
+
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ if ((a = data[y][x]) == ' ' || a == 'w')
+ pointcolour = sb->whiteGC;
+ else if (a == '.' || a == 'l')
+ pointcolour = sb->grayGC;
+ else if (a == '%' || a == 'd')
+ pointcolour = sb->darkGC;
+ else /* if (a == '#' || a == 'b' || a) */
+ pointcolour = sb->blackGC;
+
+ XDrawPoint (sb->term->dpy, d, pointcolour, x, y);
+ }
+ }
+ return d;
+}
+
+void
+scrollBar_t::init_next ()
+{
+ XGCValues gcvalue;
+ rxvt_color color;
+ Pixmap stipple;
+ unsigned long light, dark;
+
+ gcvalue.graphics_exposures = False;
+
+ gcvalue.foreground = term->pix_colors_focused[Color_Black];
+ blackGC = XCreateGC (term->dpy, win,
+ GCForeground | GCGraphicsExposures, &gcvalue);
+
+ gcvalue.foreground = term->pix_colors_focused[Color_White];
+ whiteGC = XCreateGC (term->dpy, win,
+ GCForeground | GCGraphicsExposures, &gcvalue);
+
+ light = term->pix_colors_focused[Color_scroll];
+#if 0
+ //color used by rxvt
+ if (color.set (term, rgba (0xaeba, 0xaaaa, 0xaeba)))
+ light = color;
+#endif
+ gcvalue.foreground = light;
+ grayGC = XCreateGC (term->dpy, win,
+ GCForeground | GCGraphicsExposures, &gcvalue);
+
+ dark = term->pix_colors_focused[Color_Grey25];
+#if 0
+ //color used by rxvt
+ if (color.set (term, rgba (0x51aa, 0x5555, 0x5144)))
+ dark = color;
+#endif
+ gcvalue.foreground = dark;
+ darkGC = XCreateGC (term->dpy, win,
+ GCForeground | GCGraphicsExposures, &gcvalue);
+
+ stipple = XCreateBitmapFromData (term->dpy, win,
+ (char *)n_stp_bits, n_stp_width,
+ n_stp_height);
+
+ gcvalue.foreground = dark;
+ gcvalue.background = light;
+ gcvalue.fill_style = FillOpaqueStippled;
+ gcvalue.stipple = stipple;
+
+ stippleGC = XCreateGC (term->dpy, win,
+ GCForeground | GCBackground | GCStipple
+ | GCFillStyle | GCGraphicsExposures, &gcvalue);
+
+ dimple = renderPixmap (this, SCROLLER_DIMPLE, SCROLLER_DIMPLE_WIDTH,
+ SCROLLER_DIMPLE_HEIGHT);
+
+ upArrow = renderPixmap (this, SCROLLER_ARROW_UP, ARROW_WIDTH,
+ ARROW_HEIGHT);
+ downArrow = renderPixmap (this, SCROLLER_ARROW_DOWN, ARROW_WIDTH,
+ ARROW_HEIGHT);
+ upArrowHi = renderPixmap (this, HI_SCROLLER_ARROW_UP, ARROW_WIDTH,
+ ARROW_HEIGHT);
+ downArrowHi = renderPixmap (this, HI_SCROLLER_ARROW_DOWN,
+ ARROW_WIDTH, ARROW_HEIGHT);
+}
+
+/* Draw bevel & arrows */
+static void
+drawBevel (scrollBar_t *sb, int x1, int y1, int w, int h)
+{
+ int x2, y2;
+ Drawable d = sb->win;
+ Display *dpy = sb->term->dpy;
+
+ x2 = x1 + w - 1; /* right point */
+ y2 = y1 + h - 1; /* bottom point */
+ /* white top and left */
+ XDrawLine (dpy, d, sb->whiteGC, x1, y1, x2, y1);
+ XDrawLine (dpy, d, sb->whiteGC, x1, y1, x1, y2);
+ /* black bottom and right */
+ XDrawLine (dpy, d, sb->blackGC, x1, y2, x2, y2);
+ XDrawLine (dpy, d, sb->blackGC, x2, y1, x2, y2);
+ /* dark inside bottom and right */
+ x1++, y1++, x2--, y2--; /* move in one point */
+ XDrawLine (dpy, d, sb->darkGC, x1, y2, x2, y2);
+ XDrawLine (dpy, d, sb->darkGC, x2, y1, x2, y2);
+}
+
+int
+scrollBar_t::show_next (int update)
+{
+ int height = end + SB_BUTTON_TOTAL_HEIGHT + SB_PADDING;
+ Drawable src;
+
+ if ((init & SB_STYLE_NEXT) == 0)
+ {
+ init |= SB_STYLE_NEXT;
+ init_next ();
+ last_has_sb = false;
+ }
+
+ bool has_sb = term->top_row;
+ int stipple_height = height - SB_PADDING;
+
+ if (has_sb)
+ stipple_height -= SB_BUTTON_TOTAL_HEIGHT;
+ else
+ stipple_height -= SB_PADDING;
+
+ if (has_sb != last_has_sb || !update)
+ {
+ last_has_sb = has_sb;
+ XFillRectangle (term->dpy, win, grayGC, 0, 0,
+ SB_WIDTH_NEXT + 1, height);
+ XDrawRectangle (term->dpy, win, blackGC, 0,
+ -SB_BORDER_WIDTH, SB_WIDTH_NEXT,
+ height + SB_BORDER_WIDTH);
+ XFillRectangle (term->dpy, win, stippleGC,
+ SB_LEFT_PADDING, SB_PADDING,
+ SB_BUTTON_WIDTH, stipple_height);
+ }
+
+ if (term->top_row)
+ {
+ if (last_top < top || !update)
+ XFillRectangle (term->dpy, win, stippleGC,
+ SB_LEFT_PADDING, SB_PADDING + last_top,
+ SB_BUTTON_WIDTH, top - last_top);
+
+ if (bot < last_bot || !update)
+ XFillRectangle (term->dpy, win, stippleGC,
+ SB_LEFT_PADDING, bot + SB_PADDING,
+ SB_BUTTON_WIDTH, (last_bot - bot));
+
+ XFillRectangle (term->dpy, win, grayGC,
+ SB_LEFT_PADDING, top + SB_PADDING,
+ SB_BUTTON_WIDTH, bot - top);
+
+ XCopyArea (term->dpy, dimple, win, whiteGC, 0, 0,
+ SCROLLER_DIMPLE_WIDTH, SCROLLER_DIMPLE_HEIGHT,
+ (SB_WIDTH_NEXT - SCROLLER_DIMPLE_WIDTH) / 2,
+ top + SB_BEVEL_WIDTH_UPPER_LEFT +
+ (bot - top - SCROLLER_DIMPLE_HEIGHT) / 2);
+
+ drawBevel (this, SB_BUTTON_BEVEL_X,
+ top + SB_PADDING, SB_BUTTON_WIDTH,
+ bot - top);
+ drawBevel (this, SB_BUTTON_BEVEL_X,
+ height - SB_BUTTON_BOTH_HEIGHT, SB_BUTTON_WIDTH,
+ SB_BUTTON_HEIGHT);
+ drawBevel (this, SB_BUTTON_BEVEL_X,
+ height - SB_BUTTON_SINGLE_HEIGHT, SB_BUTTON_WIDTH,
+ SB_BUTTON_HEIGHT);
+
+ src = state == SB_STATE_UP ? upArrowHi : upArrow;
+ XCopyArea (term->dpy, src, win, whiteGC, 0, 0,
+ ARROW_WIDTH, ARROW_HEIGHT, SB_BUTTON_FACE_X,
+ height - SB_BUTTON_BOTH_HEIGHT + SB_BEVEL_WIDTH_UPPER_LEFT);
+
+ src = state == SB_STATE_DOWN ? downArrowHi : downArrow;
+ XCopyArea (term->dpy, src, win, whiteGC, 0, 0,
+ ARROW_WIDTH, ARROW_HEIGHT, SB_BUTTON_FACE_X,
+ height - SB_BUTTON_SINGLE_HEIGHT + SB_BEVEL_WIDTH_UPPER_LEFT);
+ }
+
+ return 1;
+}
+#endif /* NEXT_SCROLLBAR */
+/*----------------------- end-of-file (C source) -----------------------*/
diff --git a/src/scrollbar.h b/src/scrollbar.h
new file mode 100644
index 0000000..b0f3fad
--- /dev/null
+++ b/src/scrollbar.h
@@ -0,0 +1,214 @@
+#ifndef SCROLLBAR_H
+#define SCROLLBAR_H
+
+#include <X11/Xlib.h>
+#include "rxvtutil.h"
+
+struct rxvt_term;
+
+#define SB_WIDTH_NEXT 19
+#define SB_WIDTH_XTERM 15
+#define SB_WIDTH_PLAIN 7
+#ifndef SB_WIDTH_RXVT
+# define SB_WIDTH_RXVT 10
+#endif
+
+/*
+ * NeXT scrollbar defines
+ */
+#define SB_PADDING 1
+#define SB_BORDER_WIDTH 1
+#define SB_BEVEL_WIDTH_UPPER_LEFT 1
+#define SB_BEVEL_WIDTH_LOWER_RIGHT 2
+#define SB_LEFT_PADDING (SB_PADDING + SB_BORDER_WIDTH)
+#define SB_MARGIN_SPACE (SB_PADDING * 2)
+#define SB_BUTTON_WIDTH (SB_WIDTH_NEXT - SB_MARGIN_SPACE - SB_BORDER_WIDTH)
+#define SB_BUTTON_HEIGHT (SB_BUTTON_WIDTH)
+#define SB_BUTTON_SINGLE_HEIGHT (SB_BUTTON_HEIGHT + SB_PADDING)
+#define SB_BUTTON_BOTH_HEIGHT (SB_BUTTON_SINGLE_HEIGHT * 2)
+#define SB_BUTTON_TOTAL_HEIGHT (SB_BUTTON_BOTH_HEIGHT + SB_PADDING)
+#define SB_BUTTON_BEVEL_X (SB_LEFT_PADDING)
+#define SB_BUTTON_FACE_X (SB_BUTTON_BEVEL_X + SB_BEVEL_WIDTH_UPPER_LEFT)
+#define SB_THUMB_MIN_HEIGHT (SB_BUTTON_WIDTH - (SB_PADDING * 2))
+
+enum sb_state {
+ SB_STATE_OFF,
+ SB_STATE_IDLE,
+ SB_STATE_MOTION,
+ SB_STATE_UP,
+ SB_STATE_DOWN,
+};
+
+enum sb_style {
+ SB_STYLE_NEXT = 1,
+ SB_STYLE_XTERM = 2,
+ SB_STYLE_PLAIN = 4,
+ SB_STYLE_RXVT = 8,
+};
+
+enum sb_align {
+ SB_ALIGN_CENTRE,
+ SB_ALIGN_TOP,
+ SB_ALIGN_BOTTOM,
+};
+
+struct scrollBar_t
+{
+ rxvt_term *term;
+ sb_state state; /* scrollbar state */
+ char init; /* scrollbar has been initialised */
+ int beg; /* slider sub-window begin height */
+ int end; /* slider sub-window end height */
+ int top; /* slider top position */
+ int bot; /* slider bottom position */
+ sb_style style; /* style: rxvt, xterm, next */
+ int width; /* scrollbar width */
+ int shadow; /* scrollbar shadow width */
+ int last_bot; /* scrollbar last bottom position */
+ int last_top; /* scrollbar last top position */
+ int last_state; /* scrollbar last state */
+ sb_align align;
+ Window win;
+ Cursor leftptr_cursor;
+ int (scrollBar_t::*update)(int);
+ void setup (rxvt_term *);
+ void resize ();
+ void map (int);
+ int show (int);
+ void destroy ();
+ int color ();
+
+ bool upButton (int y)
+ {
+ if (style == SB_STYLE_NEXT)
+ return y > end && y <= end + width + 1;
+ if (style == SB_STYLE_RXVT)
+ return y < beg;
+ return false;
+ }
+ bool dnButton (int y)
+ {
+ if (style == SB_STYLE_NEXT)
+ return y > end + width + 1;
+ if (style == SB_STYLE_RXVT)
+ return y > end;
+ return false;
+ }
+ int min_height ()
+ {
+ return style == SB_STYLE_NEXT ? SB_THUMB_MIN_HEIGHT : 10;
+ }
+ int size ()
+ {
+ return max (end - beg, 0);
+ }
+ int total_width ()
+ {
+ return width + shadow * 2;
+ }
+ bool above_slider (int y)
+ {
+ return y < top;
+ }
+ bool below_slider (int y)
+ {
+ return y > bot;
+ }
+ int position (int y)
+ {
+ return y - beg;
+ }
+
+
+#if defined(NEXT_SCROLLBAR)
+ GC blackGC,
+ whiteGC,
+ grayGC,
+ darkGC,
+ stippleGC;
+ Pixmap dimple,
+ upArrow,
+ downArrow,
+ upArrowHi,
+ downArrowHi;
+ bool last_has_sb;
+#endif
+
+#if defined(RXVT_SCROLLBAR)
+ GC scrollbarGC,
+ topShadowGC,
+ botShadowGC;
+#endif
+
+#if defined(XTERM_SCROLLBAR)
+ GC xscrollbarGC,
+ ShadowGC;
+#endif
+
+#if defined(PLAIN_SCROLLBAR)
+ GC pscrollbarGC;
+#endif
+
+private:
+ // update style dependent data
+ void update_data ();
+
+ // scrollbar-next.C
+ int show_next (int);
+ // scrollbar-rxvt.C
+ int show_rxvt (int);
+ // scrollbar-xterm.C
+ int show_xterm (int);
+ // scrollbar-plain.C
+ int show_plain (int);
+
+ void init_next ();
+};
+
+ /*
+ * +-------------+
+ * | | <---< SB_PADDING
+ * | ::::::::::: |
+ * | ::::::::::: |
+ * '''''''''''''''''
+ * ,,,,,,,,,,,,,,,,,
+ * | ::::::::::: |
+ * | ::::::::::: |
+ * | +---------------< SB_BEVEL_WIDTH_UPPER_LEFT
+ * | | :::::::: |
+ * | V :::: vv-------< SB_BEVEL_WIDTH_LOWER_RIGHT
+ * | +---------+ |
+ * | | ......%%| |
+ * | | ......%%| |
+ * | | .. ()..%%| |
+ * | | ......%%| |
+ * | | %%%%%%%%| |
+ * | +---------+ | <.........................
+ * | | <---< SB_PADDING :
+ * | +---------+ | <-+.......... :---< SB_BUTTON_TOTAL_HEIGHT
+ * | | ......%%| | | : :
+ * | | ../\..%%| | |---< SB_BUTTON_HEIGHT :
+ * | | %%%%%%%%| | | : :
+ * | +---------+ | <-+ : :
+ * | | : :
+ * | +---------+ | <-+ :---< SB_BUTTON_BOTH_HEIGHT
+ * | | ......%%| | | : :
+ * | | ..\/..%%| | | : :
+ * | | %%%%%%%%| | |---< SB_BUTTON_SINGLE_HEIGHT
+ * | +---------+ | | : :
+ * | | | : :
+ * +-------------+ <-+.........:............:
+ * ^^|_________| :
+ * || | :
+ * || +---< SB_BUTTON_WIDTH
+ * || :
+ * |+------< SB_PADDING
+ * |: :
+ * +----< SB_BORDER_WIDTH
+ * : :
+ * :............:
+ * |
+ * +---< SB_WIDTH_NEXT
+ */
+
+#endif