1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5'use strict';
6
7base.requireStylesheet('cc.layer_picker');
8
9base.require('cc.constants');
10base.require('cc.layer_tree_host_impl');
11base.require('cc.selection');
12base.require('tracing.analysis.generic_object_view');
13base.require('ui.drag_handle');
14base.require('ui.list_view');
15base.require('ui.dom_helpers');
16
17base.exportTo('cc', function() {
18  var constants = cc.constants;
19
20  /**
21   * @constructor
22   */
23  var LayerPicker = ui.define('layer-picker');
24
25  LayerPicker.prototype = {
26    __proto__: HTMLUnknownElement.prototype,
27
28    decorate: function() {
29      this.lthi_ = undefined;
30      this.controls_ = document.createElement('top-controls');
31
32
33      this.layerList_ = new ui.ListView();
34      this.appendChild(this.controls_);
35
36      this.appendChild(this.layerList_);
37
38      this.layerList_.addEventListener(
39          'selection-changed', this.onLayerSelectionChanged_.bind(this));
40
41      this.controls_.appendChild(ui.createSelector(
42          this, 'whichTree',
43          'layerPicker.whichTree', constants.ACTIVE_TREE,
44          [{label: 'Active tree', value: constants.ACTIVE_TREE},
45           {label: 'Pending tree', value: constants.PENDING_TREE}]));
46
47      this.hidePureTransformLayers_ = true;
48      var hideTransformLayers = ui.createCheckBox(
49          this, 'hidePureTransformLayers',
50          'layerPicker.hideTransformLayers', true,
51          'Hide transform layers');
52      hideTransformLayers.classList.add('hide-transform-layers');
53      this.controls_.appendChild(hideTransformLayers);
54    },
55
56    get lthiSnapshot() {
57      return this.lthiSnapshot_;
58    },
59
60    set lthiSnapshot(lthiSnapshot) {
61      this.lthiSnapshot_ = lthiSnapshot;
62      this.updateContents_();
63    },
64
65    get whichTree() {
66      return this.whichTree_;
67    },
68
69    set whichTree(whichTree) {
70      this.whichTree_ = whichTree;
71      this.updateContents_();
72    },
73
74    get hidePureTransformLayers() {
75      return this.hidePureTransformLayers_;
76    },
77
78    set hidePureTransformLayers(hide) {
79      this.hidePureTransformLayers_ = hide;
80      this.updateContents_();
81    },
82
83    getLayerInfos_: function() {
84      if (!this.lthiSnapshot_)
85        return [];
86
87      var tree = this.lthiSnapshot_.getTree(this.whichTree_);
88      if (!tree)
89        return [];
90
91      var layerInfos = [];
92
93      var hidePureTransformLayers = this.hidePureTransformLayers_;
94
95      function isPureTransformLayer(layer) {
96        if (layer.args.compositingReasons &&
97            layer.args.compositingReasons.length != 1 &&
98            layer.args.compositingReasons[0] != 'No reasons given')
99          return false;
100
101        if (layer.args.drawsContent)
102          return false;
103
104        return true;
105      }
106      function visitLayer(layer, depth, isMask, isReplica) {
107        var info = {layer: layer,
108          depth: depth};
109
110        if (layer.args.drawsContent)
111          info.name = layer.objectInstance.name;
112        else
113          info.name = 'cc::LayerImpl';
114
115        info.isMaskLayer = isMask;
116        info.replicaLayer = isReplica;
117
118        if (!hidePureTransformLayers || !isPureTransformLayer(layer))
119          layerInfos.push(info);
120
121      };
122      tree.iterLayers(visitLayer);
123      return layerInfos;
124    },
125
126    updateContents_: function() {
127      this.layerList_.clear();
128
129      var selectedLayerId;
130      if (this.selection_ && this.selection_.associatedLayerId)
131        selectedLayerId = this.selection_.associatedLayerId;
132
133      var layerInfos = this.getLayerInfos_();
134      layerInfos.forEach(function(layerInfo) {
135        var layer = layerInfo.layer;
136
137        var item = document.createElement('div');
138
139        var indentEl = item.appendChild(ui.createSpan());
140        indentEl.style.whiteSpace = 'pre';
141        for (var i = 0; i < layerInfo.depth; i++)
142          indentEl.textContent = indentEl.textContent + ' ';
143
144        var labelEl = item.appendChild(ui.createSpan());
145        var id = layer.layerId;
146        labelEl.textContent = layerInfo.name + ' ' + id;
147
148
149        var notesEl = item.appendChild(ui.createSpan());
150        if (layerInfo.isMaskLayer)
151          notesEl.textContent += '(mask)';
152        if (layerInfo.isReplicaLayer)
153          notesEl.textContent += '(replica)';
154
155        item.layer = layer;
156        this.layerList_.appendChild(item);
157
158        if (layer.layerId == selectedLayerId)
159          layer.selected = true;
160      }, this);
161    },
162
163    onLayerSelectionChanged_: function(e) {
164      var selectedLayer;
165      if (this.layerList_.selectedElement)
166        selectedLayer = this.layerList_.selectedElement.layer;
167
168      if (selectedLayer)
169        this.selection_ = new cc.LayerSelection(selectedLayer);
170      else
171        this.selection_ = undefined;
172      base.dispatchSimpleEvent(this, 'selection-changed', false);
173    },
174
175    get selection() {
176      return this.selection_;
177    },
178
179    set selection(selection) {
180      this.selection_ = selection;
181      this.updateContents_();
182    }
183  };
184
185  return {
186    LayerPicker: LayerPicker
187  };
188});
189