working on toolbar

This commit is contained in:
paul
2024-09-13 19:24:03 +05:30
parent fa993f7e7b
commit 1714c6f078
7 changed files with 88 additions and 34 deletions

View File

@@ -74,6 +74,7 @@ class Canvas extends React.Component {
this.fitCanvasToBoundingBox = this.fitCanvasToBoundingBox.bind(this)
this.getCanvasBoundingRect = this.getCanvasContainerBoundingRect.bind(this)
this.setSelectedWidget = this.setSelectedWidget.bind(this)
this.deleteSelectedWidgets = this.deleteSelectedWidgets.bind(this)
this.removeWidget = this.removeWidget.bind(this)
this.clearSelections = this.clearSelections.bind(this)
@@ -363,6 +364,10 @@ class Canvas extends React.Component {
}, this.applyTransform)
}
setSelectedWidget(selectedWidget){
this.setState({ selectedWidget: [selectedWidget] })
}
clearSelections(){
this.getActiveObjects().forEach(widget => {
widget.current?.deSelect()
@@ -467,6 +472,9 @@ class Canvas extends React.Component {
}), () => {
})
if (this._onWidgetListUpdated)
this._onWidgetListUpdated([])
}
removeWidget(widgetId){
@@ -474,9 +482,14 @@ class Canvas extends React.Component {
// this.widgetRefs[widgetId]?.current.remove()
delete this.widgetRefs[widgetId]
this.setState((prevState) => ({
widgets: prevState.widgets.filter(widget => widget.id !== widgetId)
}))
const widgets = this.state.widgets.filter(widget => widget.id !== widgetId)
this.setState({
widgets: widgets
})
if (this._onWidgetListUpdated)
this._onWidgetListUpdated(widgets)
}
renderWidget(widget){
@@ -522,7 +535,10 @@ class Canvas extends React.Component {
</Dropdown>
</Droppable>
<CanvasToolBar isOpen={this.state.toolbarOpen} activeWidget={this.state.selectedWidgets[0]}/>
<CanvasToolBar isOpen={this.state.toolbarOpen}
activeWidget={this.state.selectedWidgets[0]}
setActiveWidget={this.setSelectedWidget}
/>
</div>
)
}

View File

@@ -1,5 +1,6 @@
const Tools = {
INPUT: "input",
COLOR_PICKER: "color_picker",
EVENT_HANDLER: "event_handler", // shows a event handler with all the possible function in the dropdown
}

View File

@@ -1,22 +1,32 @@
import { useEffect, useState } from "react"
import { Input } from "antd"
import { capitalize } from "../utils/common"
function CanvasToolBar({isOpen, activeWidget}){
/**
*
* @param {boolean} isOpen
* @param {import("./widgets/base.js").Widget} activeWidget
* @param {React.Dispatch<React.SetStateAction<import("./widgets/base.js").Widget>>} setActiveWidget
* @returns
*/
function CanvasToolBar({isOpen, activeWidget, setActiveWidget}){
const [toolbarOpen, setToolbarOpen] = useState(isOpen)
const [widget, setWidget] = useState(activeWidget)
useEffect(() => {
setToolbarOpen(isOpen)
}, [isOpen])
useEffect(() => {
setWidget(activeWidget)
}, [activeWidget])
console.log("Widget type: ", widget?.getWidgetType())
const handleWidgetNameChange = (e) => {
const updatedWidget = { ...activeWidget } // Create a shallow copy of the widget
updatedWidget?.setWidgetName(e.target.value) // Update widget's internal state
setActiveWidget(updatedWidget) // Update the state with the modified widget
}
return (
<div className={`tw-absolute tw-top-20 tw-right-5 tw-bg-white ${toolbarOpen ? "tw-w-[320px]": "tw-w-0"}
tw-px-4 tw-p-2 tw-h-[600px] tw-rounded-md tw-z-20 tw-shadow-lg
@@ -26,9 +36,16 @@ function CanvasToolBar({isOpen, activeWidget}){
>
<h3 className="tw-text-2xl tw-text-center">
{capitalize(`${widget?.getWidgetType() || ""}`)}
{capitalize(`${activeWidget?.getWidgetType() || ""}`)}
</h3>
<div>
<Input placeholder="widget name"
value={activeWidget?.getWidgetName() || ""}
onChange={handleWidgetNameChange}
/>
</div>
</div>
)

View File

@@ -75,9 +75,6 @@ class Widget extends React.Component{
}
this.state = {
attrs: { // attributes
// replace this with this.props
},
zIndex: 0,
pos: {x: 0, y: 0},
size: { width: 100, height: 100 },
@@ -85,7 +82,27 @@ class Widget extends React.Component{
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: ""
resizeCorner: "",
attrs: {
styling: {
backgroundColor: {
tool: Tools.COLOR_PICKER, // the tool to display, can be either HTML ELement or a constant string
value: ""
},
foregroundColor: {
tool: Tools.COLOR_PICKER,
value: ""
},
},
layout: "show", // enables layout use "hide" to hide layout dropdown, takes the layout from this.layout
events: {
event1: {
tool: Tools.EVENT_HANDLER,
value: ""
}
}
},
}
this.mousePress = this.mousePress.bind(this)
@@ -97,6 +114,7 @@ class Widget extends React.Component{
// this.openRenaming = this.openRenaming.bind(this)
this.isSelected = this.isSelected.bind(this)
this.setWidgetName = this.setWidgetName.bind(this)
this.getPos = this.getPos.bind(this)
this.setPos = this.setPos.bind(this)
@@ -139,6 +157,10 @@ class Widget extends React.Component{
return this.constructor.widgetType
}
getAttributes(){
return this.state.attrs
}
/**
* removes the element/widget
*/
@@ -341,6 +363,15 @@ class Widget extends React.Component{
})
}
setWidgetName(name){
this.setState((prev) => ({
...prev,
widgetName: name.length > 0 ? name : prev.widgetName,
}))
}
renderContent(){
// throw new NotImplementedError("render method has to be implemented")
return (
@@ -373,13 +404,6 @@ class Widget extends React.Component{
height: this.boundingRect.height + 5
}
const onWidgetNameChange = (value) => {
this.setState((prev) => ({
...prev,
widgetName: value.length > 0 ? value : prev.widgetName
}))
}
// console.log("selected: ", this.state.selected)
return (
@@ -393,7 +417,7 @@ class Widget extends React.Component{
${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">
<EditableDiv value={this.state.widgetName} onChange={onWidgetNameChange}
<EditableDiv value={this.state.widgetName} onChange={this.setWidgetName}
maxLength={40}
openEdit={this.state.enableRename}
className="tw-text-sm tw-w-fit tw-max-w-[160px] tw-text-clip tw-min-w-[150px]

View File

@@ -24,16 +24,10 @@ function EditableDiv({value, onChange, openEdit=false, maxLength=Infinity, class
}, [openEdit])
const handleInput = (event) => {
console.log("Event key: ", event.key)
onChange(event.target.value)
// if (event.key === "")
}
const handleEnterKey = (event) => {
console.log("Event key: ", event.key)
if (event.key === "Enter"){
setIsEditable(false)
}

View File

@@ -1,7 +1,7 @@
import { useState } from "react"
import { Select, Input } from "antd"
import { DownOutlined } from "@ant-design/icons"
import { Select, Input, Button } from "antd"
import { DownloadOutlined, DownOutlined } from "@ant-design/icons"
const items = [
{
@@ -29,8 +29,11 @@ function Header(props){
className="tw-min-w-[150px]"
/>
<div className="tw-ml-auto tw-flex tw-place-content-center">
<div className="tw-ml-auto tw-flex tw-gap-2 tw-place-content-center">
<Input value={projectName} onChange={(e) => setProjectName(e.target.value)} placeholder="project name"/>
<Button icon={<DownloadOutlined />} >
Export code
</Button>
</div>
</div>

View File

@@ -20,6 +20,5 @@ export function removeDuplicateObjects(array, key) {
* @returns
*/
export function capitalize(str) {
console.log("Text: ", str)
return str.charAt(0).toUpperCase() + str.slice(1)
}