xref: /petsc/src/sys/classes/draw/utils/zoom.c (revision a69119a591a03a9d906b29c0a4e9802e4d7c9795)
1 
2 #include <petscdraw.h> /*I "petscdraw.h"  I*/
3 
4 /*@C
5     PetscDrawZoom - Allows one to create a graphic that users may zoom into.
6 
7     Collective on PetscDraw
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:
17 @*/
18 PetscErrorCode PetscDrawZoom(PetscDraw draw, PetscErrorCode (*func)(PetscDraw, void *), void *ctx) {
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(0);
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: scale = 0.5; break;
53     case PETSC_BUTTON_CENTER: scale = 2.0; break;
54     case PETSC_BUTTON_WHEEL_UP: scale = 8 / 10.; break;
55     case PETSC_BUTTON_WHEEL_DOWN: scale = 10 / 8.; break;
56     default: scale = 1.0;
57     }
58     xl = scale * (xl + w - xc) + xc - w * scale;
59     xr = scale * (xr - w - xc) + xc + w * scale;
60     yl = scale * (yl + h - yc) + yc - h * scale;
61     yr = scale * (yr - h - yc) + yc + h * scale;
62     w *= scale;
63     h *= scale;
64     PetscCall(PetscDrawClear(draw));
65     PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
66     PetscDrawCollectiveBegin(draw);
67     PetscCall((*func)(draw, ctx));
68     PetscDrawCollectiveEnd(draw);
69     PetscCall(PetscDrawFlush(draw));
70     PetscCall(PetscDrawGetMouseButton(draw, &button, &xc, &yc, NULL, NULL));
71   }
72   PetscCall(PetscDrawSetCoordinates(draw, xmin, ymin, xmax, ymax));
73 theend:
74   PetscFunctionReturn(0);
75 }
76