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 application required data

     13:   Calling sequence of func:
     14: + draw - the `PetscDraw` object to zoom on
     15: - ctx  - the context for the zooming operation

     17:   Level: advanced

     19: .seealso: `PetscDraw`, `PetscDrawCreate()`
     20: @*/
     21: PetscErrorCode PetscDrawZoom(PetscDraw draw, PetscErrorCode (*func)(PetscDraw draw, PetscCtx ctx), PetscCtx ctx)
     22: {
     23:   PetscDrawButton button;
     24:   PetscReal       dpause, xc, yc, scale = 1.0, w, h, xr, xl, yr, yl, xmin, xmax, ymin, ymax;
     25:   PetscBool       isnull;

     27:   PetscFunctionBegin;
     28:   PetscCall(PetscDrawIsNull(draw, &isnull));
     29:   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);

     31:   PetscCall(PetscDrawCheckResizedWindow(draw));
     32:   PetscCall(PetscDrawClear(draw));
     33:   PetscDrawCollectiveBegin(draw);
     34:   PetscCall((*func)(draw, ctx));
     35:   PetscDrawCollectiveEnd(draw);
     36:   PetscCall(PetscDrawFlush(draw));

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

     45:   PetscCall(PetscDrawGetMouseButton(draw, &button, &xc, &yc, NULL, NULL));
     46:   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
     47:   xmin = xl;
     48:   xmax = xr;
     49:   w    = xr - xl;
     50:   ymin = yl;
     51:   ymax = yr;
     52:   h    = yr - yl;

     54:   while (button != PETSC_BUTTON_NONE && button != PETSC_BUTTON_RIGHT) {
     55:     switch (button) {
     56:     case PETSC_BUTTON_LEFT:
     57:       scale = 0.5;
     58:       break;
     59:     case PETSC_BUTTON_CENTER:
     60:       scale = 2.0;
     61:       break;
     62:     case PETSC_BUTTON_WHEEL_UP:
     63:       scale = 8 / 10.;
     64:       break;
     65:     case PETSC_BUTTON_WHEEL_DOWN:
     66:       scale = 10 / 8.;
     67:       break;
     68:     default:
     69:       scale = 1.0;
     70:     }
     71:     xl = scale * (xl + w - xc) + xc - w * scale;
     72:     xr = scale * (xr - w - xc) + xc + w * scale;
     73:     yl = scale * (yl + h - yc) + yc - h * scale;
     74:     yr = scale * (yr - h - yc) + yc + h * scale;
     75:     w *= scale;
     76:     h *= scale;
     77:     PetscCall(PetscDrawClear(draw));
     78:     PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
     79:     PetscDrawCollectiveBegin(draw);
     80:     PetscCall((*func)(draw, ctx));
     81:     PetscDrawCollectiveEnd(draw);
     82:     PetscCall(PetscDrawFlush(draw));
     83:     PetscCall(PetscDrawGetMouseButton(draw, &button, &xc, &yc, NULL, NULL));
     84:   }
     85:   PetscCall(PetscDrawSetCoordinates(draw, xmin, ymin, xmax, ymax));
     86: theend:
     87:   PetscFunctionReturn(PETSC_SUCCESS);
     88: }