working on fixing canvas expansion
This commit is contained in:
@@ -31,6 +31,9 @@ class Widget extends React.Component{
|
||||
this._disableResize = false
|
||||
this._disableSelection = false
|
||||
|
||||
this.minSize = {width: 50, height: 50} // disable resizing below this number
|
||||
this.maxSize = {width: 500, height: 500} // disable resizing above this number
|
||||
|
||||
this.cursor = Cursor.POINTER
|
||||
|
||||
this.icon = "" // antd icon name representing this widget
|
||||
@@ -76,18 +79,26 @@ class Widget extends React.Component{
|
||||
},
|
||||
zIndex: 0,
|
||||
pos: {x: 0, y: 0},
|
||||
size: { width: 100, height: 100 },
|
||||
selected: false,
|
||||
widgetName: widgetName || 'unnamed widget' // this will later be converted to variable name
|
||||
widgetName: widgetName || 'unnamed widget', // this will later be converted to variable name
|
||||
resizing: false,
|
||||
resizeCorner: ""
|
||||
}
|
||||
|
||||
this.mousePress = this.mousePress.bind(this)
|
||||
this.getElement = this.getElement.bind(this)
|
||||
this.getBoundingRect = this.getBoundingRect.bind(this)
|
||||
|
||||
this.isSelected = this.isSelected.bind(this)
|
||||
|
||||
this.getPos = this.getPos.bind(this)
|
||||
this.setPos = this.setPos.bind(this)
|
||||
|
||||
this.startResizing = this.startResizing.bind(this)
|
||||
this.handleResize = this.handleResize.bind(this)
|
||||
this.stopResizing = this.stopResizing.bind(this)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -101,10 +112,16 @@ class Widget extends React.Component{
|
||||
componentDidMount(){
|
||||
console.log("mounted: ")
|
||||
this.elementRef.current?.addEventListener("click", this.mousePress)
|
||||
|
||||
this.canvas.addEventListener("mousemove", this.handleResize);
|
||||
this.canvas.addEventListener("mouseup", this.stopResizing)
|
||||
}
|
||||
|
||||
componentWillUnmount(){
|
||||
this.elementRef.current?.removeEventListener("click", this.mousePress)
|
||||
|
||||
this.canvas.addEventListener("mousemove", this.handleResize);
|
||||
this.canvas.addEventListener("mouseup", this.stopResizing)
|
||||
}
|
||||
|
||||
// TODO: add context menu items such as delete, add etc
|
||||
@@ -143,8 +160,6 @@ class Widget extends React.Component{
|
||||
this.setState({
|
||||
selected: false
|
||||
})
|
||||
console.log("DeSelected")
|
||||
|
||||
}
|
||||
|
||||
isSelected(){
|
||||
@@ -152,6 +167,12 @@ class Widget extends React.Component{
|
||||
}
|
||||
|
||||
setPos(x, y){
|
||||
|
||||
if (this.state.resizing){
|
||||
// don't change position when resizing the widget
|
||||
return
|
||||
}
|
||||
|
||||
this.setState({
|
||||
pos: {x: x, y: y}
|
||||
})
|
||||
@@ -165,6 +186,48 @@ class Widget extends React.Component{
|
||||
return this.attrs
|
||||
}
|
||||
|
||||
getBoundingRect(){
|
||||
return this.elementRef.current?.getBoundingClientRect()
|
||||
}
|
||||
|
||||
getSize(){
|
||||
const boundingRect = this.getBoundingRect()
|
||||
|
||||
return {width: boundingRect.width, height: boundingRect.height}
|
||||
}
|
||||
|
||||
getScaleAwareDimensions() {
|
||||
// Get the bounding rectangle
|
||||
const rect = this.elementRef.current.getBoundingClientRect()
|
||||
|
||||
// Get the computed style of the element
|
||||
const style = window.getComputedStyle(this.elementRef.current)
|
||||
|
||||
// Get the transform matrix
|
||||
const transform = style.transform
|
||||
|
||||
// Extract scale factors from the matrix
|
||||
let scaleX = 1
|
||||
let scaleY = 1
|
||||
|
||||
if (transform && transform !== 'none') {
|
||||
// For 2D transforms (a, c, b, d)
|
||||
const matrix = transform.match(/^matrix\(([^,]+),[^,]+,([^,]+),[^,]+,[^,]+,[^,]+\)$/);
|
||||
|
||||
if (matrix) {
|
||||
scaleX = parseFloat(matrix[1])
|
||||
scaleY = parseFloat(matrix[2])
|
||||
}
|
||||
}
|
||||
|
||||
// Return scaled width and height
|
||||
return {
|
||||
width: rect.width / scaleX,
|
||||
height: rect.height / scaleY
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getWidgetFunctions(){
|
||||
return this.functions
|
||||
}
|
||||
@@ -177,6 +240,59 @@ class Widget extends React.Component{
|
||||
return this.elementRef.current
|
||||
}
|
||||
|
||||
startResizing(corner, event) {
|
||||
event.stopPropagation()
|
||||
this.setState({ resizing: true, resizeCorner: corner })
|
||||
}
|
||||
|
||||
handleResize(event) {
|
||||
if (!this.state.resizing) return
|
||||
|
||||
const { resizeCorner, size, pos } = this.state
|
||||
const deltaX = event.movementX
|
||||
const deltaY = event.movementY
|
||||
|
||||
let newSize = { ...size }
|
||||
let newPos = { ...pos }
|
||||
|
||||
const {width: minWidth, height: minHeight} = this.minSize
|
||||
const {width: maxWidth, height: maxHeight} = this.maxSize
|
||||
console.log("resizing: ", minHeight, minHeight)
|
||||
|
||||
switch (resizeCorner) {
|
||||
case "nw":
|
||||
newSize.width = Math.max(minWidth, Math.min(maxWidth, newSize.width - deltaX))
|
||||
newSize.height = Math.max(minHeight, Math.min(maxHeight, newSize.height - deltaY))
|
||||
newPos.x += (newSize.width !== size.width) ? deltaX : 0
|
||||
newPos.y += (newSize.height !== size.height) ? deltaY : 0
|
||||
break
|
||||
case "ne":
|
||||
newSize.width = Math.max(minWidth, Math.min(maxWidth, newSize.width + deltaX))
|
||||
newSize.height = Math.max(minHeight, Math.min(maxHeight, newSize.height - deltaY))
|
||||
newPos.y += (newSize.height !== size.height) ? deltaY : 0
|
||||
break
|
||||
case "sw":
|
||||
newSize.width = Math.max(minWidth, Math.min(maxWidth, newSize.width - deltaX))
|
||||
newSize.height = Math.max(minHeight, Math.min(maxHeight, newSize.height + deltaY))
|
||||
newPos.x += (newSize.width !== size.width) ? deltaX : 0
|
||||
break
|
||||
case "se":
|
||||
newSize.width = Math.max(minWidth, Math.min(maxWidth, newSize.width + deltaX))
|
||||
newSize.height = Math.max(minHeight, Math.min(maxHeight, newSize.height + deltaY))
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
this.setState({ size: newSize, pos: newPos })
|
||||
}
|
||||
|
||||
stopResizing() {
|
||||
if (this.state.resizing) {
|
||||
this.setState({ resizing: false })
|
||||
}
|
||||
}
|
||||
|
||||
renderContent(){
|
||||
// throw new NotImplementedError("render method has to be implemented")
|
||||
return (
|
||||
@@ -196,8 +312,8 @@ class Widget extends React.Component{
|
||||
cursor: this.cursor,
|
||||
top: `${this.state.pos.y}px`,
|
||||
left: `${this.state.pos.x}px`,
|
||||
width: this.boundingRect.width,
|
||||
height: this.boundingRect.height
|
||||
width: `${this.state.size.width}px`,
|
||||
height: `${this.state.size.height}px`,
|
||||
}
|
||||
|
||||
let selectionStyle = {
|
||||
@@ -224,20 +340,36 @@ class Widget extends React.Component{
|
||||
{this.renderContent()}
|
||||
<div className={`tw-absolute tw-bg-transparent tw-scale-[1.1] tw-opacity-100
|
||||
tw-w-full tw-h-full tw-top-0
|
||||
${this.state.selected ? 'tw-border-2 tw-border-solid tw-border-blue-500' : 'tw-border-none'}`}>
|
||||
${this.state.selected ? 'tw-border-2 tw-border-solid tw-border-blue-500' : 'tw-hidden'}`}>
|
||||
|
||||
<div className="tw-relative tw-w-full tw-h-full">
|
||||
|
||||
{/* <div contentEditable="true" onClick={(e) => e.preventDefault()} className="tw-text-sm tw-w-fit tw-min-w-[100px] tw-absolute tw--top-2">
|
||||
{this._widgetName}
|
||||
</div> */}
|
||||
{ this.state.selected &&
|
||||
<EditableDiv value={this.state.widgetName} onChange={onWidgetNameChange}
|
||||
<EditableDiv value={this.state.widgetName} onChange={onWidgetNameChange}
|
||||
maxLength={40}
|
||||
className="tw-text-sm tw-w-fit tw-max-w-[160px] tw-text-clip tw-min-w-[150px]
|
||||
tw-overflow-hidden tw-absolute tw--top-4 tw-h-6"
|
||||
tw-overflow-hidden tw-absolute tw--top-6 tw-h-6"
|
||||
/>
|
||||
}
|
||||
|
||||
<div
|
||||
className="tw-w-2 tw-h-2 tw-absolute tw--left-1 tw--top-1 tw-bg-blue-500"
|
||||
style={{ cursor: Cursor.NW_RESIZE }}
|
||||
onMouseDown={(e) => this.startResizing("nw", e)}
|
||||
/>
|
||||
<div
|
||||
className="tw-w-2 tw-h-2 tw-absolute tw--right-1 tw--top-1 tw-bg-blue-500"
|
||||
style={{ cursor: Cursor.SW_RESIZE }}
|
||||
onMouseDown={(e) => this.startResizing("ne", e)}
|
||||
/>
|
||||
<div
|
||||
className="tw-w-2 tw-h-2 tw-absolute tw--left-1 tw--bottom-1 tw-bg-blue-500"
|
||||
style={{ cursor: Cursor.SW_RESIZE }}
|
||||
onMouseDown={(e) => this.startResizing("sw", e)}
|
||||
/>
|
||||
<div
|
||||
className="tw-w-2 tw-h-2 tw-absolute tw--right-1 tw--bottom-1 tw-bg-blue-500"
|
||||
style={{ cursor: Cursor.SE_RESIZE }}
|
||||
onMouseDown={(e) => this.startResizing("se", e)}
|
||||
/>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user