1 /********************************************************************
2 This file is part of the abs 0.907 distribution. abs is a spreadsheet
3 with graphical user interface.
4
5 Copyright (C) 1998-2001 Andr� Bertin (Andre.Bertin@ping.be)
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version if in the same spirit as version 2.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 Concact: abs@pi.be
22 http://home.pi.be/bertin/abs.shtml
23
24 *********************************************************************/
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 #include "myscroll.h"
52 #include "worksheet.h"
53 #include "gr_interf.h"
54 #include "memory.h"
55 #include "callback.h"
56 #include "button.h"
57
58 #include <math.h>
59
60 #include "pixmaps/up.xpm"
61 #include "pixmaps/down.xpm"
62 #include "pixmaps/left.xpm"
63 #include "pixmaps/right.xpm"
64
65
66 static int nosetval = 0;
67 static int downonthumb = 0;
68
69 int
val2pos(vmin,vmax,h,val)70 val2pos (vmin, vmax, h, val)
71 int vmin, vmax, val, h;
72 {
73 int pos = (val - vmin) * (h - 36) / (vmax - vmin) + 18;
74
75
76 return pos;
77 }
78
79 int
pos2val(vmin,vmax,h,pos)80 pos2val (vmin, vmax, h, pos)
81 int vmin, vmax, pos, h;
82 {
83 int val = (vmax - vmin) * (pos - 18) / (h - 36) + vmin;
84
85 return val;
86 }
87
88 int
redrawthumb(ms)89 redrawthumb (ms)
90 Myscroll *ms;
91 {
92 if (ms->orientation == horizontal)
93 {
94 desactivate_zoom ();
95 fillrectangle (XtDisplay (ms->back), XtWindow (ms->back), 3, 17, 2, ms->backlen, ms->h - 4, 0, 0, 0);
96 drawbuttonup (XtDisplay (ms->back), XtWindow (ms->back),
97 ms->thumbpos, 3, ms->thumbpos + ms->thumblen, 14, NULL, 0, 0);
98 reactivate_zoom ();
99 }
100 else
101 {
102 desactivate_zoom ();
103 fillrectangle (XtDisplay (ms->back), XtWindow (ms->back), 3, 2, 17, ms->w - 4, ms->backlen, 0, 0, 0);
104 drawbuttonup (XtDisplay (ms->back), XtWindow (ms->back), 3, ms->thumbpos, 14, ms->thumbpos + ms->thumblen, NULL, 0, 0);
105 reactivate_zoom ();
106 }
107 return 0;
108 }
109
110
111
112
113
114
115
116
117 int
sethpos(ms,pos)118 sethpos (ms, pos)
119 Myscroll *ms;
120 int pos;
121 {
122
123 double p, l;
124 int val;
125
126
127
128 if (pos < ms->thumbmin)
129 pos = ms->thumbmin;
130 if (pos > ms->thumbmax - ms->thumbminlen)
131 pos = ms->thumbmax - ms->thumbminlen;
132
133 p = pos - ms->thumbmin;
134 l = ms->thumbmax - ms->thumbminlen - ms->thumbmin;
135 if (l <= 0)
136 l = 1;
137 val = p / l * (ms->vmax - ms->vmin) + ms->vmin;
138
139 setscrollval (ms, val);
140 return 0;
141
142 }
143
144 void
resizescroll(widget,pointer,event,ctd)145 resizescroll (widget, pointer, event, ctd)
146 Widget widget;
147 XtPointer pointer;
148 XEvent *event;
149 Boolean *ctd;
150 {
151 int n;
152 Dimension h, w;
153 Myscroll *ms;
154 int butsize = 18;
155 Arg args[2];
156 ms = (Myscroll *) pointer;
157
158 n = 0;
159 XtSetArg (args[n], XtNheight, &h);
160 n++;
161 XtSetArg (args[n], XtNwidth, &w);
162 n++;
163 XtGetValues (widget, args, n);
164
165 ms->h = h;
166 ms->w = w;
167
168 if (ms->orientation == horizontal)
169 {
170 ms->thumbmax = w - butsize;
171 }
172 else
173 {
174 ms->thumbmax = h - butsize;
175
176 }
177 ms->backlen = ms->thumbmax - ms->thumbmin;
178 if (ms->backlen < ms->thumbminlen)
179 ms->backlen = ms->thumbminlen;
180 setscrollval (ms, ms->val);
181 }
182
183
184
185
186
187 void
btncb(widget,pointer,junk)188 btncb (widget, pointer, junk)
189 Widget widget;
190 XtPointer pointer;
191 XtPointer junk;
192 {
193
194
195 Myscroll *ms = (Myscroll *) pointer;
196
197 if (widget == ms->up || widget == ms->left)
198 {
199 setscrollval (ms, ms->val - 1);
200 }
201 if (widget == ms->down || widget == ms->right)
202 {
203 setscrollval (ms, ms->val + 1);
204 }
205 if (widget == ms->thumb)
206 {
207 }
208
209 nosetval = 1;
210 ms->cbfunction (ms->val);
211 nosetval = 0;
212 }
213
214 void
thumbupcb(w,pointer,event,ctd)215 thumbupcb (w, pointer, event, ctd)
216 Widget w;
217 XtPointer pointer;
218 XEvent *event;
219 Boolean *ctd;
220 {
221
222
223 }
224
225 void
movecb(w,pointer,event,ctd)226 movecb (w, pointer, event, ctd)
227 Widget w;
228 XtPointer pointer;
229 XEvent *event;
230 Boolean *ctd;
231 {
232 int x, y;
233 int delta;
234 Window root_return, child_return;
235 int root_x_return, root_y_return;
236 int win_x_return, win_y_return;
237 unsigned int mask_return;
238 Myscroll *ms = (Myscroll *) pointer;
239 XQueryPointer (XtDisplay (w), XtWindow (w), &root_return, &child_return, &root_x_return,
240 &root_y_return, &win_x_return, &win_y_return, &mask_return);
241
242 if (!downonthumb)
243 return;
244
245 x = root_x_return;
246 y = root_y_return;
247
248
249
250 if (ms->orientation == vertical)
251 {
252 delta = y - ms->ssy;
253 }
254 else
255 {
256 delta = x - ms->ssx;
257 }
258
259
260 sethpos (ms, ms->thumbpos0 + delta);
261 nosetval = 1;
262 ms->cbfunction (ms->val);
263 nosetval = 0;
264 }
265
266 void
redrawcb(w,pointer,event,ctd)267 redrawcb (w, pointer, event, ctd)
268 Widget w;
269 XtPointer pointer;
270 XEvent *event;
271 Boolean *ctd;
272 {
273 Myscroll *ms = (Myscroll *) pointer;
274 redrawthumb (ms);
275 }
276
277 void
stepcb(w,pointer,event,ctd)278 stepcb (w, pointer, event, ctd)
279 Widget w;
280 XtPointer pointer;
281 XEvent *event;
282 Boolean *ctd;
283 {
284 int x, y;
285 int delta;
286
287 Myscroll *ms = (Myscroll *) pointer;
288
289 x = event->xbutton.x;
290 y = event->xbutton.y;
291
292
293 if ((ms->orientation == horizontal && x > ms->thumbpos && x < ms->thumbpos + ms->thumblen) ||
294 (ms->orientation == vertical && y > ms->thumbpos && y < ms->thumbpos + ms->thumblen))
295 {
296 downonthumb = 1;
297 ms->ssx = event->xbutton.x_root;
298 ms->ssy = event->xbutton.y_root;
299 ms->thumbpos0 = ms->thumbpos;
300 return;
301 }
302
303
304 if (ms->orientation == horizontal)
305 {
306 y = x;
307 }
308
309 if (y < ms->thumbmin || y > ms->thumbmax)
310 return;
311
312 delta = (y - ms->thumbpos) / 5.0;
313 if (fabs (delta / 1.0) < 2)
314 return;
315
316 sethpos (ms, ms->thumbpos + delta);
317
318 nosetval = 1;
319 ms->cbfunction (ms->val);
320 nosetval = 0;
321
322
323 }
324
325 void
presscb(w,pointer,event,ctd)326 presscb (w, pointer, event, ctd)
327 Widget w;
328 XtPointer pointer;
329 XEvent *event;
330 Boolean *ctd;
331 {
332 int x, y;
333
334 Myscroll *ms = (Myscroll *) pointer;
335
336 x = event->xbutton.x_root;
337 y = event->xbutton.y_root;
338 fprintf (stderr, "in presscb\n");
339 ms->thumbpy = y;
340 ms->thumbpx = x;
341 ms->ssx = x;
342 ms->ssy = y;
343 }
344
345
346 int
setscrolllimit(ms,vmin,vmax)347 setscrolllimit (ms, vmin, vmax)
348 Myscroll *ms;
349 int vmin, vmax;
350 {
351 ms->vmin = vmin;
352 ms->vmax = vmax;
353 if (vmax == vmin)
354 vmax = vmin + 1;
355 return 0;
356 }
357
358 void
setscrollval(ms,val)359 setscrollval (ms, val)
360 Myscroll *ms;
361 int val;
362 {
363 if (nosetval)
364 return;
365
366 ms->val = val;
367 if (ms->val < ms->vmin)
368 ms->val = ms->vmin;
369 if (ms->val > ms->vmax)
370 ms->val = ms->vmax;
371
372 {
373 double v = val;
374 double vmin = ms->vmin;
375 double vmax = ms->vmax;
376 double loc = (v - vmin) / (vmax - vmin);
377 int i1, j1, i2, j2;
378 get_visible_cells (&i1, &j1, &i2, &j2);
379 if (ms->orientation == horizontal)
380 {
381
382
383
384 ms->thumblen = (j2 - j1) / (vmax - vmin) * ms->backlen;
385 }
386 else
387 {
388 ms->thumblen = (i2 - i1) / (vmax - vmin) * ms->backlen;
389 }
390
391 if (ms->thumblen < ms->thumbminlen)
392 ms->thumblen = ms->thumbminlen;
393 if (ms->thumblen > ms->backlen)
394 ms->thumblen = ms->backlen;
395
396 if (loc < 0)
397 loc = 0;
398 if (loc > 1)
399 loc = 1;
400 ms->thumbpos = loc * (ms->backlen - ms->thumblen) + ms->thumbmin;
401
402
403
404 redrawthumb (ms);
405
406 if (ms->orientation == horizontal)
407 {
408 ms->cury = ms->thumbpos;
409
410 }
411 else
412 {
413 ms->curx = ms->thumbpos;
414 }
415
416 }
417
418
419 }
420
421
422 Myscroll *
CreateMyscroll(parent,h,w,vmin,vmax,func)423 CreateMyscroll (parent, h, w, vmin, vmax, func)
424 Widget parent;
425 int h, w, vmin, vmax;
426 void (*func) ();
427 {
428 Arg args[16];
429 int n;
430 Myscroll *ms;
431 int butsize = 18;
432
433
434 ms = (Myscroll *) absmalloc (sizeof (Myscroll), "CreateMyscroll:ms ");
435
436 ms->parent = parent;
437 ms->cbfunction = func;
438 ms->h = h;
439 ms->w = w;
440 ms->vmin = vmin;
441 ms->vmax = vmax;
442 ms->val = 0;
443 ms->thumblen = 30;
444 ms->thumbminlen = 15;
445 ms->thumbmin = butsize;
446 ms->thumbpos = butsize;
447
448
449 XtSetArg (w_args[w_n], XtNheight, h);
450 w_n++;
451 XtSetArg (w_args[w_n], XtNwidth, w);
452 w_n++;
453 XtSetArg (w_args[w_n], XtNborderWidth, 0);
454 w_n++;
455 ms->back = (Widget) XtCreateManagedWidget ("window", formWidgetClass, parent,
456 w_args, w_n);
457 if (h > w)
458 {
459 ms->orientation = vertical;
460 ms->thumbmax = h - butsize;
461
462 ms->up = (Widget) make_repeater_pixmap (ms->back, "up", up_xpm, btncb, (XtPointer) ms);
463 n = 0;
464 XtSetArg (args[n], XtNfromHoriz, NULL);
465 n++;
466 XtSetArg (args[n], XtNhorizDistance, 1);
467 n++;
468 XtSetArg (args[n], XtNfromVert, NULL);
469 n++;
470 XtSetArg (args[n], XtNvertDistance, 1);
471 n++;
472 XtSetValues (ms->up, args, n);
473
474 ms->cury = 18;
475
476 ms->down = (Widget) make_repeater_pixmap (ms->back, "down", down_xpm, btncb, (XtPointer) ms);
477 n = 0;
478 XtSetArg (args[n], XtNfromVert, (XtPointer) NULL);
479 n++;
480 XtSetArg (args[n], XtNvertDistance, h - 14);
481 n++;
482 XtSetArg (args[n], XtNfromHoriz, NULL);
483 n++;
484 XtSetArg (args[n], XtNhorizDistance, 1);
485 n++;
486 XtSetValues (ms->down, args, n);
487 }
488 else
489 {
490 ms->orientation = horizontal;
491 ms->thumbmax = w - butsize;
492
493 ms->left = (Widget) make_repeater_pixmap (ms->back, "left", left_xpm, btncb, (XtPointer) ms);
494 n = 0;
495 XtSetArg (args[n], XtNfromHoriz, NULL);
496 n++;
497 XtSetArg (args[n], XtNhorizDistance, 1);
498 n++;
499 XtSetArg (args[n], XtNfromVert, NULL);
500 n++;
501 XtSetArg (args[n], XtNvertDistance, 1);
502 n++;
503 XtSetValues (ms->left, args, n);
504
505 ms->curx = 18;
506
507 ms->right = (Widget) make_repeater_pixmap (ms->back, "right", right_xpm, btncb, (XtPointer)
508 ms);
509 n = 0;
510 XtSetArg (args[n], XtNfromHoriz, NULL);
511 n++;
512 XtSetArg (args[n], XtNhorizDistance, w - 14);
513 n++;
514 XtSetArg (args[n], XtNfromVert, NULL);
515 n++;
516 XtSetArg (args[n], XtNvertDistance, 1);
517 n++;
518 XtSetValues (ms->right, args, n);
519
520 }
521
522 ms->backlen = ms->thumbmax - ms->thumbmin;
523 if (ms->backlen < ms->thumbminlen)
524 ms->backlen = ms->thumbminlen;
525
526
527 XtAddEventHandler (ms->back, ButtonPressMask, False, stepcb, (XtPointer) ms);
528 XtAddEventHandler (ms->back, ExposureMask, FALSE, shadow2, (XtPointer) ms->back);
529 XtAddEventHandler (ms->back, ButtonReleaseMask, False, thumbupcb, (XtPointer) ms);
530
531 XtAddEventHandler (ms->back, VisibilityChangeMask, False, redrawcb, (XtPointer) ms);
532
533
534 XtAddEventHandler (ms->back, Button1MotionMask, False, movecb, (XtPointer) ms);
535
536 XtAddEventHandler (ms->back, StructureNotifyMask, False, resizescroll, (XtPointer) ms);
537 return ms;
538 }
539