diff --git a/src/Components/Editor/ContainerOperations.ts b/src/Components/Editor/ContainerOperations.ts index cbc0a9c..fde4a72 100644 --- a/src/Components/Editor/ContainerOperations.ts +++ b/src/Components/Editor/ContainerOperations.ts @@ -1,11 +1,9 @@ -import React, { Dispatch, SetStateAction } from 'react'; +import { Dispatch, SetStateAction } from 'react'; import { HistoryState } from '../../Interfaces/HistoryState'; import { Configuration } from '../../Interfaces/Configuration'; import { ContainerModel, IContainerModel } from '../../Interfaces/ContainerModel'; import { findContainerById } from '../../utils/itertools'; import { getCurrentHistory } from './Editor'; -import { SizePointer } from '../../Interfaces/SizePointer'; -import Properties from '../../Interfaces/Properties'; /** * Select a container @@ -38,6 +36,14 @@ export function SelectContainer( setHistoryCurrentStep(history.length); } +/** + * Delete a container + * @param containerId containerId of the container to delete + * @param fullHistory History of the editor + * @param historyCurrentStep Current step + * @param setHistory State setter for History + * @param setHistoryCurrentStep State setter for current step + */ export function DeleteContainer( containerId: string, fullHistory: HistoryState[], @@ -93,6 +99,11 @@ export function DeleteContainer( /** * Add a new container to a selected container * @param type The type of container + * @param configuration Configuration of the App + * @param fullHistory History of the editor + * @param historyCurrentStep Current step + * @param setHistory State setter for History + * @param setHistoryCurrentStep State setter for current step * @returns void */ export function AddContainerToSelectedContainer( @@ -124,6 +135,18 @@ export function AddContainerToSelectedContainer( ); } +/** + * Create and add a new container at `index` in children of parent of `parentId` + * @param index Index where to insert to the new container + * @param type Type of container + * @param parentId Parent in which to insert the new container + * @param configuration Configuration of the app + * @param fullHistory History of the editor + * @param historyCurrentStep Current step + * @param setHistory State setter of History + * @param setHistoryCurrentStep State setter of the current step + * @returns void + */ export function AddContainer( index: number, type: string, @@ -217,339 +240,3 @@ export function AddContainer( }])); setHistoryCurrentStep(history.length); } - -/** - * Handled the property change event in the properties form - * @param key Property name - * @param value New value of the property - * @returns void - */ -export function OnPropertyChange( - key: string, - value: string | number | boolean, - fullHistory: HistoryState[], - historyCurrentStep: number, - setHistory: Dispatch>, - setHistoryCurrentStep: Dispatch> -): void { - const history = getCurrentHistory(fullHistory, historyCurrentStep); - const current = history[history.length - 1]; - - if (current.SelectedContainer === null || - current.SelectedContainer === undefined) { - throw new Error('[OnPropertyChange] Property was changed before selecting a Container'); - } - - if (parent === null) { - const selectedContainerClone: IContainerModel = structuredClone(current.SelectedContainer); - (selectedContainerClone.properties as any)[key] = value; - setHistory(history.concat([{ - LastAction: 'Change property of main', - MainContainer: selectedContainerClone, - SelectedContainer: selectedContainerClone, - SelectedContainerId: selectedContainerClone.properties.id, - TypeCounters: Object.assign({}, current.TypeCounters) - }])); - setHistoryCurrentStep(history.length); - return; - } - - const mainContainerClone: IContainerModel = structuredClone(current.MainContainer); - const container: ContainerModel | undefined = findContainerById(mainContainerClone, current.SelectedContainer.properties.id); - - if (container === null || container === undefined) { - throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); - } - - (container.properties as any)[key] = value; - - if (container.properties.isRigidBody) { - RecalculatePhysics(container); - } - - setHistory(history.concat([{ - LastAction: `Change property of container ${container.properties.id}`, - MainContainer: mainContainerClone, - SelectedContainer: container, - SelectedContainerId: container.properties.id, - TypeCounters: Object.assign({}, current.TypeCounters) - }])); - setHistoryCurrentStep(history.length); -} - -/** - * Handled the property change event in the properties form - * @param key Property name - * @param value New value of the property - * @returns void - */ -export function OnPropertiesSubmit( - event: React.SyntheticEvent, - properties: Properties, - fullHistory: HistoryState[], - historyCurrentStep: number, - setHistory: Dispatch>, - setHistoryCurrentStep: Dispatch> -): void { - event.preventDefault(); - const history = getCurrentHistory(fullHistory, historyCurrentStep); - const current = history[history.length - 1]; - - if (current.SelectedContainer === null || - current.SelectedContainer === undefined) { - throw new Error('[OnPropertyChange] Property was changed before selecting a Container'); - } - - if (parent === null) { - const selectedContainerClone: IContainerModel = structuredClone(current.SelectedContainer); - for (const property in properties) { - const input = (event.target as HTMLFormElement).querySelector(`#${property}`); - if (input instanceof HTMLInputElement) { - (selectedContainerClone.properties as any)[property] = input.value; - } - } - setHistory(history.concat([{ - LastAction: 'Change property of main', - MainContainer: selectedContainerClone, - SelectedContainer: selectedContainerClone, - SelectedContainerId: selectedContainerClone.properties.id, - TypeCounters: Object.assign({}, current.TypeCounters) - }])); - setHistoryCurrentStep(history.length); - return; - } - - const mainContainerClone: IContainerModel = structuredClone(current.MainContainer); - const container: ContainerModel | undefined = findContainerById(mainContainerClone, current.SelectedContainer.properties.id); - - if (container === null || container === undefined) { - throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); - } - - for (const property in properties) { - const input = (event.target as HTMLFormElement).querySelector(`#${property}`); - if (input instanceof HTMLInputElement) { - (container.properties as any)[property] = input.value; - } - } - - if (container.properties.isRigidBody) { - RecalculatePhysics(container); - } - - setHistory(history.concat([{ - LastAction: `Change property of container ${container.properties.id}`, - MainContainer: mainContainerClone, - SelectedContainer: container, - SelectedContainerId: container.properties.id, - TypeCounters: Object.assign({}, current.TypeCounters) - }])); - setHistoryCurrentStep(history.length); -} - -// TODO put this in a different file - -export function RecalculatePhysics(container: IContainerModel): IContainerModel { - container = constraintBodyInsideParent(container); - container = constraintBodyInsideUnallocatedWidth(container); - return container; -} - -/** - * Limit a rect inside a parent rect by applying the following rules : - * it cannot be bigger than the parent - * it cannot go out of bound - * @param container - * @returns - */ -function constraintBodyInsideParent(container: IContainerModel): IContainerModel { - if (container.parent === null || container.parent === undefined) { - return container; - } - - const parentProperties = container.parent.properties; - const parentWidth = Number(parentProperties.width); - const parentHeight = Number(parentProperties.height); - - return constraintBodyInsideSpace(container, 0, 0, parentWidth, parentHeight); -} - -function constraintBodyInsideSpace( - container: IContainerModel, - x: number, - y: number, - width: number, - height: number -): IContainerModel { - const containerProperties = container.properties; - const containerX = Number(containerProperties.x); - const containerY = Number(containerProperties.y); - const containerWidth = Number(containerProperties.width); - const containerHeight = Number(containerProperties.height); - - // Check size bigger than parent - const isBodyLargerThanParent = containerWidth > width; - const isBodyTallerThanParentHeight = containerHeight > height; - if (isBodyLargerThanParent || isBodyTallerThanParentHeight) { - if (isBodyLargerThanParent) { - containerProperties.x = x; - containerProperties.width = width; - } - if (isBodyTallerThanParentHeight) { - containerProperties.y = y; - containerProperties.height = height; - } - return container; - } - - // Check horizontal out of bound - if (containerX < x) { - containerProperties.x = x; - } - if (containerX + containerWidth > width) { - containerProperties.x = x + width - containerWidth; - } - - // Check vertical out of bound - if (containerY < y) { - containerProperties.y = y; - } - if (containerY + containerHeight > height) { - containerProperties.y = y + height - containerHeight; - } - - return container; -} - -/** - * Get the unallocated widths inside a container - * An allocated width is defined by its the widths of the children that are rigid bodies. - * An example of this allocation system is the disk space - * (except the fact that disk space is divided by block). - * @param container - * @returns {SizePointer[]} Array of unallocated widths (x=position of the unallocated space, width=size of the allocated space) - */ -function getAvailableWidths(container: IContainerModel, exception: IContainerModel): SizePointer[] { - const x = 0; - const width = Number(container.properties.width); - let unallocatedSpaces: SizePointer[] = [{ x, width }]; - - const rigidBodies = container.children.filter(child => child.properties.isRigidBody); - for (const child of rigidBodies) { - if (child === exception) { - continue; - } - - // get the space of the child that is inside the parent - let newUnallocatedSpace: SizePointer[] = []; - for (const unallocatedSpace of unallocatedSpaces) { - const newUnallocatedWidths = getAvailableWidthsTwoLines( - unallocatedSpace.x, - unallocatedSpace.x + unallocatedSpace.width, - child.properties.x, - child.properties.x + Number(child.properties.width)); - newUnallocatedSpace = newUnallocatedSpace.concat(newUnallocatedWidths); - } - unallocatedSpaces = newUnallocatedSpace; - } - - return unallocatedSpaces; -} - -/** - * Returns the unallocated widths between two lines in 1D - * @param min1 left of the first line - * @param max1 rigth of the first line - * @param min2 left of the second line - * @param max2 right of the second line - * @returns Available widths - */ -function getAvailableWidthsTwoLines(min1: number, max1: number, min2: number, max2: number): SizePointer[] { - if (min2 < min1 && max2 > max1) { - // object 2 is overlapping full width - return []; - } - - if (min1 >= min2) { - // object 2 is partially overlapping on the left - return [{ - x: max2, - width: max1 - max2 - }]; - } - - if (max2 >= max1) { - // object 2 is partially overlapping on the right - return [{ - x: min2, - width: max2 - min1 - }]; - } - - // object 2 is overlapping in the middle - return [ - { - x: min1, - width: min2 - min1 - }, - { - x: min2, - width: max1 - max2 - } - ]; -} - -/** - * - * @param container - * @returns - */ -function constraintBodyInsideUnallocatedWidth(container: IContainerModel): IContainerModel { - if (container.parent === null) { - return container; - } - - const availableWidths = getAvailableWidths(container.parent, container); - const containerX = Number(container.properties.x); - - // Sort the available width - availableWidths - .sort((width1, width2) => Math.abs(width1.x - containerX) - Math.abs(width2.x - containerX)); - - if (availableWidths.length === 0) { - throw new Error('No available space found on the parent container. Try to free the parent a little before placing it inside.'); - } - - const availableWidthFound = availableWidths.find( - width => isFitting(container, width) - ); - - if (availableWidthFound === undefined) { - // There is two way to reach this part of the code - // 1) toggle the isRigidBody such as width > availableWidth.width - // 2) resize a container such as width > availableWidth.width - // We want the container to fit automatically inside the available space - // even if it means to resize the container - // The end goal is that the code never show the error message no matter what action is done - // TODO: Actually give an option to not fit and show the error message shown below - const availableWidth = availableWidths[0]; - container.properties.x = availableWidth.x; - container.properties.width = availableWidth.width; - // throw new Error('[constraintBodyInsideUnallocatedWidth] BIGERR: No available space found on the parent container, even though there is some.'); - return container; - } - - return constraintBodyInsideSpace( - container, - availableWidthFound.x, - 0, - availableWidthFound.width, - Number(container.parent.properties.height) - ); -} - -function isFitting(container: IContainerModel, sizePointer: SizePointer): boolean { - const containerWidth = Number(container.properties.width); - - return containerWidth <= sizePointer.width; -} diff --git a/src/Components/Editor/Editor.tsx b/src/Components/Editor/Editor.tsx index f07d5e8..09627e4 100644 --- a/src/Components/Editor/Editor.tsx +++ b/src/Components/Editor/Editor.tsx @@ -4,9 +4,10 @@ import { Configuration } from '../../Interfaces/Configuration'; import { SVG } from '../SVG/SVG'; import { HistoryState } from '../../Interfaces/HistoryState'; import { UI } from '../UI/UI'; -import { SelectContainer, DeleteContainer, OnPropertyChange, AddContainerToSelectedContainer, AddContainer, OnPropertiesSubmit } from './ContainerOperations'; +import { SelectContainer, DeleteContainer, AddContainerToSelectedContainer, AddContainer } from './ContainerOperations'; import { SaveEditorAsJSON, SaveEditorAsSVG } from './Save'; import { onKeyDown } from './Shortcuts'; +import { OnPropertyChange, OnPropertiesSubmit } from './PropertiesOperations'; interface IEditorProps { configuration: Configuration diff --git a/src/Components/Editor/PropertiesOperations.ts b/src/Components/Editor/PropertiesOperations.ts new file mode 100644 index 0000000..f97e1cb --- /dev/null +++ b/src/Components/Editor/PropertiesOperations.ts @@ -0,0 +1,136 @@ +import { Dispatch, SetStateAction } from 'react'; +import { IContainerModel, ContainerModel } from '../../Interfaces/ContainerModel'; +import { HistoryState } from '../../Interfaces/HistoryState'; +import Properties from '../../Interfaces/Properties'; +import { findContainerById } from '../../utils/itertools'; +import { getCurrentHistory } from './Editor'; +import { RecalculatePhysics } from './RigidBodyBehaviors'; + +/** + * Handled the property change event in the properties form + * @param key Property name + * @param value New value of the property + * @returns void + */ +export function OnPropertyChange( + key: string, + value: string | number | boolean, + fullHistory: HistoryState[], + historyCurrentStep: number, + setHistory: Dispatch>, + setHistoryCurrentStep: Dispatch> +): void { + const history = getCurrentHistory(fullHistory, historyCurrentStep); + const current = history[history.length - 1]; + + if (current.SelectedContainer === null || + current.SelectedContainer === undefined) { + throw new Error('[OnPropertyChange] Property was changed before selecting a Container'); + } + + if (parent === null) { + const selectedContainerClone: IContainerModel = structuredClone(current.SelectedContainer); + (selectedContainerClone.properties as any)[key] = value; + setHistory(history.concat([{ + LastAction: 'Change property of main', + MainContainer: selectedContainerClone, + SelectedContainer: selectedContainerClone, + SelectedContainerId: selectedContainerClone.properties.id, + TypeCounters: Object.assign({}, current.TypeCounters) + }])); + setHistoryCurrentStep(history.length); + return; + } + + const mainContainerClone: IContainerModel = structuredClone(current.MainContainer); + const container: ContainerModel | undefined = findContainerById(mainContainerClone, current.SelectedContainer.properties.id); + + if (container === null || container === undefined) { + throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); + } + + (container.properties as any)[key] = value; + + if (container.properties.isRigidBody) { + RecalculatePhysics(container); + } + + setHistory(history.concat([{ + LastAction: `Change property of container ${container.properties.id}`, + MainContainer: mainContainerClone, + SelectedContainer: container, + SelectedContainerId: container.properties.id, + TypeCounters: Object.assign({}, current.TypeCounters) + }])); + setHistoryCurrentStep(history.length); +} + +/** + * Handled the property change event in the properties form + * @param key Property name + * @param properties Properties of the selected container + * @returns void + */ +export function OnPropertiesSubmit( + event: React.SyntheticEvent, + properties: Properties, + fullHistory: HistoryState[], + historyCurrentStep: number, + setHistory: Dispatch>, + setHistoryCurrentStep: Dispatch> +): void { + event.preventDefault(); + const history = getCurrentHistory(fullHistory, historyCurrentStep); + const current = history[history.length - 1]; + + if (current.SelectedContainer === null || + current.SelectedContainer === undefined) { + throw new Error('[OnPropertyChange] Property was changed before selecting a Container'); + } + + if (parent === null) { + const selectedContainerClone: IContainerModel = structuredClone(current.SelectedContainer); + for (const property in properties) { + const input = (event.target as HTMLFormElement).querySelector(`#${property}`); + if (input instanceof HTMLInputElement) { + (selectedContainerClone.properties as any)[property] = input.value; + } + } + setHistory(history.concat([{ + LastAction: 'Change property of main', + MainContainer: selectedContainerClone, + SelectedContainer: selectedContainerClone, + SelectedContainerId: selectedContainerClone.properties.id, + TypeCounters: Object.assign({}, current.TypeCounters) + }])); + setHistoryCurrentStep(history.length); + return; + } + + const mainContainerClone: IContainerModel = structuredClone(current.MainContainer); + const container: ContainerModel | undefined = findContainerById(mainContainerClone, current.SelectedContainer.properties.id); + + if (container === null || container === undefined) { + throw new Error('[OnPropertyChange] Container model was not found among children of the main container!'); + } + + for (const property in properties) { + const input = (event.target as HTMLFormElement).querySelector(`#${property}`); + if (input instanceof HTMLInputElement) { + (container.properties as any)[property] = input.value; + } + } + + if (container.properties.isRigidBody) { + RecalculatePhysics(container); + } + + setHistory(history.concat([{ + LastAction: `Change property of container ${container.properties.id}`, + MainContainer: mainContainerClone, + SelectedContainer: container, + SelectedContainerId: container.properties.id, + TypeCounters: Object.assign({}, current.TypeCounters) + }])); + setHistoryCurrentStep(history.length); +} diff --git a/src/Components/Editor/RigidBodyBehaviors.ts b/src/Components/Editor/RigidBodyBehaviors.ts new file mode 100644 index 0000000..95ce545 --- /dev/null +++ b/src/Components/Editor/RigidBodyBehaviors.ts @@ -0,0 +1,280 @@ +import { IContainerModel } from '../../Interfaces/ContainerModel'; +import { SizePointer } from '../../Interfaces/SizePointer'; + +/** + * "Transform the container into a rigid body" + * Apply the following contraints to the `container` : + * - The container must be kept inside its parent + * - The container must find an unallocated space within the parent + * If the contraints fails, an error message will be returned + * @param container Container to apply its rigid body properties + * @returns A rigid body container + */ +export function RecalculatePhysics( + container: IContainerModel +): IContainerModel { + container = constraintBodyInsideParent(container); + container = constraintBodyInsideUnallocatedWidth(container); + return container; +} + +/** + * Limit a rect inside a parent rect by applying the following rules : + * it cannot be bigger than the parent + * it cannot go out of bound + * Mutates and returns the container + * @param container + * @returns Updated container + */ +function constraintBodyInsideParent( + container: IContainerModel +): IContainerModel { + if (container.parent === null || container.parent === undefined) { + return container; + } + + const parentProperties = container.parent.properties; + const parentWidth = Number(parentProperties.width); + const parentHeight = Number(parentProperties.height); + + return constraintBodyInsideSpace(container, 0, 0, parentWidth, parentHeight); +} + +/** + * Limit a container inside a rectangle + * Mutates and returns the container + * @param container A container + * @param x x of top left of the rectangle + * @param y y of top left of the rectangle + * @param width width of the rectangle + * @param height height of the rectangle + * @returns Updated container + */ +function constraintBodyInsideSpace( + container: IContainerModel, + x: number, + y: number, + width: number, + height: number +): IContainerModel { + const containerProperties = container.properties; + const containerX = Number(containerProperties.x); + const containerY = Number(containerProperties.y); + const containerWidth = Number(containerProperties.width); + const containerHeight = Number(containerProperties.height); + + // Check size bigger than parent + const isBodyLargerThanParent = containerWidth > width; + const isBodyTallerThanParentHeight = containerHeight > height; + if (isBodyLargerThanParent || isBodyTallerThanParentHeight) { + if (isBodyLargerThanParent) { + containerProperties.x = x; + containerProperties.width = width; + } + if (isBodyTallerThanParentHeight) { + containerProperties.y = y; + containerProperties.height = height; + } + return container; + } + + // Check horizontal out of bound + if (containerX < x) { + containerProperties.x = x; + } + if (containerX + containerWidth > width) { + containerProperties.x = x + width - containerWidth; + } + + // Check vertical out of bound + if (containerY < y) { + containerProperties.y = y; + } + if (containerY + containerHeight > height) { + containerProperties.y = y + height - containerHeight; + } + + return container; +} + +/** + * Constraint the container inside unallocated width/space of the parent container + * If there is no unalloacted width/space, an error will be thrown + * Mutates and returns the container + * @param container + * @returns Updated container + */ +function constraintBodyInsideUnallocatedWidth( + container: IContainerModel +): IContainerModel { + if (container.parent === null) { + return container; + } + + // Get the available spaces of the parent + const availableWidths = getAvailableWidths(container.parent, container); + const containerX = Number(container.properties.x); + + // Sort the available width to find the closest one + availableWidths.sort( + (width1, width2) => + Math.abs(width1.x - containerX) - Math.abs(width2.x - containerX) + ); + + // Check if there is still some space + if (availableWidths.length === 0) { + throw new Error( + 'No available space found on the parent container. Try to free the parent a little before placing it inside.' + ); + } + + // Check if the container actually fit inside + // It will usually fit if it was alrady fitting + const availableWidthFound = availableWidths.find((width) => + isFitting(container, width) + ); + + if (availableWidthFound === undefined) { + // Otherwise, it is possible that it does not fit + // There is two way to reach this part of the code + // 1) Enable isRigidBody such as width > availableWidth.width + // 2) Resize a container such as width > availableWidth.width + + // We want the container to fit automatically inside the available space + // even if it means to resize the container + // The end goal is that the code never show the error message no matter what action is done + // TODO: Actually give an option to not fit and show the error message shown below + const availableWidth = availableWidths[0]; + container.properties.x = availableWidth.x; + container.properties.width = availableWidth.width; + // throw new Error('[constraintBodyInsideUnallocatedWidth] BIGERR: No available space found on the parent container, even though there is some.'); + return container; + } + + return constraintBodyInsideSpace( + container, + availableWidthFound.x, + 0, + availableWidthFound.width, + Number(container.parent.properties.height) + ); +} + +/** + * Get the unallocated widths inside a container + * An allocated width is defined by its the widths of the children that are rigid bodies. + * An example of this allocation system is the disk space of an hard drive + * (except the fact that disk space is divided by block). + * @param container Container where to find an available width + * @param exception Container to exclude of the widths (since a container will be moved, it might need to be excluded) + * @returns {SizePointer[]} Array of unallocated widths (x=position of the unallocated space, width=size of the allocated space) + */ +function getAvailableWidths( + container: IContainerModel, + exception: IContainerModel +): SizePointer[] { + // Initialize the first size pointer + // which takes full width of the available space + const x = 0; + const width = Number(container.properties.width); + let unallocatedSpaces: SizePointer[] = [{ x, width }]; + + // We will only uses containers that also have the rigid bodies + // as out-of-bound or enormouse containers should be ignored + const rigidBodies = container.children.filter( + (child) => child.properties.isRigidBody + ); + + for (const child of rigidBodies) { + // Ignore the exception + if (child === exception) { + continue; + } + + // get the space of the child that is inside the parent + let newUnallocatedSpace: SizePointer[] = []; + + // We will iterate on a mutable variable in order to divide it + for (const unallocatedSpace of unallocatedSpaces) { + // In order to find unallocated space, + // We need to calculate the overlap between the two containers + // We only works with widths meaning in 1D (with lines) + const newUnallocatedWidths = getAvailableWidthsTwoLines( + unallocatedSpace.x, + unallocatedSpace.x + unallocatedSpace.width, + child.properties.x, + child.properties.x + Number(child.properties.width) + ); + + // Concat the new list of SizePointer pointing to availables spaces + newUnallocatedSpace = newUnallocatedSpace.concat(newUnallocatedWidths); + } + // Finally update the availables spaces found, loop again with it + unallocatedSpaces = newUnallocatedSpace; + } + + return unallocatedSpaces; +} + +/** + * Returns the unallocated widths between two lines in 1D + * @param min1 left of the first line + * @param max1 rigth of the first line + * @param min2 left of the second line + * @param max2 right of the second line + * @returns Available widths + */ +function getAvailableWidthsTwoLines( + min1: number, + max1: number, + min2: number, + max2: number +): SizePointer[] { + if (min2 < min1 && max2 > max1) { + // object 2 is overlapping full width + return []; + } + + if (min1 >= min2) { + // object 2 is partially overlapping on the left + return [ + { + x: max2, + width: max1 - max2 + } + ]; + } + + if (max2 >= max1) { + // object 2 is partially overlapping on the right + return [ + { + x: min2, + width: max2 - min1 + } + ]; + } + + // object 2 is overlapping in the middle + return [ + { + x: min1, + width: min2 - min1 + }, + { + x: min2, + width: max1 - max2 + } + ]; +} + +/** + * Check if a container can fit inside a size space + * @param container Container to check + * @param sizePointer Size space to check + * @returns + */ +const isFitting = ( + container: IContainerModel, + sizePointer: SizePointer +): boolean => Number(container.properties.width) <= sizePointer.width; diff --git a/src/Interfaces/SizePointer.ts b/src/Interfaces/SizePointer.ts index 9a80057..e5ec599 100644 --- a/src/Interfaces/SizePointer.ts +++ b/src/Interfaces/SizePointer.ts @@ -1,3 +1,8 @@ +/** + * A SizePointer is a pointer in a 1 dimensional array of width/space + * x being the address where the pointer is pointing + * width being the overall (un)allocated space affected to the address + */ export interface SizePointer { x: number width: number