Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: chrome/browser/resources/print_preview/margin_settings.js

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

Powered by Google App Engine
This is Rietveld 408576698