Actual source code: zoom.c

      1: #include <petscdraw.h>

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

      6:   Collective draw

      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

     13:   Level: advanced

     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;

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

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

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

     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;

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