1 /* Copyright (c) 2012 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.
8 base
.require('quad_view_viewport');
9 base
.requireStylesheet('quad_view');
11 base
.exportTo('ccfv', function() {
13 function QuadViewSelection(quadView
, quadIndices
) {
15 this.quadIndices
= quadIndices
;
18 var QuadView
= ui
.define('x-quad-view');
20 QuadView
.prototype = {
21 __proto__
: HTMLUnknownElement
.prototype,
23 decorate: function() {
25 this.quads_
= undefined;
26 this.viewport_
= undefined;
27 this.deviceViewportSizeForFrame_
= undefined;
28 this.header_
= document
.createElement('div');
29 this.header_
.className
= 'header';
30 this.canvas_
= document
.createElement('canvas');
31 this.appendChild(this.header_
);
32 this.appendChild(this.canvas_
);
34 this.onViewportChanged_
= this.onViewportChanged_
.bind(this);
35 this.onMouseDown_
= this.onMouseDown_
.bind(this);
36 this.onMouseMove_
= this.onMouseMove_
.bind(this);
37 this.onMouseUp_
= this.onMouseUp_
.bind(this);
38 this.canvas_
.addEventListener('mousedown', this.onMouseDown_
);
40 this.canvas_
.addEventListener('focus', this.redrawCanvas_
.bind(this));
41 this.canvas_
.addEventListener('blur', this.redrawCanvas_
.bind(this));
42 this.canvas_
.tabIndex
= 0;
46 return this.headerText_
;
49 set headerText(headerText
) {
50 this.headerText_
= headerText
;
51 this.updateChildren_();
55 return this.viewport_
;
58 set viewport(viewport
) {
60 this.viewport_
.removeEventListener('change', this.onViewportChanged_
);
61 this.viewport_
= viewport
;
63 this.viewport_
.addEventListener('change', this.onViewportChanged_
);
64 this.updateChildren_();
67 onViewportChanged_: function() {
68 if (!this.hasRequiredProprties_
)
79 this.updateChildren_();
82 get deviceViewportSizeForFrame() {
83 return this.deviceViewportSizeForFrame_
;
86 set deviceViewportSizeForFrame(size
) {
87 this.deviceViewportSizeForFrame_
= size
;
88 this.updateChildren_();
91 get hasRequiredProprties_() {
96 updateChildren_: function() {
97 this.header_
.textContent
= this.headerText_
;
98 var canvas
= this.canvas_
;
99 if (!this.hasRequiredProprties_
) {
105 this.redrawCanvas_();
108 redrawCanvas_: function() {
109 if (this.canvas_
.width
!= this.viewport_
.deviceWidth
) {
110 this.canvas_
.width
= this.viewport_
.deviceWidth
;
111 this.canvas_
.style
.width
= this.viewport_
.layoutWidth
+ 'px';
113 if (this.canvas_
.height
!= this.viewport_
.deviceHeight
) {
114 this.canvas_
.height
= this.viewport_
.deviceHeight
;
115 this.canvas_
.style
.height
= this.viewport_
.layoutHeight
+ 'px';
118 var ctx
= this.canvas_
.getContext('2d');
119 var vp
= this.viewport_
;
120 ctx
.fillStyle
= 'rgb(255,255,255)';
123 this.canvas_
.width
, this.canvas_
.height
);
127 vp
.applyTransformToContext(ctx
);
128 ctx
.lineWidth
= vp
.getDeviceLineWidthAssumingTransformIsApplied(1.0);
130 var quads
= this.quads_
;
132 // Background colors.
133 var lastBackgroundColor
= 'rgb(255,255,0)';
134 ctx
.fillStyle
= lastBackgroundColor
;
135 for (var i
= 0; i
< quads
.length
; i
++) {
137 if (!quad
.backgroundColor
)
139 if (quad
.backgroundColor
!= lastBackgroundColor
) {
140 lastBackgroundColor
= quad
.backgroundColor
;
141 ctx
.fillStyle
= lastBackgroundColor
;
144 ctx
.moveTo(quad
.p1
.x
, quad
.p1
.y
);
145 ctx
.lineTo(quad
.p2
.x
, quad
.p2
.y
);
146 ctx
.lineTo(quad
.p3
.x
, quad
.p3
.y
);
147 ctx
.lineTo(quad
.p4
.x
, quad
.p4
.y
);
153 ctx
.strokeStyle
= 'rgb(128,128,128)';
154 for (var i
= 0; i
< quads
.length
; i
++) {
157 ctx
.moveTo(quad
.p1
.x
, quad
.p1
.y
);
158 ctx
.lineTo(quad
.p2
.x
, quad
.p2
.y
);
159 ctx
.lineTo(quad
.p3
.x
, quad
.p3
.y
);
160 ctx
.lineTo(quad
.p4
.x
, quad
.p4
.y
);
165 // Selection outlines.
166 ctx
.lineWidth
= vp
.getDeviceLineWidthAssumingTransformIsApplied(8.0);
167 var rules
= window
.getMatchedCSSRules(this.canvas_
);
169 // TODO(nduca): Figure out how to get these from css.
170 if (document
.activeElement
== this.canvas_
)
171 ctx
.strokeStyle
= 'rgb(187,226,54)';
173 ctx
.strokeStyle
= 'rgb(156,189,45)';
175 for (var i
= 0; i
< quads
.length
; i
++) {
180 ctx
.moveTo(quad
.p1
.x
, quad
.p1
.y
);
181 ctx
.lineTo(quad
.p2
.x
, quad
.p2
.y
);
182 ctx
.lineTo(quad
.p3
.x
, quad
.p3
.y
);
183 ctx
.lineTo(quad
.p4
.x
, quad
.p4
.y
);
188 if (this.deviceViewportSizeForFrame_
) {
189 ctx
.lineWidth
= vp
.getDeviceLineWidthAssumingTransformIsApplied(2.0);
190 ctx
.strokeStyle
= 'rgba(255,0,0,1)';
193 this.deviceViewportSizeForFrame_
.width
,
194 this.deviceViewportSizeForFrame_
.height
);
200 createSelection_: function(quadIndices
) {
201 return new QuadViewSelection(this, quadIndices
);
203 selectQuadsAtCanvasClientPoint: function(clientX
, clientY
) {
204 var selection
= this.createSelection_(
205 this.findQuadsAtCanvasClientPoint(clientX
, clientY
));
206 var e
= new base
.Event('selection-changed');
207 e
.selection
= selection
;
208 this.dispatchEvent(e
);
209 this.viewport_
.forceRedrawAll();
212 findQuadsAtCanvasClientPoint: function(clientX
, clientY
) {
213 var bounds
= this.canvas_
.getBoundingClientRect();
214 var vecInLayout
= vec2
.createXY(clientX
- bounds
.left
,
215 clientY
- bounds
.top
);
216 var vecInWorldPixels
=
217 this.viewport_
.layoutPixelsToWorldPixels2(vecInLayout
);
218 var pointInWorldPixels
= vec2
.asPoint(vecInWorldPixels
);
220 var quads
= this.quads_
;
222 for (var i
= 0; i
< quads
.length
; i
++) {
224 var hit
= base
.pointInQuad2Pt(pointInWorldPixels
,
232 onMouseDown_: function(e
) {
233 this.selectQuadsAtCanvasClientPoint(e
.clientX
, e
.clientY
);
234 document
.addEventListener('mousemove', this.onMouseMove_
);
235 document
.addEventListener('mouseup', this.onMouseUp_
);
237 this.canvas_
.focus();
241 onMouseMove_: function(e
) {
242 this.selectQuadsAtCanvasClientPoint(e
.clientX
, e
.clientY
);
245 onMouseUp_: function(e
) {
246 this.selectQuadsAtCanvasClientPoint(e
.clientX
, e
.clientY
);
247 document
.removeEventListener('mousemove', this.onMouseMove_
);
248 document
.removeEventListener('mouseup', this.onMouseUp_
);
255 QuadViewSelection
: QuadViewSelection
,