fixed getInnerRenderStyle for Tkinter widgets and positioning
This commit is contained in:
@@ -189,7 +189,9 @@ class Canvas extends React.Component {
|
||||
break
|
||||
}
|
||||
|
||||
if (ref.current.getElement().contains(target)) {
|
||||
// console.log("refs: ", ref)
|
||||
// TODO: remove the ref.current? if there are bugs it would become hard to debug
|
||||
if (ref.current?.getElement().contains(target)) {
|
||||
|
||||
if (!innerWidget) {
|
||||
innerWidget = ref.current
|
||||
@@ -657,7 +659,7 @@ class Canvas extends React.Component {
|
||||
handleDropEvent = (e, draggedElement, widgetClass = null) => {
|
||||
|
||||
e.preventDefault()
|
||||
console.log("Drop event")
|
||||
// console.log("Drop event")
|
||||
|
||||
this.setState({ isWidgetDragging: false })
|
||||
|
||||
@@ -790,7 +792,7 @@ class Canvas extends React.Component {
|
||||
x: (clientX - parentRect.left) / this.state.zoom,
|
||||
y: (clientY - parentRect.top) / this.state.zoom,
|
||||
}
|
||||
console.log("Swapp: ", swap)
|
||||
|
||||
// TODO: fix swapping for grid layouts
|
||||
if (swap) {
|
||||
// If swapping, we need to find the common parent
|
||||
|
||||
@@ -1133,7 +1133,7 @@ class Widget extends React.Component {
|
||||
>
|
||||
{/* FIXME: Swappable when the parent layout is flex/grid and gap is more, this trick won't work, add bg color to check */}
|
||||
{/* FIXME: Swappable, when the parent layout is gap is 0, it doesn't work well */}
|
||||
<div className="tw-relative tw-w-full tw-bg-red-500 tw-h-full tw-top-0 tw-left-0"
|
||||
<div className="tw-relative tw-w-full tw-h-full tw-top-0 tw-left-0"
|
||||
|
||||
>
|
||||
|
||||
@@ -1151,7 +1151,7 @@ class Widget extends React.Component {
|
||||
{/* helps with swappable: if the mouse is in this area while hovering/dropping, then swap */}
|
||||
</div>
|
||||
|
||||
<div className="tw-relative tw-top-0 tw-left-0 tw-bg-blue-500 tw-w-full tw-h-full" ref={this.innerAreaRef}
|
||||
<div className="tw-relative tw-top-0 tw-left-0 tw-w-full tw-h-full" ref={this.innerAreaRef}
|
||||
>
|
||||
{this.renderContent()}
|
||||
</div>
|
||||
|
||||
@@ -95,7 +95,7 @@ export class CheckBox extends TkinterWidgetBase{
|
||||
renderContent(){
|
||||
return (
|
||||
<div className="tw-flex tw-p-1 tw-w-full tw-h-full tw-rounded-md tw-overflow-hidden"
|
||||
style={this.state.widgetInnerStyling}
|
||||
style={this.getInnerRenderStyling()}
|
||||
>
|
||||
|
||||
<div className="tw-flex tw-gap-2 tw-w-full tw-h-full tw-place-items-center tw-place-content-center">
|
||||
@@ -132,7 +132,8 @@ export class RadioButton extends TkinterWidgetBase{
|
||||
|
||||
this.state = {
|
||||
...this.state,
|
||||
size: { width: 120, height: 'fit' },
|
||||
size: { width: 80, height: 30 },
|
||||
fitContent: { width: true, height: true },
|
||||
widgetName: "Radio button",
|
||||
attrs: {
|
||||
...this.state.attrs,
|
||||
@@ -204,33 +205,34 @@ export class RadioButton extends TkinterWidgetBase{
|
||||
|
||||
return (
|
||||
<div className="tw-flex tw-p-1 tw-w-full tw-h-full tw-rounded-md tw-overflow-hidden"
|
||||
style={this.state.widgetInnerStyling}
|
||||
style={this.getInnerRenderStyling()}
|
||||
>
|
||||
|
||||
{
|
||||
inputs.map((value, index) => {
|
||||
return (
|
||||
<div key={index} className="tw-flex tw-gap-2 tw-w-full tw-h-full tw-place-items-center ">
|
||||
<div className="tw-border-solid tw-border-[#D9D9D9] tw-border-2
|
||||
tw-min-w-[20px] tw-min-h-[20px] tw-w-[20px] tw-h-[20px]
|
||||
tw-text-blue-600 tw-flex tw-items-center tw-justify-center
|
||||
tw-rounded-full tw-overflow-hidden tw-p-1">
|
||||
|
||||
{
|
||||
selectedRadio === index &&
|
||||
<div className="tw-rounded-full tw-bg-blue-600 tw-w-full tw-h-full">
|
||||
<div className="tw-flex tw-flex-col tw-gap-2 tw-w-fit tw-h-fit">
|
||||
{
|
||||
inputs.map((value, index) => {
|
||||
return (
|
||||
<div key={index} className="tw-flex tw-gap-2 tw-w-full tw-h-full tw-place-items-center ">
|
||||
<div className="tw-border-solid tw-border-[#D9D9D9] tw-border-2
|
||||
tw-min-w-[20px] tw-min-h-[20px] tw-w-[20px] tw-h-[20px]
|
||||
tw-text-blue-600 tw-flex tw-items-center tw-justify-center
|
||||
tw-rounded-full tw-overflow-hidden tw-p-1">
|
||||
|
||||
{
|
||||
selectedRadio === index &&
|
||||
<div className="tw-rounded-full tw-bg-blue-600 tw-w-full tw-h-full">
|
||||
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<span className="tw-text-base" style={{color: this.state.widgetInnerStyling.foregroundColor}}>
|
||||
{value}
|
||||
</span>
|
||||
</div>
|
||||
<span className="tw-text-base" style={{color: this.state.widgetInnerStyling.foregroundColor}}>
|
||||
{value}
|
||||
</span>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import { Layouts, PosType } from "../../../canvas/constants/layouts"
|
||||
import Tools from "../../../canvas/constants/tools"
|
||||
import Widget from "../../../canvas/widgets/base"
|
||||
import { removeKeyFromObject } from "../../../utils/common"
|
||||
import { convertObjectToKeyValueString, removeKeyFromObject } from "../../../utils/common"
|
||||
import { Tkinter_TO_WEB_CURSOR_MAPPING } from "../constants/cursor"
|
||||
import { Tkinter_To_GFonts } from "../constants/fontFamily"
|
||||
import { JUSTIFY, RELIEF } from "../constants/styling"
|
||||
|
||||
// TODO: add full width and full height in base widget
|
||||
// TODO: the pack should configure width and height of widgets
|
||||
// FIXME: the font code is not correctly generated
|
||||
|
||||
|
||||
export class TkinterBase extends Widget {
|
||||
|
||||
@@ -23,16 +21,60 @@ export class TkinterBase extends Widget {
|
||||
getLayoutCode(){
|
||||
const {layout: parentLayout, direction, gap} = this.getParentLayout()
|
||||
|
||||
const absolutePositioning = this.getAttrValue("positioning")
|
||||
|
||||
let layoutManager = `pack()`
|
||||
|
||||
if (parentLayout === Layouts.FLEX){
|
||||
layoutManager = `pack(side=${direction === "row" ? "tk.LEFT" : "tk.TOP"})`
|
||||
if (parentLayout === Layouts.PLACE || absolutePositioning){
|
||||
|
||||
const config = {
|
||||
x: this.state.pos.x,
|
||||
y: this.state.pos.y,
|
||||
}
|
||||
|
||||
if (!this.state.fitContent.width){
|
||||
config["width"] = this.state.size.width
|
||||
}
|
||||
if (!this.state.fitContent.height){
|
||||
config["height"] = this.state.size.height
|
||||
}
|
||||
|
||||
const configStr = convertObjectToKeyValueString(config)
|
||||
|
||||
layoutManager = `place(${configStr})`
|
||||
|
||||
}if (parentLayout === Layouts.FLEX){
|
||||
|
||||
const config = {
|
||||
side: direction === "row" ? "tk.LEFT" : "tk.TOP",
|
||||
}
|
||||
|
||||
const fillX = this.getAttrValue("flexManager.fillX")
|
||||
const fillY = this.getAttrValue("flexManager.fillY")
|
||||
const expand = this.getAttrValue("flexManager.expand")
|
||||
|
||||
if (fillX){
|
||||
config['fill'] = "'x'"
|
||||
}
|
||||
|
||||
if (fillY){
|
||||
config['fill'] = "'y'"
|
||||
}
|
||||
|
||||
if (fillX && fillY){
|
||||
config['fill'] = "'both'"
|
||||
}
|
||||
|
||||
if (expand){
|
||||
config['expand'] = 'True'
|
||||
}
|
||||
|
||||
layoutManager = `pack(${convertObjectToKeyValueString(config)})`
|
||||
|
||||
}else if (parentLayout === Layouts.GRID){
|
||||
const row = this.getAttrValue("gridManager.row")
|
||||
const col = this.getAttrValue("gridManager.col")
|
||||
layoutManager = `grid(row=${row}, col=${col})`
|
||||
}else{
|
||||
layoutManager = `place(x=${this.state.pos.x}, y=${this.state.pos.y})`
|
||||
}
|
||||
|
||||
return layoutManager
|
||||
@@ -53,18 +95,36 @@ export class TkinterBase extends Widget {
|
||||
|
||||
this.removeAttr("gridManager")
|
||||
this.removeAttr("flexManager")
|
||||
this.removeAttr("positioning")
|
||||
if (parentLayout === Layouts.FLEX || parentLayout === Layouts.GRID) {
|
||||
|
||||
updates = {
|
||||
...updates,
|
||||
positionType: PosType.NONE
|
||||
positionType: PosType.NONE,
|
||||
}
|
||||
// Allow optional absolute positioning if the parent layout is flex or grid
|
||||
const updateAttrs = {
|
||||
...this.state.attrs,
|
||||
positioning: {
|
||||
label: "Absolute positioning",
|
||||
tool: Tools.CHECK_BUTTON,
|
||||
value: false,
|
||||
onChange: (value) => {
|
||||
this.setAttrValue("positioning", value)
|
||||
|
||||
this.updateState({
|
||||
positionType: value ? PosType.ABSOLUTE : PosType.NONE,
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parentLayout === Layouts.FLEX){
|
||||
updates = {
|
||||
...updates,
|
||||
attrs: {
|
||||
...this.state.attrs,
|
||||
...updateAttrs,
|
||||
flexManager: {
|
||||
label: "Flex Manager",
|
||||
display: "horizontal",
|
||||
@@ -77,9 +137,8 @@ export class TkinterBase extends Widget {
|
||||
const widgetStyle = {
|
||||
...this.state.widgetOuterStyling,
|
||||
flexGrow: value ? 1 : 0,
|
||||
minWidth: 0
|
||||
}
|
||||
|
||||
|
||||
this.updateState({
|
||||
widgetOuterStyling: widgetStyle,
|
||||
})
|
||||
@@ -129,7 +188,7 @@ export class TkinterBase extends Widget {
|
||||
updates = {
|
||||
...updates,
|
||||
attrs: {
|
||||
...this.state.attrs,
|
||||
...updateAttrs,
|
||||
gridManager: {
|
||||
label: "Grid manager",
|
||||
display: "horizontal",
|
||||
@@ -231,6 +290,34 @@ export class TkinterBase extends Widget {
|
||||
return updates
|
||||
}
|
||||
|
||||
getInnerRenderStyling(){
|
||||
let {width, height, minWidth, minHeight} = this.getRenderSize()
|
||||
|
||||
const {layout: parentLayout, direction, gap} = this.getParentLayout() || {}
|
||||
|
||||
if (parentLayout === Layouts.FLEX){
|
||||
const fillX = this.getAttrValue("flexManager.fillX")
|
||||
const fillY = this.getAttrValue("flexManager.fillY")
|
||||
|
||||
// This is needed if fillX or fillY is true, as the parent is applied flex-grow
|
||||
|
||||
if (fillX || fillY){
|
||||
width = "100%"
|
||||
height = "100%"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
const styling = {
|
||||
...this.state.widgetInnerStyling,
|
||||
width,
|
||||
height,
|
||||
minWidth,
|
||||
minHeight
|
||||
}
|
||||
return styling
|
||||
}
|
||||
|
||||
/**
|
||||
* loads the data
|
||||
* @param {object} data
|
||||
@@ -465,7 +552,7 @@ export class TkinterWidgetBase extends TkinterBase{
|
||||
code["relief"] = `"${this.getAttrValue("styling.relief")}"`
|
||||
|
||||
if (this.getAttrValue("font.fontFamily") || this.getAttrValue("font.fontSize")){
|
||||
code["font"] = [`"${this.getAttrValue("font.fontFamily")}"`, this.getAttrValue("font.fontSize"), ]
|
||||
code["font"] = `("${this.getAttrValue("font.fontFamily")}", ${this.getAttrValue("font.fontSize") || 12}, )`
|
||||
}
|
||||
|
||||
if (this.getAttrValue("cursor"))
|
||||
|
||||
@@ -68,7 +68,7 @@ class Button extends TkinterWidgetBase{
|
||||
<div className="tw-w-flex tw-flex-col tw-w-full tw-h-full tw-rounded-md
|
||||
tw-border tw-border-solid tw-border-gray-400 tw-overflow-hidden">
|
||||
<div className="tw-p-2 tw-w-full tw-flex tw-place-content-center tw-place-items-center tw-h-full tw-text-center"
|
||||
style={this.state.widgetInnerStyling}>
|
||||
style={this.getInnerRenderStyling()}>
|
||||
{/* {this.props.children} */}
|
||||
<div className="tw-text-sm" style={{color: this.getAttrValue("styling.foregroundColor")}}>
|
||||
{this.getAttrValue("buttonLabel")}
|
||||
|
||||
@@ -64,7 +64,8 @@ export class Input extends TkinterWidgetBase{
|
||||
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-p-2 tw-w-full tw-h-full tw-flex tw-place-items-center" style={this.state.widgetInnerStyling}>
|
||||
<div className="tw-p-2 tw-w-full tw-h-full tw-flex tw-place-items-center"
|
||||
style={this.getInnerRenderStyling()}>
|
||||
<div className="tw-text-sm tw-text-gray-300">
|
||||
{this.getAttrValue("placeHolder")}
|
||||
</div>
|
||||
@@ -136,7 +137,8 @@ export class Text extends TkinterWidgetBase{
|
||||
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-p-2 tw-w-full tw-h-full tw-content-start " style={this.state.widgetInnerStyling}>
|
||||
<div className="tw-p-2 tw-w-full tw-h-full tw-content-start "
|
||||
style={this.getInnerRenderStyling()}>
|
||||
<div className="tw-text-sm tw-text-gray-300">
|
||||
{this.getAttrValue("placeHolder")}
|
||||
</div>
|
||||
|
||||
@@ -77,12 +77,12 @@ class Label extends TkinterWidgetBase{
|
||||
const code = []
|
||||
|
||||
if (image.name){
|
||||
code.push(`${variableName}_img = Image.open("${getPythonAssetPath(image.name, "image")}")`)
|
||||
code.push(`${variableName}_img = Image.open(${getPythonAssetPath(image.name, "image")})`)
|
||||
code.push(`${variableName}_img = ImageTk.PhotoImage(${variableName}_img)`)
|
||||
labelInitialization = `tk.Label(master=${parent}, image="${variableName}_img", text="${labelText}")`
|
||||
}
|
||||
|
||||
code.push("\n")
|
||||
// code.push("\n")
|
||||
code.push(labelInitialization)
|
||||
return [
|
||||
...code,
|
||||
|
||||
@@ -79,7 +79,8 @@ class MainWindow extends TkinterBase{
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tw-p-2 tw-w-full tw-relative tw-h-full tw-overflow-hidden tw-content-start" style={this.state.widgetInnerStyling}>
|
||||
<div className="tw-p-2 tw-w-full tw-relative tw-h-full tw-overflow-hidden tw-content-start"
|
||||
style={this.state.widgetInnerStyling}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -93,7 +93,7 @@ class OptionMenu extends TkinterWidgetBase{
|
||||
|
||||
return (
|
||||
<div className="tw-flex tw-p-1 tw-w-full tw-h-full tw-rounded-md tw-overflow-hidden"
|
||||
style={this.state.widgetInnerStyling}
|
||||
style={this.getInnerRenderStyling()}
|
||||
onClick={this.toggleDropDownOpen}
|
||||
>
|
||||
<div className="tw-flex tw-justify-between tw-gap-1">
|
||||
|
||||
@@ -135,7 +135,7 @@ class Slider extends TkinterWidgetBase{
|
||||
return (
|
||||
<div className="tw-w-flex tw-flex-col tw-w-full tw-h-full tw-rounded-md tw-overflow-hidden">
|
||||
<div className="flex flex-col items-center justify-center h-screen
|
||||
bg-gray-100" style={this.state.widgetInnerStyling}>
|
||||
bg-gray-100" style={this.getInnerRenderStyling()}>
|
||||
<div className="w-full max-w-md">
|
||||
<input
|
||||
type="range"
|
||||
|
||||
@@ -108,7 +108,8 @@ class SpinBox extends TkinterWidgetBase{
|
||||
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-p-2 tw-w-full tw-h-full tw-flex tw-place-items-center tw-justify-between" style={this.state.widgetInnerStyling}>
|
||||
<div className="tw-p-2 tw-w-full tw-h-full tw-flex tw-place-items-center tw-justify-between"
|
||||
style={this.getInnerRenderStyling()}>
|
||||
<div className="tw-text-sm ">
|
||||
{this.getAttrValue("spinProps.default")}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user