diff --git a/src/canvas/canvas.js b/src/canvas/canvas.js index 1340cf9..1ebe6f9 100644 --- a/src/canvas/canvas.js +++ b/src/canvas/canvas.js @@ -224,6 +224,8 @@ class Canvas extends React.Component { } } + console.log("inner widget: ", innerWidget, target) + return innerWidget } @@ -253,7 +255,6 @@ class Canvas extends React.Component { } mouseDownEvent(event) { - this.mousePos = { x: event.clientX, y: event.clientY } let selectedWidget = this.getWidgetFromTarget(event.target) @@ -1217,7 +1218,7 @@ class Canvas extends React.Component { * NOTE: this would cause entire widgetList to remount * NOTE: this would cause the toolbar to loose active widget */ - updateWidgetData = (widgetId, latestData) => { + updateWidgetData = (widgetId) => { const widgetObj = this.getWidgetById(widgetId)?.current // console.log("Data unmount: ", this.widgets, this.widgetRefs, widgetObj, widgetId, widgetObj?.serialize(), latestData) @@ -1256,6 +1257,33 @@ class Canvas extends React.Component { } + // FIXME: this must update the childrens corectly + updateWidgetAndChildren = (widgetId) => { + const serializeWidgetRecursively = (widget) => { + const widgetObj = this.getWidgetById(widget.id)?.current; + if (!widgetObj) return widget; // If no widget reference found, return unchanged + + return { + ...widget, + initialData: { + ...widget.initialData, + ...widgetObj.serialize() + }, + children: widget.children?.map(serializeWidgetRecursively) || [] // Recursively serialize children + }; + }; + + this.setWidgets(prevWidgets => { + const updateWidgets = (widgets) => { + return widgets.map(widget => + widget.id === widgetId ? serializeWidgetRecursively(widget) : widget + ); + }; + + return updateWidgets(prevWidgets); + }); + }; + renderWidget = (widget) => { @@ -1305,7 +1333,8 @@ class Canvas extends React.Component { onPanToWidget={this.panToWidget} - requestWidgetDataUpdate={this.updateWidgetData} + requestWidgetDataUpdate={this.updateWidgetAndChildren} + // requestWidgetDataUpdate={this.updateWidgetData} // onWidgetUpdate={this.onActiveWidgetUpdate} // onWidgetUpdate={this.updateWidgetDataOnUnmount} // onUnmount={this.updateWidgetDataOnUnmount} diff --git a/src/canvas/widgets/base.js b/src/canvas/widgets/base.js index 56173cd..6718567 100644 --- a/src/canvas/widgets/base.js +++ b/src/canvas/widgets/base.js @@ -635,12 +635,12 @@ class Widget extends React.Component { const elementRect = this.elementRef.current.getBoundingClientRect() // console.log("winner: ", this.props.parentWidgetRef.current.getBoundingRect()) - const parentRect = this.props.parentWidgetRef.current.getBoundingRect() + const parentRect = this.props.parentWidgetRef.current?.getBoundingRect() // FIXME: (low priority) once the place is moved and back to flex the position the updated position is not reflected let pos = { - x: (elementRect.left - parentRect.left) / this.canvasMetaData.zoom, - y: (elementRect.top - parentRect.top) / this.canvasMetaData.zoom + x: (elementRect.left - (parentRect?.left || 0)) / this.canvasMetaData.zoom, + y: (elementRect.top - (parentRect?.top || 0)) / this.canvasMetaData.zoom } this.setPos(pos.x, pos.y) @@ -849,7 +849,7 @@ class Widget extends React.Component { let layoutUpdates = { - parentLayout: parentLayout.layout || null + parentLayout: parentLayout?.layout || null } if (parentLayout?.layout === Layouts.FLEX || parentLayout?.layout === Layouts.GRID){ diff --git a/src/frameworks/tkinter/widgets/base.js b/src/frameworks/tkinter/widgets/base.js index fb8fd78..fee9ec1 100644 --- a/src/frameworks/tkinter/widgets/base.js +++ b/src/frameworks/tkinter/widgets/base.js @@ -23,7 +23,7 @@ export class TkinterBase extends Widget { this.state = { ...this.state, packAttrs: { - side: "left", + side: "top", anchor: "nw" } } @@ -186,7 +186,9 @@ export class TkinterBase extends Widget { // FIXME: force parent rerender because, here only child get rerendered, if only parent get rerendered the widget would move this.setAttrValue("flexManager.side", value, () => { this.updateState((prevState) => ({packAttrs: {...prevState.packAttrs, side: value}}), () => { - this.props.requestWidgetDataUpdate(this.__id) + console.log("parent: ",this.props.parentWidgetRef.current.__id) + + this.props.requestWidgetDataUpdate(this.props.parentWidgetRef.current.__id) this.stateChangeSubscriberCallback() // call this to notify the toolbar that the widget has changed state // this.props.parentWidgetRef.current.forceRerender() }) @@ -205,7 +207,10 @@ export class TkinterBase extends Widget { this.setAttrValue("flexManager.anchor", value, () => { console.log("anchor updated") this.updateState((prevState) => ({packAttrs: {...prevState.packAttrs, anchor: value}}), () => { - this.props.requestWidgetDataUpdate(this.__id) + + this.props.requestWidgetDataUpdate(this.props.parentWidgetRef.current.__id) + + // this.props.requestWidgetDataUpdate(this.__id) this.stateChangeSubscriberCallback() // call this to notify the toolbar that the widget has changed state // this.props.parentWidgetRef.current.forceRerender() }) @@ -381,24 +386,24 @@ export class TkinterBase extends Widget { const rowStyle = { display: "flex", - gap: "10px" + gap: "10px", } const columnStyle = { display: "flex", flexDirection: "column", - gap: "10px" + gap: "10px", } switch (side) { case "top": - return { gridColumn: "1 / -1", alignSelf: "stretch", width: "100%", ...baseStyle, ...columnStyle }; + return { gridColumn: "1 / -1", alignSelf: "stretch", ...baseStyle, ...columnStyle }; case "bottom": - return { gridColumn: "1 / -1", alignSelf: "stretch", width: "100%", ...baseStyle, ...columnStyle }; + return { gridColumn: "1 / -1", alignSelf: "stretch", ...baseStyle, ...columnStyle }; case "left": - return { gridRow: "2", gridColumn: "1", justifySelf: "stretch", height: "100%", ...baseStyle, ...rowStyle }; + return { gridRow: "2", gridColumn: "1", justifySelf: "stretch", ...baseStyle, ...rowStyle }; case "right": - return { gridRow: "2", gridColumn: "3", justifySelf: "stretch", height: "100%", ...baseStyle, ...rowStyle }; + return { gridRow: "2", gridColumn: "3", justifySelf: "stretch", ...baseStyle, ...rowStyle }; case "center": return { gridRow: "2", gridColumn: "2", alignSelf: "center", justifySelf: "center", ...baseStyle, }; default: @@ -438,9 +443,92 @@ export class TkinterBase extends Widget { return { ...baseStyle, alignSelf: "stretch", // Forces stretching in grid rows justifySelf: "stretch", // Forces stretching in grid columns - // flexGrow: fill ? 1 : 0 + flexGrow: (fillX || fillY) ? 1 : 0 }; } + + + /** + * adds the layout to achieve the pack from tkinter refer: https://www.youtube.com/watch?v=rbW1iJO1psk + * @param {*} widgets + * @param {*} index + * @returns + */ + renderPackWidgetsRecursively = (widgets, index = 0, lastSide="") => { + console.log("widgets: ", widgets, index) + + //FIXME: when the first element is left, the second is top the second should also have its own container + if (index >= widgets.length) return null + + + const widget = widgets[index] + const widgetRef = widget.ref?.current + if (!widgetRef) return null // Ensure ref exists before accessing + + const side = widgetRef.getPackAttrs()?.side || "top" + + const direction = (s) => { + return (s === "bottom" + ? "column-reverse" + : s === "top" + ? "column" + : s === "right" + ? "row-reverse" + : "row") + } + + const currentWidgetDirection = direction(side) + + + const isSameSide = lastSide === side + lastSide = side; // Update last side for next recursion + + // console.log("current widget direction: ", isSameSide, currentWidgetDirection) + + if (isSameSide) { + return ( + <> + {/*