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