was.wm.js – Rev 10

Subversion Repositories:
Rev:
class wasWM {
    // Load the window manager desktop icons.
    loadWindowManagerIcons(path) {
        // Reset the current icon store.
        var wasWM = this;
        wasWM.icons = [];
        // Search and load all nucleons.
        $.get(path, function(nucleons) {
            var ix = 0, iy = 0;
            var states = {};
            var cookie = Cookies.get('window-manager-icons');
            if(cookie) {
                states = JSON.parse(cookie);
            }
            $.each(nucleons, function(index, file) {
                // Only consider HTML files.
                if (!/\.html$/.test(file)) {
                    return;
                }
                $.get(path + '/' + file, function(data) {
                    // Get DOM element.
                    data = $(data).get(0);
    
                    // Only consider icon types for display.
                    if(data.getAttribute("data-type") !== 'icon') {
                        return;
                    }
    
                    var nucleon = data.getAttribute('data-target');
                    // Add the nucleon to the store.
                    wasWM.icons.push(nucleon);
    
                    // Attach double click event.
                    data.addEventListener('dblclick', () => {
                        wasWM.openWindowManagerWindow(nucleon, path + '/' + file);
                    });
    
                    if(typeof states[nucleon] !== 'undefined') {
                        var sx = states[nucleon].x, 
                            sy = states[nucleon].y;
            
                        data.style.webkitTransform =
                            data.style.transform =
                            'translate(' + sx + 'px, ' + sy + 'px)';

                        // Update the position attributes
                        data.setAttribute('data-x', sx);
                        data.setAttribute('data-y', sy);
        
                        $('#window-manager-desktop').append(data);
                        return;
                    }
    
                    // Translate the desktop icons so they do not overlap.
                    data.style.webkitTransform =
                      data.style.transform =
                      'translate(' + ix + 'px, ' + iy + 'px)';

                    // Update the position attributes
                    data.setAttribute('data-x', ix);
                    data.setAttribute('data-y', iy);
    
                    $('#window-manager-desktop').append(data);
                    // Translate by the desktop icon size.
                    ix += 64;
                });
            });
        });
    }

    // Open a window manager window.
    openWindowManagerWindow(nucleon, file) {
        // If the nucleon already exists, then do not append the content again.
        if($('#' + nucleon).length) {
            return;
        }

        // Store the icon.
        var icon = $('#' + nucleon + '-window-manager-icon-image').attr('src');

        // Change the nucleon icon to a loading icon.
        $('#' + nucleon + '-window-manager-icon-image').attr('src', '/img/loader.gif');

        // Disable button for successive clicks.
        $('#' + nucleon + '-window-manager-icon').prop('disabled', true);

        // Load the nucleon.
        $.get(file, function(data) {
            // Retrieve the window for this nucleon.
            data = $(data).get().filter(
                (element) => 
                    $(element).attr('data-type') === 'window' && 
                    $(element).attr('id') === nucleon
            ).pop();

            // Select all new scripts that have to be inserted into the DOM.
            var nucleonScripts = [];
            $(data).find('script').each(function() {
                var src = $(this).attr('src');
                if(src === undefined) {
                    return;
                }
                nucleonScripts[src] = $(this);
            });
            // Remove scripts from the nucleon if they are already added to the DOM.
            $(document).find('script').each(function() {
                var src = $(this).attr('src');
                if(nucleonScripts[src] === undefined) {
                    return;
                }
                nucleonScripts[src].remove();
            });

            // Restore windows to their saved position.
            var cookie = Cookies.get('window-manager-windows');
            if(cookie) {
                var states = JSON.parse(cookie);
                if(typeof states[nucleon] !== 'undefined') {
                    var x = states[nucleon].x, 
                        y = states[nucleon].y,
                        wm = $(data).find('.window-manager-window').get(0);
        
                        wm.style.webkitTransform =
                            wm.style.transform =
                            'translate(' + x + 'px, ' + y + 'px)';
        
                        // Update the position attributes
                        wm.setAttribute('data-x', x);
                        wm.setAttribute('data-y', y);
                }
            }
            $(data).hide().appendTo('#window-manager-desktop').fadeIn(750);
        }).done(function(data) {
            // Change the nucleon icon back.
            $('#' + nucleon + '-window-manager-icon-image').attr('src', icon);
            // Enable the button.
            $('#' + nucleon + '-window-manager-icon').prop('disabled', false);
        });
    }

    // Retrieve the top-most window manager window z-index.
    static getTopWindowIndex() {
        return Math.max.apply(null, 
            $.map($('.window-manager-window'), function(e, n) {
                if ($(e).css('position') !== 'static') {
                    return parseInt($(e).css('z-index')) || 1;
                }
            })
        );
    }

    static dragMoveListener(event) {
        var target = event.target, states, cookie,
          // keep the dragged position in the data-x/data-y attributes
          x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
          y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;

        // translate the element
        target.style.webkitTransform =
          target.style.transform =
          'translate(' + x + 'px, ' + y + 'px)';

        // update the position attributes
        target.setAttribute('data-x', x);
        target.setAttribute('data-y', y);

        if(target.classList.contains('window-manager-window')) {
            // Save the window position.
            states = {};
            cookie = Cookies.get('window-manager-windows');
            if(cookie) {
                states = JSON.parse(cookie);
            }

            states[$(event.target).data('target')] = {
                x: x,
                y: y
            };

            Cookies.set('window-manager-windows', states, { path: '' });
        }

        if(target.classList.contains('window-manager-icon')) {
            // Save the icon position.
            states = {};
            cookie = Cookies.get('window-manager-icons');
            if(cookie) {
                states = JSON.parse(cookie);
            }

            states[$(event.target).data('target')] = {
                x: x,
                y: y
            };

            Cookies.set('window-manager-icons', states, { path: '' });
        }
    }
    
    constructor(path) {
        this.icons = [];
        // Window manager windows.
        interact('.window-manager-window')
            .draggable({
                // enable inertial throwing
                inertia: true,
                // keep the element within the area of it's parent
                restrict: {
                      restriction: $('#window-manager-desktop').get(0),
                      endOnly: true,
                      elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
                },
    
                // enable autoScroll
                autoScroll: true,
    
                onmove: wasWM.dragMoveListener,
                onend: function (event) {
                    event.target.style.opacity = 1;
                },
                onstart: function(event) {
                    // Move windows to top on drag.
                    event.target.style.zIndex = wasWM.getTopWindowIndex() + 1;
                    event.target.style.opacity = 0.5;
                }
            })
            .allowFrom('.panel-heading');

        // Window manager icons.
        interact('.window-manager-icon')
            .draggable({
                // enable inertial throwing
                inertia: false,
                // keep the element within the area of it's parent
                restrict: {
                      restriction: $('#window-manager-desktop').get(0),
                      endOnly: true,
                      elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
                },
                snap: {
                      targets: [
                        //createSnapGrid({ x: 64, y: 64 })
                      ],
                      range: Infinity,
                      relativePoints: [ { x: 0, y: 0 } ]
                },
                // enable autoScroll
                autoScroll: true,
    
                onmove: wasWM.dragMoveListener,
                onend: function (event) {
                    event.target.style.opacity = 1;
                },
                onstart: function(event) {
                    event.target.style.opacity = 0.5;
                }
            });

        // Closing windows.
        $(document).on('click', '.window-manager-close-button', function(event) {
            var wm = $('#' + $(this).data('target'));
            wm.fadeOut(750, function() {
                wm.remove();
            });
        });

        // Windows clicking brings to front.
        $(document).on('click', '.window-manager-window', function(event) {
            $(event.target)
                .closest('.window-manager-window')
                .css('z-index', wasWM.getTopWindowIndex() + 1);
        });

        // this is used later in the resizing and gesture demos
        window.dragMoveListener = wasWM.dragMoveListener;

        // Load the window manager icons.
        this.loadWindowManagerIcons(path);
    }
}

wasWM.prototype.icons = [];