Created
June 28, 2017 09:41
-
-
Save Semigradsky/6bc5b5e69192df533db4122876d4ff9e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import BaseWidget from 'widgets/mixins/base/BaseWidget'; | |
import Taggable from 'widgets/mixins/behaviour/Taggable'; | |
type TaggableWidget = BaseWidget & Taggable; | |
/** | |
* Find intersection of two intervals: (a, b) and (c, d) | |
*/ | |
function findIntersection(a: number, b: number, c: number, d: number): number { | |
if (!(b > c && a < d)) { | |
return 0; | |
} | |
return Math.min(b, d) - Math.max(a, c); | |
} | |
export default function LyingOnLongest <TBase extends planner.Mixinable<TaggableWidget>>(Base: TBase) { | |
return class LyingOnLongest extends Base { | |
public getDefaultDistanceFromFloor(): number { | |
const items = this.getTaggedItems((item) => item.is('Unit')); | |
if (items.length === 0) { | |
return super.getDefaultDistanceFromFloor(); | |
} | |
const thisCenter = this.getActualPosition(); | |
const thisWidth = this.getActualWidth(); | |
const thisCoords = { | |
startX: thisCenter.x - thisWidth / 2, | |
endX: thisCenter.x + thisWidth / 2 | |
}; | |
const groupedData: { [distance: number]: number } = {}; | |
let maxIntersection = 0; | |
let result = 0; | |
for (const item of items) { | |
const center = item.getActualPosition(); | |
const width = item.getActualWidth(); | |
const distance = item.getDistanceFromFloorToTop(); | |
const intersection = findIntersection(thisCoords.startX, thisCoords.endX, center.x - width / 2, center.x + width / 2); | |
groupedData[distance] = groupedData[distance] || 0; | |
groupedData[distance] += intersection; | |
if (groupedData[distance] > maxIntersection) { | |
maxIntersection = groupedData[distance]; | |
result = distance; | |
} | |
} | |
return result; | |
} | |
public setDefaultHeight() { | |
const current = this.getDistanceFromFloor(); | |
const proposed = this.getDefaultDistanceFromFloor(); | |
if (proposed !== current) { | |
this.setDistanceFromFloor(proposed); | |
} | |
} | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Vector2D from 'wrenderer/utils/Vector2D'; | |
import * as stringHelper from 'helpers/StringHelper'; | |
import LyingOnLongest from 'widgets/mixins/behaviour/LyingOnLongest'; | |
define(function (require) { | |
'use strict'; | |
var _ = require('lodash'); | |
var compose = require('compose'); | |
var aspect = require('aspect'); | |
// var wrenderer = require('singleton!wrenderer/Wrenderer'); | |
var planModel = require('singleton!plan/PlanModel'); | |
var worktopData = require('singleton!service/data/WorktopData'); | |
var imageHelper = require('singleton!helpers/ImageHelper'); | |
var constants = require('json!config/constants/constants.json'); | |
var viewModeManager = require('singleton!plan/PlannerViewModeManager'); | |
var worktopOverhangService = require('kitchens/services/WorktopOverhangService'); | |
var worktopConstants = require('json!config/constants/worktop.json'); | |
var worktopsHelper = require('kitchens/helpers/WorktopsHelper'); | |
var worktopEdgesHelper = require('kitchens/helpers/WorktopEdgesHelper'); | |
var worktopConfigurationHelper = require('kitchens/helpers/WorktopConfigurationHelper'); | |
var WorktopCurve = require('widgets/worktops/helpers/WorktopCurve'); | |
var worktopCornersHelper = require('kitchens/helpers/WorktopCornersHelper'); | |
var edgesHelper = require('helpers/EdgeHelper'); | |
var cornersAvailability = require('kitchens/helpers/CornersAvailability'); | |
var clipperHelper = require('helpers/math/ClipperHelper'); | |
var cornerCalculator = require('helpers/calculators/CornerCalculator'); | |
var PopoverOnHover = require('widgets/features/PopoverOnHover'); | |
var _mixins = [ | |
require('widgets/mixins/ItemWidget'), | |
require('widgets/mixins/behaviour/PreferencesFilterChange'), | |
require('widgets/mixins/behaviour/Hoverable'), | |
require('widgets/mixins/features/BadPlacement'), | |
require('widgets/mixins/behaviour/OverhangAlert'), | |
require('widgets/mixins/behaviour/HasRelatedProducts'), | |
require('widgets/mixins/base/FlushableWorktop'), | |
require('widgets/mixins/behaviour/CutWidget'), | |
require('widgets/mixins/features/WorktopCorners'), | |
require('widgets/mixins/features/CornerWorktop3D'), | |
require('widgets/mixins/features/WorktopCornersPopup'), | |
require('widgets/mixins/features/WorktopCornersAvailability'), | |
require('widgets/mixins/configurable/ConfigurableWorktopWidget'), | |
require('widgets/mixins/behaviour/WorktopInnerSnap'), // no | |
// TODO: Amend DisabledSnappingWorktopBehaviour when IntersectWorktopsFixer will be not necessary | |
require('widgets/mixins/behaviour/DisabledSnappingWorktopBehaviour'), | |
require('widgets/mixins/data/WorktopDataMixin') | |
]; | |
/** | |
* Checks if item should collide if it's rotation not multiple to 90 degree | |
*/ | |
function shouldNotHaveRotatedCollision(item) { | |
return item.is('BasicWorktop') || item.is('CornerWorktop'); | |
} | |
// NOTE: it has dynamic sprite sprites/worktop/BoltsSprite, | |
// see overridden getSprites method | |
return LyingOnLongest(compose(_mixins, | |
/** | |
* @constructs WorktopWidget | |
* @memberOf WorktopWidget# | |
*/ | |
function () { | |
this.stepsEditable = ['new-worktops']; | |
this.stepsHoverable = ['new-worktops']; | |
this.features.addFeature(new PopoverOnHover(this)); | |
this.hoverableAreas = this.hoverableAreas || []; | |
this.hoverableAreas.push({ | |
getAreaPoints: this.getRealPoints.bind(this) | |
}); | |
aspect.on(planModel, 'setFrontalRange', () => this.setDefaultHeight()); | |
}, | |
/** | |
* @lends WorktopWidget.prototype | |
* @extends ItemWidget | |
* @extends BadPlacement | |
* @extends PreferencesFilterChange | |
*/ | |
{ | |
handle: 'worktop', | |
rotatable: true, | |
cascadeMovement: false, | |
doResetBaseRotation: false, | |
mouseTargetPrecedence: true, | |
boundingThreshold: 50, | |
snapper: true, | |
isWorktop: _.constant(true), | |
doCustomXYZCollision: true, | |
canDisableSnapping: _.constant(true), | |
getSprites: function () { | |
if (this.step && this.step.isOneOf(['new-worktops', 'notes'])) { | |
return this.sprites.concat( | |
require('singleton!sprites/worktop/BoltsSprite') | |
); | |
} else { | |
return this.sprites; | |
} | |
}, | |
customXYZCollision: function (target, collision) { | |
// enable collision with walls when worktop is snapped to another worktop or current worktop is corner worktop | |
var shouldCollideWithWalls = this.target && this.target.is('Worktop') || this.is('CornerWorktop'); | |
if (target.is('OuterWall') || (shouldCollideWithWalls && target.is('Wall')) || target.is('Worktop')) { | |
this.standardXYZCollision(target, collision); | |
} | |
}, | |
to3dObject: compose.after(function () { | |
var item = this.threeDObject; | |
item.worktop = this.get3dDefaults(); | |
}), | |
getFeatureData: function () { | |
var data = false; | |
if (!this.isAnyOf('ButcherBlock', 'Upstand')) { | |
data = { | |
worktopItemId: this.itemId, | |
cutouts: [], | |
notches: this.getNotches() | |
}; | |
} | |
return data; | |
}, | |
getNotches: function () { | |
var notches = {}; | |
var taggedButcherBlocks = this.getTaggedItems(_.method('is', 'ButcherBlock')); | |
var subjectShape = this.getRealPoints(); | |
var edges = worktopEdgesHelper.getMappedEdges(this); | |
taggedButcherBlocks.forEach(function (butcher) { | |
var cutOutShape = butcher.getRealPoints(); | |
var intersection = clipperHelper.getIntersectionArea([subjectShape], [cutOutShape])[0]; | |
if (!intersection) { | |
return; | |
} | |
var adjacentEdge = _.find(edges, function (edgeMap) { | |
return _.any(intersection, function (point) { | |
return edgeMap.edge.has(point); | |
}); | |
}); | |
if (!adjacentEdge) { | |
return; | |
} | |
var sortedPoints = worktopEdgesHelper.sortAgainstEdgeStart(intersection, adjacentEdge.edge); | |
if (notches[adjacentEdge.side]) { | |
notches[adjacentEdge.side] = notches[adjacentEdge.side].concat(sortedPoints); | |
} else { | |
notches[adjacentEdge.side] = sortedPoints; | |
} | |
}, this); | |
return notches; | |
}, | |
get3dDefaults: function () { | |
var data = { | |
features: [], | |
notchPoints: { | |
back: [], | |
right: [], | |
front: [], | |
left: [] | |
}, | |
cornerConfig: [0, 0, 0, 0], | |
surfaceColour: 'None', | |
edgeColour: 'None' | |
}; | |
return data; | |
}, | |
getMaxOverhang: function () { | |
return worktopOverhangService.getMaximumOverhang(this); | |
}, | |
getMinOverhang: function () { | |
return worktopOverhangService.getMinimumOverhang(this); | |
}, | |
getSnapPriority: compose.around(function (base) { | |
return function (widget) { | |
if (widget.is('Worktop')) { | |
return 3; | |
} | |
return base.call(this, widget); | |
}; | |
}), | |
getRealEdges: function () { | |
if (this.is('CornerWorktop')) { | |
var offset; | |
if (this.is('InternalCurveWorktop')) { | |
offset = worktopConstants.LARGE_CURVE_CORNER_EDGE_OFFSET; | |
} else if (this.is('InternalSquareWorktop')) { | |
offset = worktopConstants.SQUARE_CORNER_EDGE_OFFSET; | |
} else if (this.is('ExternalSplayWorktop')) { | |
offset = worktopConstants.LARGE_SPLAY_CORNER_EDGE_OFFSET; | |
} else { | |
throw '[WorktopWidget#getRealEdges] unknown corner worktop'; | |
} | |
var matrix = this.getTranslationMatrix(); | |
var points = []; | |
if (this.is('InternalSquareWorktop')) { | |
points.push(new Vector2D(0, 0)); | |
points.push(new Vector2D(this.getWidth(), 0)); | |
points.push(new Vector2D(this.getWidth(), offset)); | |
points.push(new Vector2D(offset, offset)); | |
points.push(new Vector2D(offset, this.getDepth())); | |
points.push(new Vector2D(0, this.getDepth())); | |
} else { // curve or splay | |
points.push(new Vector2D(0, 0)); | |
points.push(new Vector2D(this.getWidth(), 0)); | |
points.push(new Vector2D(this.getWidth(), offset)); | |
points.push(new Vector2D(this.worktop.module.w, offset)); | |
points.push(new Vector2D(offset, this.worktop.module.d)); | |
points.push(new Vector2D(offset, this.getDepth())); | |
points.push(new Vector2D(0, this.getDepth())); | |
} | |
var edges = edgesHelper.getEdgesFromPoints(_.map(points, function (point) { | |
return point.applyMatrix(matrix.m); | |
})); | |
return edges.filter(function (edge) { | |
return edge[0].getDistance(edge[1]) > 1; | |
}); | |
} | |
if (this.isCutted()) { | |
var translationMatrix = this.getTranslationMatrix().m; | |
return edgesHelper.getEdgesFromPoints(this.cutWidgetPoints.map(_.method('applyMatrix', translationMatrix))); | |
} | |
return this.getEdges(); | |
}, | |
isTargetOverhangItem: function (item) { | |
return item.isAnyOf('BaseUnit', 'Appliance') && item.getDistanceFromFloorToTop() === this.getDistanceFromFloor(); | |
}, | |
isBasicWorktop: function () { | |
return !this.isCornerWorktop(); | |
}, | |
doCollisionWith: function (item) { | |
if (this.isSnappingDisabled()) { | |
return false; | |
} | |
if (item.is('SnappingDisabled')) { | |
return false; | |
} | |
var isSideElevationMode = viewModeManager.isSideElevationMode(); | |
if (isSideElevationMode) { | |
return item.getOverlapLevel && item.getOverlapLevel() === this.getOverlapLevel(); | |
} | |
if (Math.abs(this.getRotation() - item.getRotation()) % 90 > 1) { | |
if (shouldNotHaveRotatedCollision(this) && shouldNotHaveRotatedCollision(item)) { | |
return false; | |
} | |
} | |
return item.is('Wall') || | |
(item.is('Worktop') && !item.is('ButcherBlock') && !item.is('Upstand')); | |
}, | |
getTaggedForPlacement: function () { | |
var itemsToExclude = ['PipeBoxing', 'ButcherBlock', 'Stool']; | |
return this.getTaggedItems(function (taggedItem) { | |
return taggedItem.is('SubjectForPlacementCheck') && !taggedItem.isAnyOf(itemsToExclude) || | |
(!this.isCutted() && taggedItem.is('AngledWall')); | |
}, this); | |
}, | |
cascadeWith: compose.after(function (item) { | |
if (viewModeManager.isSideElevationMode()) { | |
if (item.is('SinkTop')) { | |
return true; | |
} | |
if (!this.is('Upstand') && item.is('Upstand')) { | |
var taggedItem = _.find(item.taggedItems, {itemId: this.itemId}); | |
return !!taggedItem; | |
} | |
} else { | |
if (item.is('Worktop')) { | |
return false; | |
} | |
} | |
}), | |
hasResizeableFlag: function () { | |
var resizeableFlag = _.get(this, 'model.worktop.module.resizeable', '0'); | |
return Number(resizeableFlag) === 1; | |
}, | |
isResizable: function () { | |
return !viewModeManager.isSideElevationMode() && this.hasResizeableFlag(); | |
}, | |
getSidesToResize: compose.after(function () { | |
if (this.isCornerWorktop()) { | |
var title = _.get(this, 'model.worktop.title'); | |
if (worktopsHelper.isRightHandedCorner(title)) { | |
return [this.LEFT]; | |
} else if (worktopsHelper.isLeftHandedCorner(title)) { | |
return [this.FRONT]; | |
} | |
} | |
}), | |
// Override this method for each shape to provide custom handles | |
getHandleConfig: compose.after(function () { | |
if (this.isCornerWorktop()) { | |
var handles = []; | |
var x = 600 / this.getWidth() - 1; | |
var z = 600 / this.getDepth() - 1; | |
handles.push({ | |
side: 'top', | |
type: 'edge', | |
adjust: 'depth', | |
position: new Vector2D(x, -1), | |
normal: new Vector2D(0, -1), | |
enabled: this.canAdjustSide(this.BACK) | |
}); | |
handles.push({ | |
side: 'bottom', | |
type: 'edge', | |
adjust: 'depth', | |
position: new Vector2D(x, 1), | |
normal: new Vector2D(0, 1), | |
enabled: this.canAdjustSide(this.FRONT) | |
}); | |
handles.push({ | |
side: 'left', | |
type: 'edge', | |
adjust: 'width', | |
position: new Vector2D(-1, z), | |
normal: new Vector2D(-1, 0), | |
enabled: this.canAdjustSide(this.RIGHT) | |
}); | |
handles.push({ | |
side: 'right', | |
type: 'edge', | |
adjust: 'width', | |
position: new Vector2D(1, z), | |
normal: new Vector2D(1, 0), | |
enabled: this.canAdjustSide(this.LEFT) | |
}); | |
return handles; | |
} | |
}), | |
doResizeUpTo: function (item) { | |
if (item.is('Island')) { | |
return false; | |
} | |
if (item.is('AngledWall')) { | |
return false; | |
} | |
if (item.is('Unit')) { | |
return false; | |
} | |
return this.doCollisionWith(item); | |
}, | |
handleSnappingAt: compose.before(function () { | |
var vSize = this.getVerticalSize(); | |
if (this.target && this.snapNormal && this.snapEdges) { | |
if (this.target.is('Wall')) { | |
var offset = this.getWallOffset(); | |
if (this.target.is('Island')) { | |
if (this.is('IslandWorktop')) { | |
offset = -vSize / 2; | |
} else if (this.is('BreakfastBar')) { | |
offset = -vSize + 602; | |
} else { | |
offset = 0; | |
} | |
} else if (this.getWallOffset() < 0) { | |
offset = 0; | |
} | |
if (offset !== this.getWallOffset()) { | |
this.setWallOffset(offset); | |
} | |
} | |
} | |
}), | |
getBestIntersectionRange: function (worktopEdge, intersectionAxis) { | |
var isValidIntersect = function (intersect, worktopEdge) { | |
if (_.isNaN(intersect.x) && _.isNaN(intersect.z)) { | |
return false; | |
} | |
var threshold = 2; | |
var maxXCoord = planModel.getRoomLength(); | |
var maxZCoord = planModel.getRoomWidth(); | |
// Get the very left (top) coordinate of worktop's edge | |
var leftCoord = Math.min(worktopEdge[0][intersectionAxis], worktopEdge[1][intersectionAxis]); | |
// Get the very right (bottom) coordinate of worktop's edge | |
var rightCoord = Math.max(worktopEdge[0][intersectionAxis], worktopEdge[1][intersectionAxis]); | |
var isIntersectInsideRoom = intersect.x >= 0 && intersect.x <= maxXCoord && | |
intersect.z >= 0 && intersect.z <= maxZCoord; | |
var isIntersectOnWidgetEdge = leftCoord <= intersect[intersectionAxis] + threshold && | |
rightCoord >= intersect[intersectionAxis] - threshold; | |
return isIntersectInsideRoom && isIntersectOnWidgetEdge; | |
}; | |
var calcVector = new Vector2D(); | |
var taggedWalls = this.getTaggedItems(function (item) { | |
return item.is('Wall'); | |
}); | |
var intersectionData = _(taggedWalls) | |
.map(function (taggedWall) { | |
var wallEdges = taggedWall.getEdges(); | |
var intersections = _.map(wallEdges, function (wallEdge) { | |
var worktopEdgeVector = new Vector2D(worktopEdge[0].x - worktopEdge[1].x, worktopEdge[1].z - worktopEdge[0].z); | |
var wallEdgeVector = new Vector2D(wallEdge[0].x - wallEdge[1].x, wallEdge[1].z - wallEdge[0].z); | |
var isParallel = worktopEdgeVector.isParallelToWithRounding(wallEdgeVector); | |
var intersect = calcVector.getPlaneIntersect(worktopEdge[0], worktopEdge[1], wallEdge[0], wallEdge[1]); | |
if (intersect && !isParallel && isValidIntersect(intersect, worktopEdge)) { | |
return { | |
item: taggedWall, | |
coord: intersect[intersectionAxis] | |
}; | |
} else { | |
return null; | |
} | |
}); | |
return _.compact(intersections); | |
}) | |
.flatten() | |
.sortBy('coord') | |
.value(); | |
var ranges = []; | |
var minWorktopLength = 20; | |
_.each(intersectionData, function (intersection, index) { | |
var nextIntersection = intersectionData[index + 1]; | |
if (nextIntersection && nextIntersection.item !== intersection.item) { | |
var rangeLength = nextIntersection.coord - intersection.coord; | |
if (rangeLength < minWorktopLength) { | |
return; | |
} | |
ranges.push({ | |
start: intersection.coord, | |
end: nextIntersection.coord, | |
length: rangeLength | |
}); | |
} | |
}); | |
if (_.isEmpty(ranges)) { | |
return null; | |
} | |
return _.max(ranges, 'length'); | |
}, | |
/** | |
* Resize and move the worktop to make it fit in the given area | |
* @returns {boolean} | |
*/ | |
resizeWorktop: function () { | |
if (!this.isAdjustable() || this.is('CornerWorktop') || this.isSnappingDisabled()) { | |
return false; | |
} | |
var baseRotation = this.getBaseRotation(); | |
var isRotated = baseRotation === 90 || baseRotation === 270; | |
var horizontalAxis = isRotated ? 'z' : 'x'; | |
var verticalAxis = isRotated ? 'x' : 'z'; | |
var topEdgeIntersectionRange = this.getBestIntersectionRange(this.getTopEdgePoints(), horizontalAxis); | |
var bottomEdgeIntersectionRange = this.getBestIntersectionRange(this.getBottomEdgePoints(), horizontalAxis); | |
if (topEdgeIntersectionRange || bottomEdgeIntersectionRange) { | |
var topIntersectionLength = topEdgeIntersectionRange ? topEdgeIntersectionRange.length : 0; | |
var bottomIntersectionLength = bottomEdgeIntersectionRange ? bottomEdgeIntersectionRange.length : 0; | |
var worktopEdgePoints = topIntersectionLength > bottomIntersectionLength ? this.getTopEdgePoints() : this.getBottomEdgePoints(); | |
var worktopStart = _.min([worktopEdgePoints[0][horizontalAxis], worktopEdgePoints[1][horizontalAxis]]); | |
var worktopEnd = _.max([worktopEdgePoints[0][horizontalAxis], worktopEdgePoints[1][horizontalAxis]]); | |
var largestWidthRange = _.max([topEdgeIntersectionRange, bottomEdgeIntersectionRange], 'length'); | |
var newWidth = largestWidthRange.length; | |
var rotation = this.getRotationByNormal(this.getEdgeNormal(this.getTopEdgePoints())); | |
if (isRotated) { | |
rotation = rotation - 90; | |
} | |
var rotationInRads = rotation * (Math.PI / 180); | |
/* | |
* Offset worktop by deltaX and deltaZ | |
* | |
* /| | |
* / | | |
* t/ | | |
* e/ | | |
* s/ | deltaZ | |
* f/ | | |
* f/ | | |
* o/ alpha | | |
* /________| | |
* deltaX | |
*/ | |
var cosAlpha = Math.abs(Math.cos(rotationInRads)); | |
var deltaX = (largestWidthRange.start - worktopStart + (largestWidthRange.end - worktopEnd)) / 2; | |
var deltaZ = deltaX * Math.tan(rotationInRads); | |
var newXPosition = this[horizontalAxis] + deltaX; | |
var newZPosition = this[verticalAxis] + deltaZ; | |
this.setHorizontalSize(newWidth / cosAlpha); | |
this[horizontalAxis] = newXPosition; | |
this[verticalAxis] = newZPosition; | |
return true; | |
} | |
return false; | |
}, | |
determineAutoRotate: function (target, snapNormal) { | |
var autoRotate = false; | |
if (target && snapNormal) { | |
var rotatedItems = ['AngledWall', 'Island']; | |
if (target.isAnyOf(rotatedItems)) { | |
autoRotate = true; | |
} | |
// See if we need to check that the "default" edge is at the front (facing away from the wall) | |
if (!this.hasCustomizedCorners()) { | |
this.getTaggedItems().forEach(function (item) { | |
if (this.getRotationNormal().negate().equals(item.getRotationNormal(), 0.004) && item.is('Wall')) { | |
this.setBaseRotation(this.getBaseRotation() - 180); | |
} | |
}, this); | |
} else { | |
var neededRotation = this.getNeededRotation(); | |
if (neededRotation !== 0) { | |
this.setBaseRotation(this.getBaseRotation() + neededRotation); | |
} | |
} | |
} | |
return autoRotate; | |
}, | |
appendChildProcesses: function (buffer) { | |
this.getSnappedItems().forEach(function (item) { | |
var process = item.toWorktopProcess && item.toWorktopProcess(); | |
if (process) { | |
if (buffer[process]) { | |
buffer[process] += 1; | |
} else { | |
buffer[process] = 1; | |
} | |
} | |
}); | |
}, | |
appendSundries: function (buffer) { | |
var sundries = this.getSundries(); | |
for (var property in sundries) { | |
if (sundries.hasOwnProperty(property)) { | |
var qty = sundries[property]; | |
if (qty > 0) { | |
var process = stringHelper.toHandle(property); | |
if (buffer[process]) { | |
buffer[process] += qty; | |
} else { | |
buffer[process] = qty; | |
} | |
} | |
} | |
} | |
}, | |
appendShaping: function (buffer) { | |
var corners = this.getWorktopCurveArray(); | |
corners.forEach(function (corner) { | |
var legacyCorner = worktopCornersHelper.convertCornerToLegacyCorner(corner, this); | |
var process = worktopData.getShapeProcessByTypeAndValue(legacyCorner.type, legacyCorner.value); | |
if (process) { | |
var handle = stringHelper.toHandle(process); | |
buffer[handle] = buffer[handle] ? buffer[handle] + 1 : 1; | |
} | |
}, this); | |
}, | |
getProcesses: function () { | |
var buffer = {}; | |
this.appendChildProcesses(buffer); | |
this.appendSundries(buffer); | |
this.appendShaping(buffer); | |
var processes = []; | |
for (var property in buffer) { | |
if (buffer.hasOwnProperty(property)) { | |
var process = { | |
process: property, | |
quantity: buffer[property] | |
}; | |
processes.push(process); | |
} | |
} | |
return processes; | |
}, | |
getEdgebandingLength: function () { | |
var edgebandingConfig = this.getEdgebandingConfig(); | |
var width = this.getWidth(); | |
var depth = this.getDepth(); | |
var edgebandingLengthMm = 0; | |
if (edgebandingConfig.front) { | |
edgebandingLengthMm += width; | |
} | |
if (edgebandingConfig.back) { | |
edgebandingLengthMm += width; | |
} | |
if (edgebandingConfig.left) { | |
edgebandingLengthMm += depth; | |
} | |
if (edgebandingConfig.right) { | |
edgebandingLengthMm += depth; | |
} | |
if (edgebandingConfig.curve) { | |
edgebandingLengthMm += cornerCalculator.getCornerLength(this); | |
} | |
return edgebandingLengthMm; | |
}, | |
/** | |
* Get a proposed height to set the worktop above based on | |
* units below constants.worktopHoistThreshold | |
*/ | |
getDefaultDistanceFromFloor: () => constants.worktopLineFromFloor, | |
/** | |
* Trigger a height adjustment to update any tagged items | |
* that care about the worktop | |
*/ | |
updateWorktopChildren: function () { | |
var filter = function (item) { | |
return item.is('AttachedToWorktopItem'); | |
}; | |
if (this.is('Upstand')) { | |
return; | |
} | |
var items = this.getTaggedItems(filter); | |
for (var i = 0; i < items.length; i += 1) { | |
var item = items[i]; | |
item.setDefaultHeight(); | |
} | |
}, | |
isBasketClickable: function () { | |
return false; | |
}, | |
setDepthFromPanel: function (depth) { | |
if (!this.taggedWalls || this.taggedWalls.length < 1) { | |
this.setDepthAnchorCentre(depth); | |
} else { | |
this.setDepthAnchorTop(depth); | |
} | |
}, | |
setWidthFromPanel: function (width) { | |
if (!this.taggedWalls || this.taggedWalls.length < 1) { | |
this.setWidthAnchorCentre(width); | |
} else { | |
this.setWidthAnchorLeft(width); | |
} | |
}, | |
isBaseLayerItem: function () { | |
return false; | |
}, | |
isWallLayerItem: function () { | |
return false; | |
}, | |
isWorktopLayerItem: function () { | |
return true; | |
}, | |
getInfoForPopover: function () { | |
var worktop = this.worktop; | |
if (!worktop) { | |
return null; | |
} | |
var info = { | |
imgSrc: imageHelper.getWorktopColourImageUrl(this.getSurfaceColour()), | |
material: this.getMaterial(), | |
colour: this.getSurfaceColour(), | |
thickness: this.getSelectedHeight(), | |
profile: this.getEdgeProfile() | |
}; | |
if (worktopsHelper.isLuxuryLaminate(this.getMaterial())) { | |
info.edgeBanding = this.getEdgeColour(); | |
} | |
return info; | |
}, | |
getListOfTabsForConfigurationPopup: function () { | |
return worktopConfigurationHelper.getListOfTabsForConfigurationPopup(this); | |
}, | |
isBreakfastBar: function () { | |
return _.get(this.model, 'worktop.worktopType') === constants.worktopType.BreakfastBar; | |
}, | |
getNormalsToCollide: function () { | |
var normals; | |
if (!this.isHorizontallyMovable()) { | |
normals = [ | |
this.top, | |
this.bottom | |
]; | |
} else { | |
normals = this.getAllSideNormals(); | |
} | |
return normals; | |
}, | |
getSelectedHeight: function () { | |
return this.getHeight(); | |
}, | |
setSelectedHeight: function (height) { | |
this.selectedHeight = height; | |
var heightInt = worktopsHelper.convertThicknessToHeight(height); | |
var distanceFromFloor = this.getDistanceFromFloor(); | |
this.setHeight(heightInt); | |
this.setDistanceFromFloor(distanceFromFloor); | |
this.updateCorners(); | |
}, | |
updateCorners: function () { | |
var corners = this.worktopCurve.getRaw(); | |
this.worktopCurve.setCustom(corners.map(function (cornerId, index) { | |
var isAvailable = cornersAvailability.isCornerConfigAvailableForCorner(this, index, {id: cornerId}); | |
return isAvailable ? cornerId : worktopCornersHelper.getUnfinishedCornerConfig().id; | |
}, this)); | |
this.updateAvailableCorners(); | |
}, | |
populateObject: compose.after(function (model) { | |
this.worktop = model.worktop || {}; | |
this.selectedHeight = model.selectedHeight; | |
this.worktopCurve = new WorktopCurve(); | |
var originalCurves = _.get(model.worktop, ['module', 'curve'], worktopCornersHelper.defaultCornersConfig()); | |
if (model.corners) { | |
// Handle legacy specialists' corners | |
var convertedConfig = worktopCornersHelper.convertLegacyCornersConfig(model.corners); | |
originalCurves = convertedConfig; | |
_.set(model, 'worktop.module.curve', convertedConfig); | |
} | |
if (model.customCurveConfig) { | |
this.worktopCurve.setCustom(model.customCurveConfig); | |
} | |
if (model.automaticCurveConfig) { | |
this.worktopCurve.setAutomatic(model.automaticCurveConfig); | |
} | |
this.worktopCurve.setOriginal(originalCurves); | |
this.snappingDisabled = _.get(model, 'worktop.snappingDisabled'); | |
this.updateAvailableCorners(); | |
}), | |
toPlanObject: compose.after(function () { | |
var item = this.planObject.item; | |
item.worktop = this.worktop; | |
var notRequiredGroups = _.get(this.model, 'notRequiredGroups', {}); | |
var configuredProducts = _.get(this.model, 'configuredProducts', {}); | |
item.selectedHeight = this.getSelectedHeight(); | |
item.notRequiredGroups = notRequiredGroups; | |
item.configuredProducts = configuredProducts; | |
if (this.worktopCurve.isCustomised()) { | |
item.customCurveConfig = this.worktopCurve.getRaw().join(''); | |
} | |
if (this.worktopCurve.automatic) { | |
item.automaticCurveConfig = this.worktopCurve.automatic.join(''); | |
} | |
// Legacy edge profiles config support | |
// TODO: remove | |
if (this.model.legacyEdgebandingConfig) { | |
item.legacyEdgebandingConfig = this.model.legacyEdgebandingConfig; | |
} | |
_.set(item, 'worktop.snappingDisabled', this.snappingDisabled); | |
return this.planObject; | |
}), | |
getOverlapLevel: _.constant(3), | |
getEdgebandingConfig: function () { | |
if (worktopsHelper.isLaminate(this.getMaterial())) { | |
return {}; | |
} | |
if (this.is('CornerWorktop')) { | |
return { | |
curve: true | |
}; | |
} | |
// Legacy edge profiles config support | |
// TODO: remove | |
if (this.model.legacyEdgebandingConfig) { | |
return this.model.legacyEdgebandingConfig; | |
} | |
// don't replace with just 'Wall' because islands should not trigger this (needed for stealth islands) | |
var isTaggedToWall = this.isTaggedToAny('OuterWall', 'InternalWall'); | |
var isIslandSpecialist = worktopsHelper.isSpecialist(this.getMaterial()) && !isTaggedToWall; | |
if (worktopsHelper.isSquareEdgeProfile(this.getEdgeProfile()) || isIslandSpecialist) { | |
return { | |
front: true, | |
back: true, | |
left: true, | |
right: true | |
}; | |
} | |
if (!this.hasCustomizedCorners()) { | |
return { | |
front: true | |
}; | |
} | |
var curves = this.getWorktopCurveArray(); | |
return { | |
front: curves[2] || curves[3], | |
back: curves[0] || curves[1], | |
left: curves[1] || curves[2], | |
right: curves[3] || curves[0] | |
}; | |
}, | |
getFullWorktopLength: function () { | |
return parseInt(this.worktop.module.w, 10); | |
}, | |
getFullWorktopDepth: function () { | |
return parseInt(this.worktop.module.d, 10); | |
}, | |
isConfiguredForBasket: function () { | |
var material = this.getMaterial(); | |
if (!material) { | |
return false; | |
} | |
if (((worktopsHelper.isSpecialist(material) || worktopsHelper.isTimber(material)) && !this.isAnyOf(['Upstand', 'ButcherBlock'])) && !this.getEdgeProfile()) { | |
return false; | |
} | |
if (worktopsHelper.isLuxuryLaminate(material) && !this.getEdgeColour()) { | |
return false; | |
} | |
if (!this.getSelectedHeight()) { | |
return false; | |
} | |
if (!this.getSurfaceColour()) { | |
return false; | |
} | |
if (this.is('Upstand') && worktopsHelper.isCorian(this.getMaterial()) && _.isEmpty(this.getUpstandType())) { | |
return false; | |
} | |
return true; | |
}, | |
isConfigured: function () { | |
if (this.shouldHaveUnderside() && !this.getUnderside()) { | |
return false; | |
} | |
if (!this.isConfiguredForBasket()) { | |
return false; | |
} | |
return true; | |
}, | |
shouldHaveUnderside: _.constant(false), | |
setUpstandType: _.noop, | |
getUpstandType: _.noop, | |
isSubjectForPlacementCheck: function () { | |
return !this.isSnappingDisabled(); | |
} | |
})); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment