Files
PyUIBuilder/src/App.js

160 lines
4.8 KiB
JavaScript
Raw Normal View History

import { useRef, useState } from 'react'
2024-08-04 22:47:43 +05:30
2024-08-05 22:36:05 +05:30
import { LayoutFilled, ProductFilled, CloudUploadOutlined } from "@ant-design/icons"
2024-09-14 16:03:26 +05:30
import { DndContext, useSensors, useSensor, PointerSensor, closestCorners, DragOverlay, rectIntersection } from '@dnd-kit/core'
import { snapCenterToCursor } from '@dnd-kit/modifiers'
2024-08-04 22:47:43 +05:30
2024-08-08 16:21:19 +05:30
import Canvas from './canvas/canvas'
2024-09-08 21:58:53 +05:30
import Header from './components/header'
2024-09-14 16:03:26 +05:30
import Sidebar from './sidebar/sidebar'
import UploadsContainer from './sidebar/uploadsContainer'
import WidgetsContainer from './sidebar/widgetsContainer'
import Widget from './canvas/widgets/base'
2024-09-14 16:03:26 +05:30
import { DraggableWidgetCard } from './components/cards'
2024-09-16 12:23:15 +05:30
import { DragProvider } from './components/draggable/draggableContext'
2024-09-16 22:04:24 +05:30
import { ActiveWidgetProvider } from './canvas/activeWidgetContext'
import TkinterSidebar from './frameworks/tkinter/sidebarWidgets'
2024-09-11 19:06:04 +05:30
2024-08-04 12:08:30 +05:30
function App() {
2024-08-04 22:47:43 +05:30
/**
* @type {Canvas | null>}
*/
const canvasRef = useRef()
const widgetOverlayRef = useRef()
const [initialPosition, setInitialPosition] = useState({ x: 0, y: 0 })
2024-08-05 22:36:05 +05:30
const [uploadedAssets, setUploadedAssets] = useState([]) // a global storage for assets, since redux can't store files(serialize files)
const [dropAnimation, setDropAnimation] = useState(null)
const [sidebarWidgets, setSidebarWidgets] = useState(TkinterSidebar || [])
2024-09-11 19:06:04 +05:30
const [canvasWidgets, setCanvasWidgets] = useState([]) // contains the reference to the widgets inside the canvas
const [activeSidebarWidget, setActiveSidebarWidget] = useState(null) // helps with the dnd overlay
const sensors = useSensors(
useSensor(PointerSensor)
)
2024-08-05 22:36:05 +05:30
2024-09-11 19:06:04 +05:30
const sidebarTabs = [
2024-08-04 22:47:43 +05:30
{
name: "Widgets",
icon: <LayoutFilled />,
content: <WidgetsContainer sidebarContent={TkinterSidebar} onWidgetsUpdate={(widgets) => setSidebarWidgets(widgets)}/>
2024-08-04 22:47:43 +05:30
},
{
2024-09-13 16:03:58 +05:30
name: "Plugins",
2024-08-04 22:47:43 +05:30
icon: <ProductFilled />,
content: <></>
},
{
name: "Uploads",
icon: <CloudUploadOutlined />,
2024-08-05 22:36:05 +05:30
content: <UploadsContainer assets={uploadedAssets}
onAssetUploadChange={(assets) => setUploadedAssets(assets)}/>
2024-08-04 22:47:43 +05:30
}
]
2024-09-11 19:06:04 +05:30
const handleDragStart = (event) => {
console.log("Drag start: ", event)
2024-09-11 19:06:04 +05:30
const draggedItem = sidebarWidgets.find((item) => item.name === event.active.id)
setActiveSidebarWidget(draggedItem)
const activeItemElement = widgetOverlayRef.current
if (activeItemElement) {
const rect = activeItemElement.getBoundingClientRect()
// Store the initial position of the dragged element
setInitialPosition({
x: rect.left,
y: rect.top,
})
}
2024-09-11 19:06:04 +05:30
}
const handleDragMove = (event) => {
// console.log("drag move: ", event)
2024-09-11 19:06:04 +05:30
}
const handleDragEnd = (event) => {
// add items to canvas from sidebar
const {active, over, delta, activatorEvent} = event
const widgetItem = active.data.current?.title
const activeItemElement = widgetOverlayRef.current
console.log("ended: ", activatorEvent.clientX, activatorEvent.clientY)
// console.log("over: ", active, over, activeItemElement)
if (over?.id !== "canvas-droppable" || !widgetItem) {
setDropAnimation({ duration: 250, easing: "ease" })
return
}
setDropAnimation(null)
// Get widget dimensions (assuming you have a way to get these)
const widgetWidth = activeItemElement.offsetWidth; // Adjust this based on how you get widget size
const widgetHeight = activeItemElement.offsetHeight; // Adjust this based on how you get widget size
const canvasContainerRect = canvasRef.current.getCanvasContainerBoundingRect()
const canvasTranslate = canvasRef.current.getCanvasTranslation()
const zoom = canvasRef.current.getZoom()
let finalPosition = {
x: (initialPosition.x + delta.x - canvasContainerRect.x - canvasTranslate.x) / zoom - (widgetWidth / 2),
y: (initialPosition.y + delta.y - canvasContainerRect.y - canvasTranslate.y) / zoom - (widgetHeight / 2),
}
// find the center of the active widget then set the final position
// finalPosition = {
// finalPosition
// }
console.log("drop position: ", "delta: ", delta, "activator", finalPosition, canvasTranslate,)
canvasRef.current.addWidget(Widget, ({id, widgetRef}) => {
widgetRef.current.setPos(finalPosition.x, finalPosition.y)
// widgetRef.current.setPos(10, 10)
})
2024-09-11 19:06:04 +05:30
setActiveSidebarWidget(null)
}
const handleWidgetAddedToCanvas = (widgets) => {
console.log("canvas ref: ", canvasRef)
setCanvasWidgets(widgets)
}
2024-09-11 19:06:04 +05:30
2024-08-04 12:08:30 +05:30
return (
2024-09-08 21:58:53 +05:30
<div className="tw-w-full tw-h-[100vh] tw-flex tw-flex-col tw-bg-primaryBg">
<Header className="tw-h-[6vh]"/>
2024-09-11 19:06:04 +05:30
2024-09-16 12:23:15 +05:30
<DragProvider>
2024-09-11 19:06:04 +05:30
<div className="tw-w-full tw-h-[94vh] tw-flex">
<Sidebar tabs={sidebarTabs}/>
2024-09-16 22:04:24 +05:30
{/* <ActiveWidgetProvider> */}
<Canvas ref={canvasRef} widgets={canvasWidgets} onWidgetAdded={handleWidgetAddedToCanvas}/>
2024-09-16 22:04:24 +05:30
{/* </ActiveWidgetProvider> */}
2024-09-11 19:06:04 +05:30
</div>
{/* dragOverlay (dnd-kit) helps move items from one container to another */}
2024-09-16 12:23:15 +05:30
</DragProvider>
2024-08-04 12:08:30 +05:30
</div>
2024-09-11 19:06:04 +05:30
)
2024-08-04 12:08:30 +05:30
}
export default App;