OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 cr.define('print_preview', function() { | 5 cr.define('print_preview', function() { |
6 'use strict'; | 6 'use strict'; |
7 | 7 |
8 /** | 8 /** |
9 * Creates a Margins object that holds four margin values. The units in which | |
10 * the values are expressed can be any numeric value. | |
11 * @constructor | |
12 * @param {number} left The left margin. | |
13 * @param {number} top The top margin. | |
14 * @param {number} right The right margin. | |
15 * @param {number} bottom The bottom margin. | |
16 */ | |
17 function Margins(left, top, right, bottom) { | |
18 this[MarginSettings.LEFT_GROUP] = left; | |
19 this[MarginSettings.TOP_GROUP] = top; | |
20 this[MarginSettings.RIGHT_GROUP] = right; | |
21 this[MarginSettings.BOTTOM_GROUP] = bottom; | |
22 } | |
23 | |
24 Margins.prototype = { | |
25 /** | |
26 * Checks if |rhs| is equal to |this|. | |
27 * @param {Margins} rhs The Margins object to compare against. | |
28 * @return {boolean} true if they are equal. | |
29 */ | |
30 isEqual: function(rhs) { | |
31 return this[MarginSettings.TOP_GROUP] === rhs[MarginSettings.TOP_GROUP] && | |
32 this[MarginSettings.LEFT_GROUP] === rhs[MarginSettings.LEFT_GROUP] && | |
33 this[MarginSettings.RIGHT_GROUP] === | |
34 rhs[MarginSettings.RIGHT_GROUP] && | |
35 this[MarginSettings.BOTTOM_GROUP] === | |
36 rhs[MarginSettings.BOTTOM_GROUP]; | |
37 }, | |
38 | |
39 /** | |
40 * Copies the four margin values from |rhs|. | |
41 * @param {Margins} rhs The Margins object values to be used. | |
42 */ | |
43 copy: function(rhs) { | |
44 this[MarginSettings.TOP_GROUP] = rhs[MarginSettings.TOP_GROUP]; | |
45 this[MarginSettings.LEFT_GROUP] = rhs[MarginSettings.LEFT_GROUP]; | |
46 this[MarginSettings.RIGHT_GROUP] = rhs[MarginSettings.RIGHT_GROUP]; | |
47 this[MarginSettings.BOTTOM_GROUP] = rhs[MarginSettings.BOTTOM_GROUP]; | |
48 }, | |
49 }; | |
50 | |
51 /** | |
52 * @constructor | |
53 * Class describing the layout of the page. | |
54 */ | |
55 function PageLayout(width, height, left, top, right, bottom) { | |
56 this.contentWidth_ = width; | |
57 this.contentHeight_ = height; | |
58 this.margins_ = new Margins(left, top, right, bottom); | |
59 } | |
60 | |
61 PageLayout.prototype = { | |
62 /** | |
63 * @type {number} The width of the page. | |
64 */ | |
65 get pageWidth() { | |
66 return this.margins_.left + this.margins_.right + this.contentWidth_; | |
67 }, | |
68 | |
69 /** | |
70 * @type {number} The height of the page. | |
71 */ | |
72 get pageHeight() { | |
73 return this.margins_.top + this.margins_.bottom + this.contentHeight_; | |
74 } | |
75 }; | |
76 | |
77 /** | |
9 * Creates a MarginSettings object. This object encapsulates all settings and | 78 * Creates a MarginSettings object. This object encapsulates all settings and |
10 * logic related to the margins mode. | 79 * logic related to the margins mode. |
11 * @constructor | 80 * @constructor |
12 */ | 81 */ |
13 function MarginSettings() { | 82 function MarginSettings() { |
14 this.marginsOption_ = $('margins-option'); | 83 this.marginsOption_ = $('margins-option'); |
15 this.marginList_ = $('margin-list'); | 84 this.marginList_ = $('margin-list'); |
16 // Holds the custom left margin value (if set). | 85 this.marginsUI_ = null; |
17 this.customMarginLeft_ = -1; | 86 |
18 // Holds the custom right margin value (if set). | 87 // Holds the custom margin values in points (if set). |
19 this.customMarginRight_ = -1; | 88 this.customMargins_ = new Margins(-1, -1, -1, -1); |
20 // Holds the custom top margin value (if set). | 89 // Holds the previous custom margin values in points. |
21 this.customMarginTop_ = -1; | 90 this.previousCustomMargins_ = new Margins(-1, -1, -1, -1); |
22 // Holds the custom bottom margin value (if set). | 91 // Holds the width of the page in points. |
23 this.customMarginBottom_ = -1; | 92 this.pageWidth_ = -1; |
24 // Margin list values. | 93 // Holds the height of the page in points. |
25 this.customMarginsValue_ = 2; | 94 this.pageHeight_ = -1; |
26 this.defaultMarginsValue_ = 0; | 95 // The last selected margin option. |
27 this.noMarginsValue_ = 1; | 96 this.lastSelectedOption_ = MarginSettings.MARGINS_VALUE_DEFAULT; |
28 // Default Margins option index. | 97 |
29 this.defaultMarginsIndex_ = 0; | 98 // Holds the currently updated default page layout values. |
99 this.currentDefaultPageLayout = null; | |
100 // Holds the default page layout values when the custom margins was last | |
101 // selected. | |
102 this.previousDefaultPageLayout_ = null; | |
103 | |
104 // True if the margins UI should be shown regardless of mouse position. | |
105 this.forceDisplayingMarginLines_ = true; | |
30 } | 106 } |
31 | 107 |
108 // Number of points per inch. | |
109 MarginSettings.POINTS_PER_INCH = 72; | |
110 // Margin list values. | |
111 MarginSettings.MARGINS_VALUE_DEFAULT = 0; | |
112 MarginSettings.MARGINS_VALUE_NO_MARGINS = 1; | |
113 MarginSettings.MARGINS_VALUE_CUSTOM = 2; | |
114 // Default Margins option index. | |
115 MarginSettings.DEFAULT_MARGINS_OPTION_INDEX = 0; | |
116 // Group name corresponding to the top margin. | |
117 MarginSettings.TOP_GROUP = 'top'; | |
118 // Group name corresponding to the left margin. | |
119 MarginSettings.LEFT_GROUP = 'left'; | |
120 // Group name corresponding to the right margin. | |
121 MarginSettings.RIGHT_GROUP = 'right'; | |
122 // Group name corresponding to the bottom margin. | |
123 MarginSettings.BOTTOM_GROUP = 'bottom'; | |
124 | |
125 /** | |
126 * Converts |value| from points to inches. | |
127 * @param {number} value The number in points. | |
128 * @return {number} |value| in inches. | |
129 */ | |
130 MarginSettings.convertPointsToInches = function(value) { | |
131 return value / MarginSettings.POINTS_PER_INCH; | |
132 }; | |
133 | |
134 /** | |
135 * Converts |value| from inches to points. | |
136 * @param {number} value The number in inches. | |
137 * @return {number} |value| in points. | |
138 */ | |
139 MarginSettings.convertInchesToPoints = function(value) { | |
140 return value * MarginSettings.POINTS_PER_INCH; | |
141 }; | |
142 | |
32 cr.addSingletonGetter(MarginSettings); | 143 cr.addSingletonGetter(MarginSettings); |
33 | 144 |
34 MarginSettings.prototype = { | 145 MarginSettings.prototype = { |
35 /** | 146 /** |
36 * The selection list corresponding to the margins option. | |
37 * @return {HTMLInputElement} | |
38 */ | |
39 get marginList() { | |
40 return this.marginList_; | |
41 }, | |
42 | |
43 /** | |
44 * Returns a dictionary of the four custom margin values. | 147 * Returns a dictionary of the four custom margin values. |
45 * @return {object} | 148 * @return {object} |
46 */ | 149 */ |
47 get customMargins() { | 150 get customMargins() { |
48 return {'marginLeft': this.customMarginLeft_, | 151 var margins = {}; |
49 'marginTop': this.customMarginTop_, | 152 margins.marginLeft = this.customMargins_.left; |
50 'marginRight': this.customMarginRight_, | 153 margins.marginTop = this.customMargins_.top; |
51 'marginBottom': this.customMarginBottom_}; | 154 margins.marginRight = this.customMargins_.right; |
155 margins.marginBottom = this.customMargins_.bottom; | |
156 return margins; | |
52 }, | 157 }, |
53 | 158 |
54 /** | 159 /** |
55 * Gets the value of the selected margin option. | |
56 * @private | 160 * @private |
57 * @return {number} | 161 * @return {number} The value of the selected margin option. |
58 */ | 162 */ |
59 get selectedMarginsValue_() { | 163 get selectedMarginsValue_() { |
60 return this.marginList_.options[this.marginList_.selectedIndex].value; | 164 return this.marginList_.options[this.marginList_.selectedIndex].value; |
61 }, | 165 }, |
62 | 166 |
63 /** | 167 /** |
64 * Checks whether user has selected the Default Margins option or not. | 168 * @return {boolean} True if default margins are selected. |
65 * | |
66 * @return {boolean} true if default margins are selected. | |
67 */ | 169 */ |
68 isDefaultMarginsSelected: function() { | 170 isDefaultMarginsSelected: function() { |
69 return this.selectedMarginsValue_ == this.defaultMarginsValue_; | 171 return this.selectedMarginsValue_ == MarginSettings.MARGINS_VALUE_DEFAULT; |
70 }, | 172 }, |
71 | 173 |
72 /** | 174 /** |
73 * Adds listeners to all margin related controls. The listeners take care | 175 * @return {boolean} True if no margins are selected. |
74 * of altering their behavior depending on |hasPendingPreviewRequest|. | 176 */ |
177 isNoMarginsSelected: function() { | |
178 return this.selectedMarginsValue_ == | |
179 MarginSettings.MARGINS_VALUE_NO_MARGINS; | |
180 }, | |
181 | |
182 /** | |
183 * @return {boolean} True if custom margins are selected. | |
184 */ | |
185 isCustomMarginsSelected: function() { | |
186 return this.selectedMarginsValue_ == MarginSettings.MARGINS_VALUE_CUSTOM; | |
187 }, | |
188 | |
189 /** | |
190 * If the custom margin values have changed then request a new preview based | |
191 * on the newly set margins. | |
192 * @private | |
193 */ | |
194 requestPreviewIfNeeded_: function() { | |
195 if (this.customMargins_.isEqual(this.previousCustomMargins_)) | |
196 return; | |
197 this.previousCustomMargins_.copy(this.customMargins_); | |
198 setDefaultValuesAndRegeneratePreview(false); | |
199 }, | |
200 | |
201 /** | |
202 * Listener executed when the mouse is over the sidebar. If the custom | |
203 * margin lines are displayed, then, it fades them out. | |
204 * @private | |
205 */ | |
206 onSidebarMouseOver_: function(e) { | |
207 if (!this.forceDisplayingMarginLines_) | |
208 this.marginsUI.hide(); | |
209 }, | |
210 | |
211 /** | |
212 * Listener executed when the mouse is over the main view. If the custom | |
213 * margin lines are hidden, then, it fades them in. | |
214 * @private | |
215 */ | |
216 onMainviewMouseOver_: function() { | |
217 this.forceDisplayingMarginLines_ = false; | |
218 this.marginsUI.show(); | |
219 }, | |
220 | |
221 /** | |
222 * Adds listeners to all margin related controls. | |
75 */ | 223 */ |
76 addEventListeners: function() { | 224 addEventListeners: function() { |
77 this.marginList_.onchange = this.onMarginsChanged_.bind(this); | 225 this.marginList_.onchange = this.onMarginsChanged_.bind(this); |
78 document.addEventListener('PDFLoaded', this.onPDFLoaded_.bind(this)); | 226 document.addEventListener('PDFLoaded', this.onPDFLoaded_.bind(this)); |
79 }, | 227 }, |
80 | 228 |
81 /** | 229 /** |
230 * @return {boolean} True if the margin settings are valid. | |
231 */ | |
232 areMarginSettingsValid: function() { | |
233 if (this.marginsUI_ == null) | |
234 return true; | |
235 | |
236 var pairs = this.marginsUI.pairsAsList; | |
237 for (var i = 0; i < pairs.length; i++) { | |
238 if (!pairs[i].box_.isValid) | |
239 return false; | |
240 } | |
241 return true; | |
242 }, | |
243 | |
244 /** | |
245 * Calculates the maximum allowable value of the selected margin text for | |
246 * every margin. | |
247 * @private | |
248 * @return {array} The maximum allowable value in order top, left, right, | |
249 * bottom. | |
250 */ | |
251 getMarginValueLimits_: function() { | |
252 var marginValueLimits = []; | |
253 marginValueLimits[0] = this.pageHeight_ - this.customMargins_.bottom; | |
254 marginValueLimits[1] = this.pageWidth_ - this.customMargins_.right; | |
255 marginValueLimits[2] = this.pageWidth_ - this.customMargins_.left; | |
256 marginValueLimits[3] = this.pageHeight_ - this.customMargins_.top; | |
257 return marginValueLimits; | |
258 }, | |
259 | |
260 /** | |
261 * When the user stops typing in the margin text box a new print preview is | |
262 * requested, only if | |
263 * 1) The input is compeletely valid (it can be parsed in its entirety). | |
264 * 2) The newly selected margins differ from the previous selected margins. | |
265 * @param {cr.Event} event The change event holding information about what | |
266 * changed. | |
267 * @private | |
268 */ | |
269 onMarginTextValueMayHaveChanged_: function(event) { | |
270 var marginBox = event.target; | |
271 var marginBoxValue = marginBox.margin; | |
272 | |
273 marginBoxValue = MarginSettings.convertInchesToPoints(marginBoxValue); | |
274 this.customMargins_[marginBox.marginGroup] = marginBoxValue; | |
275 | |
276 if(!this.areMarginSettingsValid()) | |
277 return; | |
278 if (this.customMargins_.isEqual(this.previousCustomMargins_)) | |
279 return; | |
280 | |
281 this.requestPreviewIfNeeded_(); | |
282 }, | |
283 | |
284 /** | |
285 * @type {print_preview.MarginsUI} The object holding the UI for specifying | |
286 * custom margins. | |
287 */ | |
288 get marginsUI() { | |
289 if (this.marginsUI_ == null) { | |
Evan Stade
2011/10/05 22:42:14
!this.marginsUI
dpapad
2011/10/06 00:05:39
Done.
| |
290 this.marginsUI_ = new print_preview.MarginsUI($('mainview')); | |
291 this.marginsUI_.addObserver( | |
292 this.onMarginTextValueMayHaveChanged_.bind(this)); | |
293 } | |
294 return this.marginsUI_; | |
295 }, | |
296 | |
297 /** | |
298 * Adds listeners when the custom margins option is selected. | |
299 * @private | |
300 */ | |
301 addCustomMarginEventListeners_: function() { | |
302 $('mainview').onmouseover = this.onMainviewMouseOver_.bind(this); | |
303 $('sidebar').onmouseover = this.onSidebarMouseOver_.bind(this); | |
304 }, | |
305 | |
306 /** | |
307 * Removes the event listeners associated with the custom margins option. | |
308 * @private | |
309 */ | |
310 removeCustomMarginEventListeners_: function() { | |
311 $('mainview').onmouseover = null; | |
312 $('sidebar').onmouseover = null; | |
313 this.marginsUI.hide(); | |
314 }, | |
315 | |
316 /** | |
317 * Updates |this.marginsUI| depending on the specified margins and the | |
318 * position of the page within the plugin. | |
319 * @private | |
320 */ | |
321 drawCustomMarginsUI_: function() { | |
322 // TODO(dpapad): find out why passing |!this.areMarginsSettingsValid()| | |
323 // directly produces the opposite value even though | |
324 // |this.getMarginsRectangleInPercent_()| and | |
325 // |this.getMarginValueLimits_()| have no side effects. | |
326 var keepDisplayedValue = !this.areMarginSettingsValid(); | |
327 this.marginsUI.update(this.getMarginsRectangleInPercent_(), | |
328 this.customMargins_, | |
329 this.getMarginValueLimits_(), | |
330 keepDisplayedValue); | |
331 this.marginsUI.draw(); | |
332 }, | |
333 | |
334 /** | |
335 * Called when there is change in the preview position or size. | |
336 */ | |
337 onPreviewPositionChanged: function() { | |
338 if (this.isCustomMarginsSelected() && previewArea.pdfLoaded && | |
339 pageSettings.totalPageCount != undefined) { | |
340 this.drawCustomMarginsUI_(); | |
341 } | |
342 }, | |
343 | |
344 /** | |
82 * Listener executing when user selects a different margin option, ie, | 345 * Listener executing when user selects a different margin option, ie, |
83 * |this.marginList_| is changed. | 346 * |this.marginList_.selectedIndex| is changed. |
84 * @private | 347 * @private |
85 */ | 348 */ |
86 onMarginsChanged_: function() { | 349 onMarginsChanged_: function() { |
87 if (this.selectedMarginsValue_ == this.defaultMarginsValue_) { | 350 if (this.isDefaultMarginsSelected()) |
88 setDefaultValuesAndRegeneratePreview(false); | 351 this.onDefaultMarginsSelected_(); |
89 } else if (this.selectedMarginsValue_ == this.noMarginsValue_) { | 352 else if (this.isNoMarginsSelected()) |
90 this.customMarginLeft_ = 0; | 353 this.onNoMarginsSelected_(); |
91 this.customMarginTop_ = 0; | 354 else if (this.isCustomMarginsSelected()) |
92 this.customMarginRight_ = 0; | 355 this.onCustomMarginsSelected_(); |
93 this.customMarginBottom_ = 0; | 356 |
94 setDefaultValuesAndRegeneratePreview(false); | 357 this.lastSelectedOption_ = this.selectedMarginsValue_; |
95 } | 358 }, |
96 // TODO(aayushkumar): Add handler for custom margins | 359 |
360 /** | |
361 * Listener executing when the default margins option is selected. | |
Evan Stade
2011/10/05 22:42:14
nit: "Listener executing" sounds mildly awkward. M
dpapad
2011/10/06 00:05:39
Done.
| |
362 * @private | |
363 */ | |
364 onDefaultMarginsSelected_: function() { | |
365 this.removeCustomMarginEventListeners_(); | |
366 this.forceDisplayingMarginLines_ = true; | |
367 setDefaultValuesAndRegeneratePreview(false); | |
368 }, | |
369 | |
370 /** | |
371 * Listener executing when the no margins option is selected. | |
372 * @private | |
373 */ | |
374 onNoMarginsSelected_: function() { | |
375 this.removeCustomMarginEventListeners_(); | |
376 this.forceDisplayingMarginLines_ = true; | |
377 this.customMargins_ = new Margins(0, 0, 0, 0); | |
378 setDefaultValuesAndRegeneratePreview(false); | |
379 }, | |
380 | |
381 /** | |
382 * Listener executing when the custom margins option is selected. | |
383 * @private | |
384 */ | |
385 onCustomMarginsSelected_: function() { | |
386 this.addCustomMarginEventListeners_(); | |
387 | |
388 if (this.lastSelectedOption_ == MarginSettings.MARGINS_VALUE_DEFAULT) | |
389 this.customMargins_ = this.currentDefaultPageLayout.margins_; | |
390 this.previousCustomMargins_.copy(this.customMargins_); | |
391 | |
392 if (this.previousDefaultPageLayout_ != this.currentDefaultPageLayout) { | |
393 this.pageWidth_ = this.currentDefaultPageLayout.pageWidth; | |
394 this.pageHeight_ = this.currentDefaultPageLayout.pageHeight; | |
395 } | |
396 | |
397 this.previousDefaultPageLayout_ = this.currentDefaultPageLayout; | |
398 this.drawCustomMarginsUI_(); | |
399 this.marginsUI.show(); | |
400 }, | |
401 | |
402 /** | |
403 * Calculates the coordinates of the four margin lines. These are the | |
404 * coordinates where the margin lines should be displayed. The coordinates | |
405 * are expressed in terms of percentages with respect to the total width | |
406 * and height of the plugin. | |
407 * @private | |
408 * @return {print_preview.Rect} A rectnangle that describes the position of | |
409 * the four margin lines. | |
410 */ | |
411 getMarginsRectangleInPercent_: function() { | |
412 var pageLocation = previewArea.getPageLocationNormalized(); | |
413 var marginsInPercent = this.getMarginsInPercent_(); | |
414 var leftX = pageLocation.x + marginsInPercent.left; | |
415 var topY = pageLocation.y + marginsInPercent.top; | |
416 var contentWidth = pageLocation.width - (marginsInPercent.left + | |
417 marginsInPercent.right); | |
418 var contentHeight = pageLocation.height - (marginsInPercent.top + | |
419 marginsInPercent.bottom); | |
420 return new print_preview.Rect( | |
421 leftX, topY, contentWidth, contentHeight); | |
422 }, | |
423 | |
424 /** | |
425 * @private | |
Evan Stade
2011/10/05 22:42:14
I think private comes after return
dpapad
2011/10/06 00:05:39
Done, for files already in this CL.
| |
426 * @return {print_preview.Margins} The currently selected margin values | |
427 * normalized to the total width and height of the plugin. | |
428 */ | |
429 getMarginsInPercent_: function() { | |
430 var pageInformation = previewArea.getPageLocationNormalized(); | |
431 var totalWidthInPoints = this.pageWidth_ / pageInformation.width; | |
432 var totalHeightInPoints = this.pageHeight_ / pageInformation.height; | |
433 var marginsInPercent = new Margins( | |
434 this.customMargins_.left / totalWidthInPoints, | |
435 this.customMargins_.top / totalHeightInPoints, | |
436 this.customMargins_.right / totalWidthInPoints, | |
437 this.customMargins_.bottom / totalHeightInPoints); | |
438 return marginsInPercent; | |
97 }, | 439 }, |
98 | 440 |
99 /** | 441 /** |
100 * If custom margins is the currently selected option then change to the | 442 * If custom margins is the currently selected option then change to the |
101 * default margins option. | 443 * default margins option. |
444 * @private | |
102 */ | 445 */ |
103 resetMarginsIfNeeded: function() { | 446 resetMarginsIfNeeded: function() { |
104 if (this.selectedMarginsValue_ == this.customMarginsValue_) | 447 if (this.isCustomMarginsSelected()) { |
105 this.marginList_.options[this.defaultMarginsIndex_].selected = true; | 448 this.marginList_.options[ |
106 }, | 449 MarginSettings.DEFAULT_MARGINS_OPTION_INDEX].selected = true; |
107 | 450 this.removeCustomMarginEventListeners_(); |
108 /** | 451 this.lastSelectedOption_ = MarginSettings.MARGINS_VALUE_DEFAULT; |
452 } | |
453 }, | |
454 | |
455 /** | |
109 * Listener executing when a PDFLoaded event occurs. | 456 * Listener executing when a PDFLoaded event occurs. |
110 * @private | 457 * @private |
111 */ | 458 */ |
112 onPDFLoaded_: function() { | 459 onPDFLoaded_: function() { |
113 if (!previewModifiable) | 460 if (!previewModifiable) |
114 fadeOutElement(this.marginsOption_); | 461 fadeOutElement(this.marginsOption_); |
115 } | 462 } |
116 }; | 463 }; |
117 | 464 |
118 return { | 465 return { |
119 MarginSettings: MarginSettings, | 466 MarginSettings: MarginSettings, |
467 PageLayout: PageLayout, | |
120 }; | 468 }; |
121 }); | 469 }); |
OLD | NEW |