Actual source code: zoom.c


  2: #include <petscdraw.h>

  4: /*@C
  5:     PetscDrawZoom - Allows one to provide a function that gets called for zooming in on a drawing using the mouse buttons

  7:     Collective draw

  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

 14:   Level: advanced

 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;

 24:   PetscFunctionBegin;
 25:   PetscCall(PetscDrawIsNull(draw, &isnull));
 26:   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);

 28:   PetscCall(PetscDrawCheckResizedWindow(draw));
 29:   PetscCall(PetscDrawClear(draw));
 30:   PetscDrawCollectiveBegin(draw);
 31:   PetscCall((*func)(draw, ctx));
 32:   PetscDrawCollectiveEnd(draw);
 33:   PetscCall(PetscDrawFlush(draw));

 35:   PetscCall(PetscDrawGetPause(draw, &dpause));
 36:   if (dpause >= 0) {
 37:     PetscCall(PetscSleep(dpause));
 38:     goto theend;
 39:   }
 40:   if (dpause != -1) goto theend;

 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;

 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: }