Index: chrome/browser/resources/print_preview/previewarea/margins_ui.js |
diff --git a/chrome/browser/resources/print_preview/margin_settings.js b/chrome/browser/resources/print_preview/previewarea/margins_ui.js |
similarity index 54% |
rename from chrome/browser/resources/print_preview/margin_settings.js |
rename to chrome/browser/resources/print_preview/previewarea/margins_ui.js |
index 0ffca9f9e8858b05123d023c422d4ed555481e94..17c59ad6e74a919d5fdafbad00e31162e7054e39 100644 |
--- a/chrome/browser/resources/print_preview/margin_settings.js |
+++ b/chrome/browser/resources/print_preview/previewarea/margins_ui.js |
@@ -5,319 +5,205 @@ |
cr.define('print_preview', function() { |
'use strict'; |
- /** |
- * Creates a Margins object that holds four margin values. The units in which |
- * the values are expressed can be any numeric value. |
- * @constructor |
- * @param {number} left The left margin. |
- * @param {number} top The top margin. |
- * @param {number} right The right margin. |
- * @param {number} bottom The bottom margin. |
- */ |
- function Margins(left, top, right, bottom) { |
- this[MarginSettings.LEFT_GROUP] = left; |
- this[MarginSettings.TOP_GROUP] = top; |
- this[MarginSettings.RIGHT_GROUP] = right; |
- this[MarginSettings.BOTTOM_GROUP] = bottom; |
- } |
- |
- /** |
- * Rounds |value| keeping |precision| decimal numbers. Example: 32.76643 |
- * becomes 32.77. |
- * @param {number} value The number to round. |
- * @param {number} precision The desired precision. |
- * @return {number} The rounded number. |
- */ |
- Margins.roundToPrecision = function(value, precision) { |
- return Math.round(value * Math.pow(10, precision)) / |
- Math.pow(10, precision); |
- }; |
- |
- Margins.prototype = { |
- /** |
- * Checks if |rhs| is equal to |this|. |
- * @param {Margins} rhs The Margins object to compare against. |
- * @return {boolean} true if they are equal. |
- */ |
- isEqual: function(rhs) { |
- if (!rhs) |
- return false; |
- return this[MarginSettings.TOP_GROUP] === rhs[MarginSettings.TOP_GROUP] && |
- this[MarginSettings.LEFT_GROUP] === rhs[MarginSettings.LEFT_GROUP] && |
- this[MarginSettings.RIGHT_GROUP] === |
- rhs[MarginSettings.RIGHT_GROUP] && |
- this[MarginSettings.BOTTOM_GROUP] === |
- rhs[MarginSettings.BOTTOM_GROUP]; |
- }, |
- |
- clone: function() { |
- return new Margins(this[MarginSettings.LEFT_GROUP], |
- this[MarginSettings.TOP_GROUP], |
- this[MarginSettings.RIGHT_GROUP], |
- this[MarginSettings.BOTTOM_GROUP]); |
- }, |
- |
- /** |
- * Helper method returning an array of the string indices used for accessing |
- * all margins. |
- * @return {array} An array of string indices. |
- * @private |
- */ |
- indicesAsArray_: function() { |
- return [MarginSettings.LEFT_GROUP, MarginSettings.TOP_GROUP, |
- MarginSettings.RIGHT_GROUP, MarginSettings.BOTTOM_GROUP]; |
- }, |
- |
- /** |
- * Rounds |this| based on the precision used when displaying the margins in |
- * the user's prefered units. This is done by converting from points to |
- * those units (mm/inches) and back to points. |
- */ |
- roundToLocaleUnits: function() { |
- var indicesAsArray = this.indicesAsArray_(); |
- for (var i = 0; i < indicesAsArray.length; i++) { |
- this[indicesAsArray[i]] = |
- print_preview.convertPointsToLocaleUnitsAndBack( |
- this[indicesAsArray[i]]); |
- } |
- } |
- }; |
- |
- /** |
- * @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); |
- this.margins_.roundToLocaleUnits(); |
- } |
- |
- 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_; |
- } |
- }; |
- |
- /** |
- * Creates a MarginSettings object. This object encapsulates all settings and |
- * logic related to the margins mode. |
- * @constructor |
- */ |
- function MarginSettings() { |
- this.marginsOption_ = $('margins-option'); |
- this.marginList_ = $('margin-list'); |
- this.marginsUI_ = null; |
- |
- // Holds the custom margin values in points (if set). |
- this.customMargins_ = null; |
- // Holds the previous custom margin values in points. |
- this.previousCustomMargins_ = null; |
- // Holds the width of the page in points. |
- this.pageWidth_ = -1; |
- // Holds the height of the page in points. |
- this.pageHeight_ = -1; |
- // @type {boolean} True if the margins UI should be diplayed when the next |
- // |customEvents.PDF_LOADED| event occurs. |
- this.forceMarginsUIOnPDFLoad_ = false; |
- // Holds the currently updated default page layout values. |
- this.currentDefaultPageLayout = null; |
- |
- // True if the margins UI should be shown regardless of mouse position. |
- this.forceDisplayingMarginLines_ = true; |
+ function MarginsUI() { |
+ var marginsUI = document.createElement('div'); |
+ marginsUI.__proto__ = MarginsUI.prototype; |
+ marginsUI.id = 'customized-margins'; |
+ |
+ // @type {print_preview.MarginsUIPair} The object corresponding to the top |
+ // margin. |
+ marginsUI.topPair_ = new print_preview.MarginsUIPair( |
+ print_preview.MarginSettings.TOP_GROUP); |
+ // @type {print_preview.MarginsUIPair} The object corresponding to the left |
+ // margin. |
+ marginsUI.leftPair_ = new print_preview.MarginsUIPair( |
+ print_preview.MarginSettings.LEFT_GROUP); |
+ // @type {print_preview.MarginsUIPair} The object corresponding to the right |
+ // margin. |
+ marginsUI.rightPair_ = new print_preview.MarginsUIPair( |
+ print_preview.MarginSettings.RIGHT_GROUP); |
+ // @type {print_preview.MarginsUIPair} The object corresponding to the |
+ // bottom margin. |
+ marginsUI.bottomPair_ = new print_preview.MarginsUIPair( |
+ print_preview.MarginSettings.BOTTOM_GROUP); |
+ |
+ var uiPairs = marginsUI.pairsAsList; |
+ for (var i = 0; i < uiPairs.length; i++) |
+ marginsUI.appendChild(uiPairs[i]); |
+ |
+ // @type {print_preview.MarginsUIPair} The object that is being dragged. |
+ // null if no drag session is in progress. |
+ marginsUI.lastClickedMarginsUIPair = null; |
// @type {EventTracker} Used to keep track of certain event listeners. |
- this.eventTracker_ = new EventTracker(); |
+ marginsUI.eventTracker_ = new EventTracker(); |
- this.addEventListeners_(); |
+ marginsUI.addEventListeners_(); |
+ return marginsUI; |
} |
- // Number of points per inch. |
- MarginSettings.POINTS_PER_INCH = 72; |
- // Minimum allowed distance in points between top-bottom, left-right margins. |
- MarginSettings.MINIMUM_MARGINS_DISTANCE = 36; |
- // Margin list values. Matches enum MarginType in |
- // printing/print_job_constants.h. |
- MarginSettings.MARGINS_VALUE_DEFAULT = 0; |
- MarginSettings.MARGINS_VALUE_NO_MARGINS = 1; |
- MarginSettings.MARGINS_VALUE_MINIMUM = 2; |
- MarginSettings.MARGINS_VALUE_CUSTOM = 3; |
- // Default Margins option index. |
- MarginSettings.OPTION_INDEX_DEFAULT = 0; |
- // Group name corresponding to the top margin. |
- MarginSettings.TOP_GROUP = 'top'; |
- // Group name corresponding to the left margin. |
- MarginSettings.LEFT_GROUP = 'left'; |
- // Group name corresponding to the right margin. |
- MarginSettings.RIGHT_GROUP = 'right'; |
- // Group name corresponding to the bottom margin. |
- MarginSettings.BOTTOM_GROUP = 'bottom'; |
- |
/** |
- * Extracts the number formatting and measurement system for the current |
- * locale. |
- * @param {string} numberFormat Is the formatted version of a sample number |
- * sent from the backend. |
- * @param {number} measurementSystem 0 for SI (aka metric system), 1 for the |
- * system used in the US. Note: Mathces UMeasurementSystem enum in |
- * third_party/icu/public/i18n/unicode/ulocdata.h. |
+ * @param {{x: number, y: number}} point The point with respect to the top |
+ * left corner of the webpage. |
+ * @return {{x: number, y: number}} The point with respect to the top left |
+ * corner of the plugin area. |
*/ |
- MarginSettings.setNumberFormatAndMeasurementSystem = function( |
- numberFormat, measurementSystem) { |
- var symbols = parseNumberFormat(numberFormat); |
- MarginSettings.thousandsPoint = symbols[0]; |
- MarginSettings.decimalPoint = symbols[1]; |
- MarginSettings.useMetricSystem = measurementSystem == 0; |
- }; |
+ MarginsUI.convert = function(point) { |
+ var mainview = $('mainview'); |
+ return { x: point.x - mainview.offsetLeft, |
+ y: point.y - mainview.offsetTop }; |
+ } |
- cr.addSingletonGetter(MarginSettings); |
+ MarginsUI.prototype = { |
+ __proto__: HTMLDivElement.prototype, |
- MarginSettings.prototype = { |
/** |
- * Returns a dictionary containing the four custom margin values. |
- * @return {{marginLeft: number, marginTop: number, marginRight: number, |
- * marginBottom: number}} The dictionary. |
+ * Adds an observer for |customEvents.MARGINS_MAY_HAVE_CHANGED| event. |
+ * @param {function} func A callback function to be called when |
+ * |customEvents.MARGINS_MAY_HAVE_CHANGED| event occurs. |
*/ |
- get customMargins() { |
- var margins = {}; |
- margins.marginLeft = this.customMargins_.left; |
- margins.marginTop = this.customMargins_.top; |
- margins.marginRight = this.customMargins_.right; |
- margins.marginBottom = this.customMargins_.bottom; |
- return margins; |
+ addObserver: function(func) { |
+ var uiPairs = this.pairsAsList; |
+ for (var i = 0; i < uiPairs.length; i++) { |
+ uiPairs[i].box_.addEventListener( |
+ customEvents.MARGINS_MAY_HAVE_CHANGED, func); |
+ } |
}, |
/** |
- * Sets |this.customMargins_| according to |margins|. |
- * @param {{marginLeft: number, marginTop: number, marginRight: number, |
- * marginBottom: number}} margins An object holding the four margin |
- * values. |
+ * @return {array} An array including all |MarginUIPair| objects. |
*/ |
- set customMargins(margins) { |
- this.customMargins_.left = margins.marginLeft; |
- this.customMargins_.top = margins.marginTop; |
- this.customMargins_.right = margins.marginRight; |
- this.customMargins_.bottom = margins.marginBottom; |
+ get pairsAsList() { |
+ return [this.topPair_, this.leftPair_, this.rightPair_, this.bottomPair_]; |
}, |
/** |
- * @return {number} The value of the selected margin option. |
+ * Updates the state of the margins UI. |
+ * @param {print_preview.Rect} marginsRectangle A rectangle describing the |
+ * four margins. |
+ * @param {Margins} marginValues The margin values in points. |
+ * @param {Array.<number>} valueLimits The maximum allowed margins for each |
+ * side in points. |
+ * @param {boolean} keepDisplayedValue True if the currently displayed |
+ * margin values should not be updated. |
+ * @param {Array.<number>} valueLimitsInPercent The maximum allowed margins |
+ * for each side in percentages. |
*/ |
- get selectedMarginsValue() { |
- var val = this.marginList_.options[this.marginList_.selectedIndex].value; |
- return parseInt(val, 10); |
+ update: function(marginsRectangle, marginValues, valueLimits, |
+ keepDisplayedValue, valueLimitsInPercent) { |
+ var uiPairs = this.pairsAsList; |
+ var order = ['top', 'left', 'right', 'bottom']; |
+ for (var i = 0; i < uiPairs.length; i++) { |
+ uiPairs[i].update(marginsRectangle, |
+ marginValues[order[i]], |
+ valueLimits[i], |
+ keepDisplayedValue, |
+ valueLimitsInPercent[i]); |
+ } |
}, |
/** |
- * Sets the current margin selection to |lastUsedMarginType|. |
- * @param {number} lastUsedMarginType An integer value identifying a margin |
- * type according to MarginType enum in printing/print_job_constants.h. |
- * @param {Object} lastUsedCustomMargins The last used custom margins. If |
- * custom margins have not been used before |
- * |margin{Top|Bottom|Left|Right}| attributes are missing. |
+ * Draws |this| based on the latest state. |
*/ |
- setLastUsedMargins: function(lastUsedMarginsSettings) { |
- var lastUsedMarginsType = lastUsedMarginsSettings['marginsType']; |
- this.forceMarginsUIOnPDFLoad_ = |
- lastUsedMarginsType == MarginSettings.MARGINS_VALUE_CUSTOM; |
- this.marginList_.selectedIndex = |
- this.getMarginOptionIndexByValue_(lastUsedMarginsType); |
- if (lastUsedMarginsSettings.hasOwnProperty('marginTop') && |
- lastUsedMarginsSettings.hasOwnProperty('marginBottom') && |
- lastUsedMarginsSettings.hasOwnProperty('marginRight') && |
- lastUsedMarginsSettings.hasOwnProperty('marginLeft')) { |
- this.customMargins_ = new Margins(-1, -1, -1 , -1); |
- this.customMargins = lastUsedMarginsSettings; |
- } |
+ draw: function() { |
+ this.applyClippingMask_(); |
+ this.pairsAsList.forEach(function(pair) { pair.draw(); }); |
}, |
/** |
- * @return {number} The total width of the plugin in points. |
+ * Shows the margins UI. |
*/ |
- get totalWidthInPoints() { |
- var pageInformation = previewArea.pageLocationNormalized; |
- return this.pageWidth_ / pageInformation.width; |
+ show: function() { |
+ this.hidden = false; |
+ this.classList.remove('invisible'); |
}, |
/** |
- * @return {number} The total height of the plugin in points. |
+ * Hides the margins UI and removes from the rendering flow if requested. |
+ * @param {boolean} removeFromFlow True if |this| should also be removed |
+ * from the rendering flow (in order to not interfere with the tab |
+ * order). |
*/ |
- get totalHeightInPoints() { |
- var pageInformation = previewArea.pageLocationNormalized; |
- return this.pageHeight_ / pageInformation.height; |
+ hide: function(removeFromFlow) { |
+ removeFromFlow ? this.hidden = true : this.classList.add('invisible'); |
}, |
/** |
- * Maps margin type values to indices within |this.marginList_|. |
- * @param {number} marginTypeValue An integer value identifying a margin |
- * type according to MarginType enum in printing/print_job_constants.h. |
- * @return {number} The index within |this.marginList_| that corrsponds to |
- * |marginTypeValue|. |
- * @private |
+ * Applies a clipping mask on |this| so that it does not paint on top of the |
+ * scrollbars (if any). |
*/ |
- getMarginOptionIndexByValue_: function(marginTypeValue) { |
- var options = this.marginList_.options; |
- for (var i = 0; i < options.length; i++) { |
- if (options[i].getAttribute('value') == marginTypeValue) |
- return i; |
- } |
- return MarginSettings.OPTION_INDEX_DEFAULT; |
+ applyClippingMask_: function() { |
+ var bottom = previewArea.height; |
+ var right = previewArea.width; |
+ this.style.clip = 'rect(0, ' + right + 'px, ' + bottom + 'px, 0)'; |
}, |
/** |
- * @return {boolean} True if default margins are selected. |
+ * Adds event listeners for various events. |
+ * @private |
*/ |
- isDefaultMarginsSelected: function() { |
- return this.selectedMarginsValue == MarginSettings.MARGINS_VALUE_DEFAULT; |
+ addEventListeners_: function() { |
+ var uiPairs = this.pairsAsList; |
+ for (var i = 0; i < uiPairs.length; i++) { |
+ uiPairs[i].addEventListener(customEvents.MARGIN_LINE_MOUSE_DOWN, |
+ this.onMarginLineMouseDown.bind(this)); |
+ } |
+ // After snapping to min/max the MarginUIPair might not receive the |
+ // mouseup event since it is not under the mouse pointer, so it is handled |
+ // here. |
+ window.document.addEventListener('mouseup', |
+ this.onMarginLineMouseUp.bind(this)); |
}, |
/** |
- * @return {boolean} True if no margins are selected. |
+ * Executes when a "MarginLineMouseDown" event occurs. |
+ * @param {cr.Event} e The event that triggered this listener. |
*/ |
- isNoMarginsSelected: function() { |
- return this.selectedMarginsValue == |
- MarginSettings.MARGINS_VALUE_NO_MARGINS; |
+ onMarginLineMouseDown: function(e) { |
+ this.lastClickedMarginsUIPair = e.target; |
+ this.bringToFront(this.lastClickedMarginsUIPair); |
+ // Note: Capturing mouse events at a higher level in the DOM than |this|, |
+ // so that the plugin can still receive mouse events. |
+ this.eventTracker_.add( |
+ window.document, 'mousemove', this.onMouseMove_.bind(this), false); |
}, |
/** |
- * @return {boolean} True if custom margins are selected. |
+ * Executes when a "MarginLineMouseUp" event occurs. |
+ * @param {cr.Event} e The event that triggered this listener. |
*/ |
- isCustomMarginsSelected: function() { |
- return this.selectedMarginsValue == MarginSettings.MARGINS_VALUE_CUSTOM; |
+ onMarginLineMouseUp: function(e) { |
+ if (this.lastClickedMarginsUIPair == null) |
+ return; |
+ this.lastClickedMarginsUIPair.onMouseUp(); |
+ this.lastClickedMarginsUIPair = null; |
+ this.eventTracker_.remove(window.document, 'mousemove'); |
}, |
/** |
- * @return {boolean} True if minimum margins are selected. |
+ * Brings |uiPair| in front of the other pairs. Used to make sure that the |
+ * dragged pair is visible when overlapping with a not dragged pair. |
+ * @param {print_preview.MarginsUIPair} uiPair The pair to bring in front. |
*/ |
- isMinimumMarginsSelected: function() { |
- return this.selectedMarginsValue == MarginSettings.MARGINS_VALUE_MINIMUM; |
+ bringToFront: function(uiPair) { |
+ this.pairsAsList.forEach(function(pair) { |
+ pair.classList.remove('dragging'); |
+ }); |
+ uiPair.classList.add('dragging'); |
}, |
/** |
- * If the custom margin values have changed then request a new preview based |
- * on the newly set margins. |
- * @private |
+ * Executes when a mousemove event occurs. |
+ * @param {MouseEvent} e The event that triggered this listener. |
*/ |
- requestPreviewIfNeeded_: function() { |
- if (!this.areMarginSettingsValid()) |
- return; |
- |
- if (this.customMargins_.isEqual(this.previousCustomMargins_)) |
- return; |
+ onMouseMove_: function(e) { |
+ var point = MarginsUI.convert({ x: e.x, y: e.y }); |
- this.previousCustomMargins_ = this.customMargins_.clone(); |
- setDefaultValuesAndRegeneratePreview(false); |
+ var dragEvent = new cr.Event(customEvents.MARGIN_LINE_DRAG); |
+ dragEvent.dragDelta = |
+ this.lastClickedMarginsUIPair.getDragDisplacementFrom(point); |
+ dragEvent.destinationPoint = point; |
+ this.dispatchEvent(dragEvent); |
}, |
/** |
@@ -345,18 +231,6 @@ cr.define('print_preview', function() { |
}, |
/** |
- * Adds listeners to all margin related controls. |
- * @private |
- */ |
- addEventListeners_: function() { |
- this.marginList_.onchange = this.onMarginsChanged_.bind(this); |
- document.addEventListener(customEvents.PDF_LOADED, |
- this.onPDFLoaded_.bind(this)); |
- document.addEventListener(customEvents.PDF_GENERATION_ERROR, |
- this.onPDFGenerationError_.bind(this)); |
- }, |
- |
- /** |
* Executes when a |customEvents.PDF_GENERATION_ERROR| event occurs. |
* @private |
*/ |
@@ -413,13 +287,13 @@ cr.define('print_preview', function() { |
getMarginValueLimits_: function() { |
var marginValueLimits = []; |
marginValueLimits[0] = this.pageHeight_ - this.customMargins_.bottom - |
- MarginSettings.MINIMUM_MARGINS_DISTANCE; |
+ MarginSettings.MINIMUM_MARGINS_DISTANCE_; |
marginValueLimits[1] = this.pageWidth_ - this.customMargins_.right - |
- MarginSettings.MINIMUM_MARGINS_DISTANCE; |
+ MarginSettings.MINIMUM_MARGINS_DISTANCE_; |
marginValueLimits[2] = this.pageWidth_ - this.customMargins_.left - |
- MarginSettings.MINIMUM_MARGINS_DISTANCE; |
+ MarginSettings.MINIMUM_MARGINS_DISTANCE_; |
marginValueLimits[3] = this.pageHeight_ - this.customMargins_.top - |
- MarginSettings.MINIMUM_MARGINS_DISTANCE; |
+ MarginSettings.MINIMUM_MARGINS_DISTANCE_; |
for (var i = 0; i < marginValueLimits.length; i++) { |
marginValueLimits[i] = Math.max(marginValueLimits[i], 0); |
@@ -556,7 +430,7 @@ cr.define('print_preview', function() { |
/** |
* Executes when user selects a different margin option, ie, |
- * |this.marginList_.selectedIndex| is changed. |
+ * |this.select_.selectedIndex| is changed. |
* @private |
*/ |
onMarginsChanged_: function() { |
@@ -657,12 +531,10 @@ cr.define('print_preview', function() { |
*/ |
resetMarginsIfNeeded: function() { |
if (this.isCustomMarginsSelected()) { |
- this.marginList_.options[ |
+ this.select_.options[ |
MarginSettings.OPTION_INDEX_DEFAULT].selected = true; |
this.removeCustomMarginEventListeners_(); |
this.forceDisplayingMarginLines_ = true; |
- this.customMargins_ = null; |
- this.previousCustomMargins_ = null; |
} |
}, |
@@ -699,7 +571,6 @@ cr.define('print_preview', function() { |
}; |
return { |
- MarginSettings: MarginSettings, |
- PageLayout: PageLayout |
+ MarginsUI: MarginsUI |
}; |
}); |