1 /*
2  * wmslib/src/abut/swin.c, part of wmslib (Library functions)
3  * Copyright (C) 1994-1996 William Shubert.
4  * See "configure.h.in" for more copyright information.
5  */
6 
7 #include <wms.h>
8 
9 #if  X11_DISP
10 
11 #include <but/but.h>
12 #include <but/slide.h>
13 #include <but/canvas.h>
14 #include <but/box.h>
15 #include <but/ctext.h>
16 #include <but/timer.h>
17 #ifdef  _ABUT_SWIN_H_
18   Levelization Error.
19 #endif
20 #include "swin.h"
21 
22 
23 /**********************************************************************
24  * Forward Declarations
25  **********************************************************************/
26 static void  draw_uparrow(void *packet, ButWin *win,
27 			  int x, int y, int w, int h);
28 static void  draw_downarrow(void *packet, ButWin *win,
29 			    int x, int y, int w, int h);
30 static void  draw_leftarrow(void *packet, ButWin *win,
31 			    int x, int y, int w, int h);
32 static void  draw_rightarrow(void *packet, ButWin *win,
33 			     int x, int y, int w, int h);
34 static ButOut  pressUp(But *but), pressDown(But *but);
35 static ButOut  pressLeft(But *but), pressRight(But *but);
36 static ButOut  releaseVArrow(But *but), releaseHArrow(But *but);
37 static ButOut  v_moved(But *but, int new_yoff, bool newPress);
38 static ButOut  hMoved(But *but, int new_xOff, bool newPress);
39 static void  redo_slider(void *packet, int xoff, int yoff,
40 			 int w, int h, int viewW, int viewH);
41 
42 
43 /**********************************************************************
44  * Functions
45  **********************************************************************/
abutSwin_create(void * packet,ButWin * parent,int layer,uint flags,ButWinFunc resize)46 AbutSwin  *abutSwin_create(void *packet, ButWin *parent, int layer, uint flags,
47 			   ButWinFunc resize)  {
48   AbutSwin  *swin;
49   ButEnv  *env = butWin_env(parent);
50   static ButKey  upKeys[] = {{XK_Prior, 0, ShiftMask}, {0,0,0}};
51   static ButKey  downKeys[] = {{XK_Next, 0, ShiftMask}, {0,0,0}};
52   static ButKey  leftKeys[] = {{XK_Left, 0, ShiftMask}, {0,0,0}};
53   static ButKey  rightKeys[] = {{XK_Right, 0, ShiftMask}, {0,0,0}};
54 
55   butEnv_setChar(env, 1.0, ABUT_UPPIC,    draw_uparrow,    NULL);
56   butEnv_setChar(env, 1.0, ABUT_DOWNPIC,  draw_downarrow,  NULL);
57   butEnv_setChar(env, 1.0, ABUT_LEFTPIC,  draw_leftarrow,  NULL);
58   butEnv_setChar(env, 1.0, ABUT_RIGHTPIC, draw_rightarrow, NULL);
59   swin = wms_malloc(sizeof(AbutSwin));
60   MAGIC_SET(swin);
61   if (flags & (ABUTSWIN_LSLIDE | ABUTSWIN_RSLIDE))  {
62     swin->up = butAct_vCreate(pressUp, releaseVArrow,
63 			      swin, parent, layer,
64 			      BUT_DRAWABLE|BUT_PRESSABLE,
65 			      ABUT_UPPIC, BUT_SRIGHT|BUT_SLEFT);
66     but_setKeys(swin->up, upKeys);
67     swin->down = butAct_vCreate(pressDown, releaseVArrow,
68 				swin, parent, layer,
69 				BUT_DRAWABLE|BUT_PRESSABLE,
70 				ABUT_DOWNPIC, BUT_SRIGHT|BUT_SLEFT);
71     but_setKeys(swin->down, downKeys);
72     swin->vSlide = butSlide_vCreate(v_moved, swin, parent, layer,
73 				    BUT_DRAWABLE|BUT_PRESSABLE,
74 				    100,10,10);
75   }
76   if (flags & (ABUTSWIN_TSLIDE | ABUTSWIN_BSLIDE))  {
77     swin->left = butAct_vCreate(pressLeft, releaseHArrow,
78 				swin, parent, layer,
79 				BUT_DRAWABLE|BUT_PRESSABLE,
80 				ABUT_LEFTPIC, BUT_SRIGHT|BUT_SLEFT);
81     but_setKeys(swin->left, leftKeys);
82     swin->right = butAct_vCreate(pressRight, releaseHArrow,
83 				 swin, parent, layer,
84 				 BUT_DRAWABLE|BUT_PRESSABLE,
85 				 ABUT_RIGHTPIC, BUT_SRIGHT|BUT_SLEFT);
86     but_setKeys(swin->right, rightKeys);
87     swin->hSlide = butSlide_hCreate(hMoved, swin, parent, layer,
88 				    BUT_DRAWABLE|BUT_PRESSABLE,
89 				    100,10,10);
90   }
91   swin->box = butBox_create(parent, layer, BUT_DRAWABLE);
92   butBox_setColors(swin->box, BUT_SHAD, BUT_LIT);
93   swin->win = butCan_create(swin, parent, layer, resize, NULL, redo_slider);
94   swin->flags = flags;
95   swin->timer = NULL;
96   swin->xCenter = swin->yCenter = 0.0;
97   swin->packet = packet;
98   return(swin);
99 }
100 
101 
abutSwin_resize(AbutSwin * swin,int x,int y,int w,int h,int slideW,int lineH)102 void  abutSwin_resize(AbutSwin *swin, int x, int y, int w, int h,
103 		       int slideW, int lineH)  {
104   int  bx, by, bw, bh;
105   int  canWinW, canWinH, canViewW, canViewH;
106   int  butbw = butEnv_stdBw(butWin_env(swin->win));
107   int  new_yoff = 0, new_xoff = 0;
108   float  yratio = swin->yCenter, xratio = swin->xCenter;
109 
110   assert(MAGIC(swin));
111   if (x == BUT_NOCHANGE)
112     x = swin->x;
113   if (y == BUT_NOCHANGE)
114     y = swin->y;
115   if (w == BUT_NOCHANGE)
116     w = swin->w;
117   if (h == BUT_NOCHANGE)
118     h = swin->h;
119   if (slideW == BUT_NOCHANGE)
120     slideW = swin->slideW;
121   if (lineH == BUT_NOCHANGE)
122     lineH = swin->lineH;
123   swin->x = x;
124   swin->y = y;
125   swin->w = w;
126   swin->h = h;
127   swin->slideW = slideW;
128   swin->lineH = lineH;
129 
130   bx = x;
131   by = y;
132   bw = w;
133   bh = h;
134 
135   if (swin->flags & ABUTSWIN_LSLIDE)  {
136     bx += slideW;
137     bw -= slideW;
138   } else if (swin->flags & ABUTSWIN_RSLIDE)  {
139     bw -= slideW;
140   }
141   if (swin->flags & ABUTSWIN_TSLIDE)  {
142     by += slideW;
143     bh -= slideW;
144   } else if (swin->flags & ABUTSWIN_BSLIDE)  {
145     bh -= slideW;
146   }
147   butCan_resizeView(swin->win, bx+butbw,by+butbw, bw-2*butbw,bh-2*butbw,
148 		    FALSE);
149   canViewW = bw - butbw*2;
150   canViewH = bh - butbw*2;
151   canWinW = butWin_w(swin->win);
152   canWinH = butWin_h(swin->win);
153   if (swin->flags & (ABUTSWIN_TSLIDE|ABUTSWIN_BSLIDE))  {
154     new_xoff = xratio * (canWinW - canViewW) + 0.5;
155   }
156   if (swin->flags & (ABUTSWIN_LSLIDE|ABUTSWIN_RSLIDE))  {
157     new_yoff = yratio * (canWinH - canViewH) + 0.5;
158   }
159   if (new_xoff > canWinW - canViewW)
160     new_xoff = canWinW - canViewW;
161   if (new_yoff > canWinH - canViewH)
162     new_yoff = canWinH - canViewH;
163   if (new_xoff < 0)
164     new_xoff = 0;
165   if (new_yoff < 0)
166     new_yoff = 0;
167   if (swin->flags & ABUTSWIN_LSLIDE)  {
168     if (bh - 2*slideW < butbw * 5)  {
169       but_resize(swin->up, x, by, slideW, bh/2);
170       but_resize(swin->down, x, by + bh/2, slideW, (bh + 1) / 2);
171       but_resize(swin->vSlide, 0, 0, 0, 0);
172       butSlide_set(swin->vSlide, canWinH - canViewH, new_yoff, canViewH);
173       v_moved(swin->vSlide, new_yoff, FALSE);
174     } else  {
175       but_resize(swin->up, x,by,slideW,slideW);
176       but_resize(swin->down, x,by+bh-slideW,slideW,slideW);
177       but_resize(swin->vSlide, x,by+slideW,slideW,bh-2*slideW);
178       butSlide_set(swin->vSlide, canWinH - canViewH, new_yoff, canViewH);
179       v_moved(swin->vSlide, new_yoff, FALSE);
180     }
181   } else if (swin->flags & ABUTSWIN_RSLIDE)  {
182     but_resize(swin->up, x+w-slideW,by,slideW,slideW);
183     but_resize(swin->down, x+w-slideW,by+h-slideW,slideW,slideW);
184     but_resize(swin->vSlide, x+w-slideW,by+slideW,slideW,bh-2*slideW);
185     butSlide_set(swin->vSlide, canWinH - canViewH, new_yoff, canViewH);
186     v_moved(swin->vSlide, new_yoff, FALSE);
187   }
188   if (swin->flags & ABUTSWIN_TSLIDE)  {
189     but_resize(swin->left, bx, y, slideW, slideW);
190     but_resize(swin->right, bx + bw - slideW, y, slideW, slideW);
191     but_resize(swin->hSlide, bx + slideW, y, bw - 2 * slideW, slideW);
192     butSlide_set(swin->hSlide, canWinW - canViewW, new_xoff, canViewW);
193     v_moved(swin->hSlide, new_xoff, FALSE);
194   } else if (swin->flags & ABUTSWIN_BSLIDE)  {
195     but_resize(swin->left, bx, y + h - slideW, slideW, slideW);
196     but_resize(swin->right, bx + bw - slideW, y + h - slideW, slideW, slideW);
197     but_resize(swin->hSlide, bx + slideW, y + h - slideW,
198 	       bw - 2 * slideW, slideW);
199     butSlide_set(swin->hSlide, canWinW - canViewW, new_xoff, canViewW);
200     v_moved(swin->hSlide, new_xoff, FALSE);
201   }
202   but_resize(swin->box, bx,by,bw,bh);
203   swin->canButW = bw - butbw*2;
204   swin->canButH = bh - butbw*2;
205 }
206 
207 
draw_uparrow(void * packet,ButWin * win,int x,int y,int w,int h)208 static void  draw_uparrow(void *packet, ButWin *win,
209 			  int x, int y, int w, int h)  {
210   XPoint  points[3];
211   Display  *dpy = butEnv_dpy(butWin_env(win));
212   Window  xwin = butWin_xwin(win);
213   GC  gc = butEnv_gc(butWin_env(win));
214 
215   h &= ~1;
216   w &= ~1;
217   points[0].x = x;
218   points[0].y = y+h/2;
219   points[1].x = x+w/2;
220   points[1].y = y;
221   points[2].x = x+w;
222   points[2].y = y+h/2;
223   XFillPolygon(dpy, xwin, gc, points, 3, Nonconvex, CoordModeOrigin);
224 }
225 
226 
draw_downarrow(void * packet,ButWin * win,int x,int y,int w,int h)227 static void  draw_downarrow(void *packet, ButWin *win,
228 			    int x, int y, int w, int h)  {
229   XPoint  points[3];
230   Display  *dpy = butEnv_dpy(butWin_env(win));
231   Window  xwin = butWin_xwin(win);
232   GC  gc = butEnv_gc(butWin_env(win));
233 
234   h &= ~1;
235   w &= ~1;
236   points[0].x = x;
237   points[0].y = y+h/2;
238   points[1].x = x+w/2;
239   points[1].y = y+h;
240   points[2].x = x+w;
241   points[2].y = y+h/2;
242   XFillPolygon(dpy, xwin, gc, points, 3, Nonconvex, CoordModeOrigin);
243 }
244 
245 
draw_leftarrow(void * packet,ButWin * win,int x,int y,int w,int h)246 static void  draw_leftarrow(void *packet, ButWin *win,
247 			    int x, int y, int w, int h)  {
248   XPoint  points[3];
249   Display  *dpy = butEnv_dpy(butWin_env(win));
250   Window  xwin = butWin_xwin(win);
251   GC  gc = butEnv_gc(butWin_env(win));
252 
253   h &= ~1;
254   w &= ~1;
255   points[0].x = x;
256   points[0].y = y+h/2;
257   points[1].x = x+w/2;
258   points[1].y = y;
259   points[2].x = x+w/2;
260   points[2].y = y+h;
261   XFillPolygon(dpy, xwin, gc, points, 3, Nonconvex, CoordModeOrigin);
262 }
263 
264 
draw_rightarrow(void * packet,ButWin * win,int x,int y,int w,int h)265 static void  draw_rightarrow(void *packet, ButWin *win,
266 			     int x, int y, int w, int h)  {
267   XPoint  points[3];
268   Display  *dpy = butEnv_dpy(butWin_env(win));
269   Window  xwin = butWin_xwin(win);
270   GC  gc = butEnv_gc(butWin_env(win));
271 
272   h &= ~1;
273   w &= ~1;
274   points[0].x = x+w;
275   points[0].y = y+h/2;
276   points[1].x = x+w/2;
277   points[1].y = y;
278   points[2].x = x+w/2;
279   points[2].y = y+h;
280   XFillPolygon(dpy, xwin, gc, points, 3, Nonconvex, CoordModeOrigin);
281 }
282 
283 
pressUp(But * but)284 static ButOut  pressUp(But *but)  {
285   AbutSwin  *swin;
286 
287   swin = but_packet(but);
288   assert(MAGIC(swin));
289   butSlide_startSlide(swin->vSlide, TRUE, -2*swin->lineH, TRUE);
290   return(0);
291 }
292 
293 
pressDown(But * but)294 static ButOut  pressDown(But *but)  {
295   AbutSwin  *swin;
296 
297   swin = but_packet(but);
298   assert(MAGIC(swin));
299   butSlide_startSlide(swin->vSlide, TRUE, 2*swin->lineH, TRUE);
300   return(0);
301 }
302 
303 
pressLeft(But * but)304 static ButOut  pressLeft(But *but)  {
305   AbutSwin  *swin;
306 
307   swin = but_packet(but);
308   assert(MAGIC(swin));
309   butSlide_startSlide(swin->hSlide, TRUE, -2*swin->lineH, TRUE);
310   return(0);
311 }
312 
313 
pressRight(But * but)314 static ButOut  pressRight(But *but)  {
315   AbutSwin  *swin;
316 
317   swin = but_packet(but);
318   assert(MAGIC(swin));
319   butSlide_startSlide(swin->hSlide, TRUE, 2*swin->lineH, TRUE);
320   return(0);
321 }
322 
323 
releaseVArrow(But * but)324 static ButOut  releaseVArrow(But *but)  {
325   AbutSwin  *swin = but_packet(but);
326 
327   assert(MAGIC(swin));
328   butSlide_stopSlide(swin->vSlide);
329   return(0);
330 }
331 
332 
releaseHArrow(But * but)333 static ButOut  releaseHArrow(But *but)  {
334   AbutSwin  *swin = but_packet(but);
335 
336   assert(MAGIC(swin));
337   butSlide_stopSlide(swin->hSlide);
338   return(0);
339 }
340 
341 
abutSwin_vMove(AbutSwin * swin,int newLoc)342 void  abutSwin_vMove(AbutSwin *swin, int newLoc)  {
343   butSlide_set(swin->vSlide, BUT_NOCHANGE, newLoc, BUT_NOCHANGE);
344   v_moved(swin->vSlide, newLoc, FALSE);
345 }
346 
347 
v_moved(But * but,int new_yoff,bool newPress)348 static ButOut  v_moved(But *but, int new_yoff, bool newPress)  {
349   AbutSwin  *swin = but_packet(but);
350 
351   assert(MAGIC(swin));
352   if (butWin_viewH(swin->win) == butWin_h(swin->win))
353     swin->yCenter = 0.0;
354   else
355     swin->yCenter = (float)new_yoff / (float)(butWin_h(swin->win) -
356 					       butWin_viewH(swin->win));
357   if (swin->yCenter > 1.0)
358     swin->yCenter = 1.0;
359   if (swin->yCenter < 0.0)
360     swin->yCenter = 0.0;
361   butCan_slide(swin->win, BUT_NOCHANGE, new_yoff, FALSE);
362   return(0);
363 }
364 
365 
hMoved(But * but,int newXOff,bool newPress)366 static ButOut  hMoved(But *but, int newXOff, bool newPress)  {
367   AbutSwin  *swin = but_packet(but);
368 
369   assert(MAGIC(swin));
370   if (butWin_viewW(swin->win) == butWin_w(swin->win))
371     swin->xCenter = 0.0;
372   else
373     swin->xCenter = (float)newXOff / (float)(butWin_w(swin->win) -
374 					      butWin_viewW(swin->win));
375   if (swin->xCenter > 1.0)
376     swin->xCenter = 1.0;
377   if (swin->xCenter < 0.0)
378     swin->xCenter = 0.0;
379   butCan_slide(swin->win, newXOff, BUT_NOCHANGE, FALSE);
380   return(0);
381 }
382 
383 
abutSwin_destroy(AbutSwin * swin)384 void  abutSwin_destroy(AbutSwin *swin)  {
385   assert(MAGIC(swin));
386   MAGIC_UNSET(swin);
387   wms_free(swin);
388 }
389 
390 
redo_slider(void * packet,int xoff,int yoff,int w,int h,int viewW,int viewH)391 static void  redo_slider(void *packet, int xoff, int yoff,
392 			 int w, int h, int viewW, int viewH)  {
393   AbutSwin  *swin = packet;
394 
395   assert(MAGIC(swin));
396   if (swin->flags & (ABUTSWIN_TSLIDE|ABUTSWIN_BSLIDE))  {
397     butSlide_set(swin->hSlide, w-viewW, xoff, viewW);
398     if (viewW == w)
399       swin->xCenter = 0.0;
400     else
401       swin->xCenter = (float)xoff / (float)(w - viewW);
402   }
403   if (swin->flags & (ABUTSWIN_LSLIDE|ABUTSWIN_RSLIDE))  {
404     butSlide_set(swin->vSlide, h-viewH, yoff, viewH);
405     if (viewH == h)
406       swin->yCenter = 0.0;
407     else
408       swin->yCenter = (float)yoff / (float)(h - viewH);
409   }
410 }
411 
412 #endif  /* X11_DISP */
413