1 /* $Header: /home/yav/xpx/RCS/scrl.c,v 1.11 1995/11/23 16:28:39 yav Exp $
2  * xpx scroll
3  * written by yav (UHD98984@pcvan.or.jp)
4  */
5 
6 #include <X11/Xlib.h>
7 #include <X11/Xutil.h>
8 
9 #include "headers.h"
10 #include "xpx.h"
11 #include "work.h"
12 #include "scrldef.h"
13 #include "icondef.h"
14 #define PUBLIC_SCRL_C
15 #include "extern.h"
16 
17 
18 char rcsid_scrl[] = "$Id: scrl.c,v 1.11 1995/11/23 16:28:39 yav Exp $";
19 
20 int create_slider_window();
21 
22 #define IMASK (ExposureMask|EnterWindowMask|LeaveWindowMask|\
23 	       ButtonPressMask|ButtonReleaseMask)
24 
25 int scrlev();
26 
27 MENU scrlbar[] = {
28   {
29     SCRLBAR_TOP,	MenuModeMaskBorder,
30     0, 0, 0, 0,
31     0, IMASK, 0,
32     scrlev, NULL, 0, 0, NULL},
33   {
34     SCRLBAR_BOTTOM,	MenuModeMaskBorder,
35     0, 0, 0, 0,
36     0, IMASK, 0,
37     scrlev, NULL, 0, 0, NULL},
38   {
39     SCRLBAR_LEFT,	MenuModeMaskBorder,
40     0, 0, 0, 0,
41     0, IMASK, 0,
42     scrlev, NULL, 0, 0, NULL},
43   {
44     SCRLBAR_RIGHT,	MenuModeMaskBorder,
45     0, 0, 0, 0,
46     0, IMASK, 0,
47     scrlev, NULL, 0, 0, NULL},
48   {
49     -1,	0,
50     0, 0, 0, 0,
51     0, 0, 0,
52     NULL, NULL, 0, 0, NULL}};
53 
calc_resize_scrl(x0,y0,w0,h0)54 void calc_resize_scrl(x0, y0, w0, h0)
55      int x0;
56      int y0;
57      int w0;
58      int h0;
59 {
60   scrlbar[SCRLBAR_TOP].y = y0-IMGSCRLW-1;
61   scrlbar[SCRLBAR_BOTTOM].y = y0+h0+1;
62   scrlbar[SCRLBAR_TOP].x = scrlbar[SCRLBAR_BOTTOM].x = x0;
63   scrlbar[SCRLBAR_TOP].w = scrlbar[SCRLBAR_BOTTOM].w = w0;
64   scrlbar[SCRLBAR_TOP].h = scrlbar[SCRLBAR_BOTTOM].h = IMGSCRLW;
65   scrlbar[SCRLBAR_LEFT].x = x0-IMGSCRLW-1;
66   scrlbar[SCRLBAR_RIGHT].x = x0+w0+1;
67   scrlbar[SCRLBAR_LEFT].y = scrlbar[SCRLBAR_RIGHT].y = y0;
68   scrlbar[SCRLBAR_LEFT].w = scrlbar[SCRLBAR_RIGHT].w = IMGSCRLW;
69   scrlbar[SCRLBAR_LEFT].h = scrlbar[SCRLBAR_RIGHT].h = h0;
70 }
71 
resize_scrl_sub(n)72 void resize_scrl_sub(n)
73      int n;
74 {
75   MENU *p;
76 
77   p = scrlbar+n;
78   XMoveResizeWindow(dsp, p->win, p->x, p->y, p->w, p->h);
79   if (scrollbarmode & 1)
80     XMapWindow(dsp, p->win);
81 }
82 
resize_scrl()83 void resize_scrl()
84 {
85   calc_resize_scrl(imgwx, imgwy, imgwinwidth, imgwinheight);
86   resize_scrl_sub(SCRLBAR_TOP);
87   resize_scrl_sub(SCRLBAR_BOTTOM);
88   resize_scrl_sub(SCRLBAR_LEFT);
89   resize_scrl_sub(SCRLBAR_RIGHT);
90 }
91 
92 
create_scrlbar_window()93 void create_scrlbar_window()
94 {
95   MENU *p;
96   XSetWindowAttributes attr;
97 
98   calc_resize_scrl(imgwx, imgwy, imgwinwidth, imgwinheight);
99   menuwin_create2(scrlbar, win, 0, 0, scrollbarmode & 1 ? 1 : 0);
100   for (p = scrlbar; p->n >= 0; p++) {
101     attr.win_gravity = UnmapGravity;
102     XChangeWindowAttributes(dsp, p->win, CWWinGravity, &attr);
103   }
104   create_slider_window();
105 }
106 
scrlev(p,ev)107 int scrlev(p, ev)
108      MENU *p;
109      XEvent *ev;
110 {
111   int r;
112 
113   switch(ev->type) {
114   case Expose:
115     if (ev->xexpose.count)
116       break;
117     switch(p->n) {
118     case SCRLBAR_TOP:
119       r = ICON_up;
120       break;
121     case SCRLBAR_BOTTOM:
122       r = ICON_down;
123       break;
124     case SCRLBAR_LEFT:
125       r = ICON_left;
126       break;
127     case SCRLBAR_RIGHT:
128       r = ICON_right;
129       break;
130     }
131     menu_icon_center(p, r);
132     return 1;
133   case ButtonRelease:
134     scroll_dx = scroll_dy = 0;
135     break;
136   }
137   return 0;
138 }
139 
140 /*
141  * slider bar
142  */
143 
144 #define HSLIDER_X	0
145 #define HSLIDER_Y	(BDW*2+1)
146 #define VSLIDER_X	(BDW*2+1)
147 #define VSLIDER_Y	0
148 #define SLIDER_MIN	IMGSCRLW
149 
150 Window hsliderbase;
151 Window vsliderbase;
152 int hslide_range;
153 int vslide_range;
154 
hslidev(p,ev)155 int hslidev(p, ev)
156      MENU *p;
157      XEvent *ev;
158 {
159   int r;
160 
161   switch(ev->type) {
162   case Expose:
163     if (ev->xexpose.count)
164       break;
165     switch(p->n) {
166     case HSLIDER_LEFT:
167       r = ICON_left;
168       break;
169     case HSLIDER_RIGHT:
170       r = ICON_right;
171       break;
172     }
173     menu_icon_center(p, r);
174     return 1;
175   case ButtonRelease:
176     scroll_dx = scroll_dy = 0;
177     break;
178   }
179   return 0;
180 }
181 
vslidev(p,ev)182 int vslidev(p, ev)
183      MENU *p;
184      XEvent *ev;
185 {
186   int r;
187 
188   switch(ev->type) {
189   case Expose:
190     if (ev->xexpose.count)
191       break;
192     switch(p->n) {
193     case VSLIDER_UP:
194       r = ICON_up;
195       break;
196     case VSLIDER_DOWN:
197       r = ICON_down;
198       break;
199     }
200     menu_icon_center(p, r);
201     return 1;
202   case ButtonRelease:
203     scroll_dx = scroll_dy = 0;
204     break;
205   }
206   return 0;
207 }
208 
hslidev2(p,ev)209 int hslidev2(p, ev)
210      MENU *p;
211      XEvent *ev;
212 {
213   int i;
214   static int ox;
215 
216   switch(ev->type) {
217   case ButtonPress:
218     ox = p->x - (BDW+SLIDER_MIN+BDW) - ev->xbutton.x_root;
219     return 1;
220   case ButtonRelease:
221     i = ev->xbutton.x_root;
222     break;
223   case MotionNotify:
224     i = ev->xmotion.x_root;
225     break;
226   default:
227     return 0;
228   }
229   i += ox;
230   i *= imgfilew*zoomfactor - imgwinwidth;
231   i = hslide_range ? i / hslide_range : 0;
232   img_scroll(i-imgofsx, 0);
233   return 1;
234 }
235 
vslidev2(p,ev)236 int vslidev2(p, ev)
237      MENU *p;
238      XEvent *ev;
239 {
240   int i;
241   static int oy;
242 
243   switch(ev->type) {
244   case ButtonPress:
245     oy = p->y - (BDW+SLIDER_MIN+BDW) - ev->xbutton.y_root;
246     return 1;
247   case ButtonRelease:
248     i = ev->xbutton.y_root;
249     break;
250   case MotionNotify:
251     i = ev->xmotion.y_root;
252     break;
253   default:
254     return 0;
255   }
256   i += oy;
257   i *= imgfileh*zoomfactor - imgwinheight;
258   i = vslide_range ? i / vslide_range : 0;
259   img_scroll(0, i-imgofsy);
260   return 1;
261 }
262 
263 MENU hslider[] = {
264   {
265     HSLIDER_BAR,	MenuModeMaskBorder,
266     0, 0, SLIDER_MIN, SLIDER_MIN,
267     0, (ExposureMask|ButtonPressMask|ButtonReleaseMask|ButtonMotionMask), 0,
268     hslidev2, NULL, 0, 0, NULL},
269   {
270     HSLIDER_LEFT,	MenuModeMaskBorder,
271     0, 0, SLIDER_MIN, SLIDER_MIN,
272     0, IMASK, 0,
273     hslidev, NULL, 0, 0, NULL},
274   {
275     HSLIDER_RIGHT,	MenuModeMaskBorder,
276     0, 0, SLIDER_MIN, SLIDER_MIN,
277     0, IMASK, 0,
278     hslidev, NULL, 0, 0, NULL},
279   {
280     -1,	0,
281     0, 0, 0, 0,
282     0, 0, 0,
283     NULL, NULL, 0, 0, NULL}};
284 
285 MENU vslider[] = {
286   {
287     VSLIDER_BAR,	MenuModeMaskBorder,
288     0, 0, SLIDER_MIN, SLIDER_MIN,
289     0, (ExposureMask|ButtonPressMask|ButtonReleaseMask|ButtonMotionMask), 0,
290     vslidev2, NULL, 0, 0, NULL},
291   {
292     VSLIDER_UP,	MenuModeMaskBorder,
293     0, 0, SLIDER_MIN, SLIDER_MIN,
294     0, IMASK, 0,
295     vslidev, NULL, 0, 0, NULL},
296   {
297     VSLIDER_DOWN,	MenuModeMaskBorder,
298     0, 0, SLIDER_MIN, SLIDER_MIN,
299     0, IMASK, 0,
300     vslidev, NULL, 0, 0, NULL},
301   {
302     -1,	0,
303     0, 0, 0, 0,
304     0, 0, 0,
305     NULL, NULL, 0, 0, NULL}};
306 
calc_hslider_pos()307 void calc_hslider_pos()
308 {
309   int i;
310 
311   i = (imgfilew * zoomfactor) - imgwinwidth;
312   if (i > 0) {
313     i = (imgofsx * hslide_range) / i;
314   } else {
315     i = 0;
316   }
317   hslider[HSLIDER_BAR].x = BDW+SLIDER_MIN+BDW + i;
318 }
319 
calc_vslider_pos()320 void calc_vslider_pos()
321 {
322   int i;
323 
324   i = (imgfileh * zoomfactor) - imgwinheight;
325   if (i > 0) {
326     i = (imgofsy * vslide_range) / i;
327   } else {
328     i = 0;
329   }
330   vslider[VSLIDER_BAR].y = BDW+SLIDER_MIN+BDW + i;
331 }
332 
calc_resize_hslider(w0)333 void calc_resize_hslider(w0)
334      int w0;
335 {
336   int i;
337 
338   hslider[HSLIDER_LEFT].w = SLIDER_MIN;
339   hslider[HSLIDER_RIGHT].w = SLIDER_MIN;
340   i = w0 - (BDW+SLIDER_MIN+BDW);
341   hslider[HSLIDER_RIGHT].x = i;
342   i = w0 - (BDW + hslider[HSLIDER_LEFT].w + BDW
343 	    + BDW + BDW
344 	    + BDW + hslider[HSLIDER_RIGHT].w + BDW);
345   i *= imgwinwidth;
346   if (imgfilew)
347     i /= imgfilew*zoomfactor;
348   if (i < SLIDER_MIN)
349     i = SLIDER_MIN;
350   hslider[HSLIDER_BAR].w = i;
351   i = w0 - (BDW + hslider[HSLIDER_LEFT].w + BDW
352 	    + BDW + hslider[HSLIDER_BAR].w + BDW
353 	    + BDW + hslider[HSLIDER_RIGHT].w + BDW);
354   if (i < 0)
355     i = 0;
356   hslide_range = i;
357   calc_hslider_pos();
358 }
359 
calc_resize_vslider(h0)360 void calc_resize_vslider(h0)
361      int h0;
362 {
363   int i;
364 
365   vslider[VSLIDER_UP].h = SLIDER_MIN;
366   vslider[VSLIDER_DOWN].h = SLIDER_MIN;
367   i = h0 - (BDW+SLIDER_MIN+BDW);
368   vslider[VSLIDER_DOWN].y = i;
369   i = h0 - (BDW + vslider[VSLIDER_UP].h + BDW
370 	    + BDW + BDW
371 	    + BDW + vslider[VSLIDER_DOWN].h + BDW);
372   i *= imgwinheight;
373   if (imgfileh)
374     i /= imgfileh*zoomfactor;
375   if (i < SLIDER_MIN)
376     i = SLIDER_MIN;
377   vslider[VSLIDER_BAR].h = i;
378   i = h0 - (BDW + vslider[VSLIDER_UP].h + BDW
379 	    + BDW + vslider[VSLIDER_BAR].h + BDW
380 	    + BDW + vslider[VSLIDER_DOWN].h + BDW);
381   if (i < 0)
382     i = 0;
383   vslide_range = i;
384   calc_vslider_pos();
385 }
386 
create_slider_window()387 int create_slider_window()
388 {
389   XSetWindowAttributes attr;
390 
391   hsliderbase = XCreateSimpleWindow(dsp, win,
392 				    imgwx+HSLIDER_X,
393 				    imgwy+imgwinheight+HSLIDER_Y,
394 				    imgwinwidth, BDW+SLIDER_MIN+BDW,
395 				    BDW, border_color, bg);
396   attr.win_gravity = SouthWestGravity;
397   attr.background_pixmap = hatch_pixmap;
398   XChangeWindowAttributes(dsp, hsliderbase, CWWinGravity|CWBackPixmap, &attr);
399   calc_resize_hslider(imgwinwidth);
400   menuwin_create(hslider, hsliderbase, 0, 0);
401   if (scrollbarmode & 2)
402     XMapRaised(dsp, hsliderbase);
403 
404   vsliderbase = XCreateSimpleWindow(dsp, win,
405 				    imgwx+imgwinwidth+VSLIDER_X,
406 				    imgwy+HSLIDER_Y,
407 				    BDW+SLIDER_MIN+BDW, imgwinheight,
408 				    BDW, border_color, bg);
409   attr.win_gravity = NorthEastGravity;
410   attr.background_pixmap = hatch_pixmap;
411   XChangeWindowAttributes(dsp, vsliderbase, CWBackPixmap|CWWinGravity, &attr);
412   calc_resize_vslider(imgwinheight);
413   menuwin_create(vslider, vsliderbase, 0, 0);
414 
415   if (scrollbarmode & 2)
416     XMapRaised(dsp, vsliderbase);
417   return 0;
418 }
419 
resize_scroll_slider()420 void resize_scroll_slider()
421 {
422   MENU *p;
423 
424   XMoveResizeWindow(dsp, hsliderbase,
425 		    imgwx+HSLIDER_X,
426 		    imgwy+imgwinheight+HSLIDER_Y,
427 		    imgwinwidth, BDW+SLIDER_MIN+BDW);
428   calc_resize_hslider(imgwinwidth);
429   p = hslider;
430   while (p->n >= 0) {
431     XMoveResizeWindow(dsp, p->win, p->x, p->y, p->w, p->h);
432     p++;
433   }
434   XMoveResizeWindow(dsp, vsliderbase,
435 		    imgwx+imgwinwidth+VSLIDER_X,
436 		    imgwy+VSLIDER_Y,
437 		    BDW+SLIDER_MIN+BDW, imgwinheight);
438   calc_resize_vslider(imgwinheight);
439   p = vslider;
440   while (p->n >= 0) {
441     XMoveResizeWindow(dsp, p->win, p->x, p->y, p->w, p->h);
442     p++;
443   }
444 }
445 
move_hslider()446 void move_hslider()
447 {
448   MENU *p;
449 
450   calc_hslider_pos();
451   p = &hslider[HSLIDER_BAR];
452   XMoveWindow(dsp, p->win, p->x, p->y);
453 }
454 
move_vslider()455 void move_vslider()
456 {
457   MENU *p;
458 
459   calc_vslider_pos();
460   p = &vslider[VSLIDER_BAR];
461   XMoveWindow(dsp, p->win, p->x, p->y);
462 }
463 
464 /* End of file */
465