fix: fixed the selection and delete widget

This commit is contained in:
paul
2024-09-13 12:28:32 +05:30
parent c94fd3918d
commit 23f1e08fbc
7 changed files with 170 additions and 57 deletions

View File

@@ -2,13 +2,14 @@ import React from "react"
import {DndContext} from '@dnd-kit/core'
import { CloseOutlined, FullscreenOutlined, ReloadOutlined } from "@ant-design/icons"
import { CloseOutlined, DeleteOutlined, EditOutlined, FullscreenOutlined, ReloadOutlined } from "@ant-design/icons"
import { Button, Tooltip, Dropdown } from "antd"
import Droppable from "../components/utils/droppable"
import Widget from "./widgets/base"
import Cursor from "./constants/cursor"
import { UID } from "../utils/uid"
import { removeDuplicateObjects } from "../utils/common"
const CanvasModes = {
@@ -71,6 +72,8 @@ class Canvas extends React.Component {
this.fitCanvasToBoundingBox = this.fitCanvasToBoundingBox.bind(this)
this.getCanvasBoundingRect = this.getCanvasContainerBoundingRect.bind(this)
this.deleteSelectedWidgets = this.deleteSelectedWidgets.bind(this)
this.removeWidget = this.removeWidget.bind(this)
this.clearSelections = this.clearSelections.bind(this)
this.clearCanvas = this.clearCanvas.bind(this)
@@ -159,19 +162,23 @@ class Canvas extends React.Component {
if (selectedWidget){
// if the widget is selected don't pan, instead move the widget
if (!selectedWidget._disableSelection){
selectedWidget.select()
if (this.selectedWidgets.length >= 1){ // allow only one selection for now
this.clearSelections()
const selectedLength = this.selectedWidgets.length
if (selectedLength === 0 || (selectedLength === 1 && selectedWidget.__id !== this.selectedWidgets[0].__id)){
this.selectedWidgets[0]?.deSelect() // deselect the previous widget before adding the new one
this.selectedWidgets[0]?.setZIndex(0)
selectedWidget.setZIndex(1000)
selectedWidget.select()
this.selectedWidgets[0] = selectedWidget
}
this.selectedWidgets.push(selectedWidget)
this.currentMode = CanvasModes.MOVE_WIDGET
}
this.currentMode = CanvasModes.PAN
}else if (this.state?.widgets?.length > 0){
}else if (!selectedWidget){
// get the canvas ready to pan, if there are widgets on the canvas
this.clearSelections()
this.currentMode = CanvasModes.PAN
@@ -187,24 +194,36 @@ class Canvas extends React.Component {
// })
}else if (event.button === 2){
//right click
if (selectedWidget)
this.setState({
contextMenuItems: [{
key: "delete",
label: "Delete"
}]
})
if (this.selectedWidgets.length > 0 && this.selectedWidgets[0].__id !== selectedWidget.__id){
this.clearSelections()
}
// this.setState({
// showContextMenu: true
// })
console.log("button: ", selectedWidget)
if (selectedWidget)
this.selectedWidgets[0] = selectedWidget
console.log("renaming: ", selectedWidget)
this.setState({
contextMenuItems: [
{
key: "rename",
label: (<div onClick={() => selectedWidget.openRenaming()}><EditOutlined /> Rename</div>),
icons: <EditOutlined />,
},
{
key: "delete",
label: (<div onClick={() => this.deleteSelectedWidgets([selectedWidget])}><DeleteOutlined /> Delete</div>),
icons: <DeleteOutlined />,
danger: true
}
]
})
}
}
mouseMoveEvent(event){
// console.log("mode: ", this.currentMode, this.getActiveObjects())
if (this.mousePressed && [CanvasModes.PAN, CanvasModes.MOVE_WIDGET].includes(this.currentMode)) {
const deltaX = event.clientX - this.mousePos.x
@@ -401,16 +420,38 @@ class Canvas extends React.Component {
return {id, widgetRef}
}
deleteSelectedWidgets(widgets){
let activeWidgets = removeDuplicateObjects([...widgets, ...this.selectedWidgets], "__id")
console.log("active widget: ", widgets, activeWidgets)
const widgetIds = activeWidgets.map(widget => widget.__id)
for (let widgetId of widgetIds){
console.log("removed: ", widgetId)
// this.widgetRefs[widgetId]?.current.remove()
delete this.widgetRefs[widgetId]
this.setState((prevState) => ({
widgets: prevState.widgets.filter(widget => widget.id !== widgetId)
}))
// value.current?.remove()
}
}
/**
* removes all the widgets from the canvas
*/
clearCanvas(){
for (let [key, value] of Object.entries(this.widgetRefs)){
console.log("removed: ", value, value.current?.getElement())
// NOTE: Don't remove from it using remove() function since, it already removed from the DOM tree when its removed from widgets
// for (let [key, value] of Object.entries(this.widgetRefs)){
// console.log("removed: ", value, value.current?.getElement())
value.current?.remove()
}
// value.current?.remove()
// }
this.widgetRefs = {}
this.setState(() => ({
@@ -422,7 +463,7 @@ class Canvas extends React.Component {
removeWidget(widgetId){
this.widgetRefs[widgetId]?.current.remove()
// this.widgetRefs[widgetId]?.current.remove()
delete this.widgetRefs[widgetId]
this.setState((prevState) => ({
@@ -454,7 +495,7 @@ class Canvas extends React.Component {
</div>
<Droppable id="canvas-droppable" className="tw-w-full tw-h-full">
<Dropdown trigger={['contextMenu']} menu={{items: this.state.contextMenuItems, }}>
<Dropdown trigger={['contextMenu']} mouseLeaveDelay={0} menu={{items: this.state.contextMenuItems, }}>
<div className="tw-w-full tw-h-full tw-flex tw-relative tw-bg-black tw-overflow-hidden"
ref={this.canvasContainerRef}
style={{transition: " transform 0.3s ease-in-out"}}

View File

@@ -23,8 +23,6 @@ class Widget extends React.Component{
// console.log("Id: ", id)
// this id has to be unique inside the canvas, it will be set automatically and should never be changed
this.__id = id
this._zIndex = 0
this.canvas = canvasRef?.current || null
// this._selected = false
@@ -85,6 +83,7 @@ class Widget extends React.Component{
size: { width: 100, height: 100 },
selected: false,
widgetName: widgetName || 'unnamed widget', // this will later be converted to variable name
enableRename: false, // will open the widgets editable div for renaming
resizing: false,
resizeCorner: ""
}
@@ -93,6 +92,8 @@ class Widget extends React.Component{
this.getElement = this.getElement.bind(this)
this.getBoundingRect = this.getBoundingRect.bind(this)
// this.openRenaming = this.openRenaming.bind(this)
this.isSelected = this.isSelected.bind(this)
this.getPos = this.getPos.bind(this)
@@ -155,7 +156,7 @@ class Widget extends React.Component{
this.setState({
selected: true
})
console.log("selected")
}
deSelect(){
@@ -209,9 +210,9 @@ class Widget extends React.Component{
}
getSize(){
const boundingRect = this.getBoundingRect()
// const boundingRect = this.getBoundingRect()
return {width: boundingRect.width, height: boundingRect.height}
return {width: this.state.size.width, height: this.state.size.height}
}
getScaleAwareDimensions() {
@@ -263,6 +264,12 @@ class Widget extends React.Component{
this.setState({ resizing: true, resizeCorner: corner })
}
setZIndex(zIndex){
this.setState({
zIndex: zIndex
})
}
handleResize(event) {
if (!this.state.resizing) return
@@ -311,6 +318,19 @@ class Widget extends React.Component{
}
}
openRenaming(){
this.setState({
selected: true,
enableRename: true
})
}
closeRenaming(){
this.setState({
enableRename: false
})
}
renderContent(){
// throw new NotImplementedError("render method has to be implemented")
return (
@@ -328,11 +348,12 @@ class Widget extends React.Component{
let style = {
cursor: this.cursor,
zIndex: this.state.zIndex,
position: "absolute", // don't change this if it has to be movable on the canvas
top: `${this.state.pos.y}px`,
left: `${this.state.pos.x}px`,
width: `${this.state.size.width}px`,
height: `${this.state.size.height}px`,
position: "absolute" // don't change this
}
let selectionStyle = {
@@ -349,7 +370,7 @@ class Widget extends React.Component{
widgetName: value.length > 0 ? value : prev.widgetName
}))
}
// console.log("selected: ", this.state.selected)
return (
<div data-id={this.__id} ref={this.elementRef} className="tw-absolute tw-w-fit tw-h-fit"
@@ -364,6 +385,7 @@ class Widget extends React.Component{
<div className="tw-relative tw-w-full tw-h-full">
<EditableDiv value={this.state.widgetName} onChange={onWidgetNameChange}
maxLength={40}
openEdit={this.state.enableRename}
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-6 tw-h-6"
/>