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

Unified Diff: chrome/browser/resources/print_preview/previewarea/margin_control_container.js

Issue 10108001: Refactor print preview web ui (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Resolve conflicts Created 8 years, 7 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/resources/print_preview/previewarea/margin_control_container.js
diff --git a/chrome/browser/resources/print_preview/previewarea/margin_control_container.js b/chrome/browser/resources/print_preview/previewarea/margin_control_container.js
new file mode 100644
index 0000000000000000000000000000000000000000..1209da930fb08ff2f74c960c2876b3c72a97cee9
--- /dev/null
+++ b/chrome/browser/resources/print_preview/previewarea/margin_control_container.js
@@ -0,0 +1,446 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('print_preview', function() {
+ 'use strict';
+
+ /**
+ * UI component used for setting custom print margins.
+ * @param {!print_preview.PrintTicketStore} printTicketStore Used to read and
+ * write custom margin values.
+ * @constructor
+ * @extends {print_preview.Component}
+ */
+ function MarginControlContainer(printTicketStore) {
+ print_preview.Component.call(this);
+
+ /**
+ * Used to read and write custom margin values.
+ * @type {!print_preview.PrintTicketStore}
+ * @private
+ */
+ this.printTicketStore_ = printTicketStore;
+
+ /**
+ * Used to convert between the system's local units and points.
+ * @type {!print_preview.MeasurementSystem}
+ * @private
+ */
+ this.measurementSystem_ = printTicketStore.measurementSystem;
+
+ /**
+ * Convenience array that contains all of the margin controls.
+ * @type {!Object<
+ * print_preview.ticket_items.CustomMargins.Orientation,
+ * !print_preview.MarginControl>}
+ * @private
+ */
+ this.controls_ = {};
+ for (var key in print_preview.ticket_items.CustomMargins.Orientation) {
+ var orientation = print_preview.ticket_items.CustomMargins.Orientation[
+ key];
+ var control = new print_preview.MarginControl(orientation);
+ this.controls_[orientation] = control;
+ this.addChild(control);
+ }
+
+ /**
+ * Margin control currently being dragged. Null if no control is being
+ * dragged.
+ * @type {print_preview.MarginControl}
+ * @private
+ */
+ this.draggedControl_ = null;
+
+ /**
+ * Translation transformation in pixels to translate from the origin of the
+ * custom margins component to the top-left corner of the most visible
+ * preview page.
+ * @type {!print_preview.Coordinate2d}
+ * @private
+ */
+ this.translateTransform_ = new print_preview.Coordinate2d(0, 0);
+
+ /**
+ * Scaling transformation to scale from pixels to the units which the
+ * print preview is in. The scaling factor is the same in both dimensions,
+ * so this field is just a single number.
+ * @type {number}
+ * @private
+ */
+ this.scaleTransform_ = 1;
+
+ /**
+ * Clipping size for clipping the margin controls.
+ * @type {print_preview.Size}
+ * @private
+ */
+ this.clippingSize_ = null;
+ };
+
+ /**
+ * CSS classes used by the custom margins component.
+ * @enum {string}
+ * @private
+ */
+ MarginControlContainer.Classes_ = {
+ DRAGGING_HORIZONTAL: 'margin-control-container-dragging-horizontal',
+ DRAGGING_VERTICAL: 'margin-control-container-dragging-vertical'
+ };
+
+ /**
+ * @param {print_preview.ticket_items.CustomMargins.Orientation} orientation
+ * Orientation value to test.
+ * @return {boolean} Whether the given orientation is TOP or BOTTOM.
+ * @private
+ */
+ MarginControlContainer.isTopOrBottom_ = function(orientation) {
+ return orientation ==
+ print_preview.ticket_items.CustomMargins.Orientation.TOP ||
+ orientation ==
+ print_preview.ticket_items.CustomMargins.Orientation.BOTTOM;
+ };
+
+ MarginControlContainer.prototype = {
+ __proto__: print_preview.Component.prototype,
+
+ /**
+ * Updates the translation transformation that translates pixel values in
+ * the space of the HTML DOM.
+ * @param {print_preview.Coordinate2d} translateTransform Updated value of
+ * the translation transformation.
+ */
+ updateTranslationTransform: function(translateTransform) {
+ if (!translateTransform.equals(this.translateTransform_)) {
+ this.translateTransform_ = translateTransform;
+ for (var orientation in this.controls_) {
+ this.controls_[orientation].setTranslateTransform(translateTransform);
+ }
+ }
+ },
+
+ /**
+ * Updates the scaling transform that scales pixels values to point values.
+ * @param {number} scaleTransform Updated value of the scale transform.
+ */
+ updateScaleTransform: function(scaleTransform) {
+ if (scaleTransform != this.scaleTransform_) {
+ this.scaleTransform_ = scaleTransform;
+ for (var orientation in this.controls_) {
+ this.controls_[orientation].setScaleTransform(scaleTransform);
+ }
+ }
+ },
+
+ /**
+ * Clips margin controls to the given clip size in pixels.
+ * @param {print_preview.Size} Size to clip the margin controls to.
+ */
+ updateClippingMask: function(clipSize) {
+ if (!clipSize) {
+ return;
+ }
+ this.clippingSize_ = clipSize;
+ for (var orientation in this.controls_) {
+ var el = this.controls_[orientation].getElement();
+ el.style.clip = 'rect(' +
+ (-el.offsetTop) + 'px, ' +
+ (clipSize.width - el.offsetLeft) + 'px, ' +
+ (clipSize.height - el.offsetTop) + 'px, ' +
+ (-el.offsetLeft) + 'px)';
+ }
+ },
+
+ /** Shows the margin controls if the need to be shown. */
+ showMarginControlsIfNeeded: function() {
+ if (this.printTicketStore_.getMarginsType() ==
+ print_preview.ticket_items.MarginsType.Value.CUSTOM) {
+ this.setIsMarginControlsVisible_(true);
+ }
+ },
+
+ /** @override */
+ enterDocument: function() {
+ print_preview.Component.prototype.enterDocument.call(this);
+
+ // We want to respond to mouse up events even beyond the component's
+ // element.
+ this.tracker.add(window, 'mouseup', this.onMouseUp_.bind(this));
+ this.tracker.add(window, 'mousemove', this.onMouseMove_.bind(this));
+ this.tracker.add(
+ this.getElement(), 'mouseover', this.onMouseOver_.bind(this));
+ this.tracker.add(
+ this.getElement(), 'mouseout', this.onMouseOut_.bind(this));
+
+ this.tracker.add(
+ this.printTicketStore_,
+ print_preview.PrintTicketStore.EventType.INITIALIZE,
+ this.onTicketChange_.bind(this));
+ this.tracker.add(
+ this.printTicketStore_,
+ print_preview.PrintTicketStore.EventType.TICKET_CHANGE,
+ this.onTicketChange_.bind(this));
+ this.tracker.add(
+ this.printTicketStore_,
+ print_preview.PrintTicketStore.EventType.DOCUMENT_CHANGE,
+ this.onTicketChange_.bind(this));
+ this.tracker.add(
+ this.printTicketStore_,
+ print_preview.PrintTicketStore.EventType.CAPABILITIES_CHANGE,
+ this.onTicketChange_.bind(this));
+
+ for (var orientation in this.controls_) {
+ this.tracker.add(
+ this.controls_[orientation],
+ print_preview.MarginControl.EventType.DRAG_START,
+ this.onControlDragStart_.bind(this, this.controls_[orientation]));
+ this.tracker.add(
+ this.controls_[orientation],
+ print_preview.MarginControl.EventType.TEXT_CHANGE,
+ this.onControlTextChange_.bind(this, this.controls_[orientation]));
+ }
+ },
+
+ /** @override */
+ decorateInternal: function() {
+ for (var orientation in this.controls_) {
+ this.controls_[orientation].render(this.getElement());
+ }
+ },
+
+ /**
+ * @param {boolean} isVisible Whether the margin controls are visible.
+ * @private
+ */
+ setIsMarginControlsVisible_: function(isVisible) {
+ for (var orientation in this.controls_) {
+ this.controls_[orientation].setIsVisible(isVisible);
+ }
+ },
+
+ /**
+ * Moves the position of the given control to the desired position in
+ * pixels within some constraint minimum and maximum.
+ * @param {!print_preview.MarginControl} control Control to move.
+ * @param {!print_preview.Coordinate2d} posInPixels Desired position to move
+ * to in pixels.
+ * @private
+ */
+ moveControlWithConstraints_: function(control, posInPixels) {
+ var newPosInPts;
+ if (MarginControlContainer.isTopOrBottom_(control.getOrientation())) {
+ newPosInPts = control.convertPixelsToPts(posInPixels.y);
+ } else {
+ newPosInPts = control.convertPixelsToPts(posInPixels.x);
+ }
+ newPosInPts = Math.min(
+ this.printTicketStore_.getCustomMarginMax(control.getOrientation()),
+ newPosInPts);
+ newPosInPts = Math.max(0, newPosInPts);
+ newPosInPts = Math.round(newPosInPts);
+ control.setPositionInPts(newPosInPts);
+ control.setTextboxValue(this.serializeValueFromPts_(newPosInPts));
+ },
+
+ /**
+ * @param {string} value Value to parse to points. E.g. '3.40"' or '200mm'.
+ * @return {number} Value in points represented by the input value.
+ * @private
+ */
+ parseValueToPts_: function(value) {
+ // Removing whitespace anywhere in the string.
+ value = value.replace(/\s*/g, '');
+ if (value.length == 0) {
+ return null;
+ }
+ var validationRegex = new RegExp('^(^-?)(\\d)+(\\' +
+ this.measurementSystem_.thousandsDelimeter + '\\d{3})*(\\' +
+ this.measurementSystem_.decimalDelimeter + '\\d*)?' +
+ '(' + this.measurementSystem_.unitSymbol + ')?$');
+ if (validationRegex.test(value)) {
+ // Replacing decimal point with the dot symbol in order to use
+ // parseFloat() properly.
+ var replacementRegex =
+ new RegExp('\\' + this.measurementSystem_.decimalDelimeter + '{1}');
+ value = value.replace(replacementRegex, '.');
+ return this.measurementSystem_.convertToPoints(parseFloat(value));
+ }
+ return null;
+ },
+
+ /**
+ * @param {number} value Value in points to serialize.
+ * @return {string} String representation of the value in the system's local
+ * units.
+ * @private
+ */
+ serializeValueFromPts_: function(value) {
+ value = this.measurementSystem_.convertFromPoints(value);
+ value = this.measurementSystem_.roundValue(value);
+ return value + this.measurementSystem_.unitSymbol;
+ },
+
+ /**
+ * Called when a margin control starts to drag.
+ * @param {print_preview.MarginControl} control The control which started to
+ * drag.
+ * @private
+ */
+ onControlDragStart_: function(control) {
+ this.draggedControl_ = control;
+ this.getElement().classList.add(
+ MarginControlContainer.isTopOrBottom_(control.getOrientation()) ?
+ MarginControlContainer.Classes_.DRAGGING_VERTICAL :
+ MarginControlContainer.Classes_.DRAGGING_HORIZONTAL);
+ },
+
+ /**
+ * Called when the mouse moves in the custom margins component. Moves the
+ * dragged margin control.
+ * @param {MouseEvent} event Contains the position of the mouse.
+ * @private
+ */
+ onMouseMove_: function(event) {
+ if (this.draggedControl_) {
+ this.moveControlWithConstraints_(
+ this.draggedControl_,
+ this.draggedControl_.translateMouseToPositionInPixels(
+ new print_preview.Coordinate2d(event.x, event.y)));
+ this.updateClippingMask(this.clippingSize_);
+ }
+ },
+
+ /**
+ * Called when the mouse is released in the custom margins component.
+ * Releases the dragged margin control.
+ * @param {MouseEvent} event Contains the position of the mouse.
+ * @private
+ */
+ onMouseUp_: function(event) {
+ if (this.draggedControl_) {
+ this.getElement().classList.remove(
+ MarginControlContainer.Classes_.DRAGGING_VERTICAL);
+ this.getElement().classList.remove(
+ MarginControlContainer.Classes_.DRAGGING_HORIZONTAL);
+ if (event) {
+ var posInPixels =
+ this.draggedControl_.translateMouseToPositionInPixels(
+ new print_preview.Coordinate2d(event.x, event.y));
+ this.moveControlWithConstraints_(this.draggedControl_, posInPixels);
+ }
+ this.updateClippingMask(this.clippingSize_);
+ this.printTicketStore_.updateCustomMargin(
+ this.draggedControl_.getOrientation(),
+ this.draggedControl_.getPositionInPts());
+ this.draggedControl_ = null;
+ }
+ },
+
+ /**
+ * Called when the mouse moves onto the component. Shows the margin
+ * controls.
+ * @private
+ */
+ onMouseOver_: function() {
+ var fromElement = event.fromElement;
+ while (fromElement != null) {
+ if (fromElement == this.getElement()) {
+ return;
+ }
+ fromElement = fromElement.parentElement;
+ }
+ if (this.printTicketStore_.hasMarginsCapability() &&
+ this.printTicketStore_.getMarginsType() ==
+ print_preview.ticket_items.MarginsType.Value.CUSTOM) {
+ this.setIsMarginControlsVisible_(true);
+ }
+ },
+
+ /**
+ * Called when the mouse moves off of the component. Hides the margin
+ * controls.
+ * @private
+ */
+ onMouseOut_: function(event) {
+ var toElement = event.toElement;
+ while (toElement != null) {
+ if (toElement == this.getElement()) {
+ return;
+ }
+ toElement = toElement.parentElement;
+ }
+ if (this.draggedControl_ != null) {
+ return;
+ }
+ for (var orientation in this.controls_) {
+ if (this.controls_[orientation].getIsFocused() ||
+ this.controls_[orientation].getIsInError()) {
+ return;
+ }
+ }
+ this.setIsMarginControlsVisible_(false);
+ },
+
+ /**
+ * Called when the print ticket changes. Updates the position of the margin
+ * controls.
+ * @private
+ */
+ onTicketChange_: function() {
+ var margins = this.printTicketStore_.getCustomMargins();
+ for (var orientation in this.controls_) {
+ var control = this.controls_[orientation];
+ control.setPageSize(this.printTicketStore_.pageSize);
+ control.setTextboxValue(
+ this.serializeValueFromPts_(margins.get(orientation)));
+ control.setPositionInPts(margins.get(orientation));
+ control.setIsInError(false);
+ control.setIsEnabled(true);
+ }
+ this.updateClippingMask(this.clippingSize_);
+ if (this.printTicketStore_.getMarginsType() !=
+ print_preview.ticket_items.MarginsType.Value.CUSTOM) {
+ this.setIsMarginControlsVisible_(false);
+ }
+ },
+
+ /**
+ * Called when the text in a textbox of a margin control changes or the
+ * textbox loses focus.
+ * Updates the print ticket store.
+ * @param {!print_preview.MarginControl} control Updated control.
+ * @private
+ */
+ onControlTextChange_: function(control) {
+ var marginValue = this.parseValueToPts_(control.getTextboxValue());
+ if (marginValue != null) {
+ this.printTicketStore_.updateCustomMargin(
+ control.getOrientation(), marginValue);
+ } else {
+ var enableOtherControls;
+ if (!control.getIsFocused()) {
+ // If control no longer in focus, revert to previous valid value.
+ control.setTextboxValue(
+ this.serializeValueFromPts_(control.getPositionInPts()));
+ control.setIsInError(false);
+ enableOtherControls = true;
+ } else {
+ control.setIsInError(true);
+ enableOtherControls = false;
+ }
+ // Enable other controls.
+ for (var o in this.controls_) {
+ if (control.getOrientation() != o) {
+ this.controls_[o].setIsEnabled(enableOtherControls);
+ }
+ }
+ }
+ }
+ };
+
+ // Export
+ return {
+ MarginControlContainer: MarginControlContainer
+ };
+});

Powered by Google App Engine
This is Rietveld 408576698