added MainWindow widget and updated readme
This commit is contained in:
@@ -713,6 +713,8 @@ class Canvas extends React.Component {
|
||||
throw new Error("widgetComponentType must be a subclass of Widget class")
|
||||
}
|
||||
|
||||
console.log("componete: ", widgetComponentType)
|
||||
|
||||
const widgetRef = React.createRef()
|
||||
|
||||
const id = `${widgetComponentType.widgetType}_${UID()}`
|
||||
@@ -842,7 +844,7 @@ class Canvas extends React.Component {
|
||||
|
||||
// TODO: handle drop from sidebar
|
||||
// if the widget is being dropped from the sidebar, use the info to create the widget first
|
||||
this.createWidget(Widget, ({ id, widgetRef }) => {
|
||||
this.createWidget(widgetClass, ({ id, widgetRef }) => {
|
||||
widgetRef.current.setPos(finalPosition.x, finalPosition.y)
|
||||
})
|
||||
|
||||
@@ -968,6 +970,7 @@ class Canvas extends React.Component {
|
||||
|
||||
{/* <ActiveWidgetProvider> */}
|
||||
<DroppableWrapper id="canvas-droppable"
|
||||
droppableTags={{exclude: ["image", "video"]}}
|
||||
className="tw-w-full tw-h-full"
|
||||
onDrop={this.handleDropEvent}>
|
||||
{/* <DragWidgetProvider> */}
|
||||
|
||||
@@ -55,7 +55,7 @@ class Widget extends React.Component {
|
||||
"load": { "args1": "number", "args2": "string" }
|
||||
}
|
||||
|
||||
this.droppableTags = ["widget"] // This indicates if the draggable can be dropped on this widget
|
||||
this.droppableTags = {} // This indicates if the draggable can be dropped on this widget
|
||||
this.boundingRect = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -143,7 +143,6 @@ class Widget extends React.Component {
|
||||
},
|
||||
}
|
||||
|
||||
this.mousePress = this.mousePress.bind(this)
|
||||
this.getElement = this.getElement.bind(this)
|
||||
|
||||
this.getId = this.getId.bind(this)
|
||||
@@ -169,7 +168,6 @@ class Widget extends React.Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.elementRef.current?.addEventListener("click", this.mousePress)
|
||||
|
||||
// FIXME: initial layout is not set properly
|
||||
console.log("prior layout: ", this.state.attrs.layout.value)
|
||||
@@ -182,7 +180,6 @@ class Widget extends React.Component {
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.elementRef.current?.removeEventListener("click", this.mousePress)
|
||||
}
|
||||
|
||||
updateState = (newState, callback) => {
|
||||
@@ -273,12 +270,6 @@ class Widget extends React.Component {
|
||||
return this.__id
|
||||
}
|
||||
|
||||
mousePress(event) {
|
||||
// event.preventDefault()
|
||||
if (!this._disableSelection) {
|
||||
}
|
||||
}
|
||||
|
||||
select() {
|
||||
this.setState({
|
||||
selected: true
|
||||
@@ -642,7 +633,12 @@ class Widget extends React.Component {
|
||||
show: true
|
||||
}
|
||||
|
||||
if (this.droppableTags.length === 0 || this.droppableTags.includes(dragEleType)) {
|
||||
const allowDrop = (this.droppableTags && (Object.keys(this.droppableTags).length === 0 ||
|
||||
(this.droppableTags.include?.length > 0 && this.droppableTags.include?.includes(dragEleType)) ||
|
||||
(this.droppableTags.exclude?.length > 0 && !this.droppableTags.exclude?.includes(dragEleType))
|
||||
))
|
||||
|
||||
if (allowDrop) {
|
||||
showDrop = {
|
||||
allow: true,
|
||||
show: true
|
||||
@@ -670,7 +666,12 @@ class Widget extends React.Component {
|
||||
// console.log("Drag over: ", e.dataTransfer.getData("text/plain"), e.dataTransfer)
|
||||
const dragEleType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
if (this.droppableTags.length === 0 || this.droppableTags.includes(dragEleType)) {
|
||||
const allowDrop = (this.droppableTags && (Object.keys(this.droppableTags).length === 0 ||
|
||||
(this.droppableTags.include?.length > 0 && this.droppableTags.include?.includes(dragEleType)) ||
|
||||
(this.droppableTags.exclude?.length > 0 && !this.droppableTags.exclude?.includes(dragEleType))
|
||||
))
|
||||
|
||||
if (allowDrop) {
|
||||
e.preventDefault() // NOTE: this is necessary to allow drop to take place
|
||||
}
|
||||
|
||||
@@ -692,7 +693,12 @@ class Widget extends React.Component {
|
||||
|
||||
const dragEleType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
if (this.droppableTags.length > 0 && !this.droppableTags.includes(dragEleType)) {
|
||||
const allowDrop = (this.droppableTags && (Object.keys(this.droppableTags).length === 0 ||
|
||||
(this.droppableTags.include?.length > 0 && this.droppableTags.include?.includes(dragEleType)) ||
|
||||
(this.droppableTags.exclude?.length > 0 && !this.droppableTags.exclude?.includes(dragEleType))
|
||||
))
|
||||
|
||||
if (allowDrop) {
|
||||
return // prevent drop if the draggable element doesn't match
|
||||
}
|
||||
|
||||
@@ -771,11 +777,14 @@ class Widget extends React.Component {
|
||||
this.elementRef.current.style.pointerEvents = "auto"
|
||||
}
|
||||
|
||||
// FIXME: children outside the bounding box, add tw-overflow-hidden
|
||||
renderContent() {
|
||||
/**
|
||||
* Note: you must implement this method in subclass, if you want children make sure to pass
|
||||
* {this.props.children}, to modify the style add this.state.widgetStyling
|
||||
*/
|
||||
renderContent() {
|
||||
// throw new NotImplementedError("render method has to be implemented")
|
||||
return (
|
||||
<div className="tw-w-full tw-h-full tw-p-2 tw-content-start tw-rounded-md" style={this.state.widgetStyling}>
|
||||
<div className="tw-w-full tw-h-full tw-p-2 tw-content-start tw-rounded-md tw-overflow-hidden" style={this.state.widgetStyling}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ import { useDragContext } from "../../components/draggable/draggableContext"
|
||||
*/
|
||||
const WidgetDraggable = memo(({ widgetRef, enableDrag=true, dragElementType="widget",
|
||||
onDragEnter, onDragLeave, onDrop, style={},
|
||||
droppableTags = ["widget"], ...props }) => {
|
||||
droppableTags = {}, ...props }) => {
|
||||
|
||||
// const { draggedElement, onDragStart, onDragEnd } = useDragWidgetContext()
|
||||
const { draggedElement, onDragStart, onDragEnd, overElement, setOverElement } = useDragContext()
|
||||
@@ -71,8 +71,12 @@ const WidgetDraggable = memo(({ widgetRef, enableDrag=true, dragElementType="wid
|
||||
allow: true,
|
||||
show: true
|
||||
}
|
||||
const allowDrop = (Object.keys(droppableTags).length === 0 ||
|
||||
(droppableTags.include.length > 0 && droppableTags.include.includes(dragEleType)) ||
|
||||
(droppableTags.exclude.length > 0 && !droppableTags.exclude.includes(dragEleType))
|
||||
)
|
||||
|
||||
if (droppableTags.length === 0 || droppableTags.includes(dragEleType)) {
|
||||
if (allowDrop) {
|
||||
showDrop = {
|
||||
allow: true,
|
||||
show: true
|
||||
@@ -99,7 +103,12 @@ const WidgetDraggable = memo(({ widgetRef, enableDrag=true, dragElementType="wid
|
||||
// console.log("Drag over: ", e.dataTransfer.getData("text/plain"), e.dataTransfer)
|
||||
const dragEleType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
if (droppableTags.length === 0 || droppableTags.includes(dragEleType)) {
|
||||
const allowDrop = (Object.keys(droppableTags).length === 0 ||
|
||||
(droppableTags.include.length > 0 && droppableTags.include.includes(dragEleType)) ||
|
||||
(droppableTags.exclude.length > 0 && !droppableTags.exclude.includes(dragEleType))
|
||||
)
|
||||
|
||||
if (allowDrop) {
|
||||
e.preventDefault() // this is necessary to allow drop to take place
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,10 @@ import { memo, useState } from "react"
|
||||
import { useDragContext } from "./draggableContext"
|
||||
|
||||
|
||||
const DroppableWrapper = memo(({onDrop, droppableTags=["widget"], ...props}) => {
|
||||
/**
|
||||
* @param {{include: [], exclude: []} || {}} - droppableTags - if empty object, allows everything to be dropped, define include to allow only included widgets, define exclude to exclude
|
||||
*/
|
||||
const DroppableWrapper = memo(({onDrop, droppableTags={}, ...props}) => {
|
||||
|
||||
|
||||
const { draggedElement, overElement, setOverElement, widgetClass } = useDragContext()
|
||||
@@ -17,11 +20,16 @@ const DroppableWrapper = memo(({onDrop, droppableTags=["widget"], ...props}) =>
|
||||
|
||||
const dragElementType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
// console.log("Current target: ", e.currentTarget)
|
||||
console.log("Current target: ", droppableTags, Object.keys(droppableTags))
|
||||
|
||||
setOverElement(e.currentTarget)
|
||||
|
||||
if (droppableTags.length === 0 || droppableTags.includes(dragElementType)){
|
||||
const allowDrop = (droppableTags && (Object.keys(droppableTags).length === 0 ||
|
||||
(droppableTags.include?.length > 0 && droppableTags.include?.includes(dragElementType)) ||
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
if (allowDrop){
|
||||
setShowDroppable({
|
||||
allow: true,
|
||||
show: true
|
||||
@@ -37,8 +45,13 @@ const DroppableWrapper = memo(({onDrop, droppableTags=["widget"], ...props}) =>
|
||||
const handleDragOver = (e) => {
|
||||
// console.log("Drag over: ", e.dataTransfer.getData("text/plain"), e.dataTransfer)
|
||||
const dragElementType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
if (droppableTags.length === 0 || droppableTags.includes(dragElementType)){
|
||||
|
||||
const allowDrop = (droppableTags && (Object.keys(droppableTags).length === 0 ||
|
||||
(droppableTags.include?.length > 0 && droppableTags.include?.includes(dragElementType)) ||
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
if (allowDrop){
|
||||
e.preventDefault() // this is necessary to allow drop to take place
|
||||
}
|
||||
|
||||
@@ -51,8 +64,15 @@ const DroppableWrapper = memo(({onDrop, droppableTags=["widget"], ...props}) =>
|
||||
allow: false,
|
||||
show: false
|
||||
})
|
||||
const dragElementType = draggedElement.getAttribute("data-draggable-type")
|
||||
|
||||
if(onDrop){
|
||||
|
||||
const allowDrop = (droppableTags && (Object.keys(droppableTags).length === 0 ||
|
||||
(droppableTags.include?.length > 0 && droppableTags.include?.includes(dragElementType)) ||
|
||||
(droppableTags.exclude?.length > 0 && !droppableTags.exclude?.includes(dragElementType))
|
||||
))
|
||||
|
||||
if(onDrop && allowDrop){
|
||||
onDrop(e, draggedElement, widgetClass)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import Widget from "../../canvas/widgets/base"
|
||||
|
||||
import ButtonWidget from "./assets/widgets/button.png"
|
||||
import MainWindow from "./widgets/mainWindow"
|
||||
|
||||
|
||||
const TkinterSidebar = [
|
||||
@@ -9,7 +10,7 @@ const TkinterSidebar = [
|
||||
name: "Main window",
|
||||
img: ButtonWidget,
|
||||
link: "https://github.com",
|
||||
widgetClass: Widget
|
||||
widgetClass: MainWindow
|
||||
},
|
||||
{
|
||||
name: "Top Level",
|
||||
|
||||
46
src/frameworks/tkinter/widgets/mainWindow.js
Normal file
46
src/frameworks/tkinter/widgets/mainWindow.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import { CloseCircleFilled, ExpandOutlined, MinusCircleFilled } from "@ant-design/icons"
|
||||
import Widget from "../../../canvas/widgets/base"
|
||||
|
||||
|
||||
class MainWindow extends Widget{
|
||||
|
||||
static widgetType = "main_window"
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
||||
this.droppableTags = {
|
||||
exclude: ["image", "video", "media"]
|
||||
}
|
||||
|
||||
this.state = {
|
||||
...this.state,
|
||||
|
||||
}
|
||||
this.setAttrValue("styling.backgroundColor", "#E4E2E2")
|
||||
}
|
||||
|
||||
renderContent(){
|
||||
return (
|
||||
<div className="tw-w-flex tw-flex-col tw-w-full tw-h-full tw-rounded-md tw-overflow-hidden">
|
||||
<div className="tw-flex tw-w-full tw-h-[25px] tw-bg-[#adadad] tw-shadow-md">
|
||||
<div className="tw-ml-auto tw-flex tw-gap-1 tw-p-1 tw-place-items-center">
|
||||
<div className="tw-bg-yellow-400 tw-rounded-full tw-w-[15px] tw-h-[15px]">
|
||||
</div>
|
||||
<div className="tw-bg-blue-400 tw-rounded-full tw-w-[15px] tw-h-[15px]">
|
||||
</div>
|
||||
<div className="tw-bg-red-400 tw-rounded-full tw-w-[15px] tw-h-[15px]">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tw-p-2 tw-w-full tw-h-full tw-content-start" style={this.state.widgetStyling}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default MainWindow
|
||||
@@ -11,7 +11,7 @@ function Share({children, className=""}){
|
||||
const shareInfo = useMemo(() => {
|
||||
|
||||
return {
|
||||
url: encodeURI("https://github.com/PaulleDemon/font-tester-chrome"),
|
||||
url: encodeURI("https://github.com/PaulleDemon/tkbuilder"),
|
||||
text: "Check out Framework agnostic GUI builder for python"
|
||||
}
|
||||
}, [])
|
||||
|
||||
Reference in New Issue
Block a user