Source: view/Toolbar.js

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/** @module */

import {h} from "inferno-hyperscript";
import {VirtualDOMView} from "./VirtualDOMView";
import screenfull from "screenfull";
import pkg from "../../package.json";

/** Toolbar in the presentation editor.
 *
 * @extends module:view/VirtualDOMView.VirtualDOMView
 * @todo Add documentation.
 */
export class Toolbar extends VirtualDOMView {

    /** Initialize a new toolbar view.
     *
     * @param {HTMLElement} container - The HTML element that will contain this preview area.
     * @param {module:view/Properties.Properties} properties - The properties view of the editor.
     * @param {module:model/Presentation.Presentation} presentation - The current Sozi presentation.
     * @param {module:player/Viewport.Viewport} viewport - The viewport where the presentation is displayed.
     * @param {module:Controller.Controller} controller - The controller that manages the current editor.
     */
    constructor(container, properties, presentation, viewport, controller) {
        super(container, controller);

        /** The properties view of the editor.
         *
         * @type {module:view/Properties.Properties} */
        this.properties = properties;

        /** The current Sozi presentation.
         *
         * @type {module:model/Presentation.Presentation} */
        this.presentation = presentation;

        /** The viewport where the presentation is displayed.
         *
         * @type {module:player/Viewport.Viewport} */
        this.viewport = viewport;

        screenfull.on("change",     () => this.repaint());
        properties.on("modeChange", () => this.repaint());
    }

    /** @inheritdoc */
    render() {
        const properties = this.properties;
        const controller = this.controller;
        const _          = controller.gettext;

        this.state["aspect-width"]  = {value: this.presentation.aspectWidth};
        this.state["aspect-height"] = {value: this.presentation.aspectHeight};

        return h("div", [
            h("span.group", [
                _("Aspect ratio: "),
                h("input.aspect", {
                    id: "field-aspect-width",
                    type: "number",
                    pattern: "\\d+",
                    min: "1",
                    step: "1",
                    size: "3",
                    onchange() {
                        const width = parseInt(this.value);
                        if (!width.isNaN) {
                            controller.setAspectWidth(width);
                        }
                    }
                }),
                " : ",
                h("input.aspect", {
                    id: "field-aspect-height",
                    type: "number",
                    pattern: "\\d+",
                    min: "1",
                    step: "1",
                    size: "3",
                    onchange() {
                        const height = parseInt(this.value);
                        if (!height.isNaN) {
                            controller.setAspectHeight(height);
                        }
                    }
                })
            ]),
            h("span.group.btn-group", [
                h("button", {
                    title: _("Move the selected layers (hold Alt to zoom, Shift to rotate)"),
                    className: this.viewport.dragMode === "translate" ? "active" : "",
                    onclick() { controller.setDragMode("translate"); }
                }, h("i.fas.fa-arrows-alt")),
                h("button", {
                    title: _("Zoom in/out on the selected layers (you can also hold the Alt key in Move mode)"),
                    className: this.viewport.dragMode === "scale" ? "active" : "",
                    onclick() { controller.setDragMode("scale"); }
                }, h("i.fas.fa-expand")),
                h("button", {
                    title: _("Rotate the selected layers (you can also hold the Shift key in Move mode)"),
                    className: this.viewport.dragMode === "rotate" ? "active" : "",
                    onclick() { controller.setDragMode("rotate"); }
                }, h("i.fas.fa-undo")), // "undo" icon shows a counter-clockwise circular arrow
                h("button", {
                    title: _("Edit the clipping area"),
                    className: this.viewport.dragMode === "clip" ? "active" : "",
                    onclick() { controller.setDragMode("clip"); }
                }, h("i.fas.fa-crop"))
            ]),
            h("span.group.btn-group", [
                h("button", {
                    title: _("Undo"),
                    disabled: controller.undoStack.length ? undefined : "disabled",
                    onclick() { controller.undo(); }
                }, h("i.fas.fa-reply")), // "reply" icon preferred to the official "undo" icon
                h("button", {
                    title: _("Redo"),
                    disabled: controller.redoStack.length ? undefined : "disabled",
                    onclick() { controller.redo(); }
                }, h("i.fas.fa-share")) // "share" icon preferred to the official "redo" icon
            ]),
            h("span.group", [
                h("button", {
                    title: screenfull.isFullscreen ? _("Disable full-screen mode") : _("Enable full-screen mode"),
                    id: "btn-fullscreen",
                    className: screenfull.isFullscreen ? "active" : undefined,
                    disabled: !screenfull.isEnabled,
                    onclick() { screenfull.toggle(document.documentElement); }
                }, h("i.fas.fa-desktop"))
            ]),
            h("span.group.btn-group", [
                h("button", {
                    title: _("Save the presentation"),
                    disabled: controller.storage && controller.storage.htmlNeedsSaving ? undefined : "disabled",
                    onclick() { controller.save(); }
                }, h("i.fas.fa-download")), // "download" icon preferred to the official "save" icon
                h("button", {
                    title: _("Reload the SVG document"),
                    onclick() { controller.reload(); }
                }, h("i.fas.fa-sync")),
                // TODO disable the Export button if the feature is not available
                h("button", {
                    title: _("Export the presentation"),
                    className: properties.mode === "export" ? "active" : undefined,
                    onclick() { properties.toggleMode("export"); }
                }, h("i.fas.fa-file-export"))
            ]),
            h("span.group.btn-group", [
                h("button", {
                    title: _("Preferences"),
                    className: properties.mode === "preferences" ? "active" : undefined,
                    onclick() { properties.toggleMode("preferences"); }
                }, h("i.fas.fa-sliders-h")),
                h("button", {
                    title: _("Information"),
                    onclick() { controller.info(`Sozi ${pkg.version}`, true); }
                }, h("i.fas.fa-info"))
            ])
        ]);
    }
}