Add support for multiple layers to flatten(). Add move() to LayerContainer. Track properties of LayerContainer.

This commit is contained in:
Michael Jumper
2014-01-15 13:33:09 -08:00
parent 350b1a5e0b
commit ad5ab18605

View File

@@ -92,7 +92,7 @@ Guacamole.Client = function(tunnel) {
"0 0"; "0 0";
// Create default layer // Create default layer
var default_layer_container = new Guacamole.Client.LayerContainer(displayWidth, displayHeight); var default_layer_container = new Guacamole.Client.LayerContainer(0, displayWidth, displayHeight);
// Position default layer // Position default layer
var default_layer_container_element = default_layer_container.getElement(); var default_layer_container_element = default_layer_container.getElement();
@@ -102,7 +102,7 @@ Guacamole.Client = function(tunnel) {
default_layer_container_element.style.overflow = "hidden"; default_layer_container_element.style.overflow = "hidden";
// Create cursor layer // Create cursor layer
var cursor = new Guacamole.Client.LayerContainer(0, 0); var cursor = new Guacamole.Client.LayerContainer(null, 0, 0);
cursor.getLayer().setChannelMask(Guacamole.Layer.SRC); cursor.getLayer().setChannelMask(Guacamole.Layer.SRC);
cursor.getLayer().autoflush = true; cursor.getLayer().autoflush = true;
@@ -431,7 +431,7 @@ Guacamole.Client = function(tunnel) {
if (layer == null) { if (layer == null) {
// Add new layer // Add new layer
layer = new Guacamole.Client.LayerContainer(displayWidth, displayHeight); layer = new Guacamole.Client.LayerContainer(index, displayWidth, displayHeight);
layers[index] = layer; layers[index] = layer;
// Get and position layer // Get and position layer
@@ -862,16 +862,10 @@ Guacamole.Client = function(tunnel) {
// Get container element // Get container element
var layer_container = getLayerContainer(layer_index); var layer_container = getLayerContainer(layer_index);
var layer_container_element = layer_container.getElement(); var parent = getLayerContainer(parent_index);
var parent = getLayerContainer(parent_index).getElement();
// Set parent if necessary
if (!(layer_container_element.parentNode === parent))
parent.appendChild(layer_container_element);
// Move layer // Move layer
layer_container.translate(x, y); layer_container.move(parent, x, y, z);
layer_container_element.style.zIndex = z;
} }
@@ -1303,18 +1297,41 @@ Guacamole.Client = function(tunnel) {
*/ */
this.flatten = function() { this.flatten = function() {
// Get source and destination canvases // Get default layer
var source = getLayer(0).getCanvas(); var default_layer = getLayerContainer(0);
var canvas = document.createElement("canvas");
// Set dimensions // Get destination canvas
canvas.width = source.width; var canvas = document.createElement("canvas");
canvas.height = source.height; canvas.width = default_layer.width;
canvas.height = default_layer.height;
// Copy image from source // Copy image from source
var context = canvas.getContext("2d"); var context = canvas.getContext("2d");
context.drawImage(source, 0, 0); context.drawImage(default_layer.getLayer().getCanvas(), 0, 0);
function draw_all(layers, x, y) {
var index, layer;
// Draw all immediate children
for (index in layers) {
var layer = layers[index];
var context = canvas.getContext("2d");
context.drawImage(layer.getLayer().getCanvas(),
layer.x + x, layer.y + y);
}
// Draw all children of children
for (layer in layers) {
var layer = layers[index];
draw_all(layer.children, layer.x + x, layer.y + y);
}
}
// Draw all immediate children
draw_all(default_layer.children, 0, 0);
// Return new canvas copy // Return new canvas copy
return canvas; return canvas;
@@ -1328,14 +1345,16 @@ Guacamole.Client = function(tunnel) {
* through DOM manipulation, rather than raster operations. * through DOM manipulation, rather than raster operations.
* *
* @constructor * @constructor
* *
* @param {Number} index The unique integer which identifies this layer.
*
* @param {Number} width The width of the Layer, in pixels. The canvas element * @param {Number} width The width of the Layer, in pixels. The canvas element
* backing this Layer will be given this width. * backing this Layer will be given this width.
* *
* @param {Number} height The height of the Layer, in pixels. The canvas element * @param {Number} height The height of the Layer, in pixels. The canvas element
* backing this Layer will be given this height. * backing this Layer will be given this height.
*/ */
Guacamole.Client.LayerContainer = function(width, height) { Guacamole.Client.LayerContainer = function(index, width, height) {
/** /**
* Reference to this LayerContainer. * Reference to this LayerContainer.
@@ -1343,6 +1362,56 @@ Guacamole.Client.LayerContainer = function(width, height) {
*/ */
var layer_container = this; var layer_container = this;
/**
* Unique integer identifying this layer container.
* @type Number
*/
this.index = index;
/**
* X coordinate of the upper-left corner of this layer container within
* its parent, in pixels.
* @type Number
*/
this.x = 0;
/**
* Y coordinate of the upper-left corner of this layer container within
* its parent, in pixels.
* @type Number
*/
this.y = 0;
/**
* Z stacking order of this layer relative to other sibling layers.
* @type Number
*/
this.z = 0;
/**
* The width of this layer in pixels.
* @type Number
*/
this.width = 0;
/**
* The height of this layer in pixels.
* @type Number
*/
this.height = 0;
/**
* The parent layer container of this layer, if any.
* @type Guacamole.Client.LayerContainer
*/
this.parent = null;
/**
* Set of all children of this layer, indexed by layer index. This object
* will have one property per child.
*/
this.children = {};
// Create layer with given size // Create layer with given size
var layer = new Guacamole.Layer(width, height); var layer = new Guacamole.Layer(width, height);
@@ -1367,6 +1436,9 @@ Guacamole.Client.LayerContainer = function(width, height) {
*/ */
this.resize = function(width, height) { this.resize = function(width, height) {
layer_container.width = width;
layer_container.height = height;
// Resize layer // Resize layer
layer.resize(width, height); layer.resize(width, height);
@@ -1415,6 +1487,9 @@ Guacamole.Client.LayerContainer = function(width, height) {
*/ */
this.translate = function(x, y) { this.translate = function(x, y) {
layer_container.x = x;
layer_container.y = y;
// Generate translation // Generate translation
translate = "translate(" translate = "translate("
+ x + "px," + x + "px,"
@@ -1431,6 +1506,42 @@ Guacamole.Client.LayerContainer = function(width, height) {
}; };
/**
* Moves the upper-left corner of this LayerContainer to the given X and Y
* coordinate, sets the Z stacking order, and reparents this LayerContainer
* to the given LayerContainer.
*
* @param {Guacamole.Client.LayerContainer} parent The parent to set.
* @param {Number} x The X coordinate to move to.
* @param {Number} y The Y coordinate to move to.
* @param {Number} z The Z coordinate to move to.
*/
this.move = function(parent, x, y, z) {
var layer_container_element = layer_container.getElement();
// Set parent if necessary
if (layer_container.parent !== parent) {
// Maintain relationship
if (layer_container.parent)
delete layer_container.parent.children[layer_container.index];
layer_container.parent = parent;
parent.children[layer_container.index] = layer_container;
// Reparent element
var parent_element = parent.getElement();
parent_element.appendChild(layer_container_element);
}
// Set location
layer_container.translate(x, y);
layer_container.z = z;
layer_container_element.style.zIndex = z;
};
/** /**
* Applies the given affine transform (defined with six values from the * Applies the given affine transform (defined with six values from the
* transform's matrix). * transform's matrix).