Chromium Code Reviews| Index: chrome/browser/resources/print_preview/margin_settings.js |
| diff --git a/chrome/browser/resources/print_preview/margin_settings.js b/chrome/browser/resources/print_preview/margin_settings.js |
| index f9d81a3053927d16cfb72ae8662cbff1d0e08e9f..bc5ba979072e82c55a0fa3dcb6a3f797c979a0d5 100644 |
| --- a/chrome/browser/resources/print_preview/margin_settings.js |
| +++ b/chrome/browser/resources/print_preview/margin_settings.js |
| @@ -6,6 +6,101 @@ cr.define('print_preview', function() { |
| 'use strict'; |
| /** |
| + * Creates a Margins object that holds the four margin values. |
| + * @constructor |
| + */ |
| + function Margins(left, top, right, bottom) { |
| + this.left = left; |
| + this.top = top; |
| + this.right = right; |
| + this.bottom = bottom; |
| + } |
| + |
| + Margins.prototype = { |
| + /** |
| + * Checks if the Margins object passed is equal to |this|. |
| + * @param {Margins} rhs The Margins object to compare against. |
| + * @return {boolean} true if they are equal. |
| + */ |
| + isEqual: function(rhs) { |
| + return this.top == rhs.top && |
|
Evan Stade
2011/10/04 02:49:18
use ===
dpapad
2011/10/04 20:41:21
Done.
|
| + this.left == rhs.left && |
| + this.right == rhs.right && |
| + this.bottom == rhs.bottom; |
| + }, |
| + |
| + /** |
| + * Copies the four margin values from |rhs|. |
| + * @param {Margins} rhs The Margins object values to be used. |
| + */ |
| + copy: function(rhs) { |
| + this.top = rhs.top; |
| + this.left = rhs.left; |
| + this.right = rhs.right; |
| + this.bottom = rhs.bottom; |
| + }, |
| + |
| + /** |
| + * Updates one of the members based on |marginGroupName| with |value|. |
| + * @param {string} marginGroupName The group name of the margin for which |
| + * the member variable has to be updated. |
| + */ |
| + update: function(marginGroupName, value) { |
| + if (marginGroupName == MarginSettings.TOP_GROUP_NAME) |
| + this.top = value; |
| + else if (marginGroupName == MarginSettings.LEFT_GROUP_NAME) |
| + this.left = value; |
| + else if (marginGroupName == MarginSettings.RIGHT_GROUP_NAME) |
| + this.right = value; |
| + else if (marginGroupName == MarginSettings.BOTTOM_GROUP_NAME) |
| + this.bottom = value; |
| + }, |
| + |
| + /** |
| + * Gets the value of the member variable based on |marginGroupName|. |
| + * @param {string} marginGroupName The group name of the margin for which |
| + * the member variable has to be retrieved. |
| + */ |
| + getValue: function(marginGroupName) { |
| + if (marginGroupName == MarginSettings.TOP_GROUP_NAME) |
| + return this.top; |
| + else if (marginGroupName == MarginSettings.LEFT_GROUP_NAME) |
| + return this.left; |
| + else if (marginGroupName == MarginSettings.RIGHT_GROUP_NAME) |
| + return this.right; |
| + else if (marginGroupName == MarginSettings.BOTTOM_GROUP_NAME) |
| + return this.bottom; |
| + } |
| + }; |
| + |
| + /** |
| + * @constructor |
| + * Class describing the layout of the page. |
| + */ |
| + function PageLayout(width, height, left, top, right, bottom) { |
| + this.contentWidth_ = width; |
| + this.contentHeight_ = height; |
| + this.margins_ = new Margins(left, top, right, bottom); |
| + } |
| + |
| + PageLayout.prototype = { |
| + /** |
| + * @type {number} The width of the page. |
| + */ |
| + get pageWidth() { |
| + return this.margins_.left + this.margins_.right + this.contentWidth_; |
| + }, |
| + |
| + /** |
| + * @type {number} The height of the page. |
| + */ |
| + get pageHeight() { |
| + return this.margins_.top + this.margins_.bottom + this.contentHeight_; |
| + } |
| + |
|
Evan Stade
2011/10/04 02:49:18
extra line
dpapad
2011/10/04 20:41:21
Done.
|
| + }; |
| + |
| + /** |
| * Creates a MarginSettings object. This object encapsulates all settings and |
| * logic related to the margins mode. |
| * @constructor |
| @@ -13,65 +108,144 @@ cr.define('print_preview', function() { |
| function MarginSettings() { |
| this.marginsOption_ = $('margins-option'); |
| this.marginList_ = $('margin-list'); |
| - // Holds the custom left margin value (if set). |
| - this.customMarginLeft_ = -1; |
| - // Holds the custom right margin value (if set). |
| - this.customMarginRight_ = -1; |
| - // Holds the custom top margin value (if set). |
| - this.customMarginTop_ = -1; |
| - // Holds the custom bottom margin value (if set). |
| - this.customMarginBottom_ = -1; |
| - // Margin list values. |
| - this.customMarginsValue_ = 2; |
| - this.defaultMarginsValue_ = 0; |
| - this.noMarginsValue_ = 1; |
| - // Default Margins option index. |
| - this.defaultMarginsIndex_ = 0; |
| + this.marginsUI_ = null; |
| + |
| + // Holds the custom margin values in points (if set). |
| + this.customMargins_ = new Margins(-1, -1, -1, -1); |
| + // Holds the previous custom margin values in points. |
| + this.previousCustomMargins_ = new Margins(-1, -1, -1, -1); |
| + // Holds the width of the page in points. |
| + this.pageWidth_ = -1; |
| + // Holds the height of the page in points. |
| + this.pageHeight_ = -1; |
| + // The last selected margin option. |
| + this.lastSelectedOption_ = MarginSettings.MARGINS_VALUE_DEFAULT; |
| + |
| + // Holds the currently updated default page layout values. |
| + this.currentDefaultPageLayout = null; |
| + // Holds the default page layout values when the custom margins was last |
| + // selected. |
| + this.previousDefaultPageLayout_ = null; |
| + |
| + // True if the margins UI should be shown regardless of mouse position. |
| + this.forceDisplayingMarginLines_ = true; |
| } |
| + // Number of points per inch. |
| + MarginSettings.POINTS_PER_INCH = 72; |
| + // Margin list values. |
| + MarginSettings.MARGINS_VALUE_CUSTOM = 2; |
|
Evan Stade
2011/10/04 02:49:18
order these by value, not alphabet
dpapad
2011/10/04 20:41:21
Done.
|
| + MarginSettings.MARGINS_VALUE_DEFAULT = 0; |
| + MarginSettings.MARGINS_VALUE_NO_MARGINS = 1; |
| + // Default Margins option index. |
| + MarginSettings.DEFAULT_MARGINS_OPTION_INDEX = 0; |
| + // Group name corresponding to the top margin. |
| + MarginSettings.TOP_GROUP_NAME = 'margin-top'; |
| + // Group name corresponding to the left margin. |
| + MarginSettings.LEFT_GROUP_NAME = 'margin-left'; |
| + // Group name corresponding to the right margin. |
| + MarginSettings.RIGHT_GROUP_NAME = 'margin-right'; |
| + // Group name corresponding to the bottom margin. |
| + MarginSettings.BOTTOM_GROUP_NAME = 'margin-bottom'; |
| + |
| + /** |
| + * Converts |value| from points to inches. |
| + * @param {number} value The number in points. |
| + * @return {number} |value| in inches. |
| + */ |
| + MarginSettings.convertPointsToInches = function(value) { |
| + return value / MarginSettings.POINTS_PER_INCH; |
| + }; |
| + |
| + /** |
| + * Converts |value| from inches to points. |
| + * @param {number} value The number in inches. |
| + * @return {number} |value| in points. |
| + */ |
| + MarginSettings.convertInchesToPoints = function(value) { |
| + return value * MarginSettings.POINTS_PER_INCH; |
| + }; |
| + |
| cr.addSingletonGetter(MarginSettings); |
| MarginSettings.prototype = { |
| /** |
| - * The selection list corresponding to the margins option. |
| - * @return {HTMLInputElement} |
| - */ |
| - get marginList() { |
| - return this.marginList_; |
| - }, |
| - |
| - /** |
| * Returns a dictionary of the four custom margin values. |
| * @return {object} |
| */ |
| get customMargins() { |
| - return {'marginLeft': this.customMarginLeft_, |
| - 'marginTop': this.customMarginTop_, |
| - 'marginRight': this.customMarginRight_, |
| - 'marginBottom': this.customMarginBottom_}; |
| + var margins = {}; |
| + margins.marginLeft = this.customMargins_.left; |
| + margins.marginTop = this.customMargins_.top; |
| + margins.marginRight = this.customMargins_.right; |
| + margins.marginBottom = this.customMargins_.bottom; |
| + return margins; |
| }, |
| /** |
| - * Gets the value of the selected margin option. |
| * @private |
| - * @return {number} |
| + * @return {number} The value of the selected margin option. |
| */ |
| get selectedMarginsValue_() { |
| return this.marginList_.options[this.marginList_.selectedIndex].value; |
| }, |
| /** |
| - * Checks whether user has selected the Default Margins option or not. |
| - * |
| - * @return {boolean} true if default margins are selected. |
| + * @return {boolean} True if default margins are selected. |
| */ |
| isDefaultMarginsSelected: function() { |
| - return this.selectedMarginsValue_ == this.defaultMarginsValue_; |
| + return this.selectedMarginsValue_ == MarginSettings.MARGINS_VALUE_DEFAULT; |
| + }, |
| + |
| + /** |
| + * @return {boolean} True if no margins are selected. |
| + */ |
| + isNoMarginsSelected: function() { |
| + return this.selectedMarginsValue_ == |
| + MarginSettings.MARGINS_VALUE_NO_MARGINS; |
| + }, |
| + |
| + /** |
| + * @return {boolean} True if custom margins are selected. |
| + */ |
| + isCustomMarginsSelected: function() { |
| + return this.selectedMarginsValue_ == MarginSettings.MARGINS_VALUE_CUSTOM; |
| + }, |
| + |
| + /** |
| + * If the custom margin values have changed then request a new preview based |
| + * on the newly set margins. |
| + * @private |
| + */ |
| + requestPreviewIfNeeded_: function() { |
| + if (this.customMargins_.isEqual(this.previousCustomMargins_)) |
| + return; |
| + this.previousCustomMargins_.copy(this.customMargins_); |
| + setDefaultValuesAndRegeneratePreview(false); |
| + }, |
| + |
| + /** |
| + * Listener executed when the mouse is over the sidebar. If the custom |
| + * margin lines are displayed, then, it fades them out. |
| + * @private |
| + */ |
| + onSidebarMouseOver_: function(e) { |
| + if (!this.forceDisplayingMarginLines_) |
| + this.marginsUI.hide(); |
| + }, |
| + |
| + /** |
| + * Listener executed when the mouse is over the main view. If the custom |
| + * margin lines are hidden, then, it fades them in. |
| + * @private |
| + */ |
| + onMainviewMouseOver_: function() { |
| + this.forceDisplayingMarginLines_ = false; |
| + this.marginsUI.show(); |
| }, |
| /** |
| - * Adds listeners to all margin related controls. The listeners take care |
| - * of altering their behavior depending on |hasPendingPreviewRequest|. |
| + * Adds listeners to all margin related controls. |
| */ |
| addEventListeners: function() { |
| this.marginList_.onchange = this.onMarginsChanged_.bind(this); |
| @@ -79,30 +253,230 @@ cr.define('print_preview', function() { |
| }, |
| /** |
| + * @return {boolean} True if the margin settings are valid. |
| + */ |
| + areMarginSettingsValid: function() { |
| + if (this.marginsUI_ == null) |
| + return true; |
| + |
| + var pairs = this.marginsUI.pairsAsList; |
| + for (var i = 0; i < pairs.length; i++) { |
| + if (!pairs[i].box_.isValid) |
| + return false; |
| + } |
| + return true; |
| + }, |
| + |
| + /** |
| + * Calculates the maximum allowable value of the selected margin text for |
| + * every margin. |
| + * @private |
| + * @return {array} The maximum allowable value in order top, left, right, |
| + * bottom. |
| + */ |
| + getMarginValueLimits_: function() { |
| + var marginValueLimits = []; |
| + marginValueLimits[0] = this.pageHeight_ - this.customMargins_.bottom; |
| + marginValueLimits[1] = this.pageWidth_ - this.customMargins_.right; |
| + marginValueLimits[2] = this.pageWidth_ - this.customMargins_.left; |
| + marginValueLimits[3] = this.pageHeight_ - this.customMargins_.top; |
| + return marginValueLimits; |
| + }, |
| + |
| + /** |
| + * When the user stops typing in the margin text box a new print preview is |
| + * requested, only if |
| + * 1) The input is compeletely valid (it can be parsed in its entirety). |
| + * 2) The newly selected margins differ from the previous selected margins. |
| + * @param {cr.Event} event The change event holding information about what |
| + * changed. |
| + * @private |
| + */ |
| + onMarginTextValueMayHaveChanged_: function(event) { |
| + var marginBox = event.target; |
| + var marginGroupName = marginBox.getAttribute('margin-group'); |
| + var marginBoxValue = marginBox.margin; |
| + |
| + marginBoxValue = MarginSettings.convertInchesToPoints(marginBoxValue); |
| + this.customMargins_.update(marginGroupName, marginBoxValue); |
| + |
| + if(!this.areMarginSettingsValid()) |
| + return; |
| + if (this.customMargins_.isEqual(this.previousCustomMargins_)) |
| + return; |
| + |
| + this.requestPreviewIfNeeded_(); |
| + }, |
| + |
| + /** |
| + * @type {print_preview.MarginsUI} The object holding the UI for specifying |
| + * custom margins. |
| + */ |
| + get marginsUI() { |
| + if (this.marginsUI_ == null) { |
| + this.marginsUI_ = new print_preview.MarginsUI($('mainview')); |
| + this.marginsUI_.addObserver( |
| + this.onMarginTextValueMayHaveChanged_.bind(this)); |
| + } |
| + return this.marginsUI_; |
| + }, |
| + |
| + /** |
| + * Adds listeners when the custom margins option is selected. |
| + * @private |
| + */ |
| + addCustomMarginEventListeners_: function() { |
| + $('mainview').onmouseover = this.onMainviewMouseOver_.bind(this); |
| + $('sidebar').onmouseover = this.onSidebarMouseOver_.bind(this); |
| + }, |
| + |
| + /** |
| + * Removes the event listeners associated with the custom margins option. |
| + * @private |
| + */ |
| + removeCustomMarginEventListeners_: function() { |
| + $('mainview').onmouseover = null; |
| + $('sidebar').onmouseover = null; |
| + this.marginsUI.hide(); |
| + }, |
| + |
| + /** |
| + * Updates |this.marginsUI| depending on the specified margins and the |
| + * position of the page within the plugin. |
| + * @private |
| + */ |
| + drawCustomMarginsUI_: function() { |
| + // TODO(dpapad): find out why passing |!this.areMarginsSettingsValid()| |
| + // directly produces the opposite value even though |
| + // |this.getMarginsRectangleInPercent_()| and |
| + // |this.getMarginValueLimits_()| have no side effects. |
| + var keepDisplayedValue = !this.areMarginSettingsValid(); |
| + this.marginsUI.update(this.getMarginsRectangleInPercent_(), |
| + this.customMargins_, |
| + this.getMarginValueLimits_(), |
| + keepDisplayedValue); |
| + this.marginsUI.draw(); |
| + }, |
| + |
| + /** |
| + * Called when there is change in the preview position or size. |
| + */ |
| + onPreviewPositionChanged: function() { |
| + if (this.isCustomMarginsSelected() && previewArea.pdfLoaded && |
| + pageSettings.totalPageCount != undefined) { |
| + this.drawCustomMarginsUI_(); |
| + } |
| + }, |
| + |
| + /** |
| * Listener executing when user selects a different margin option, ie, |
| - * |this.marginList_| is changed. |
| + * |this.marginList_.selectedIndex| is changed. |
| * @private |
| */ |
| onMarginsChanged_: function() { |
| - if (this.selectedMarginsValue_ == this.defaultMarginsValue_) { |
| - setDefaultValuesAndRegeneratePreview(false); |
| - } else if (this.selectedMarginsValue_ == this.noMarginsValue_) { |
| - this.customMarginLeft_ = 0; |
| - this.customMarginTop_ = 0; |
| - this.customMarginRight_ = 0; |
| - this.customMarginBottom_ = 0; |
| - setDefaultValuesAndRegeneratePreview(false); |
| + if (this.isDefaultMarginsSelected()) |
| + this.onDefaultMarginsSelected_(); |
| + else if (this.isNoMarginsSelected()) |
| + this.onNoMarginsSelected_(); |
| + else if (this.isCustomMarginsSelected()) |
| + this.onCustomMarginsSelected_(); |
| + |
| + this.lastSelectedOption_ = this.selectedMarginsValue_; |
| + }, |
| + |
| + /** |
| + * Listener executing when the default margins option is selected. |
| + * @private |
| + */ |
| + onDefaultMarginsSelected_: function() { |
| + this.removeCustomMarginEventListeners_(); |
| + this.forceDisplayingMarginLines_ = true; |
| + setDefaultValuesAndRegeneratePreview(false); |
| + }, |
| + |
| + /** |
| + * Listener executing when the no margins option is selected. |
| + * @private |
| + */ |
| + onNoMarginsSelected_: function() { |
| + this.removeCustomMarginEventListeners_(); |
| + this.forceDisplayingMarginLines_ = true; |
| + this.customMargins_ = new Margins(0, 0, 0, 0); |
| + setDefaultValuesAndRegeneratePreview(false); |
| + }, |
| + |
| + /** |
| + * Listener executing when the custom margins option is selected. |
| + * @private |
| + */ |
| + onCustomMarginsSelected_: function() { |
| + this.addCustomMarginEventListeners_(); |
| + |
| + if (this.lastSelectedOption_ == MarginSettings.MARGINS_VALUE_DEFAULT) |
| + this.customMargins_ = this.currentDefaultPageLayout.margins_; |
| + this.previousCustomMargins_.copy(this.customMargins_); |
| + |
| + if (this.previousDefaultPageLayout_ != this.currentDefaultPageLayout) { |
| + this.pageWidth_ = this.currentDefaultPageLayout.pageWidth; |
| + this.pageHeight_ = this.currentDefaultPageLayout.pageHeight; |
| } |
| - // TODO(aayushkumar): Add handler for custom margins |
| + |
| + this.previousDefaultPageLayout_ = this.currentDefaultPageLayout; |
| + this.drawCustomMarginsUI_(); |
| + this.marginsUI.show(); |
| + }, |
| + |
| + /** |
| + * Calculates the coordinates of the four margin lines. These are the |
| + * coordinates where the margin lines should be displayed. The coordinates |
| + * are expressed in terms of percentages with respect to the total width |
| + * and height of the plugin. |
| + * @private |
| + * @return {print_preview.Rect} A rectnangle that describes the position of |
| + * the four margin lines. |
| + */ |
| + getMarginsRectangleInPercent_: function() { |
| + var pageLocation = previewArea.getPageLocationNormalized(); |
| + var marginsInPercent = this.getMarginsInPercent_(); |
| + var leftX = pageLocation.x + marginsInPercent.left; |
| + var topY = pageLocation.y + marginsInPercent.top; |
| + var contentWidth = pageLocation.width - (marginsInPercent.left + |
| + marginsInPercent.right); |
| + var contentHeight = pageLocation.height - (marginsInPercent.top + |
| + marginsInPercent.bottom); |
| + return new print_preview.Rect( |
| + leftX, topY, contentWidth, contentHeight); |
| + }, |
| + |
| + /** |
| + * @private |
| + * @return {print_preview.Margins} The currently selected margin values |
| + * normalized to the total width and height of the plugin. |
| + */ |
| + getMarginsInPercent_: function() { |
| + var pageInformation = previewArea.getPageLocationNormalized(); |
| + var totalWidthInPoints = this.pageWidth_ / pageInformation.width; |
| + var totalHeightInPoints = this.pageHeight_ / pageInformation.height; |
| + var marginsInPercent = new Margins( |
| + this.customMargins_.left / totalWidthInPoints, |
| + this.customMargins_.top / totalHeightInPoints, |
| + this.customMargins_.right / totalWidthInPoints, |
| + this.customMargins_.bottom / totalHeightInPoints); |
| + return marginsInPercent; |
| }, |
| /** |
| * If custom margins is the currently selected option then change to the |
| * default margins option. |
| + * @private |
| */ |
| resetMarginsIfNeeded: function() { |
| - if (this.selectedMarginsValue_ == this.customMarginsValue_) |
| - this.marginList_.options[this.defaultMarginsIndex_].selected = true; |
| + if (this.isCustomMarginsSelected()) { |
| + this.marginList_.options[ |
| + MarginSettings.DEFAULT_MARGINS_OPTION_INDEX].selected = true; |
| + this.removeCustomMarginEventListeners_(); |
| + this.lastSelectedOption_ = MarginSettings.MARGINS_VALUE_DEFAULT; |
| + } |
| }, |
| /** |
| @@ -117,5 +491,6 @@ cr.define('print_preview', function() { |
| return { |
| MarginSettings: MarginSettings, |
| + PageLayout: PageLayout, |
| }; |
| }); |