blob: 871c6476b9ca8d1ebde6433bec7043a974534980 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* @fileoverview
* Class handling setting of the local app window shape to account for windows
* on the remote desktop, as well as any client-side UI.
*/
'use strict';
/** @suppress {duplicate} */
var remoting = remoting || {};
/** @constructor */
remoting.WindowShape = function() {
/** @private {Array<{left: number, top: number,
width: number, height: number}>} */
this.desktopRects_ = [];
/** @private {Array<remoting.WindowShape.ClientUI>} */
this.clientUIs_ = [];
};
/**
* @return {boolean} True if setShape is available and implemented for the
* current platform.
*/
remoting.WindowShape.isSupported = function() {
return base.isAppsV2() &&
typeof(chrome.app.window.current().setShape) != 'undefined' &&
!remoting.platformIsMac();
};
/**
* Adds a client-side UI.
*
* @param {remoting.WindowShape.ClientUI} callback
*/
remoting.WindowShape.prototype.registerClientUI = function(callback) {
if (this.clientUIs_.indexOf(callback) === -1) {
this.clientUIs_.push(callback);
this.updateClientWindowShape();
}
};
/**
* Removes a client-side UI.
*
* @param {remoting.WindowShape.ClientUI} callback
*/
remoting.WindowShape.prototype.unregisterClientUI = function(callback) {
var index = this.clientUIs_.indexOf(callback);
this.clientUIs_.splice(index, 1);
this.updateClientWindowShape();
};
/**
* Center aligns a DOM element to the desktop shape.
*
* @param {HTMLElement} element
*/
remoting.WindowShape.prototype.centerToDesktop = function(element) {
var desktop = {
left: Number.MAX_VALUE,
right: Number.MIN_VALUE,
top: Number.MAX_VALUE,
bottom: Number.MIN_VALUE
};
// If there is no desktop window, center it to the current viewport.
if (this.desktopRects_.length === 0) {
desktop.left = 0;
desktop.right = window.innerWidth;
desktop.top = 0;
desktop.bottom = window.innerHeight;
} else {
// Compute the union of the bounding rects of all desktop windows.
this.desktopRects_.forEach(function(
/**{left: number, top: number, width: number, height: number}*/ rect) {
desktop.left = Math.min(rect.left, desktop.left);
desktop.right = Math.max(rect.left + rect.width, desktop.right);
desktop.top = Math.min(rect.top, desktop.top);
desktop.bottom = Math.max(rect.top + rect.height, desktop.bottom);
});
}
// Center the element to the desktop window bounding rect.
var rect = element.getBoundingClientRect();
var left = (desktop.right - desktop.left - rect.width) / 2 + desktop.left;
var top = (desktop.bottom - desktop.top - rect.height) / 2 + desktop.top;
element.style.left = Math.round(left) + 'px';
element.style.top = Math.round(top) + 'px';
this.updateClientWindowShape();
};
/**
* Sets the region associated with the remote desktop windows.
*
* @param {Array<{left: number, top: number, width: number, height: number}>}
* rects
*/
remoting.WindowShape.prototype.setDesktopRects = function(rects) {
this.desktopRects_ = rects;
this.updateClientWindowShape();
};
/**
* Updates the client window shape.
*/
remoting.WindowShape.prototype.updateClientWindowShape = function() {
if (!remoting.WindowShape.isSupported()) {
return;
}
var rects = this.desktopRects_.slice();
for (var i = 0; i < this.clientUIs_.length; ++i) {
this.clientUIs_[i].addToRegion(rects);
}
for (var i = 0; i < rects.length; ++i) {
var rect = /** @type {ClientRect} */ (rects[i]);
var left = Math.floor(rect.left);
var right = Math.ceil(rect.left + rect.width);
var top = Math.floor(rect.top);
var bottom = Math.ceil(rect.top + rect.height);
rects[i] = { left: left,
top: top,
width: right - left,
height: bottom - top };
}
chrome.app.window.current().setShape({rects: rects});
};
/**
* @interface
*/
remoting.WindowShape.ClientUI = function () {
};
/**
* Adds the context menu's bounding rectangle to the specified region.
*
* @param {Array<{left: number, top: number, width: number, height: number}>}
* rects
*/
remoting.WindowShape.ClientUI.prototype.addToRegion = function(rects) {};