1 /*--------------------------------*-C-*---------------------------------*
2  * File:	scrollbar-next.c
3  *----------------------------------------------------------------------*
4  * $Id: scrollbar-next.c,v 1.15 2001/07/27 06:38:37 gcw Exp $
5  *
6  * Copyright (c) 1997,1998 mj olesen <olesen@me.QueensU.CA>
7  * Copyright (c) 1998      Alfredo K. Kojima <kojima@windowmaker.org>
8  *				- N*XTstep like scrollbars
9  * Copyright (c) 1999-2001 Geoff Wing <gcw@pobox.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24  *----------------------------------------------------------------------*/
25 
26 #include "../config.h"		/* NECESSARY */
27 #include "xvt.h"		/* NECESSARY */
28 #include "scrollbar-next.intpro"	/* PROTOS for internal routines */
29 
30 /*----------------------------------------------------------------------*/
31 #define n_stp_width	8
32 #define n_stp_height	2
33 const unsigned char n_stp_bits[] = { 0x55, 0xaa };
34 
35 /*
36  * N*XTSTEP like scrollbar - written by Alfredo K. Kojima
37  */
38 #define SCROLLER_DIMPLE_WIDTH   6
39 #define SCROLLER_DIMPLE_HEIGHT  6
40 #define ARROW_WIDTH   13
41 #define ARROW_HEIGHT  13
42 
43 const char     *const SCROLLER_DIMPLE[] = {
44     ".%###.",
45     "%#%%%%",
46     "#%%...",
47     "#%..  ",
48     "#%.   ",
49     ".%.  ."
50 };
51 const char     *const SCROLLER_ARROW_UP[] = {
52     ".............",
53     ".............",
54     "......%......",
55     "......#......",
56     ".....%#%.....",
57     ".....###.....",
58     "....%###%....",
59     "....#####....",
60     "...%#####%...",
61     "...#######...",
62     "..%#######%..",
63     ".............",
64     "............."
65 };
66 const char     *const SCROLLER_ARROW_DOWN[] = {
67     ".............",
68     ".............",
69     "..%#######%..",
70     "...#######...",
71     "...%#####%...",
72     "....#####....",
73     "....%###%....",
74     ".....###.....",
75     ".....%#%.....",
76     "......#......",
77     "......%......",
78     ".............",
79     "............."
80 };
81 const char     *const HI_SCROLLER_ARROW_UP[] = {
82     "             ",
83     "             ",
84     "      %      ",
85     "      %      ",
86     "     %%%     ",
87     "     %%%     ",
88     "    %%%%%    ",
89     "    %%%%%    ",
90     "   %%%%%%%   ",
91     "   %%%%%%%   ",
92     "  %%%%%%%%%  ",
93     "             ",
94     "             "
95 };
96 const char     *const HI_SCROLLER_ARROW_DOWN[] = {
97     "             ",
98     "             ",
99     "  %%%%%%%%%  ",
100     "   %%%%%%%   ",
101     "   %%%%%%%   ",
102     "    %%%%%    ",
103     "    %%%%%    ",
104     "     %%%     ",
105     "     %%%     ",
106     "      %      ",
107     "      %      ",
108     "             ",
109     "             "
110 };
111 
112 /* INTPROTO */
113 Pixmap
xvt_renderPixmap(xvt_t * r,const char * const * data,int width,int height)114 xvt_renderPixmap(xvt_t *r, const char *const *data, int width, int height)
115 {
116     char            a;
117     int             x, y;
118     Pixmap          d;
119     GC              pointcolour;
120 
121     d = XCreatePixmap(r->Xdisplay, r->scrollBar.win, width, height, XDEPTH);
122 
123     for (y = 0; y < height; y++) {
124 	for (x = 0; x < width; x++) {
125 	    if ((a = data[y][x]) == ' ' || a == 'w')
126 		pointcolour = r->h->whiteGC;
127 	    else if (a == '.' || a == 'l')
128 		pointcolour = r->h->grayGC;
129 	    else if (a == '%' || a == 'd')
130 		pointcolour = r->h->darkGC;
131 	    else		/* if (a == '#' || a == 'b' || a) */
132 		pointcolour = r->h->blackGC;
133 	    XDrawPoint(r->Xdisplay, d, pointcolour, x, y);
134 	}
135     }
136     return d;
137 }
138 
139 /* INTPROTO */
140 void
xvt_init_scrollbar_stuff(xvt_t * r)141 xvt_init_scrollbar_stuff(xvt_t *r)
142 {
143     XGCValues       gcvalue;
144     XColor          xcol;
145     Pixmap          stipple;
146     unsigned long   light, dark;
147 
148     gcvalue.graphics_exposures = False;
149 
150     gcvalue.foreground = r->PixColors[Color_Black];
151     r->h->blackGC = XCreateGC(r->Xdisplay, r->scrollBar.win,
152 			      GCForeground | GCGraphicsExposures, &gcvalue);
153 
154     gcvalue.foreground = r->PixColors[Color_White];
155     r->h->whiteGC = XCreateGC(r->Xdisplay, r->scrollBar.win,
156 			      GCForeground | GCGraphicsExposures, &gcvalue);
157 
158     xcol.red = 0xaeba;
159     xcol.green = 0xaaaa;
160     xcol.blue = 0xaeba;
161     if (!xvt_rXAllocColor(r, &xcol, "light gray"))
162 	xcol.pixel = r->PixColors[Color_AntiqueWhite];
163     light = gcvalue.foreground = xcol.pixel;
164     r->h->grayGC = XCreateGC(r->Xdisplay, r->scrollBar.win,
165 			     GCForeground | GCGraphicsExposures, &gcvalue);
166 
167     xcol.red = 0x51aa;
168     xcol.green = 0x5555;
169     xcol.blue = 0x5144;
170     if (!xvt_rXAllocColor(r, &xcol, "dark gray"))
171 	xcol.pixel = r->PixColors[Color_Grey25];
172     dark = gcvalue.foreground = xcol.pixel;
173     r->h->darkGC = XCreateGC(r->Xdisplay, r->scrollBar.win,
174 			     GCForeground | GCGraphicsExposures, &gcvalue);
175 
176     stipple = XCreateBitmapFromData(r->Xdisplay, r->scrollBar.win,
177 				    (char *)n_stp_bits, n_stp_width,
178 				    n_stp_height);
179 
180     gcvalue.foreground = dark;
181     gcvalue.background = light;
182     gcvalue.fill_style = FillOpaqueStippled;
183     gcvalue.stipple = stipple;
184 
185 /*    XSetWindowBackground(r->Xdisplay, r->scrollBar.win, r->PixColors[Color_Red]); */
186 
187     r->h->stippleGC = XCreateGC(r->Xdisplay, r->scrollBar.win,
188 				GCForeground | GCBackground | GCStipple
189 				| GCFillStyle | GCGraphicsExposures, &gcvalue);
190 
191     r->h->dimple = xvt_renderPixmap(r, SCROLLER_DIMPLE, SCROLLER_DIMPLE_WIDTH,
192 				     SCROLLER_DIMPLE_HEIGHT);
193 
194     r->h->upArrow = xvt_renderPixmap(r, SCROLLER_ARROW_UP, ARROW_WIDTH,
195 				      ARROW_HEIGHT);
196     r->h->downArrow = xvt_renderPixmap(r, SCROLLER_ARROW_DOWN, ARROW_WIDTH,
197 					ARROW_HEIGHT);
198     r->h->upArrowHi = xvt_renderPixmap(r, HI_SCROLLER_ARROW_UP, ARROW_WIDTH,
199 					ARROW_HEIGHT);
200     r->h->downArrowHi = xvt_renderPixmap(r, HI_SCROLLER_ARROW_DOWN,
201 					  ARROW_WIDTH, ARROW_HEIGHT);
202 }
203 
204 /* Draw bevel & arrows */
205 /* INTPROTO */
206 void
xvt_drawBevel(xvt_t * r,Drawable d,int x1,int y1,int w,int h)207 xvt_drawBevel(xvt_t *r, Drawable d, int x1, int y1, int w, int h)
208 {
209     int             x2, y2;
210 
211     x2 = x1 + w - 1;		/* right  point */
212     y2 = y1 + h - 1;		/* bottom point */
213 /* white top and left */
214     XDrawLine(r->Xdisplay, d, r->h->whiteGC, x1, y1, x2, y1);
215     XDrawLine(r->Xdisplay, d, r->h->whiteGC, x1, y1, x1, y2);
216 /* black bottom and right */
217     XDrawLine(r->Xdisplay, d, r->h->blackGC, x1, y2, x2, y2);
218     XDrawLine(r->Xdisplay, d, r->h->blackGC, x2, y1, x2, y2);
219 /* dark inside bottom and right */
220     x1++, y1++, x2--, y2--;	/* move in one point */
221     XDrawLine(r->Xdisplay, d, r->h->darkGC, x1, y2, x2, y2);
222     XDrawLine(r->Xdisplay, d, r->h->darkGC, x2, y1, x2, y2);
223 }
224 
225 /* EXTPROTO */
226 int
xvt_scrollbar_show_next(xvt_t * r,int update,int last_top,int last_bot,int scrollbar_len)227 xvt_scrollbar_show_next(xvt_t *r, int update, int last_top, int last_bot, int scrollbar_len)
228 {
229     int             height = r->scrollBar.end + SB_BUTTON_TOTAL_HEIGHT + SB_PADDING;
230     Drawable        s;
231 
232     if ((r->scrollBar.init & R_SB_NEXT) == 0) {
233 	r->scrollBar.init |= R_SB_NEXT;
234 	xvt_init_scrollbar_stuff(r);
235     }
236 
237     if (r->TermWin.nscrolled == 0 || !update) {
238 	XFillRectangle(r->Xdisplay, r->scrollBar.win, r->h->grayGC, 0, 0,
239 		       SB_WIDTH_NEXT + 1, height);
240 	XDrawRectangle(r->Xdisplay, r->scrollBar.win, r->h->blackGC, 0,
241 		       -SB_BORDER_WIDTH, SB_WIDTH_NEXT,
242 		       height + SB_BORDER_WIDTH);
243 	XFillRectangle(r->Xdisplay, r->scrollBar.win, r->h->stippleGC,
244 		       SB_LEFT_PADDING, 0, SB_BUTTON_WIDTH, height);
245     }
246     if (r->TermWin.nscrolled) {
247 	if (last_top < r->scrollBar.top || !update)
248 	    XFillRectangle(r->Xdisplay, r->scrollBar.win, r->h->stippleGC,
249 			   SB_LEFT_PADDING, SB_PADDING + last_top,
250 			   SB_BUTTON_WIDTH, r->scrollBar.top - last_top);
251 	if (r->scrollBar.bot < last_bot || !update)
252 	    XFillRectangle(r->Xdisplay, r->scrollBar.win, r->h->stippleGC,
253 			   SB_LEFT_PADDING, r->scrollBar.bot + SB_PADDING,
254 			   SB_BUTTON_WIDTH, (last_bot - r->scrollBar.bot));
255 	XFillRectangle(r->Xdisplay, r->scrollBar.win, r->h->grayGC,
256 		       SB_LEFT_PADDING, r->scrollBar.top + SB_PADDING,
257 		       SB_BUTTON_WIDTH, scrollbar_len);
258 	XCopyArea(r->Xdisplay, r->h->dimple, r->scrollBar.win, r->h->whiteGC, 0, 0,
259 		  SCROLLER_DIMPLE_WIDTH, SCROLLER_DIMPLE_HEIGHT,
260 		  (SB_WIDTH_NEXT - SCROLLER_DIMPLE_WIDTH) / 2,
261 		  r->scrollBar.top + SB_BEVEL_WIDTH_UPPER_LEFT +
262 		  (scrollbar_len - SCROLLER_DIMPLE_HEIGHT) / 2);
263 
264 	xvt_drawBevel(r, r->scrollBar.win, SB_BUTTON_BEVEL_X,
265 		       r->scrollBar.top + SB_PADDING, SB_BUTTON_WIDTH,
266 		       scrollbar_len);
267 	xvt_drawBevel(r, r->scrollBar.win, SB_BUTTON_BEVEL_X,
268 		       height - SB_BUTTON_BOTH_HEIGHT, SB_BUTTON_WIDTH,
269 		       SB_BUTTON_HEIGHT);
270 	xvt_drawBevel(r, r->scrollBar.win, SB_BUTTON_BEVEL_X,
271 		       height - SB_BUTTON_SINGLE_HEIGHT, SB_BUTTON_WIDTH,
272 		       SB_BUTTON_HEIGHT);
273 
274 	s = (scrollbar_isUp()) ? r->h->upArrowHi : r->h->upArrow;
275 	XCopyArea(r->Xdisplay, s, r->scrollBar.win, r->h->whiteGC, 0, 0,
276 		  ARROW_WIDTH, ARROW_HEIGHT, SB_BUTTON_FACE_X,
277 		  height - SB_BUTTON_BOTH_HEIGHT + SB_BEVEL_WIDTH_UPPER_LEFT);
278 
279 	s = (scrollbar_isDn()) ? r->h->downArrowHi : r->h->downArrow;
280 	XCopyArea(r->Xdisplay, s, r->scrollBar.win, r->h->whiteGC, 0, 0,
281 		  ARROW_WIDTH, ARROW_HEIGHT, SB_BUTTON_FACE_X,
282 		  height - SB_BUTTON_SINGLE_HEIGHT + SB_BEVEL_WIDTH_UPPER_LEFT);
283     }
284     return 1;
285 }
286 /*----------------------- end-of-file (C source) -----------------------*/
287