Blame templates/html/svgpan.js

Packit 1c1d7e
/*
Packit 1c1d7e
 @licstart  The following is the entire license notice for the
Packit 1c1d7e
 JavaScript code in this file.
Packit 1c1d7e
Packit 1c1d7e
 Copyright (C) 1997-2017 by Dimitri van Heesch
Packit 1c1d7e
Packit 1c1d7e
 This program is free software; you can redistribute it and/or modify
Packit 1c1d7e
 it under the terms of the GNU General Public License as published by
Packit 1c1d7e
 the Free Software Foundation; either version 2 of the License, or
Packit 1c1d7e
 (at your option) any later version.
Packit 1c1d7e
Packit 1c1d7e
 This program is distributed in the hope that it will be useful,
Packit 1c1d7e
 but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 1c1d7e
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 1c1d7e
 GNU General Public License for more details.
Packit 1c1d7e
Packit 1c1d7e
 You should have received a copy of the GNU General Public License along
Packit 1c1d7e
 with this program; if not, write to the Free Software Foundation, Inc.,
Packit 1c1d7e
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Packit 1c1d7e
Packit 1c1d7e
 @licend  The above is the entire license notice
Packit 1c1d7e
 for the JavaScript code in this file
Packit 1c1d7e
 */
Packit 1c1d7e
/**
Packit 1c1d7e
 * The code below is based on SVGPan Library 1.2 and was modified for doxygen
Packit 1c1d7e
 * to support both zooming and panning via the mouse and via embedded bottons.
Packit 1c1d7e
 *
Packit 1c1d7e
 * This code is licensed under the following BSD license:
Packit 1c1d7e
 *
Packit 1c1d7e
 * Copyright 2009-2010 Andrea Leofreddi <a.leofreddi@itcharm.com>. All rights reserved.
Packit 1c1d7e
 *
Packit 1c1d7e
 * Redistribution and use in source and binary forms, with or without modification, are
Packit 1c1d7e
 * permitted provided that the following conditions are met:
Packit 1c1d7e
 *
Packit 1c1d7e
 *    1. Redistributions of source code must retain the above copyright notice, this list of
Packit 1c1d7e
 *       conditions and the following disclaimer.
Packit 1c1d7e
 *
Packit 1c1d7e
 *    2. Redistributions in binary form must reproduce the above copyright notice, this list
Packit 1c1d7e
 *       of conditions and the following disclaimer in the documentation and/or other materials
Packit 1c1d7e
 *       provided with the distribution.
Packit 1c1d7e
 *
Packit 1c1d7e
 * THIS SOFTWARE IS PROVIDED BY Andrea Leofreddi ``AS IS'' AND ANY EXPRESS OR IMPLIED
Packit 1c1d7e
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
Packit 1c1d7e
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Andrea Leofreddi OR
Packit 1c1d7e
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
Packit 1c1d7e
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
Packit 1c1d7e
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
Packit 1c1d7e
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit 1c1d7e
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
Packit 1c1d7e
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 1c1d7e
 *
Packit 1c1d7e
 * The views and conclusions contained in the software and documentation are those of the
Packit 1c1d7e
 * authors and should not be interpreted as representing official policies, either expressed
Packit 1c1d7e
 * or implied, of Andrea Leofreddi.
Packit 1c1d7e
 */
Packit 1c1d7e
Packit 1c1d7e
var root = document.documentElement;
Packit 1c1d7e
var state = 'none';
Packit 1c1d7e
var stateOrigin;
Packit 1c1d7e
var stateTf = root.createSVGMatrix();
Packit 1c1d7e
var cursorGrab = ' url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAlQTFRFAAAA////////c3ilYwAAAAN0Uk5T//8A18oNQQAAAD1JREFUeNp0zlEKACAIA9Bt9z90bZBZkQj29qFBEuBOzQHSnWTTyckEfqUuZgFvslH4ch3qLCO/Kr8cAgwATw4Ax6XRCcoAAAAASUVORK5CYII="), move';
Packit 1c1d7e
var zoomSteps = 10;
Packit 1c1d7e
var zoomInFactor;
Packit 1c1d7e
var zoomOutFactor;
Packit 1c1d7e
var windowWidth;
Packit 1c1d7e
var windowHeight;
Packit 1c1d7e
var svgDoc;
Packit 1c1d7e
var minZoom;
Packit 1c1d7e
var maxZoom;
Packit 1c1d7e
if (!window) window=this;
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Show the graph in the middle of the view, scaled to fit
Packit 1c1d7e
 */
Packit 1c1d7e
function show()
Packit 1c1d7e
{
Packit 1c1d7e
  if (window.innerHeight) // Firefox
Packit 1c1d7e
  {
Packit 1c1d7e
    windowWidth = window.innerWidth;
Packit 1c1d7e
    windowHeight = window.innerHeight;
Packit 1c1d7e
  }
Packit 1c1d7e
  else if (document.documentElement.clientWidth) // Chrome/Safari
Packit 1c1d7e
  {
Packit 1c1d7e
    windowWidth = document.documentElement.clientWidth
Packit 1c1d7e
    windowHeight = document.documentElement.clientHeight
Packit 1c1d7e
  }
Packit 1c1d7e
  if (!windowWidth || !windowHeight) // failsafe
Packit 1c1d7e
  {
Packit 1c1d7e
    windowWidth = 800;
Packit 1c1d7e
    windowHeight = 600;
Packit 1c1d7e
  }
Packit 1c1d7e
  minZoom = Math.min(Math.min(viewHeight,windowHeight)/viewHeight,Math.min(viewWidth,windowWidth)/viewWidth);
Packit 1c1d7e
  maxZoom = minZoom+1.5;
Packit 1c1d7e
  zoomInFactor = Math.pow(maxZoom/minZoom,1.0/zoomSteps);
Packit 1c1d7e
  zoomOutFactor = 1.0/zoomInFactor;
Packit 1c1d7e
Packit 1c1d7e
  var g = svgDoc.getElementById('viewport');
Packit 1c1d7e
  try
Packit 1c1d7e
  {
Packit 1c1d7e
    var bb = g.getBBox(); // this can throw an exception if css { display: none }
Packit 1c1d7e
    var tx = (windowWidth-viewWidth*minZoom+8)/(2*minZoom);
Packit 1c1d7e
    var ty = viewHeight+(windowHeight-viewHeight*minZoom)/(2*minZoom);
Packit 1c1d7e
    var a = 'scale('+minZoom+') rotate(0) translate('+tx+' '+ty+')';
Packit 1c1d7e
    g.setAttribute('transform',a);
Packit 1c1d7e
  }
Packit 1c1d7e
  catch(e) {}
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Register handlers
Packit 1c1d7e
 */
Packit 1c1d7e
function init(evt)
Packit 1c1d7e
{
Packit 1c1d7e
  svgDoc = evt.target.ownerDocument;
Packit 1c1d7e
  try {
Packit 1c1d7e
    if (top.window && top.window.registerShow) { // register show function in html doc for dynamic sections
Packit 1c1d7e
      top.window.registerShow(sectionId,show);
Packit 1c1d7e
    }
Packit 1c1d7e
  } catch(e) {
Packit 1c1d7e
    // ugh, we are not allowed to talk to the parent; can happen with Chrome when viewing pages
Packit 1c1d7e
    // locally, since they treat every local page as having a different origin
Packit 1c1d7e
  }
Packit 1c1d7e
  show();
Packit 1c1d7e
Packit 1c1d7e
  setAttributes(root, {
Packit 1c1d7e
     "onmousedown" : "handleMouseDown(evt)",
Packit 1c1d7e
     "onmousemove" : "handleMouseMove(evt)",
Packit 1c1d7e
     "onmouseup"   : "handleMouseUp(evt)"
Packit 1c1d7e
  });
Packit 1c1d7e
Packit 1c1d7e
  if (window.addEventListener)
Packit 1c1d7e
  {
Packit 1c1d7e
    if (navigator.userAgent.toLowerCase().indexOf('webkit') >= 0 ||
Packit 1c1d7e
        navigator.userAgent.toLowerCase().indexOf("opera") >= 0 ||
Packit 1c1d7e
        navigator.appVersion.indexOf("MSIE") != -1)
Packit 1c1d7e
    {
Packit 1c1d7e
      window.addEventListener('mousewheel', handleMouseWheel, false); // Chrome/Safari/IE9
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      window.addEventListener('DOMMouseScroll', handleMouseWheel, false); // Others
Packit 1c1d7e
    }
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
window.onresize=function()
Packit 1c1d7e
{
Packit 1c1d7e
  if (svgDoc) { show(); }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Instance an SVGPoint object with given event coordinates.
Packit 1c1d7e
 */
Packit 1c1d7e
function getEventPoint(evt)
Packit 1c1d7e
{
Packit 1c1d7e
  var p = root.createSVGPoint();
Packit 1c1d7e
  p.x = evt.clientX;
Packit 1c1d7e
  p.y = evt.clientY;
Packit 1c1d7e
  return p;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Sets the current transform matrix of an element.
Packit 1c1d7e
 */
Packit 1c1d7e
function setCTM(element, matrix)
Packit 1c1d7e
{
Packit 1c1d7e
  var s = "matrix(" + matrix.a + "," + matrix.b + "," + matrix.c + "," + matrix.d + "," + matrix.e + "," + matrix.f + ")";
Packit 1c1d7e
  element.setAttribute("transform", s);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Sets attributes of an element.
Packit 1c1d7e
 */
Packit 1c1d7e
function setAttributes(element, attributes)
Packit 1c1d7e
{
Packit 1c1d7e
  for (i in attributes)
Packit 1c1d7e
    element.setAttributeNS(null, i, attributes[i]);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
function doZoom(g,point,zoomFactor)
Packit 1c1d7e
{
Packit 1c1d7e
  var p = point.matrixTransform(g.getCTM().inverse());
Packit 1c1d7e
  var k = root.createSVGMatrix().translate(p.x, p.y).scale(zoomFactor).translate(-p.x, -p.y);
Packit 1c1d7e
  var n = g.getCTM().multiply(k);
Packit 1c1d7e
  var s = Math.max(n.a,n.d);
Packit 1c1d7e
  if      (s>maxZoom) n=n.translate(p.x,p.y).scale(maxZoom/s).translate(-p.x,-p.y);
Packit 1c1d7e
  else if (s
Packit 1c1d7e
  setCTM(g, n);
Packit 1c1d7e
  stateTf = stateTf.multiply(n.inverse());
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Handle mouse move event.
Packit 1c1d7e
 */
Packit 1c1d7e
function handleMouseWheel(evt)
Packit 1c1d7e
{
Packit 1c1d7e
  if (!evt) evt = window.evt;
Packit 1c1d7e
  if (!evt.shiftKey) return; // only zoom when shift is pressed
Packit 1c1d7e
  if (evt.preventDefault) evt.preventDefault();
Packit 1c1d7e
  evt.returnValue = false;
Packit 1c1d7e
Packit 1c1d7e
  if (state!='pan')
Packit 1c1d7e
  {
Packit 1c1d7e
    var delta;
Packit 1c1d7e
    if (evt.wheelDelta)
Packit 1c1d7e
    {
Packit 1c1d7e
      delta = evt.wheelDelta / 7200; // Opera/Chrome/IE9/Safari
Packit 1c1d7e
    }
Packit 1c1d7e
    else
Packit 1c1d7e
    {
Packit 1c1d7e
      delta = evt.detail / -180; // Mozilla
Packit 1c1d7e
    }
Packit 1c1d7e
    var svgDoc = evt.target.ownerDocument;
Packit 1c1d7e
    var g = svgDoc.getElementById("viewport");
Packit 1c1d7e
    var p = getEventPoint(evt);
Packit 1c1d7e
    doZoom(g,p,1+delta);
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Handle mouse move event.
Packit 1c1d7e
 */
Packit 1c1d7e
function handleMouseMove(evt)
Packit 1c1d7e
{
Packit 1c1d7e
  if(evt.preventDefault)
Packit 1c1d7e
    evt.preventDefault();
Packit 1c1d7e
Packit 1c1d7e
  evt.returnValue = false;
Packit 1c1d7e
Packit 1c1d7e
  var g = svgDoc.getElementById("viewport");
Packit 1c1d7e
Packit 1c1d7e
  if (state == 'pan')
Packit 1c1d7e
  {
Packit 1c1d7e
    // Pan mode
Packit 1c1d7e
    var p = getEventPoint(evt).matrixTransform(stateTf);
Packit 1c1d7e
    setCTM(g,stateTf.inverse().translate(p.x - stateOrigin.x, p.y - stateOrigin.y));
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Handle click event.
Packit 1c1d7e
 */
Packit 1c1d7e
function handleMouseDown(evt)
Packit 1c1d7e
{
Packit 1c1d7e
  if(evt.preventDefault)
Packit 1c1d7e
    evt.preventDefault();
Packit 1c1d7e
  evt.returnValue = false;
Packit 1c1d7e
  var g = svgDoc.getElementById("viewport");
Packit 1c1d7e
  state = 'pan';
Packit 1c1d7e
  stateTf = g.getCTM().inverse();
Packit 1c1d7e
  stateOrigin = getEventPoint(evt).matrixTransform(stateTf);
Packit 1c1d7e
  g.style.cursor = cursorGrab;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Handle mouse button release event.
Packit 1c1d7e
 */
Packit 1c1d7e
function handleMouseUp(evt)
Packit 1c1d7e
{
Packit 1c1d7e
  if (evt.preventDefault) evt.preventDefault();
Packit 1c1d7e
  evt.returnValue = false;
Packit 1c1d7e
  var g = svgDoc.getElementById("viewport");
Packit 1c1d7e
  g.style.cursor = "default";
Packit 1c1d7e
  // Quit pan mode
Packit 1c1d7e
  state = '';
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Dumps a matrix to a string (useful for debug).
Packit 1c1d7e
 */
Packit 1c1d7e
function dumpMatrix(matrix)
Packit 1c1d7e
{
Packit 1c1d7e
  var s = "[ " + matrix.a + ", " + matrix.c + ", " + matrix.e + "\n  " + matrix.b + ", " + matrix.d + ", " + matrix.f + "\n  0, 0, 1 ]";
Packit 1c1d7e
  return s;
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Handler for pan buttons
Packit 1c1d7e
 */
Packit 1c1d7e
function handlePan(x,y)
Packit 1c1d7e
{
Packit 1c1d7e
  var g = svgDoc.getElementById("viewport");
Packit 1c1d7e
  setCTM(g,g.getCTM().translate(x*20/minZoom,y*20/minZoom));
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Handle reset button
Packit 1c1d7e
 */
Packit 1c1d7e
function handleReset()
Packit 1c1d7e
{
Packit 1c1d7e
  show();
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Handler for zoom buttons
Packit 1c1d7e
 */
Packit 1c1d7e
function handleZoom(evt,direction)
Packit 1c1d7e
{
Packit 1c1d7e
  var g = svgDoc.getElementById("viewport");
Packit 1c1d7e
  var factor = direction=='in' ? zoomInFactor : zoomOutFactor;
Packit 1c1d7e
  var m = g.getCTM();
Packit 1c1d7e
  var p = root.createSVGPoint();
Packit 1c1d7e
  p.x = windowWidth/2;
Packit 1c1d7e
  p.y = windowHeight/2;
Packit 1c1d7e
  doZoom(g,p,factor);
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
function serializeXmlNode(xmlNode)
Packit 1c1d7e
{
Packit 1c1d7e
  if (typeof window.XMLSerializer != "undefined") {
Packit 1c1d7e
    return (new window.XMLSerializer()).serializeToString(xmlNode);
Packit 1c1d7e
  } else if (typeof xmlNode.xml != "undefined") {
Packit 1c1d7e
    return xmlNode.xml;
Packit 1c1d7e
  }
Packit 1c1d7e
  return "";
Packit 1c1d7e
}
Packit 1c1d7e
Packit 1c1d7e
/**
Packit 1c1d7e
 * Handler for print function
Packit 1c1d7e
 */
Packit 1c1d7e
function handlePrint(evt)
Packit 1c1d7e
{
Packit 1c1d7e
  evt.returnValue = false;
Packit 1c1d7e
  var g = svgDoc.getElementById("graph");
Packit 1c1d7e
  var xs = serializeXmlNode(g);
Packit 1c1d7e
  try {
Packit 1c1d7e
    var w = window.open('about:blank','_blank','width='+windowWidth+',height='+windowHeight+
Packit 1c1d7e
                        ',toolbar=0,status=0,menubar=0,scrollbars=0,resizable=0,location=0,directories=0');
Packit 1c1d7e
    var d = w.document;
Packit 1c1d7e
    d.write('
Packit 1c1d7e
            'xmlns:svg="http://www.w3.org/2000/svg" '+
Packit 1c1d7e
            'xmlns:xlink="http://www.w3.org/1999/xlink">');
Packit 1c1d7e
    d.write('<head><title>Print SVG</title></head>');
Packit 1c1d7e
    d.write('<body style="margin: 0px; padding: 0px;" onload="window.print();">');
Packit 1c1d7e
    d.write('
'+xs+'
');
Packit 1c1d7e
    d.write('</body>');
Packit 1c1d7e
    d.write('</html>');
Packit 1c1d7e
    d.close();
Packit 1c1d7e
  } catch(e) {
Packit 1c1d7e
    alert('Failed to open popup window needed for printing!\n'+e.message);
Packit 1c1d7e
  }
Packit 1c1d7e
}
Packit 1c1d7e
/* @license-end */