Add interactive zoom_rect.
[scilab.git] / scilab / modules / graphics / src / c / axesScale.c
index 8df372f..cd3a17a 100644 (file)
@@ -1,7 +1,18 @@
+/*
+ * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ * Copyright (C) 2004-2006 - INRIA - Fabrice Leray
+ * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
+ * 
+ * This file must be used under the terms of the CeCILL.
+ * This source file is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution.  The terms
+ * are also available at    
+ * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
 /*------------------------------------------------------------------------*/
 /* file: axesScale.c                                                      */
-/* Copyright INRIA 2006                                                   */
-/* Authors : Fabrice Leray, Jean-Baptiste Silvy                           */
 /* desc : Contains functions to compute scale changes in a specific       */
 /*        subwindow.                                                      */
 /*------------------------------------------------------------------------*/
 #include "math_graphics.h"
 #include "MALLOC.h"
 #include "GetProperty.h"
+#include "SetProperty.h"
 #include "sciprint.h"
 #include "PloEch.h"
 #include "GraphicZoom.h"
 #include "Vertices.h"
 #include "localization.h"
+#include "SetPropertyStatus.h"
+#include "SetJavaProperty.h"
+#include "GraphicSynchronizerInterface.h"
+#include "DrawingBridge.h"
+#include "CurrentObjectsManagement.h"
+#include "Interaction.h"
+#include "DoublyLinkedList.h"
 
 /*------------------------------------------------------------------------------*/
+void zoomSubwin(sciPointObj * pSubwin, int posX, int posY, int width, int height);
+void zoomFigure(sciPointObj * pFigure, int posX, int posY, int width, int height);
+/*------------------------------------------------------------------------------*/
 double InvAxis( double min, double max, double u )
 {
   /*return (u-min) / (max-min) * min + (u-max) / (min-max) * max ;*/
@@ -340,3 +362,255 @@ int trans3d( sciPointObj * pobj,
   return(1);
 }
 /*------------------------------------------------------------------------------*/
+/**
+ * Specify new zoom box for a subwin object.
+ * @param zoomRect vector [xMin, yMin, xMax, yMax]
+ */
+int sciZoom2D(sciPointObj * pObj, const double zoomRect[4])
+{
+  double zoomBox[6];
+
+  // add Z scale to data bounds.
+  sciGetDataBounds(pObj, zoomBox);
+  zoomBox[0] = zoomRect[0];
+  zoomBox[1] = zoomRect[1];
+  zoomBox[2] = zoomRect[2];
+  zoomBox[3] = zoomRect[3];
+
+  return sciZoom3D(pObj, zoomBox);
+
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Specify a new zoom box for a subwin object
+ * @param zoomBox vector [xMin, yMin, xMax, yMax, zMin, zMax].
+ */
+int sciZoom3D(sciPointObj * pObj, const double zoomBox[6])
+{
+  // convert zoomBox to [xMin, xMax, yMin, yMax, zMin, zMax]
+  double zoomBox3D[6];
+  zoomBox3D[0] = zoomBox[0];
+  zoomBox3D[1] = zoomBox[2];
+  zoomBox3D[2] = zoomBox[1];
+  zoomBox3D[3] = zoomBox[3];
+  zoomBox3D[4] = zoomBox[4];
+  zoomBox3D[5] = zoomBox[5];
+
+  if (!checkDataBounds(pObj, zoomBox3D[0], zoomBox3D[1], zoomBox3D[2],
+                       zoomBox3D[3], zoomBox3D[4], zoomBox3D[5]))
+  {
+    return SET_PROPERTY_ERROR;
+  }
+
+  sciSetZoomBox(pObj, zoomBox3D);
+
+  sciSetZooming(pObj, TRUE);
+
+  return SET_PROPERTY_SUCCEED;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * get the zoom box to dispplay in Scilab for a sunwin object
+ * @param[out] zoomBox [xMin, yMin, xMax, yMax, zMin, zMax];
+ */
+void sciGetZoom3D(sciPointObj * pObj, double zoomBox[6])
+{
+  double temp;
+
+  // here we get [xMin, xMax, yMin, yMax, zMin, zMax]
+  // we need to switch xMax and yMin
+  sciGetZoomBox(pObj, zoomBox);
+  temp = zoomBox[1];
+  zoomBox[1] = zoomBox[2];
+  zoomBox[2] = temp;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Try to zoom on a single subwindow using a selection area
+ */
+void zoomSubwin(sciPointObj * pSubwin, int posX, int posY, int width, int height)
+{
+  if (sciJavaZoomRect(pSubwin, posX, posY, width, height))
+  {
+    /* subwindow has been zoomed */
+    /* force zooming */
+    sciSetZooming(pSubwin, TRUE);
+
+    // window has changed
+    forceRedraw(pSubwin);
+  }
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Zoom a figure using an already computed selection area
+ */
+void zoomFigure(sciPointObj * pFigure, int posX, int posY, int width, int height)
+{
+  /* try to zoom on all the subwindows */
+  sciSons * pSons = sciGetSons(pFigure);
+  while (pSons != NULL)
+  {
+    sciPointObj * curObj = pSons->pointobj;
+    if (sciGetEntityType(curObj) == SCI_SUBWIN)
+    {
+      zoomSubwin(curObj, posX, posY, width, height);
+    }
+    pSons = pSons->pnext;
+  }
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Perform a zoom rect (rectangular selection + zoom) on the current figure
+ */
+void sciZoomRect(void)
+{
+  int selectionRectangleCorners[4];
+  int x;
+  int y;
+  int w;
+  int h;
+  int button;
+  sciPointObj * curFigure;
+  sciPointObj * curSubWin;
+
+  startGraphicDataWriting();
+  curFigure = sciGetCurrentFigure();
+  curSubWin = sciGetCurrentSubWin();
+  endGraphicDataWriting();
+
+  /* create a ruuber box to select a rectangular area */
+  pixelRubberBox(curFigure, TRUE, NULL, selectionRectangleCorners, &button);
+
+  /* convert found data to [x,y,w,h] */
+  x = Min(selectionRectangleCorners[0], selectionRectangleCorners[2]);
+  y = Min(selectionRectangleCorners[1], selectionRectangleCorners[3]);
+  w = Abs(selectionRectangleCorners[0] - selectionRectangleCorners[2]);
+  h = Abs(selectionRectangleCorners[1] - selectionRectangleCorners[3]); 
+
+  /* Zoom using the found pixels */
+  startFigureDataWriting(curFigure);
+  zoomFigure(curFigure, x, y, w, h);
+  endFigureDataWriting(curFigure);
+
+  /* redraw */
+  sciDrawObj(curFigure);
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Check if the follawing data bounds can be used as new data bounds for the subwin object
+ * @return TRUE if values can be used, false otherwise
+ */
+BOOL checkDataBounds(sciPointObj * pObj, double xMin, double xMax,
+                     double yMin, double yMax, double zMin, double zMax)
+{
+  char logFlags[3];
+  sciGetLogFlags(pObj, logFlags);
+
+  /* check if there is not an inf within the values */
+  /* since this has not any meaning */
+  if (    !finite(xMin) || !finite(xMax)
+       || !finite(yMin) || !finite(yMax)
+       || !finite(zMin) || !finite(zMax) )
+  {
+    sciprint("Error : data bounds values must be finite.");
+    return FALSE ;
+  }
+
+
+  /* check if the bounds are corrects */
+  /* allows equality with bounds since it is working */
+  if ( xMin > xMax || yMin > yMax || zMin > zMax )
+  {
+    sciprint("Error : Min and Max values for one axis do not verify Min <= Max.\n");
+    return FALSE ;
+  }
+
+  /* check for logflags that values are greater than 0 */
+  if (   ( logFlags[0] == 'l' && xMin <= 0.0 )
+      || ( logFlags[1] == 'l' && yMin <= 0.0 )
+      || ( logFlags[2] == 'l' && zMin <= 0.0 ) )
+  {
+    sciprint("Error: bounds on axis must be strictly positive to use logarithmic mode.\n" ) ;
+    return FALSE ;
+  }
+
+  return TRUE;
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Unzoom a single subwindow
+ */
+void sciUnzoom(sciPointObj * subwin)
+{
+  int currentStatus;
+  sciPointObj * parentFig = sciGetParentFigure(subwin);
+  startFigureDataWriting(parentFig);
+  currentStatus = sciSetZooming(subwin, FALSE);
+  endFigureDataWriting(parentFig);
+
+  if (currentStatus == 0)
+  {
+    /* redraw only if needed */
+    forceRedraw(subwin);
+  }
+
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Un zoom all the subwindow of a figure
+ */
+void sciUnzoomAll(void)
+{
+  sciPointObj * pFigure = NULL;
+  sciSons * pSons = NULL;
+
+  startGraphicDataWriting();
+  pFigure = sciGetCurrentFigure();
+  endGraphicDataWriting();
+
+  /* Copy subwins into the array */ 
+  pSons = sciGetSons(pFigure);
+  while (pSons != NULL)
+  {
+    sciPointObj * curObj = pSons->pointobj;
+    if (sciGetEntityType(curObj) == SCI_SUBWIN)
+    {
+      sciUnzoom(curObj);
+    }
+    pSons = pSons->pnext;
+  }
+
+  sciDrawObj(pFigure);
+}
+/*------------------------------------------------------------------------------*/
+/**
+ * Unzoom a set of subwindows given by their handles
+ */
+void sciUnzoomArray(unsigned long * subwinHandles, int nbSubwin)
+{
+  int i;
+  /* list of parent figure to redraw */
+  DoublyLinkedList * redrawnFigures = DoublyLinkedList_new();
+  for (i = 0; i < nbSubwin; i++)
+  {
+    sciPointObj * curSubwin = sciGetPointerFromHandle(subwinHandles[i]);
+    sciPointObj * parentFigure = sciGetParentFigure(curSubwin);
+    sciUnzoom(curSubwin);
+    if (List_find(redrawnFigures, parentFigure) == NULL)
+    {
+      /* figure not already added for redraw */
+      redrawnFigures = List_push(redrawnFigures, parentFigure);
+    }
+  }
+
+  /* redraw only needed figures */
+  while (!List_is_empty(redrawnFigures))
+  {
+    sciPointObj * curFigure = NULL;
+    redrawnFigures = List_pop(redrawnFigures, &curFigure);
+    sciDrawObj(curFigure);
+  }
+
+  List_free(redrawnFigures);
+}
+/*------------------------------------------------------------------------------*/