PMA.UI Documentation by Pathomation

view/controls/associatedImage.js

import { Control } from 'ol/control';

export
    /**
     * Displays an interface with an associated image for a slide, barcode, macro or label.
     * @alias AssociatedImage
     * @memberof PMA.UI.View.Controls
     * @param {object} opt_options Options to initialize
     * @param {Viewport} [opt_options.pmaViewport] Viewport instance this control belongs to
     * @param {number} [opt_options.rotation] The initial rotation for this associated image
     * @param {boolean} [opt_options.collapsed] Whether the control starts collapsed
     * @param {"barcode" | "macro" | "label"} [opt_options.imageType] The type of associated image to show
     * @param {string} [opt_options.tipLabel] The label of the button
     * @param {Object} [opt_options.stateManager] The state manager to keep settings in sync
     * @category Controls
     */
    class AssociatedImage extends Control {
    constructor(opt_options) {
        var options = opt_options || {};

        var element = document.createElement('div');
        super({
            element: element,
            target: options.target
        });

        this.pmaViewport = options.pmaViewport;

        this.stateManager = options.stateManager ? options.stateManager : null;
        if (this.stateManager) {
            if (!this.stateManager.associatedImage) {
                this.stateManager.associatedImage = {};
                this.stateManager.associatedImage.collapsed = (options.collapsed) ? options.collapsed : false;
            }

            this.collapsed_ = this.stateManager.associatedImage.collapsed === true;
        }
        else {
            this.collapsed_ = (options.collapsed) ? options.collapsed : false;
        }

        var className = (options.className) ? options.className : 'ol-associated-image';
        var tipLabel = (options.tipLabel) ? options.tipLabel : 'Barcode';

        var collapseLabel = (options.collapseLabel) ? options.collapseLabel : '\u00AB';
        this.collapseLabel_ = document.createElement('span');
        this.collapseLabel_.innerHTML = collapseLabel;

        var label = (options.label) ? options.label : '\u00BB';
        this.label_ = document.createElement('span');
        this.label_.innerHTML = label;

        var activeLabel = this.collapsed_ ? this.collapseLabel_ : this.label_;

        var button = document.createElement('button');
        button.type = 'button';
        button.title = tipLabel;
        button.appendChild(activeLabel);
        if ('ontouchstart' in document.documentElement) {
            button.addEventListener('touchstart', this.buttonClk.bind(this), false);
        }
        else {
            button.addEventListener('click', this.buttonClk.bind(this), false);
        }

        if (this.stateManager && typeof this.stateManager.associatedImage.rotation === "number") {
            this.rotation = this.stateManager.associatedImage.rotation;
        }
        else {
            this.rotation = opt_options.rotation ? opt_options.rotation : 0;
        }

        this.imageType = opt_options.imageType.toLowerCase();

        var imgEl = document.createElement("img");
        imgEl.src = opt_options.url ? opt_options.url : this.getImageUrl();

        var container = document.createElement('div');
        container.className = "ol-associated-image-container";
        container.appendChild(imgEl);

        var cssClasses = className + ' ' + 'ol-unselectable ol-control ' +
            (this.collapsed_ ? ' ol-collapsed' : '');

        element.className = cssClasses;
        element.appendChild(container);

        function rotateImage(event) {
            event.preventDefault();
            event.stopPropagation();

            this.rotation = (this.rotation + 90) % 360;
            if (this.stateManager) {
                this.stateManager.associatedImage.rotation = this.rotation;
            }

            imgEl.src = opt_options.url ? opt_options.url : this.getImageUrl();
        }

        if ('ontouchstart' in document.documentElement) {
            imgEl.addEventListener('touchstart', rotateImage.bind(this), false);
        }
        else {
            imgEl.addEventListener('click', rotateImage.bind(this), false);
        }

        this.imageElement = imgEl;

        var rotateBtn = document.createElement('button');
        rotateBtn.type = 'button';
        rotateBtn.title = "Rotate";
        rotateBtn.className = "size";
        rotateBtn.innerHTML = "\u2b6e";
        if ('ontouchstart' in document.documentElement) {
            rotateBtn.addEventListener('touchstart', rotateImage.bind(this), false);
        }
        else {
            rotateBtn.addEventListener('click', rotateImage.bind(this), false);
        }

        element.appendChild(rotateBtn);

        function zoomOutCb() {
            window.open(opt_options.url ? opt_options.url : this.getImageUrl(false), "_blank");
        }

        var zoomOutBtn = document.createElement('button');
        zoomOutBtn.type = 'button';
        zoomOutBtn.title = "Open associated image in new tab";
        zoomOutBtn.className = "size";
        zoomOutBtn.innerHTML = "\u2315";
        if ('ontouchstart' in document.documentElement) {
            zoomOutBtn.addEventListener('touchstart', zoomOutCb.bind(this), false);
        }
        else {
            zoomOutBtn.addEventListener('click', zoomOutCb.bind(this), false);
        }

        element.appendChild(zoomOutBtn);
        element.appendChild(button);
    }

    getImageUrl(resize = true) {
        var resizeQuery = "";
        if (resize) {
            if (this.rotation === 90 || this.rotation === 270) {
                resizeQuery = "&h=150";
            } else {
                resizeQuery = "&w=150";
            }
        }

        return this.pmaViewport.getActiveServerUrl() + this.imageType + "?sessionID=" + encodeURIComponent(this.pmaViewport.getSessionID()) + "&pathOrUid=" + encodeURIComponent(this.pmaViewport.imageInfo.UID || this.pmaViewport.imageInfo.Filename) + "&rotation=" + this.rotation + resizeQuery;
    }

    /** 
    * Sets the rotation for this image
*/
    setRotation(rotation) {
        this.rotation = rotation;
        if (this.stateManager) {
            this.stateManager.associatedImage.rotation = this.rotation;
        }

        this.imageElement.src = this.getImageUrl();
    }

    /** 
    * Gets the current rotation for this image
    * @param {Number} rotation - The current rotation for this in degrees
    */
    getRotation() {
        return this.rotation;
    }

    /** 
     * Gets the collapsed state of the control
     * @return {boolean} True if the control is currently collapsed
    */
    getCollapsed() {
        return (" " + this.element.className + " ").indexOf(' ol-collapsed ') > -1;
    }

    /** 
     * Sets the collapsed state of the control
     * @param {boolean} collapsed - True to collapse the control, otherwise false
    */
    setCollapsed(collapsed) {
        if (this.getCollapsed() != collapsed) {
            this.buttonClk();
        }
    }

    buttonClk(event) {
        if (event) {
            event.preventDefault();
            event.stopPropagation();
        }

        if ((" " + this.element.className + " ").indexOf(' ol-collapsed ') > -1) {
            this.element.className = this.element.className.replace(/ol-collapsed/g, '');
        }
        else {
            this.element.className += ' ol-collapsed';
        }

        if (!this.collapsed_) {
            this.label_.parentNode.replaceChild(this.collapseLabel_, this.label_);
        } else {
            this.collapseLabel_.parentNode.replaceChild(this.label_, this.collapseLabel_);
        }

        this.collapsed_ = !this.collapsed_;
        if (this.stateManager) {
            this.stateManager.associatedImage.collapsed = this.collapsed_;
        }
    }
}