void
NavigateAxisArray::ZoomVertical(double f)
{
    vtkRenderWindowInteractor *rwi = Interactor;

    //
    // Calculate the zoom factor.
    //
    double zoomFactor = pow((double)1.1, f);

    //
    // Calculate the new parallel scale.
    //
    VisWindow *vw = proxy;

    avtViewAxisArray newViewAxisArray = vw->GetViewAxisArray();

    double yDist = newViewAxisArray.range[1] - newViewAxisArray.range[0];
    double dY = ((1. / zoomFactor) - 1.) * (yDist / 2.);

    newViewAxisArray.range[0]  -= dY;
    newViewAxisArray.range[1]  += dY;

    vw->SetViewAxisArray(newViewAxisArray);
}
void
NavigateAxisArray::ZoomHorizontal(double f)
{
    vtkRenderWindowInteractor *rwi = Interactor;

    //
    // Calculate the zoom factor.
    //
    double zoomFactor = pow((double)1.1, f);

    //
    // Calculate the new parallel scale.
    //
    VisWindow *vw = proxy;

    avtViewAxisArray newViewAxisArray = vw->GetViewAxisArray();

    double xDist = newViewAxisArray.domain[1] - newViewAxisArray.domain[0];
    double dX = ((1. / zoomFactor) - 1.) * (xDist / 2.);

    newViewAxisArray.domain[0] -= dX;
    newViewAxisArray.domain[1] += dX;

    vw->SetViewAxisArray(newViewAxisArray);
}
void
NavigateAxisArray::ZoomVerticalFixed(double f)
{
    vtkRenderWindowInteractor *rwi = Interactor;

    VisWindow *vw = proxy;

    avtViewAxisArray newViewAxisArray = vw->GetViewAxisArray();

    newViewAxisArray.range[0] -= f;
    newViewAxisArray.range[1] += f;
    if (newViewAxisArray.range[0] >= newViewAxisArray.domain[1])
    {
        newViewAxisArray.range[0] += f;
        newViewAxisArray.range[1] -= f;
    }

    vw->SetViewAxisArray(newViewAxisArray);
}
void
VisWinAxesArray::GetRange(double &min_x, double &max_x,
                          double &min_y, double &max_y)
{
    VisWindow *vw = mediator;

    switch (vw->GetWindowMode())
    {
      case WINMODE_AXISARRAY:
        {
        const avtViewAxisArray viewAxisArray = vw->GetViewAxisArray();
        min_x = viewAxisArray.domain[0];
        max_x = viewAxisArray.domain[1];
        min_y = viewAxisArray.range[0];
        max_y = viewAxisArray.range[1];
        }
        break;
      default:
        break;
    }
}
void
NavigateAxisArray::PanCamera(const int x, const int y, bool snap_horiz)
{
    vtkRenderWindowInteractor *rwi = Interactor;

    if ((OldX != x) || (OldY != y))
    {
        //
        // Determine the size of the window.
        //
        int       size[2];

        rwi->GetSize(size);

        //
        // Get the current view information.
        //
        VisWindow *vw = proxy;

        double    pan[2];

        avtViewAxisArray newView = vw->GetViewAxisArray();
        
        double xscale = (newView.domain[1] - newView.domain[0]) /
            ((newView.viewport[1] - newView.viewport[0]) * (double)(size[0]));
        double yscale = (newView.range[1] - newView.range[0]) /
            ((newView.viewport[3] - newView.viewport[2]) * (double)(size[0]));

        pan[0] = (double)(x - OldX) * xscale;
        pan[1] = (double)(y - OldY) * yscale;

        newView.domain[0] -= pan[0];
        newView.domain[1] -= pan[0];
        newView.range[0]  -= pan[1];
        newView.range[1]  -= pan[1];

        // perform a horizontal snap
        int newX = x;
        if (snap_horiz)
        {
            double dx0 = newView.domain[0] - double(int(newView.domain[0]));
            double dx1 = newView.domain[1] - double(int(newView.domain[1]));
            double dx0check = dx0 / (newView.domain[1] - newView.domain[0]);
            double dx1check = dx1 / (newView.domain[1] - newView.domain[0]);

            const double threshold = 0.025;
            if (fabs(dx0check) < threshold)
            {
                newView.domain[0] -= dx0;
                newView.domain[1] -= dx0;
                newX += int(.5 + dx0 / xscale);
            }
            else if (fabs(dx1check) < threshold)
            {
                newView.domain[0] -= dx1;
                newView.domain[1] -= dx1;
                newX += int(.5 + dx1 / xscale);
            }
        }

        if (newX == OldX && OldY == y)
        {
            // do nothing
        }
        else
        {
            vw->SetViewAxisArray(newView);

            OldX = newX;
            OldY = y;
            rwi->Render();
        }
    }
}