fixed styling issues and fixed setParentLayout
This commit is contained in:
16
README.md
16
README.md
@@ -35,12 +35,22 @@ Build Python GUI's with the ease of Canva
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
While there are a lot of features, here are few you need to know.
|
||||
|
||||
* Framework agnostic - Can outputs code in multiple frameworks.
|
||||
* Easy to use.
|
||||
* Pre-built UI components
|
||||
* Pre-built UI widgets
|
||||
* Plugins to extend 3rd party UI libraries
|
||||
* Generates Code.
|
||||
|
||||
## Supported Frameworks/Libraries
|
||||
|
||||
- [x] Tkinter
|
||||
- [x] CustomTkinter
|
||||
- [ ] Kivy (work in progress)
|
||||
- [ ] PySide (work in progress)
|
||||
|
||||
## Roadmap
|
||||
Here are some of the upcoming features.
|
||||
* Treeview on the sidebar
|
||||
@@ -55,9 +65,9 @@ To stay in loop, subscribe to the free [newsletter](https://paulfreeman.substack
|
||||
|
||||
## License - Fund the development
|
||||
|
||||
To support open-source and development of this tool and upcoming free open-source tools and libraries, consider buying a one-time license.
|
||||
Help fund open-source work and development of this and upcoming projects by purchasing a one-time license.
|
||||
|
||||
Purchasing License will allow me to focus on this work and give you access to more advance features, early access and more.
|
||||
Purchasing License will allow me to focus on development of this tool and provide you access to more advance features, early access and more.
|
||||
|
||||
The discount's will be available for limited time only on pre-orders.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useRef, useState } from 'react'
|
||||
|
||||
import { LayoutFilled, ProductFilled, CloudUploadOutlined } from "@ant-design/icons"
|
||||
import { LayoutFilled, ProductFilled, CloudUploadOutlined, DatabaseFilled } from "@ant-design/icons"
|
||||
// import { DndContext, useSensors, useSensor, PointerSensor, closestCorners, DragOverlay, rectIntersection } from '@dnd-kit/core'
|
||||
// import { snapCenterToCursor } from '@dnd-kit/modifiers'
|
||||
|
||||
@@ -17,6 +17,7 @@ import TkinterPluginWidgets from './frameworks/tkinter/sidebarPlugins'
|
||||
import FrameWorks from './constants/frameworks'
|
||||
import generateTkinterCode from './frameworks/tkinter/engine/code'
|
||||
import { FileUploadProvider, useFileUploadContext } from './contexts/fileUploadContext'
|
||||
import TemplatesContainer from './sidebar/templatesContainer'
|
||||
|
||||
|
||||
function App() {
|
||||
@@ -51,6 +52,11 @@ function App() {
|
||||
name: "Uploads",
|
||||
icon: <CloudUploadOutlined />,
|
||||
content: <UploadsContainer />
|
||||
},
|
||||
{
|
||||
name: "Templates",
|
||||
icon: <DatabaseFilled />,
|
||||
content: <TemplatesContainer />
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
BIN
src/assets/images/doggy.png
Normal file
BIN
src/assets/images/doggy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 144 KiB |
@@ -312,7 +312,6 @@ const CanvasToolBar = memo(({ isOpen, widgetType, attrs = {} }) => {
|
||||
if (isFirstLevel && keys.length < 3) keys.push(keyName)
|
||||
|
||||
if (isFirstLevel){
|
||||
|
||||
return (
|
||||
<Collapse key={keyName} ghost defaultActiveKey={keys}>
|
||||
<Collapse.Panel header={val.label} key={keyName}>
|
||||
|
||||
@@ -631,7 +631,6 @@ class Widget extends React.Component {
|
||||
widgetOuterStyling: widgetStyle
|
||||
})
|
||||
|
||||
console.log("widget styling: ", widgetStyle)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import { Select, Input, Button } from "antd"
|
||||
import { DownloadOutlined, DownOutlined } from "@ant-design/icons"
|
||||
import { CrownFilled, DownloadOutlined, DownOutlined } from "@ant-design/icons"
|
||||
import FrameWorks from "../constants/frameworks"
|
||||
import Premium from "../sidebar/utils/premium"
|
||||
|
||||
|
||||
const items = [
|
||||
@@ -35,6 +36,13 @@ function Header({projectName, onProjectNameChange, framework, onFrameworkChange,
|
||||
/>
|
||||
|
||||
<div className="tw-ml-auto tw-flex tw-gap-2 tw-place-content-center">
|
||||
<Premium className="tw-text-2xl tw-bg-purple-600 tw-text-center
|
||||
tw-w-[40px] tw-min-w-[40px] tw-h-[35px] tw-rounded-md
|
||||
tw-cursor-pointer tw-text-white
|
||||
tw-transition-all
|
||||
hover:tw-scale-[1.2]">
|
||||
<CrownFilled />
|
||||
</Premium>
|
||||
<Input value={projectName} onChange={(e) => onProjectNameChange(e.target.value)} placeholder="project name"/>
|
||||
<Button icon={<DownloadOutlined />} onClick={onExportClick}>
|
||||
Export code
|
||||
|
||||
@@ -31,28 +31,27 @@ export class TkinterBase extends Widget {
|
||||
const col = this.getAttrValue("gridManager.col")
|
||||
layoutManager = `grid(row=${row}, col=${col})`
|
||||
}else{
|
||||
// FIXME: position may not be correct
|
||||
layoutManager = `place(x=${this.state.pos.x}, y=${this.state.pos.y})`
|
||||
}
|
||||
|
||||
return layoutManager
|
||||
}
|
||||
|
||||
setParentLayout(parentLayout){
|
||||
setParentLayout(layout){
|
||||
|
||||
if (!parentLayout){
|
||||
if (!layout){
|
||||
return {}
|
||||
}
|
||||
|
||||
const {layout, direction, gap} = parentLayout
|
||||
const {layout: parentLayout, direction, gap} = layout
|
||||
|
||||
// show attributes related to the layout manager
|
||||
let updates = {
|
||||
parentLayout: parentLayout,
|
||||
parentLayout: layout,
|
||||
}
|
||||
|
||||
this.removeAttr("gridManager")
|
||||
if (layout === Layouts.FLEX || layout === Layouts.GRID) {
|
||||
if (parentLayout === Layouts.FLEX || parentLayout === Layouts.GRID) {
|
||||
|
||||
updates = {
|
||||
...updates,
|
||||
@@ -154,7 +153,7 @@ export class TkinterBase extends Widget {
|
||||
|
||||
}
|
||||
|
||||
} else if (layout === Layouts.PLACE) {
|
||||
} else if (parentLayout === Layouts.PLACE) {
|
||||
updates = {
|
||||
...updates,
|
||||
positionType: PosType.ABSOLUTE
|
||||
@@ -204,11 +203,10 @@ export class TkinterBase extends Widget {
|
||||
...layoutUpdates
|
||||
}
|
||||
|
||||
console.log("new data: ", newData, data)
|
||||
|
||||
this.setState(newData, () => {
|
||||
let layoutAttrs = this.setParentLayout(parentLayout) || {}
|
||||
|
||||
let layoutAttrs = this.setParentLayout(parentLayout).attrs || {}
|
||||
|
||||
// UPdates attrs
|
||||
let newAttrs = { ...this.state.attrs, ...layoutAttrs }
|
||||
|
||||
@@ -257,6 +255,8 @@ export class TkinterWidgetBase extends TkinterBase{
|
||||
|
||||
const newAttrs = removeKeyFromObject("layout", this.state.attrs)
|
||||
|
||||
console.log("new attrs: ", newAttrs)
|
||||
|
||||
this.state = {
|
||||
...this.state,
|
||||
attrs: {
|
||||
|
||||
@@ -62,6 +62,27 @@ class Slider extends TkinterWidgetBase{
|
||||
onChange: (value) => this.setAttrValue("scale.default", value)
|
||||
}
|
||||
},
|
||||
orientation: {
|
||||
label: "Orientation",
|
||||
tool: Tools.SELECT_DROPDOWN,
|
||||
toolProps: {placeholder: "select orientation"},
|
||||
value: "",
|
||||
options: [{value: "horizontal", label: "horizontal"}, {value: "vertical", label: "vertical"}],
|
||||
onChange: (value) => {
|
||||
|
||||
// const widgetStyling = {
|
||||
// transformOrigin: "0 0",
|
||||
// transform: value === "horizontal" ? "rotate(0deg)" : "rotate(90deg)"
|
||||
// }
|
||||
|
||||
// this.setState((prev) => ({
|
||||
// widgetOuterStyling: {...prev, ...widgetStyling}
|
||||
// }))
|
||||
// this.setWidgetOuterStyle("transform-origin", "0 0")
|
||||
// this.setWidgetOuterStyle("transform", value === "horizontal" ? "rotate(0deg)" : "rotate(90deg)")
|
||||
this.setAttrValue("orientation", value)
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
@@ -81,6 +102,10 @@ class Slider extends TkinterWidgetBase{
|
||||
config["to"] = this.getAttrValue("scale.max")
|
||||
config["resolution"] = this.getAttrValue("scale.step")
|
||||
|
||||
if (this.getAttrValue("orientation")){
|
||||
config["orientation"] = this.getAttrValue("orientation")
|
||||
}
|
||||
|
||||
const defaultValue = this.getAttrValue("defaultValue")
|
||||
|
||||
return [
|
||||
@@ -109,7 +134,8 @@ class Slider 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="flex flex-col items-center justify-center h-screen bg-gray-100">
|
||||
<div className="flex flex-col items-center justify-center h-screen
|
||||
bg-gray-100" style={this.state.widgetInnerStyling}>
|
||||
<div className="w-full max-w-md">
|
||||
<input
|
||||
type="range"
|
||||
@@ -117,6 +143,7 @@ class Slider extends TkinterWidgetBase{
|
||||
max={this.getAttrValue("scale.max")}
|
||||
step={this.getAttrValue("scale.step")}
|
||||
value={this.getAttrValue("scale.default")}
|
||||
style={{backgroundColor: this.getAttrValue("styling.troughColor") }}
|
||||
className="tw-pointer-events-none w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer accent-blue-500"
|
||||
/>
|
||||
|
||||
|
||||
67
src/sidebar/templatesContainer.js
Normal file
67
src/sidebar/templatesContainer.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import { useEffect, useState } from "react"
|
||||
|
||||
import Doggy from "../assets/images/doggy.png"
|
||||
|
||||
import { filterObjectListStartingWith } from "../utils/filter"
|
||||
import { SearchComponent } from "../components/inputs"
|
||||
|
||||
|
||||
|
||||
function TemplatesContainer(){
|
||||
|
||||
|
||||
const [searchValue, setSearchValue] = useState("")
|
||||
const [widgetData, setWidgetData] = useState([])
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
if (searchValue.length > 0){
|
||||
const searchData = filterObjectListStartingWith([], "name", searchValue)
|
||||
setWidgetData(searchData)
|
||||
}else{
|
||||
setWidgetData([])
|
||||
}
|
||||
|
||||
}, [searchValue])
|
||||
|
||||
function onSearch(event){
|
||||
|
||||
setSearchValue(event.target.value)
|
||||
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="tw-w-full tw-p-2 tw-gap-4 tw-flex tw-flex-col tw-overflow-x-hidden">
|
||||
|
||||
<SearchComponent onSearch={onSearch} searchValue={searchValue}
|
||||
onClear={() => setSearchValue("")} />
|
||||
<div className="tw-flex tw-flex-col tw-place-items-center
|
||||
tw-gap-2 tw-h-full tw-p-1">
|
||||
|
||||
<div className="tw-w-full tw-text-center tw-text-base tw-mt-6">
|
||||
Templates coming soon. until then, here's a picture of doggo :)
|
||||
</div>
|
||||
|
||||
<div className="tw-w-full tw-h-[250px]">
|
||||
<img src={Doggy} alt="can i pet that dawg?"
|
||||
className="tw-bg-contain tw-w-full tw-h-auto" />
|
||||
</div>
|
||||
|
||||
<div className="tw-flex tw-flex-col tw-mt-6 tw-gap-2">
|
||||
<div>Want to be notified of the release?</div>
|
||||
<a href="https://paulfreeman.substack.com/subscribe?utm_source=pyGUIBuilder_web"
|
||||
className="tw-p-2 tw-w-full tw-bg-blue-500 tw-rounded-md tw-no-underline
|
||||
tw-text-white tw-text-center tw-py-3"
|
||||
target="_blank" rel="noreferrer noopener">Subscribe to newsletter</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default TemplatesContainer
|
||||
@@ -24,7 +24,8 @@ function Premium({ children, className = "" }) {
|
||||
{children}
|
||||
<Modal
|
||||
title={<h3 className="tw-text-xl tw-font-medium">Fund development. Pre-order one Time License</h3>}
|
||||
style={{ zIndex: 14000, gap: '10px', maxWidth: '80vw', placeItems: "center" }}
|
||||
style={{ zIndex: 14000, gap: '5px', placeItems: "center" }}
|
||||
className="max-xl:tw-max-w-full"
|
||||
onCancel={onClose}
|
||||
centered
|
||||
onOk={onClose}
|
||||
@@ -32,12 +33,12 @@ function Premium({ children, className = "" }) {
|
||||
width={'auto'}
|
||||
open={premiumModalOpen}
|
||||
>
|
||||
<div className="tw-mt-5 tw-text-lg tw-max-w-[850px] tw-w-full ">
|
||||
<div className="tw-mt-5 tw-text-lg tw-max-w-[850px] tw-w-full ">
|
||||
I am Paul, a self-funded open-source dev.
|
||||
If you find this tool useful and want to fund and support it's development, consider buying a <b>one time license</b>.
|
||||
<br />
|
||||
<br />
|
||||
By buying pre-order license, you get advance features, priority support, early access, upcoming features, and more.
|
||||
By buying pre-order license, you get advance features, priority support, early access, upcoming features, and
|
||||
<a
|
||||
href="https://github.com/PaulleDemon/tab=readme-ov-file"
|
||||
target="_blank"
|
||||
@@ -189,7 +190,7 @@ function Premium({ children, className = "" }) {
|
||||
</div>
|
||||
|
||||
{/* Paid Plan */}
|
||||
<div className="tw-flex tw-w-[380px] tw-flex-col tw-place-items-center tw-gap-2 tw-rounded-lg tw-border-2 tw-border-solid
|
||||
<div className="tw-flex tw-w-[380px] tw-flex-col tw-place-items-center tw-gap-2 tw-rounded-lg tw-border-3 tw-border-solid
|
||||
tw-border-green-600 tw-p-8 tw-shadow-xl max-lg:tw-w-[340px]">
|
||||
<div className="tw-text-white tw-p-1 tw-px-3 tw-bg-blue-500 tw-rounded-full">
|
||||
Limited time offer
|
||||
|
||||
Reference in New Issue
Block a user