xref: /petsc/src/sys/classes/draw/utils/zoom.c (revision fbf9dbe564678ed6eff1806adbc4c4f01b9743f4)
1 
2 #include <petscdraw.h> /*I "petscdraw.h"  I*/
3 
4 /*@C
5     PetscDrawZoom - Allows one to provide a function that gets called for zooming in on a drawing using the mouse buttons
6 
7     Collective draw
8 
9     Input Parameters:
10 +   draw - the window where the graph will be made.
11 .   func - users function that draws the graphic
12 -   ctx - pointer to any user required data
13 
14   Level: advanced
15 
16 .seealso: `PetscDraw`, `PetscDrawCreate()`
17 @*/
18 PetscErrorCode PetscDrawZoom(PetscDraw draw, PetscErrorCode (*func)(PetscDraw, void *), void *ctx)
19 {
20   PetscDrawButton button;
21   PetscReal       dpause, xc, yc, scale = 1.0, w, h, xr, xl, yr, yl, xmin, xmax, ymin, ymax;
22   PetscBool       isnull;
23 
24   PetscFunctionBegin;
25   PetscCall(PetscDrawIsNull(draw, &isnull));
26   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
27 
28   PetscCall(PetscDrawCheckResizedWindow(draw));
29   PetscCall(PetscDrawClear(draw));
30   PetscDrawCollectiveBegin(draw);
31   PetscCall((*func)(draw, ctx));
32   PetscDrawCollectiveEnd(draw);
33   PetscCall(PetscDrawFlush(draw));
34 
35   PetscCall(PetscDrawGetPause(draw, &dpause));
36   if (dpause >= 0) {
37     PetscCall(PetscSleep(dpause));
38     goto theend;
39   }
40   if (dpause != -1) goto theend;
41 
42   PetscCall(PetscDrawGetMouseButton(draw, &button, &xc, &yc, NULL, NULL));
43   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
44   xmin = xl;
45   xmax = xr;
46   w    = xr - xl;
47   ymin = yl;
48   ymax = yr;
49   h    = yr - yl;
50 
51   while (button != PETSC_BUTTON_NONE && button != PETSC_BUTTON_RIGHT) {
52     switch (button) {
53     case PETSC_BUTTON_LEFT:
54       scale = 0.5;
55       break;
56     case PETSC_BUTTON_CENTER:
57       scale = 2.0;
58       break;
59     case PETSC_BUTTON_WHEEL_UP:
60       scale = 8 / 10.;
61       break;
62     case PETSC_BUTTON_WHEEL_DOWN:
63       scale = 10 / 8.;
64       break;
65     default:
66       scale = 1.0;
67     }
68     xl = scale * (xl + w - xc) + xc - w * scale;
69     xr = scale * (xr - w - xc) + xc + w * scale;
70     yl = scale * (yl + h - yc) + yc - h * scale;
71     yr = scale * (yr - h - yc) + yc + h * scale;
72     w *= scale;
73     h *= scale;
74     PetscCall(PetscDrawClear(draw));
75     PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
76     PetscDrawCollectiveBegin(draw);
77     PetscCall((*func)(draw, ctx));
78     PetscDrawCollectiveEnd(draw);
79     PetscCall(PetscDrawFlush(draw));
80     PetscCall(PetscDrawGetMouseButton(draw, &button, &xc, &yc, NULL, NULL));
81   }
82   PetscCall(PetscDrawSetCoordinates(draw, xmin, ymin, xmax, ymax));
83 theend:
84   PetscFunctionReturn(PETSC_SUCCESS);
85 }
86