michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: // ********** michael@0: // Title: trench.js michael@0: michael@0: // ########## michael@0: // Class: Trench michael@0: // michael@0: // Class for drag-snapping regions; called "trenches" as they are long and narrow. michael@0: michael@0: // Constructor: Trench michael@0: // michael@0: // Parameters: michael@0: // element - the DOM element for Item (GroupItem or TabItem) from which the trench is projected michael@0: // xory - either "x" or "y": whether the trench's is along the x- or y-axis. michael@0: // In other words, if "x", the trench is vertical; if "y", the trench is horizontal. michael@0: // type - either "border" or "guide". Border trenches mark the border of an Item. michael@0: // Guide trenches extend out (unless they are intercepted) and act as "guides". michael@0: // edge - which edge of the Item that this trench corresponds to. michael@0: // Either "top", "left", "bottom", or "right". michael@0: function Trench(element, xory, type, edge) { michael@0: //---------- michael@0: // Variable: id michael@0: // (integer) The id for the Trench. Set sequentially via michael@0: this.id = Trenches.nextId++; michael@0: michael@0: // --------- michael@0: // Variables: Initial parameters michael@0: // element - (DOMElement) michael@0: // parentItem - which projects this trench; to be set with setParentItem michael@0: // xory - (string) "x" or "y" michael@0: // type - (string) "border" or "guide" michael@0: // edge - (string) "top", "left", "bottom", or "right" michael@0: this.el = element; michael@0: this.parentItem = null; michael@0: this.xory = xory; // either "x" or "y" michael@0: this.type = type; // "border" or "guide" michael@0: this.edge = edge; // "top", "left", "bottom", or "right" michael@0: michael@0: this.$el = iQ(this.el); michael@0: michael@0: //---------- michael@0: // Variable: dom michael@0: // (array) DOM elements for visible reflexes of the Trench michael@0: this.dom = []; michael@0: michael@0: //---------- michael@0: // Variable: showGuide michael@0: // (boolean) Whether this trench will project a visible guide (dotted line) or not. michael@0: this.showGuide = false; michael@0: michael@0: //---------- michael@0: // Variable: active michael@0: // (boolean) Whether this trench is currently active or not. michael@0: // Basically every trench aside for those projected by the Item currently being dragged michael@0: // all become active. michael@0: this.active = false; michael@0: this.gutter = Items.defaultGutter; michael@0: michael@0: //---------- michael@0: // Variable: position michael@0: // (integer) position is the position that we should snap to. michael@0: this.position = 0; michael@0: michael@0: //---------- michael@0: // Variables: some Ranges michael@0: // range - () explicit range; this is along the transverse axis michael@0: // minRange - () the minimum active range michael@0: // activeRange - () the currently active range michael@0: this.range = new Range(0,10000); michael@0: this.minRange = new Range(0,0); michael@0: this.activeRange = new Range(0,10000); michael@0: }; michael@0: michael@0: Trench.prototype = { michael@0: // ---------- michael@0: // Function: toString michael@0: // Prints [Trench edge type (parentItem)] for debug use michael@0: toString: function Trench_toString() { michael@0: return "[Trench " + this.edge + " " + this.type + michael@0: (this.parentItem ? " (" + this.parentItem + ")" : "") + michael@0: "]"; michael@0: }, michael@0: michael@0: //---------- michael@0: // Variable: radius michael@0: // (integer) radius is how far away we should snap from michael@0: get radius() this.customRadius || Trenches.defaultRadius, michael@0: michael@0: setParentItem: function Trench_setParentItem(item) { michael@0: if (!item.isAnItem) { michael@0: Utils.assert(false, "parentItem must be an Item"); michael@0: return false; michael@0: } michael@0: this.parentItem = item; michael@0: return true; michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: setPosition michael@0: // set the trench's position. michael@0: // michael@0: // Parameters: michael@0: // position - (integer) px center position of the trench michael@0: // range - () the explicit active range of the trench michael@0: // minRange - () the minimum range of the trench michael@0: setPosition: function Trench_setPosition(position, range, minRange) { michael@0: this.position = position; michael@0: michael@0: var page = Items.getPageBounds(true); michael@0: michael@0: // optionally, set the range. michael@0: if (Utils.isRange(range)) { michael@0: this.range = range; michael@0: } else { michael@0: this.range = new Range(0, (this.xory == 'x' ? page.height : page.width)); michael@0: } michael@0: michael@0: // if there's a minRange, set that too. michael@0: if (Utils.isRange(minRange)) michael@0: this.minRange = minRange; michael@0: michael@0: // set the appropriate bounds as a rect. michael@0: if (this.xory == "x") // vertical michael@0: this.rect = new Rect(this.position - this.radius, this.range.min, 2 * this.radius, this.range.extent); michael@0: else // horizontal michael@0: this.rect = new Rect(this.range.min, this.position - this.radius, this.range.extent, 2 * this.radius); michael@0: michael@0: this.show(); // DEBUG michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: setActiveRange michael@0: // set the trench's currently active range. michael@0: // michael@0: // Parameters: michael@0: // activeRange - () michael@0: setActiveRange: function Trench_setActiveRange(activeRange) { michael@0: if (!Utils.isRange(activeRange)) michael@0: return false; michael@0: this.activeRange = activeRange; michael@0: if (this.xory == "x") { // horizontal michael@0: this.activeRect = new Rect(this.position - this.radius, this.activeRange.min, 2 * this.radius, this.activeRange.extent); michael@0: this.guideRect = new Rect(this.position, this.activeRange.min, 0, this.activeRange.extent); michael@0: } else { // vertical michael@0: this.activeRect = new Rect(this.activeRange.min, this.position - this.radius, this.activeRange.extent, 2 * this.radius); michael@0: this.guideRect = new Rect(this.activeRange.min, this.position, this.activeRange.extent, 0); michael@0: } michael@0: return true; michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: setWithRect michael@0: // Set the trench's position using the given rect. We know which side of the rect we should match michael@0: // because we've already recorded this information in . michael@0: // michael@0: // Parameters: michael@0: // rect - () michael@0: setWithRect: function Trench_setWithRect(rect) { michael@0: michael@0: if (!Utils.isRect(rect)) michael@0: Utils.error('argument must be Rect'); michael@0: michael@0: // First, calculate the range for this trench. michael@0: // Border trenches are always only active for the length of this range. michael@0: // Guide trenches, however, still use this value as its minRange. michael@0: if (this.xory == "x") michael@0: var range = new Range(rect.top - this.gutter, rect.bottom + this.gutter); michael@0: else michael@0: var range = new Range(rect.left - this.gutter, rect.right + this.gutter); michael@0: michael@0: if (this.type == "border") { michael@0: // border trenches have a range, so set that too. michael@0: if (this.edge == "left") michael@0: this.setPosition(rect.left - this.gutter, range); michael@0: else if (this.edge == "right") michael@0: this.setPosition(rect.right + this.gutter, range); michael@0: else if (this.edge == "top") michael@0: this.setPosition(rect.top - this.gutter, range); michael@0: else if (this.edge == "bottom") michael@0: this.setPosition(rect.bottom + this.gutter, range); michael@0: } else if (this.type == "guide") { michael@0: // guide trenches have no range, but do have a minRange. michael@0: if (this.edge == "left") michael@0: this.setPosition(rect.left, false, range); michael@0: else if (this.edge == "right") michael@0: this.setPosition(rect.right, false, range); michael@0: else if (this.edge == "top") michael@0: this.setPosition(rect.top, false, range); michael@0: else if (this.edge == "bottom") michael@0: this.setPosition(rect.bottom, false, range); michael@0: } michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: show michael@0: // michael@0: // Show guide (dotted line), if is true. michael@0: // michael@0: // If is true, we will draw the trench. Active portions are drawn with 0.5 michael@0: // opacity. If is false, the entire trench will be michael@0: // very translucent. michael@0: show: function Trench_show() { // DEBUG michael@0: if (this.active && this.showGuide) { michael@0: if (!this.dom.guideTrench) michael@0: this.dom.guideTrench = iQ("
").addClass('guideTrench').css({id: 'guideTrench'+this.id}); michael@0: var guideTrench = this.dom.guideTrench; michael@0: guideTrench.css(this.guideRect); michael@0: iQ("body").append(guideTrench); michael@0: } else { michael@0: if (this.dom.guideTrench) { michael@0: this.dom.guideTrench.remove(); michael@0: delete this.dom.guideTrench; michael@0: } michael@0: } michael@0: michael@0: if (!Trenches.showDebug) { michael@0: this.hide(true); // true for dontHideGuides michael@0: return; michael@0: } michael@0: michael@0: if (!this.dom.visibleTrench) michael@0: this.dom.visibleTrench = iQ("
") michael@0: .addClass('visibleTrench') michael@0: .addClass(this.type) // border or guide michael@0: .css({id: 'visibleTrench'+this.id}); michael@0: var visibleTrench = this.dom.visibleTrench; michael@0: michael@0: if (!this.dom.activeVisibleTrench) michael@0: this.dom.activeVisibleTrench = iQ("
") michael@0: .addClass('activeVisibleTrench') michael@0: .addClass(this.type) // border or guide michael@0: .css({id: 'activeVisibleTrench'+this.id}); michael@0: var activeVisibleTrench = this.dom.activeVisibleTrench; michael@0: michael@0: if (this.active) michael@0: activeVisibleTrench.addClass('activeTrench'); michael@0: else michael@0: activeVisibleTrench.removeClass('activeTrench'); michael@0: michael@0: visibleTrench.css(this.rect); michael@0: activeVisibleTrench.css(this.activeRect || this.rect); michael@0: iQ("body").append(visibleTrench); michael@0: iQ("body").append(activeVisibleTrench); michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: hide michael@0: // Hide the trench. michael@0: hide: function Trench_hide(dontHideGuides) { michael@0: if (this.dom.visibleTrench) michael@0: this.dom.visibleTrench.remove(); michael@0: if (this.dom.activeVisibleTrench) michael@0: this.dom.activeVisibleTrench.remove(); michael@0: if (!dontHideGuides && this.dom.guideTrench) michael@0: this.dom.guideTrench.remove(); michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: rectOverlaps michael@0: // Given a , compute whether it overlaps with this trench. If it does, return an michael@0: // adjusted ("snapped") ; if it does not overlap, simply return false. michael@0: // michael@0: // Note that simply overlapping is not all that is required to be affected by this function. michael@0: // Trenches can only affect certain edges of rectangles... for example, a "left"-edge guide michael@0: // trench should only affect left edges of rectangles. We don't snap right edges to left-edged michael@0: // guide trenches. For border trenches, the logic is a bit different, so left snaps to right and michael@0: // top snaps to bottom. michael@0: // michael@0: // Parameters: michael@0: // rect - () the rectangle in question michael@0: // stationaryCorner - which corner is stationary? by default, the top left. michael@0: // "topleft", "bottomleft", "topright", "bottomright" michael@0: // assumeConstantSize - (boolean) whether the rect's dimensions are sacred or not michael@0: // keepProportional - (boolean) if we are allowed to change the rect's size, whether the michael@0: // dimensions should scaled proportionally or not. michael@0: // michael@0: // Returns: michael@0: // false - if rect does not overlap with this trench michael@0: // newRect - () an adjusted version of rect, if it is affected by this trench michael@0: rectOverlaps: function Trench_rectOverlaps(rect,stationaryCorner,assumeConstantSize,keepProportional) { michael@0: var edgeToCheck; michael@0: if (this.type == "border") { michael@0: if (this.edge == "left") michael@0: edgeToCheck = "right"; michael@0: else if (this.edge == "right") michael@0: edgeToCheck = "left"; michael@0: else if (this.edge == "top") michael@0: edgeToCheck = "bottom"; michael@0: else if (this.edge == "bottom") michael@0: edgeToCheck = "top"; michael@0: } else { // if trench type is guide or barrier... michael@0: edgeToCheck = this.edge; michael@0: } michael@0: michael@0: rect.adjustedEdge = edgeToCheck; michael@0: michael@0: switch (edgeToCheck) { michael@0: case "left": michael@0: if (this.ruleOverlaps(rect.left, rect.yRange)) { michael@0: if (stationaryCorner.indexOf('right') > -1) michael@0: rect.width = rect.right - this.position; michael@0: rect.left = this.position; michael@0: return rect; michael@0: } michael@0: break; michael@0: case "right": michael@0: if (this.ruleOverlaps(rect.right, rect.yRange)) { michael@0: if (assumeConstantSize) { michael@0: rect.left = this.position - rect.width; michael@0: } else { michael@0: var newWidth = this.position - rect.left; michael@0: if (keepProportional) michael@0: rect.height = rect.height * newWidth / rect.width; michael@0: rect.width = newWidth; michael@0: } michael@0: return rect; michael@0: } michael@0: break; michael@0: case "top": michael@0: if (this.ruleOverlaps(rect.top, rect.xRange)) { michael@0: if (stationaryCorner.indexOf('bottom') > -1) michael@0: rect.height = rect.bottom - this.position; michael@0: rect.top = this.position; michael@0: return rect; michael@0: } michael@0: break; michael@0: case "bottom": michael@0: if (this.ruleOverlaps(rect.bottom, rect.xRange)) { michael@0: if (assumeConstantSize) { michael@0: rect.top = this.position - rect.height; michael@0: } else { michael@0: var newHeight = this.position - rect.top; michael@0: if (keepProportional) michael@0: rect.width = rect.width * newHeight / rect.height; michael@0: rect.height = newHeight; michael@0: } michael@0: return rect; michael@0: } michael@0: } michael@0: michael@0: return false; michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: ruleOverlaps michael@0: // Computes whether the given "rule" (a line segment, essentially), given by the position and michael@0: // range arguments, overlaps with the current trench. Note that this function assumes that michael@0: // the rule and the trench are in the same direction: both horizontal, or both vertical. michael@0: // michael@0: // Parameters: michael@0: // position - (integer) a position in px michael@0: // range - () the rule's range michael@0: ruleOverlaps: function Trench_ruleOverlaps(position, range) { michael@0: return (this.position - this.radius < position && michael@0: position < this.position + this.radius && michael@0: this.activeRange.overlaps(range)); michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: adjustRangeIfIntercept michael@0: // Computes whether the given boundary (given as a position and its active range), perpendicular michael@0: // to the trench, intercepts the trench or not. If it does, it returns an adjusted for michael@0: // the trench. If not, it returns false. michael@0: // michael@0: // Parameters: michael@0: // position - (integer) the position of the boundary michael@0: // range - () the target's range, on the trench's transverse axis michael@0: adjustRangeIfIntercept: function Trench_adjustRangeIfIntercept(position, range) { michael@0: if (this.position - this.radius > range.min && this.position + this.radius < range.max) { michael@0: var activeRange = new Range(this.activeRange); michael@0: michael@0: // there are three ways this can go: michael@0: // 1. position < minRange.min michael@0: // 2. position > minRange.max michael@0: // 3. position >= minRange.min && position <= minRange.max michael@0: michael@0: if (position < this.minRange.min) { michael@0: activeRange.min = Math.min(this.minRange.min,position); michael@0: } else if (position > this.minRange.max) { michael@0: activeRange.max = Math.max(this.minRange.max,position); michael@0: } else { michael@0: // this should be impossible because items can't overlap and we've already checked michael@0: // that the range intercepts. michael@0: } michael@0: return activeRange; michael@0: } michael@0: return false; michael@0: }, michael@0: michael@0: //---------- michael@0: // Function: calculateActiveRange michael@0: // Computes and sets the for the trench, based on the around. michael@0: // This makes it so trenches' active ranges don't extend through other groupItems. michael@0: calculateActiveRange: function Trench_calculateActiveRange() { michael@0: michael@0: // set it to the default: just the range itself. michael@0: this.setActiveRange(this.range); michael@0: michael@0: // only guide-type trenches need to set a separate active range michael@0: if (this.type != 'guide') michael@0: return; michael@0: michael@0: var groupItems = GroupItems.groupItems; michael@0: var trench = this; michael@0: groupItems.forEach(function(groupItem) { michael@0: if (groupItem.isDragging) // floating groupItems don't block trenches michael@0: return; michael@0: if (trench.el == groupItem.container) // groupItems don't block their own trenches michael@0: return; michael@0: var bounds = groupItem.getBounds(); michael@0: var activeRange = new Range(); michael@0: if (trench.xory == 'y') { // if this trench is horizontal... michael@0: activeRange = trench.adjustRangeIfIntercept(bounds.left, bounds.yRange); michael@0: if (activeRange) michael@0: trench.setActiveRange(activeRange); michael@0: activeRange = trench.adjustRangeIfIntercept(bounds.right, bounds.yRange); michael@0: if (activeRange) michael@0: trench.setActiveRange(activeRange); michael@0: } else { // if this trench is vertical... michael@0: activeRange = trench.adjustRangeIfIntercept(bounds.top, bounds.xRange); michael@0: if (activeRange) michael@0: trench.setActiveRange(activeRange); michael@0: activeRange = trench.adjustRangeIfIntercept(bounds.bottom, bounds.xRange); michael@0: if (activeRange) michael@0: trench.setActiveRange(activeRange); michael@0: } michael@0: }); michael@0: } michael@0: }; michael@0: michael@0: // ########## michael@0: // Class: Trenches michael@0: // Singelton for managing all es. michael@0: var Trenches = { michael@0: // --------- michael@0: // Variables: michael@0: // nextId - (integer) a counter for the next 's value. michael@0: // showDebug - (boolean) whether to draw the es or not. michael@0: // defaultRadius - (integer) the default radius for new es. michael@0: // disabled - (boolean) whether trench-snapping is disabled or not. michael@0: nextId: 0, michael@0: showDebug: false, michael@0: defaultRadius: 10, michael@0: disabled: false, michael@0: michael@0: // --------- michael@0: // Variables: snapping preferences; used to break ties in snapping. michael@0: // preferTop - (boolean) prefer snapping to the top to the bottom michael@0: // preferLeft - (boolean) prefer snapping to the left to the right michael@0: preferTop: true, michael@0: get preferLeft() { return !UI.rtl; }, michael@0: michael@0: trenches: [], michael@0: michael@0: // ---------- michael@0: // Function: toString michael@0: // Prints [Trenches count=count] for debug use michael@0: toString: function Trenches_toString() { michael@0: return "[Trenches count=" + this.trenches.length + "]"; michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: getById michael@0: // Return the specified . michael@0: // michael@0: // Parameters: michael@0: // id - (integer) michael@0: getById: function Trenches_getById(id) { michael@0: return this.trenches[id]; michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: register michael@0: // Register a new and returns the resulting ID. michael@0: // michael@0: // Parameters: michael@0: // See the constructor 's parameters. michael@0: // michael@0: // Returns: michael@0: // id - (int) the new 's ID. michael@0: register: function Trenches_register(element, xory, type, edge) { michael@0: var trench = new Trench(element, xory, type, edge); michael@0: this.trenches[trench.id] = trench; michael@0: return trench.id; michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: registerWithItem michael@0: // Register a whole set of es using an and returns the resulting IDs. michael@0: // michael@0: // Parameters: michael@0: // item - the to project trenches michael@0: // type - either "border" or "guide" michael@0: // michael@0: // Returns: michael@0: // ids - array of the new es' IDs. michael@0: registerWithItem: function Trenches_registerWithItem(item, type) { michael@0: var container = item.container; michael@0: var ids = {}; michael@0: ids.left = Trenches.register(container,"x",type,"left"); michael@0: ids.right = Trenches.register(container,"x",type,"right"); michael@0: ids.top = Trenches.register(container,"y",type,"top"); michael@0: ids.bottom = Trenches.register(container,"y",type,"bottom"); michael@0: michael@0: this.getById(ids.left).setParentItem(item); michael@0: this.getById(ids.right).setParentItem(item); michael@0: this.getById(ids.top).setParentItem(item); michael@0: this.getById(ids.bottom).setParentItem(item); michael@0: michael@0: return ids; michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: unregister michael@0: // Unregister one or more es. michael@0: // michael@0: // Parameters: michael@0: // ids - (integer) a single ID or (array) a list of IDs. michael@0: unregister: function Trenches_unregister(ids) { michael@0: if (!Array.isArray(ids)) michael@0: ids = [ids]; michael@0: var self = this; michael@0: ids.forEach(function(id) { michael@0: self.trenches[id].hide(); michael@0: delete self.trenches[id]; michael@0: }); michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: activateOthersTrenches michael@0: // Activate all es other than those projected by the current element. michael@0: // michael@0: // Parameters: michael@0: // element - (DOMElement) the DOM element of the Item being dragged or resized. michael@0: activateOthersTrenches: function Trenches_activateOthersTrenches(element) { michael@0: this.trenches.forEach(function(t) { michael@0: if (t.el === element) michael@0: return; michael@0: if (t.parentItem && (t.parentItem.isAFauxItem || t.parentItem.isDragging)) michael@0: return; michael@0: t.active = true; michael@0: t.calculateActiveRange(); michael@0: t.show(); // debug michael@0: }); michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: disactivate michael@0: // After , disactivates all the es again. michael@0: disactivate: function Trenches_disactivate() { michael@0: this.trenches.forEach(function(t) { michael@0: t.active = false; michael@0: t.showGuide = false; michael@0: t.show(); michael@0: }); michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: hideGuides michael@0: // Hide all guides (dotted lines) en masse. michael@0: hideGuides: function Trenches_hideGuides() { michael@0: this.trenches.forEach(function(t) { michael@0: t.showGuide = false; michael@0: t.show(); michael@0: }); michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: snap michael@0: // Used to "snap" an object's bounds to active trenches and to the edge of the window. michael@0: // If the meta key is down (), it will not snap but will still enforce the rect michael@0: // not leaving the safe bounds of the window. michael@0: // michael@0: // Parameters: michael@0: // rect - () the object's current bounds michael@0: // stationaryCorner - which corner is stationary? by default, the top left. michael@0: // "topleft", "bottomleft", "topright", "bottomright" michael@0: // assumeConstantSize - (boolean) whether the rect's dimensions are sacred or not michael@0: // keepProportional - (boolean) if we are allowed to change the rect's size, whether the michael@0: // dimensions should scaled proportionally or not. michael@0: // michael@0: // Returns: michael@0: // () - the updated bounds, if they were updated michael@0: // false - if the bounds were not updated michael@0: snap: function Trenches_snap(rect,stationaryCorner,assumeConstantSize,keepProportional) { michael@0: // hide all the guide trenches, because the correct ones will be turned on later. michael@0: Trenches.hideGuides(); michael@0: michael@0: var updated = false; michael@0: var updatedX = false; michael@0: var updatedY = false; michael@0: michael@0: var snappedTrenches = {}; michael@0: michael@0: for (var i in this.trenches) { michael@0: var t = this.trenches[i]; michael@0: if (!t.active) michael@0: continue; michael@0: // newRect will be a new rect, or false michael@0: var newRect = t.rectOverlaps(rect,stationaryCorner,assumeConstantSize,keepProportional); michael@0: michael@0: if (newRect) { // if rectOverlaps returned an updated rect... michael@0: michael@0: if (assumeConstantSize && updatedX && updatedY) michael@0: break; michael@0: if (assumeConstantSize && updatedX && (newRect.adjustedEdge == "left"||newRect.adjustedEdge == "right")) michael@0: continue; michael@0: if (assumeConstantSize && updatedY && (newRect.adjustedEdge == "top"||newRect.adjustedEdge == "bottom")) michael@0: continue; michael@0: michael@0: rect = newRect; michael@0: updated = true; michael@0: michael@0: // register this trench as the "snapped trench" for the appropriate edge. michael@0: snappedTrenches[newRect.adjustedEdge] = t; michael@0: michael@0: // if updatedX, we don't need to update x any more. michael@0: if (newRect.adjustedEdge == "left" && this.preferLeft) michael@0: updatedX = true; michael@0: if (newRect.adjustedEdge == "right" && !this.preferLeft) michael@0: updatedX = true; michael@0: michael@0: // if updatedY, we don't need to update x any more. michael@0: if (newRect.adjustedEdge == "top" && this.preferTop) michael@0: updatedY = true; michael@0: if (newRect.adjustedEdge == "bottom" && !this.preferTop) michael@0: updatedY = true; michael@0: michael@0: } michael@0: } michael@0: michael@0: if (updated) { michael@0: rect.snappedTrenches = snappedTrenches; michael@0: return rect; michael@0: } michael@0: return false; michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: show michael@0: // all es. michael@0: show: function Trenches_show() { michael@0: this.trenches.forEach(function(t) { michael@0: t.show(); michael@0: }); michael@0: }, michael@0: michael@0: // --------- michael@0: // Function: toggleShown michael@0: // Toggle and trigger michael@0: toggleShown: function Trenches_toggleShown() { michael@0: this.showDebug = !this.showDebug; michael@0: this.show(); michael@0: } michael@0: };