From 5f3525d56b70f0760485ead805ee1f9fd2057021 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 5 Apr 2025 19:20:58 +0530 Subject: [PATCH] fix: customtk error and option menu --- src/frameworks/customtk/widgets/base.js | 13 +++- .../customtk/widgets/checkButton.js | 45 +++++++++++++- src/frameworks/customtk/widgets/optionMenu.js | 4 +- src/frameworks/tkinter/widgets/base.js | 19 +++--- src/frameworks/tkinter/widgets/checkButton.js | 60 +++++++++++++++++-- src/frameworks/tkinter/widgets/optionMenu.js | 4 +- 6 files changed, 123 insertions(+), 22 deletions(-) diff --git a/src/frameworks/customtk/widgets/base.js b/src/frameworks/customtk/widgets/base.js index 3fa63f3..40839c8 100644 --- a/src/frameworks/customtk/widgets/base.js +++ b/src/frameworks/customtk/widgets/base.js @@ -88,8 +88,8 @@ export class CustomTkBase extends Widget { config['x'] = Math.trunc(this.state.pos.x) config['y'] = Math.trunc(this.state.pos.y) - config["width"] = Math.trunc(this.state.size.width) - config["height"] = Math.trunc(this.state.size.height) + // config["width"] = Math.trunc(this.state.size.width) + // config["height"] = Math.trunc(this.state.size.height) // if (!this.state.fitContent.width){ // config["width"] = this.state.size.width @@ -1017,6 +1017,7 @@ export class CustomTkWidgetBase extends CustomTkBase{ ...this.state, attrs: { ...newAttrs, + fitContent: {width: false, height: false}, styling: { ...newAttrs.styling, foregroundColor: { @@ -1167,7 +1168,7 @@ export class CustomTkWidgetBase extends CustomTkBase{ label: "font size", tool: Tools.NUMBER_INPUT, toolProps: {min: 3, max: 140}, - value: null, + value: undefined, onChange: (value) => { this.setWidgetInnerStyle("fontSize", `${value}px`) this.setAttrValue("font.fontSize", value) @@ -1197,6 +1198,12 @@ export class CustomTkWidgetBase extends CustomTkBase{ fg_color: `"${this.getAttrValue("styling.backgroundColor")}"`, } + if (!this.state.fitContent.width) + config["width"] = Math.trunc(this.state.size.width) + + if (!this.state.fitContent.height) + config["height"] = Math.trunc(this.state.size.height) + if (this.getAttrValue("styling.foregroundColor")){ config["text_color"] = `"${this.getAttrValue("styling.foregroundColor")}"` } diff --git a/src/frameworks/customtk/widgets/checkButton.js b/src/frameworks/customtk/widgets/checkButton.js index 8faeff0..d68cefd 100644 --- a/src/frameworks/customtk/widgets/checkButton.js +++ b/src/frameworks/customtk/widgets/checkButton.js @@ -3,6 +3,8 @@ import Tools from "../../../canvas/constants/tools" import { convertObjectToKeyValueString, removeKeyFromObject } from "../../../utils/common" import { CheckSquareFilled } from "@ant-design/icons" import { CustomTkWidgetBase } from "./base" +import { Layouts } from "../../../canvas/constants/layouts" +import React from "react" export class CheckBox extends CustomTkWidgetBase{ @@ -132,6 +134,8 @@ export class RadioButton extends CustomTkWidgetBase{ this.minSize = {width: 50, height: 30} + this.firstDivRef = React.createRef() + this.state = { ...this.state, size: { width: 80, height: 30 }, @@ -180,7 +184,7 @@ export class RadioButton extends CustomTkWidgetBase{ code.push(`\n`) code.push(`${radioBtnVariable} = ctk.CTkRadioButton(master=${parent}, variable=${variableName}_var, text="${radio_text}", value=${idx})`) code.push(`${radioBtnVariable}.configure(${convertObjectToKeyValueString(config)})`) - code.push(`${radioBtnVariable}.${this.getLayoutCode()}`) + code.push(`${radioBtnVariable}.${this.getLayoutCode({index: idx})}`) }) const defaultSelected = radios.selectedRadio @@ -193,6 +197,39 @@ export class RadioButton extends CustomTkWidgetBase{ return code } + /** + * + * The index is required for pack as in pack every widget would be packed on top of each other in radio button + */ + getLayoutCode({index=0}){ + let layoutManager = super.getLayoutCode() + + const {layout: parentLayout, direction, gap, align="start"} = this.getParentLayout() + const absolutePositioning = this.getAttrValue("positioning") + + + if (parentLayout === Layouts.PLACE || absolutePositioning){ + const config = {} + + const elementRect = this.firstDivRef.current?.getBoundingClientRect() + + config['x'] = Math.trunc(this.state.pos.x) + config['y'] = Math.trunc(this.state.pos.y) + + if (elementRect?.height){ + config['y'] = Math.trunc(config['y'] + (index * elementRect.height)) // the index is the radiobutton index + } + + const configStr = convertObjectToKeyValueString(config) + + layoutManager = `place(${configStr})` + + } + + return layoutManager + + } + getToolbarAttrs(){ const toolBarAttrs = super.getToolbarAttrs() @@ -219,8 +256,12 @@ export class RadioButton extends CustomTkWidgetBase{
{ inputs.map((value, index) => { + + const ref = index === 0 ? this.firstDivRef : null + + return ( -
+
{ - this.setAttrValue("options", {inputs, selectedRadio}) + onChange: (value) => { + this.setAttrValue("defaultValue", value) } }, widgetOptions: { diff --git a/src/frameworks/tkinter/widgets/base.js b/src/frameworks/tkinter/widgets/base.js index ead1e78..f474627 100644 --- a/src/frameworks/tkinter/widgets/base.js +++ b/src/frameworks/tkinter/widgets/base.js @@ -88,15 +88,15 @@ export class TkinterBase extends Widget { config['x'] = Math.trunc(this.state.pos.x) config['y'] = Math.trunc(this.state.pos.y) - config["width"] = Math.trunc(this.state.size.width) - config["height"] = Math.trunc(this.state.size.height) + // config["width"] = Math.trunc(this.state.size.width) + // config["height"] = Math.trunc(this.state.size.height) - // if (!this.state.fitContent.width){ - // config["width"] = this.state.size.width - // } - // if (!this.state.fitContent.height){ - // config["height"] = this.state.size.height - // } + if (!this.state.fitContent.width){ + config["width"] = Math.trunc(this.state.size.width) + } + if (!this.state.fitContent.height){ + config["height"] = Math.trunc(this.state.size.height) + } const configStr = convertObjectToKeyValueString(config) @@ -1034,6 +1034,7 @@ export class TkinterWidgetBase extends TkinterBase{ ...this.state, attrs: { ...newAttrs, + fitContent: {width: false, height: false}, styling: { ...newAttrs.styling, foregroundColor: { @@ -1181,7 +1182,7 @@ export class TkinterWidgetBase extends TkinterBase{ label: "font size", tool: Tools.NUMBER_INPUT, toolProps: {min: 3, max: 140}, - value: null, + value: 10, onChange: (value) => { this.setWidgetInnerStyle("fontSize", `${value}px`) this.setAttrValue("font.fontSize", value) diff --git a/src/frameworks/tkinter/widgets/checkButton.js b/src/frameworks/tkinter/widgets/checkButton.js index b9d5834..0abeab6 100644 --- a/src/frameworks/tkinter/widgets/checkButton.js +++ b/src/frameworks/tkinter/widgets/checkButton.js @@ -3,6 +3,8 @@ import Tools from "../../../canvas/constants/tools" import { convertObjectToKeyValueString, removeKeyFromObject } from "../../../utils/common" import { CheckSquareFilled } from "@ant-design/icons" import { TkinterWidgetBase } from "./base" +import { Layouts } from "../../../canvas/constants/layouts" +import React from "react" export class CheckBox extends TkinterWidgetBase{ @@ -136,6 +138,8 @@ export class RadioButton extends TkinterWidgetBase{ let newAttrs = removeKeyFromObject("layout", this.state.attrs) + this.firstDivRef = React.createRef() + this.state = { ...this.state, size: { width: 80, height: 30 }, @@ -146,10 +150,9 @@ export class RadioButton extends TkinterWidgetBase{ radios: { label: "Radio Group", tool: Tools.INPUT_RADIO_LIST, - value: {inputs: ["default"], selectedRadio: null}, + value: {inputs: ["default"], selectedRadio: -1}, onChange: ({inputs, selectedRadio}) => { this.setAttrValue("radios", {inputs, selectedRadio}, () => { - console.log("attribute set: ", this.state.attrs.radios, {inputs, selectedRadio},) }) } } @@ -164,6 +167,49 @@ export class RadioButton extends TkinterWidgetBase{ this.setWidgetInnerStyle("backgroundColor", "#fff0") } + /** + * + * The index is required for pack as in pack every widget would be packed on top of each other in radio button + */ + getLayoutCode({index=0}){ + let layoutManager = super.getLayoutCode() + + const {layout: parentLayout, direction, gap, align="start"} = this.getParentLayout() + const absolutePositioning = this.getAttrValue("positioning") + + + if (parentLayout === Layouts.PLACE || absolutePositioning){ + const config = {} + + const elementRect = this.firstDivRef.current?.getBoundingClientRect() + + config['x'] = Math.trunc(this.state.pos.x) + config['y'] = Math.trunc(this.state.pos.y) + + if (elementRect?.height){ + config['y'] = Math.trunc(config['y'] + (index * elementRect.height)) // the index is the radiobutton index + } + + // config["width"] = Math.trunc(this.state.size.width) + // config["height"] = Math.trunc(this.state.size.height) + + if (!this.state.fitContent.width){ + config["width"] = Math.trunc(this.state.size.width) + } + if (!this.state.fitContent.height){ + config["height"] = Math.trunc(this.state.size.height) + } + + const configStr = convertObjectToKeyValueString(config) + + layoutManager = `place(${configStr})` + + } + + return layoutManager + + } + generateCode(variableName, parent){ const config = convertObjectToKeyValueString(this.getConfigCode()) @@ -178,9 +224,10 @@ export class RadioButton extends TkinterWidgetBase{ const radioBtnVariable = `${variableName}_${idx}` code.push(`\n`) + // TODO increment the next widget with the height of the previous code.push(`${radioBtnVariable} = tk.Radiobutton(master=${parent}, variable=${variableName}_var, text="${radio_text}")`) code.push(`${radioBtnVariable}.config(${config}, value=${idx})`) - code.push(`${radioBtnVariable}.${this.getLayoutCode()}`) + code.push(`${radioBtnVariable}.${this.getLayoutCode({index: idx})}`) }) const defaultSelected = radios.selectedRadio @@ -218,8 +265,13 @@ export class RadioButton extends TkinterWidgetBase{
{ inputs.map((value, index) => { + + const ref = index === 0 ? this.firstDivRef : null + return ( -
+
{ - this.setAttrValue("options", {inputs, selectedRadio}) + onChange: (value) => { + this.setAttrValue("defaultValue", value) } }, widgetOptions: {