working on sidebar and widget context
This commit is contained in:
33
src/App.js
33
src/App.js
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
import { LayoutFilled, ProductFilled, CloudUploadOutlined, DatabaseFilled } from "@ant-design/icons"
|
||||
import { LayoutFilled, ProductFilled, CloudUploadOutlined, DatabaseFilled, AlignLeftOutlined } from "@ant-design/icons"
|
||||
// import { DndContext, useSensors, useSensor, PointerSensor, closestCorners, DragOverlay, rectIntersection } from '@dnd-kit/core'
|
||||
// import { snapCenterToCursor } from '@dnd-kit/modifiers'
|
||||
|
||||
@@ -31,6 +31,8 @@ import generateTkinterCode from './frameworks/tkinter/engine/code'
|
||||
|
||||
import TkMainWindow from './frameworks/tkinter/widgets/mainWindow'
|
||||
import CTkMainWindow from './frameworks/customtk/widgets/mainWindow'
|
||||
import TreeviewContainer from './sidebar/treeviewContainer'
|
||||
import { WidgetContextProvider } from './canvas/context/widgetContext'
|
||||
|
||||
|
||||
function App() {
|
||||
@@ -64,6 +66,11 @@ function App() {
|
||||
icon: <ProductFilled />,
|
||||
content: <PluginsContainer sidebarContent={sidebarPlugins}/>
|
||||
},
|
||||
{
|
||||
name: "Tree view",
|
||||
icon: <AlignLeftOutlined />,
|
||||
content: <TreeviewContainer />
|
||||
},
|
||||
{
|
||||
name: "Uploads",
|
||||
icon: <CloudUploadOutlined />,
|
||||
@@ -162,6 +169,7 @@ function App() {
|
||||
|
||||
const handleWidgetAddedToCanvas = (widgets) => {
|
||||
setCanvasWidgets(widgets)
|
||||
console.log("widget added: ", widgets)
|
||||
}
|
||||
|
||||
const handleCodeGen = () => {
|
||||
@@ -208,16 +216,19 @@ function App() {
|
||||
<p>Are you sure you want to change the framework? This will clear the canvas.</p>
|
||||
</Modal> */}
|
||||
|
||||
<DragProvider>
|
||||
<div className="tw-w-full tw-h-[94vh] tw-flex">
|
||||
<Sidebar tabs={sidebarTabs}/>
|
||||
|
||||
{/* <ActiveWidgetProvider> */}
|
||||
<Canvas ref={canvasRef} widgets={canvasWidgets} onWidgetAdded={handleWidgetAddedToCanvas}/>
|
||||
{/* </ActiveWidgetProvider> */}
|
||||
</div>
|
||||
{/* dragOverlay (dnd-kit) helps move items from one container to another */}
|
||||
</DragProvider>
|
||||
<WidgetContextProvider>
|
||||
<DragProvider>
|
||||
<div className="tw-w-full tw-h-[94vh] tw-flex">
|
||||
<Sidebar tabs={sidebarTabs}/>
|
||||
|
||||
{/* <ActiveWidgetProvider> */}
|
||||
<Canvas ref={canvasRef} widgets={canvasWidgets}
|
||||
onWidgetAdded={handleWidgetAddedToCanvas}/>
|
||||
{/* </ActiveWidgetProvider> */}
|
||||
</div>
|
||||
{/* dragOverlay (dnd-kit) helps move items from one container to another */}
|
||||
</DragProvider>
|
||||
</WidgetContextProvider>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -798,32 +798,32 @@ class Canvas extends React.Component {
|
||||
__checkClosestShiftElement = ({ event, parentWidgetId, dragElementID }) => {
|
||||
|
||||
// NOTE: work on this more maybe even check all four corners
|
||||
const parentWidget = this.findWidgetFromListById(parentWidgetId);
|
||||
if (!parentWidget) return;
|
||||
const parentWidget = this.findWidgetFromListById(parentWidgetId)
|
||||
if (!parentWidget) return
|
||||
|
||||
const dropX = event.clientX;
|
||||
const dropY = event.clientY;
|
||||
const dropX = event.clientX
|
||||
const dropY = event.clientY
|
||||
|
||||
let closestChild = null;
|
||||
let closestIndex = parentWidget.children.length;
|
||||
let minDistance = Infinity;
|
||||
let closestChild = null
|
||||
let closestIndex = parentWidget.children.length
|
||||
let minDistance = Infinity
|
||||
|
||||
// Only check the first level of children
|
||||
parentWidget.children.forEach((child, index) => {
|
||||
if (child.id !== dragElementID) {
|
||||
const childElement = this.widgetRefs[child.id]
|
||||
|
||||
if (!childElement) return;
|
||||
if (!childElement) return
|
||||
|
||||
const rect = childElement.current.getBoundingRect()
|
||||
const childTopRightX = rect.right
|
||||
const childTopRightY = rect.top
|
||||
|
||||
// Compute Euclidean distance from drop position
|
||||
const distance = Math.hypot(childTopRightX - dropX, childTopRightY - dropY);
|
||||
const distance = Math.hypot(childTopRightX - dropX, childTopRightY - dropY)
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
closestChild = child;
|
||||
minDistance = distance
|
||||
closestChild = child
|
||||
closestIndex = index + 1
|
||||
}
|
||||
}
|
||||
@@ -836,7 +836,7 @@ class Canvas extends React.Component {
|
||||
const rect = childElement.current.getBoundingRect()
|
||||
|
||||
// Closest is first child, check if dropped before or after
|
||||
closestIndex = dropX < rect.left ? 0 : 1;
|
||||
closestIndex = dropX < rect.left ? 0 : 1
|
||||
}
|
||||
|
||||
return {closestChild, closestIndex}
|
||||
|
||||
@@ -1,35 +1,19 @@
|
||||
import React, { createContext, Component } from 'react'
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
|
||||
const WidgetContext = createContext()
|
||||
const widgetContext = createContext()
|
||||
|
||||
// NOTE: Don't use this context provider
|
||||
export const useSelectedWidgetContext = () => useContext(widgetContext)
|
||||
|
||||
class WidgetProvider extends Component {
|
||||
state = {
|
||||
activeWidget: null, // Keeps track of the active widget's data
|
||||
widgetMethods: null, // Function to update active widget's state
|
||||
}
|
||||
|
||||
setActiveWidget = (widgetData, widgetMethods) => {
|
||||
this.setState({
|
||||
activeWidget: widgetData,
|
||||
widgetMethods: widgetMethods, // Store the update function of the active widget
|
||||
})
|
||||
}
|
||||
export const WidgetContextProvider = ({ children }) => {
|
||||
const [widgets, setWidgets] = useState(null)
|
||||
|
||||
render() {
|
||||
return (
|
||||
<WidgetContext.Provider
|
||||
value={{
|
||||
activeWidget: this.state.activeWidget,
|
||||
setActiveWidget: this.setActiveWidget,
|
||||
widgetMethods: this.state.widgetMethods, // Expose the update function
|
||||
}}
|
||||
>
|
||||
{this.props.children}
|
||||
</WidgetContext.Provider>
|
||||
)
|
||||
}
|
||||
const [widgetRef, setWidgetRef] = useState({})
|
||||
// const []
|
||||
|
||||
return (
|
||||
<widgetContext.Provider value={{ widgets, setWidgets, widgetRef, setWidgetRef }}>
|
||||
{children}
|
||||
</widgetContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export { WidgetContext, WidgetProvider }
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
import { useEffect, useMemo, useRef } from "react"
|
||||
import Draggable from "./utils/draggableDnd"
|
||||
|
||||
import { Button } from "antd"
|
||||
import { GithubOutlined, GitlabOutlined, LinkOutlined,
|
||||
AudioOutlined, FileTextOutlined,
|
||||
DeleteFilled,
|
||||
DeleteOutlined,
|
||||
GlobalOutlined} from "@ant-design/icons"
|
||||
GlobalOutlined,
|
||||
EyeOutlined} from "@ant-design/icons"
|
||||
|
||||
import DraggableWrapper from "./draggable/draggable"
|
||||
import { Button } from "antd"
|
||||
|
||||
|
||||
export function SidebarWidgetCard({ name, img, url, license, widgetClass, innerRef}){
|
||||
@@ -148,4 +150,22 @@ export function DraggableAssetCard({file, onDelete}){
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
export function TreeViewCard({widgetId, onDelete, title}){
|
||||
|
||||
return (
|
||||
<div className="tw-flex tw-place-items-center tw-px-2 tw-p-1 tw-place-content-between
|
||||
tw-gap-4 tw-w-full" style={{width: "100%"}}>
|
||||
<div className="tw-text-sm">
|
||||
{title}
|
||||
</div>
|
||||
|
||||
<div className="tw-ml-auto tw-flex tw-gap-1">
|
||||
<Button color="danger" size="small" variant="text" danger icon={<DeleteOutlined />}></Button>
|
||||
<Button variant="text" size="small" icon={<EyeOutlined />}></Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
89
src/sidebar/treeviewContainer.js
Normal file
89
src/sidebar/treeviewContainer.js
Normal file
@@ -0,0 +1,89 @@
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
|
||||
import { CloseCircleFilled, SearchOutlined } from "@ant-design/icons"
|
||||
|
||||
import { SidebarWidgetCard, TreeViewCard } from "../components/cards"
|
||||
|
||||
import ButtonWidget from "../assets/widgets/button.png"
|
||||
|
||||
import { filterObjectListStartingWith } from "../utils/filter"
|
||||
import Widget from "../canvas/widgets/base"
|
||||
import { SearchComponent } from "../components/inputs"
|
||||
import { Tree } from "antd"
|
||||
import { TreeNode } from "antd/es/tree-select"
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {function} onWidgetsUpdate - this is a callback that will be called once the sidebar is populated with widgets
|
||||
* @returns
|
||||
*/
|
||||
function TreeviewContainer({ sidebarContent, onWidgetsUpdate }) {
|
||||
|
||||
|
||||
const [searchValue, setSearchValue] = useState("")
|
||||
const [widgetData, setWidgetData] = useState(sidebarContent)
|
||||
|
||||
|
||||
const treeData = [
|
||||
{
|
||||
title: 'Parent',
|
||||
key: '0-0',
|
||||
children: [
|
||||
{ title: 'Child 1', key: '0-0-1' },
|
||||
{ title: 'Child 2', key: '0-0-2' },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
setWidgetData(sidebarContent)
|
||||
// if (onWidgetsUpdate){
|
||||
// onWidgetsUpdate(widgets)
|
||||
// }
|
||||
|
||||
}, [sidebarContent])
|
||||
|
||||
|
||||
|
||||
// useEffect(() => {
|
||||
|
||||
// if (searchValue.length > 0) {
|
||||
// const searchData = filterObjectListStartingWith(sidebarContent, "name", searchValue)
|
||||
// setWidgetData(searchData)
|
||||
// } else {
|
||||
// setWidgetData(sidebarContent)
|
||||
// }
|
||||
|
||||
// }, [searchValue])
|
||||
|
||||
function onSearch(event) {
|
||||
|
||||
setSearchValue(event.target.value)
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="tw-w-full tw-p-2 tw-gap-4 tw-flex tw-flex-col tw-overflow-x-hidden">
|
||||
|
||||
{/* <SearchComponent onSearch={onSearch} searchValue={searchValue}
|
||||
onClear={() => setSearchValue("")} /> */}
|
||||
<div className="tw-flex tw-flex-col tw-gap-2 tw-w-full tw-h-full tw-p-1">
|
||||
|
||||
<Tree treeData={treeData}
|
||||
titleRender={(nodeData) =>
|
||||
<TreeViewCard title={nodeData.title}/>
|
||||
}
|
||||
>
|
||||
|
||||
</Tree>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default TreeviewContainer
|
||||
Reference in New Issue
Block a user