Source: BKGWebMap/Control/SidePanel.js

/*
 * Copyright (c) 2013 Bundesamt für Kartographie und Geodäsie.
 * See license.txt in the BKG WebMap distribution or repository for the
 * full text of the license.
 *
 * Author: Dirk Thalheim
 */

/**
 * @requires OpenLayers/BaseTypes/Class.js
 * @requires OpenLayers/BaseTypes/Element.js
 * @requires OpenLayers/Control.js
 * @requires OpenLayers/Events.js
 * @requires BKGWebMap/Control.js
 * @requires BKGWebMap/Util.js
 * @requires BKGWebMap/Util/Toggler.js
 */

/**
 * @classdesc SidePanel stellt einen HTML-Bereich bereit, der am Rand der Karte ein- bzw. ausgeblendet werden kann
 *
 * @constructor BKGWebMap.Control.SidePanel
 * @param {object} options - Optionen für das Controlelement
 */
BKGWebMap.Control.SidePanel = OpenLayers.Class(OpenLayers.Control, {

  /**
   * Zeigt an, ob das Panel ein- oder ausgeblendet ist
   * @memberOf BKGWebMap.Control.SidePanel
   * @type {boolean}
   */
  maximized: false,

  /**
   * CSS-Klasse für content
   * @memberOf BKGWebMap.Control.SidePanel
   * @type {string}
   */
  style: 'wmPanel',

  /**
   * Position des Panels: left|right
   * @memberOf BKGWebMap.Control.SidePanel
   * @type {string}
   */
  contentPosition: 'left',

  /**
   * Breite des Panels
   * @memberOf BKGWebMap.Control.SidePanel
   * @type {int}
   */
  size: 150,

  /**
   * Tooltip für Toggle-Button
   * @memberOf BKGWebMap.Control.SidePanel
   * @type {string}
   */
  title: 'Sidepanel ein-/ausblenden',

  // -- DOM - Elemente ----

  /**
   * HTML-Bereich für Inhalt.
   * @memberOf BKGWebMap.Control.SidePanel
   * @type {HTMLElement}
   */
  content: null,

  initialize: function(options) {
    OpenLayers.Control.prototype.initialize.apply(this, [options]);

    // content-Bereich initialisieren, um Inhalte schon einfügen zu können
    this.content = document.createElement('div');
    OpenLayers.Element.addClass(this.content, this.style);
    OpenLayers.Element.addClass(this.content, this.contentPosition);
  },

  destroy: function() {
    if(this.toggler) {
      this.toggler.destroy();
      this.toggler = null;
    }
    OpenLayers.Control.prototype.destroy.apply(this, arguments);
  },

  /**
   * Erstellt die HTML-Elemente des Panels
   *
   * @return {node} Eine Referenz zum DOMElement welches die Legende beinhaltet.
   * @memberOf BKGWebMap.Control.SidePanel
   */
  draw: function() {
    // Control-Div zum ein- und ausblenden
    var div = OpenLayers.Control.prototype.draw.apply(this);
    OpenLayers.Element.addClass(div, this.contentPosition);

    // Map Wrapper hinzufügen
    this.addMapWrapper(this.map);

    // Inhalts-Div
    this.map.wmWrapperDiv.appendChild(this.content);
    this.content.style.width = this.maximized ? this.size + 'px' : '0';

    // Toggler zum Ein- und Ausblenden des Panels
    this.toggler = new BKGWebMap.Util.Toggler( this.div, this.content, { closed: !this.maximized });
    this.toggler.observeTouchEvents();

    this.toggler.events.on({
      statechanged: this.onStateTogglerChange,
      scope: this
    });

    if(!this.toggler.closed) this.show(); else this.hide();

    return div;
  },

  /**
   * Fügt dem Kartendiv einen Wrapper hinzu, der das Sidepanel ermöglicht.
   * Dies ist notwendig, damit der Viewport und alle Steuerelemente nicht vom ausgeklappten Panel verdeckt werden.
   * @param map {OpenLayers.Map} - Kartenobjekt, für das ein Wrapper erzeugt werden soll.
   * @memberOf BKGWebMap.Control.SidePanel
   */
  addMapWrapper: function(map) {
    if (map.wmWrapperDiv) return;

    map.wmWrapperDiv = map.div.cloneNode(false);
    map.wmWrapperDiv.removeAttribute('id');
    OpenLayers.Element.addClass(map.wmWrapperDiv, 'wmMapWrapper');

    // Wrapper hinzufügen
    map.div.parentNode.replaceChild(map.wmWrapperDiv, map.div);
    map.wmWrapperDiv.appendChild(map.div);

    // Map-Div CSS modifizieren, damit Panel links bzw. rechts positioniert werden kann
    // und viewPortDiv entsprechend angepasst werden kann.
    if(BKGWebMap.Util.getStyle(this.map.wmWrapperDiv, 'position') != 'absolute') {
      this.map.wmWrapperDiv.style.position = 'relative';
    }

    // störende Styles des Map divs entfernen
    this.map.div.style.position = 'absolute';
    this.map.div.style.left = '0';
    this.map.div.style.right = '0';
    this.map.div.style.top = '0';
    this.map.div.style.bottom = '0';
    this.map.div.style.margin = '0';
    this.map.div.style.padding = '0';
    this.map.div.style.border = 'none';
    this.map.div.style.width = 'auto';
  },

  /**
   * Callback, wenn sich der Status des Panels geändert hat.
   * @memberOf BKGWebMap.Control.SidePanel
   */
  onStateTogglerChange: function() {
    if(!this.toggler.closed) {
      this.show();
    } else {
      this.hide();
    }
    this.map.updateSize();
  },

  toggle: function() {
    this.toggler.toggle()
  },

  /**
   * Blendet das Sidepanel ein
   * @memberOf BKGWebMap.Control.SidePanel
   */
  show: function() {
    this.maximized = true;
    this.content.style.width = this.size + 'px';

    this.map.div.style[this.contentPosition] = this.size + 'px';
  },

  /**
   * Blendet das Sidepanel aus
   * @memberOf BKGWebMap.Control.SidePanel
   */
  hide: function() {
    this.maximized = false;
    this.content.style.width = '0';

    this.map.div.style[this.contentPosition] = '0';
  },

  CLASS_NAME: "BKGWebMap.Control.SidePanel"
});