added license and roadmap
This commit is contained in:
50
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
50
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
name: Bug report
|
||||||
|
description: Create a report to help us improve
|
||||||
|
title: "[BUG]: "
|
||||||
|
labels: ["bug"]
|
||||||
|
assignees:
|
||||||
|
- PaulleDemon
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
Thanks for taking the time to fill out this bug report!
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: template-name
|
||||||
|
attributes:
|
||||||
|
label: Template name
|
||||||
|
description: Please tell us which template is the issue related to
|
||||||
|
placeholder: Template name
|
||||||
|
value: "Template name"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: input
|
||||||
|
id: browser
|
||||||
|
attributes:
|
||||||
|
label: Browser & version
|
||||||
|
description: Please tell us which browser and version of the browser you are using
|
||||||
|
placeholder: Browser name & version
|
||||||
|
value: "Browser name"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: what-happened
|
||||||
|
attributes:
|
||||||
|
label: What happened?
|
||||||
|
description: Also tell us, what did you expect to happen?
|
||||||
|
placeholder: Tell us what you see!
|
||||||
|
value: "A bug happened!"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: checkboxes
|
||||||
|
id: related-issues
|
||||||
|
attributes:
|
||||||
|
label: This is a new issue
|
||||||
|
description: I have checked for the same issue in the issues panel
|
||||||
|
options:
|
||||||
|
- label: "Yes"
|
||||||
|
required: true
|
||||||
46
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
46
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: New Feature request
|
||||||
|
description: Have an idea for new feature? well tell us
|
||||||
|
title: "[FEATURE REQUEST]: "
|
||||||
|
labels: ["feature request"]
|
||||||
|
assignees:
|
||||||
|
- PaulleDemon
|
||||||
|
body:
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
> [!NOTE]
|
||||||
|
> Please make sure to check the issues tab before requesting a new feature.
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: feature-description
|
||||||
|
attributes:
|
||||||
|
label: Feature Description
|
||||||
|
description: "Describe about the feature in brief"
|
||||||
|
placeholder: "Tell us about the feature request in brief"
|
||||||
|
value: "Feature description"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: textarea
|
||||||
|
id: functionalities
|
||||||
|
attributes:
|
||||||
|
label: Functionalities of the Feature
|
||||||
|
description: "What should the feature do? eg: a bold button to make the text bold"
|
||||||
|
placeholder: Functions of the feature
|
||||||
|
value: "Functions of the feature"
|
||||||
|
validations:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: checkboxes
|
||||||
|
id: related-issues
|
||||||
|
attributes:
|
||||||
|
label: This is a new feature request
|
||||||
|
description: I acknowledge that I have checked the issues section for similar request and found none.
|
||||||
|
options:
|
||||||
|
- label: "Yes"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
- type: markdown
|
||||||
|
attributes:
|
||||||
|
value: |
|
||||||
|
The feature request priority are based on number of reaction, a good number of thumbs up will make it to priority queue
|
||||||
3
.github/funding.yaml
vendored
Normal file
3
.github/funding.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
ko_fi: artpaul
|
||||||
|
github: [PaulleDemon]
|
||||||
|
buy_me_a_coffee: artpaul
|
||||||
23
License.txt
Normal file
23
License.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
License held by paul
|
||||||
|
Github username: PaulleDemon
|
||||||
|
|
||||||
|
1. License Grant
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to use, copy, modify, merge, publish, and distribute the source code, subject to the following conditions:
|
||||||
|
|
||||||
|
2. Derived Work License
|
||||||
|
Any modifications, derivative works, or copies of the Software must retain this license. All derivative works must be open-sourced under the same license terms. You are not permitted to relicense or sub-license any portion of the Software under a different license without explicit prior written permission from the original author.
|
||||||
|
|
||||||
|
3. Distribution Restriction on Executables
|
||||||
|
You are not permitted to distribute the Software in compiled, executable, or binary form without prior written consent from the original author. This applies to both original and derivative works.
|
||||||
|
|
||||||
|
4. Commercial Use Restriction
|
||||||
|
The Software, in its original or modified form, cannot be used for any commercial purpose without prior written permission from the original author. This includes selling, licensing, or offering the Software as part of a service.
|
||||||
|
|
||||||
|
5. Non-Commercial Use
|
||||||
|
You may freely use, copy, modify, and distribute the source code of the Software for non-commercial purposes, provided that the same terms of this license are maintained in all copies or derivative works.
|
||||||
|
|
||||||
|
6. Changes to the License
|
||||||
|
The original author reserves the right to modify, amend, or update this license at any time. Any changes will apply only to future versions of the Software. Any prior versions of the Software, including derivative works, will continue to be governed by the version of the license in effect at the time the work was created.
|
||||||
|
|
||||||
|
7. Disclaimer
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -13,3 +13,6 @@
|
|||||||
* Generate Code.
|
* Generate Code.
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
|
|
||||||
|
### All code generated by the builder tools are under MIT license and can be used commercially
|
||||||
29
roadmap.md
Normal file
29
roadmap.md
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
## Road map for PyUIBuilder
|
||||||
|
|
||||||
|
Any feature that has 👑 beside it, is meant only for [premium users](./readme.md#license--support)
|
||||||
|
|
||||||
|
### 1.0.0
|
||||||
|
- [x] Create the initial version for UI builder
|
||||||
|
|
||||||
|
### 1.1.0
|
||||||
|
- [ ] Allow swappable layout - (swappy/react-dnd-kit)
|
||||||
|
- [ ] UI fixes and enhancement
|
||||||
|
- [ ] Add text editor to help with event handlers
|
||||||
|
|
||||||
|
### 1.5.0
|
||||||
|
- [ ] Add canvas support (try fabricjs)
|
||||||
|
- [ ] Initial version for Electron App 👑
|
||||||
|
- [ ] Save files locally 👑
|
||||||
|
- [ ] Load UI files 👑
|
||||||
|
- [ ] Light/Dark theme 👑
|
||||||
|
- [ ] Run the preview 👑
|
||||||
|
|
||||||
|
### 2.0.0
|
||||||
|
- [ ] Support for more third party plugins
|
||||||
|
- [ ] Support for Kivy
|
||||||
|
- [ ] Sharable Templates
|
||||||
|
- [ ] Dark theme 👑
|
||||||
|
|
||||||
|
|
||||||
|
### 3.0.0
|
||||||
|
- [ ] Support for PySide / PyQt 👑 (commercial license only)
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<svg width="100%" height="100%">
|
<svg width="100%" height="100%">
|
||||||
|
|
||||||
<pattern id="pattern-circles" x="0" y="0" width="50" height="50" patternUnits="userSpaceOnUse" patternContentUnits="userSpaceOnUse">
|
<pattern id="pattern-circles" x="0" y="0" width="25" height="25" patternUnits="userSpaceOnUse" patternContentUnits="userSpaceOnUse">
|
||||||
<circle id="pattern-circle" cx="10" cy="10" r="1.6257413380501518" fill="#000"></circle>
|
<circle id="pattern-circle" cx="10" cy="10" r="1.6257413380501518" fill="#4d4f4e"></circle>
|
||||||
</pattern>
|
</pattern>
|
||||||
|
|
||||||
<rect id="rect" x="0" y="0" width="100%" height="100%" fill="url(#pattern-circles)"></rect>
|
<rect id="rect" x="0" y="0" width="100%" height="100%" fill="url(#pattern-circles)"></rect>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 387 B After Width: | Height: | Size: 390 B |
@@ -17,13 +17,16 @@ import { removeDuplicateObjects } from "../utils/common"
|
|||||||
import { WidgetContext } from './context/widgetContext'
|
import { WidgetContext } from './context/widgetContext'
|
||||||
// import {ReactComponent as DotsBackground} from "../assets/background/dots.svg"
|
// import {ReactComponent as DotsBackground} from "../assets/background/dots.svg"
|
||||||
|
|
||||||
import DotsBackground from "../assets/background/dots.svg"
|
// import DotsBackground from "../assets/background/dots.svg"
|
||||||
|
import {ReactComponent as DotsBackground} from "../assets/background/dots.svg"
|
||||||
|
|
||||||
import DroppableWrapper from "../components/draggable/droppable"
|
import DroppableWrapper from "../components/draggable/droppable"
|
||||||
import { ActiveWidgetContext, ActiveWidgetProvider, withActiveWidget } from "./activeWidgetContext"
|
import { ActiveWidgetContext, ActiveWidgetProvider, withActiveWidget } from "./activeWidgetContext"
|
||||||
import { DragWidgetProvider } from "./widgets/draggableWidgetContext"
|
import { DragWidgetProvider } from "./widgets/draggableWidgetContext"
|
||||||
|
|
||||||
// const DotsBackground = require("../assets/background/dots.svg")
|
// const DotsBackground = require("../assets/background/dots.svg")
|
||||||
|
|
||||||
|
|
||||||
const CanvasModes = {
|
const CanvasModes = {
|
||||||
DEFAULT: 0,
|
DEFAULT: 0,
|
||||||
PAN: 1,
|
PAN: 1,
|
||||||
@@ -43,8 +46,6 @@ class Canvas extends React.Component {
|
|||||||
this.canvasRef = React.createRef()
|
this.canvasRef = React.createRef()
|
||||||
this.canvasContainerRef = React.createRef()
|
this.canvasContainerRef = React.createRef()
|
||||||
|
|
||||||
this.widgetRefs = {} // stores the actual refs to the widgets inside the canvas
|
|
||||||
|
|
||||||
|
|
||||||
this.currentMode = CanvasModes.DEFAULT
|
this.currentMode = CanvasModes.DEFAULT
|
||||||
|
|
||||||
@@ -57,9 +58,10 @@ class Canvas extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// this._contextMenuItems = []
|
// this._contextMenuItems = []
|
||||||
|
this.widgetRefs = {} // stores the actual refs to the widgets inside the canvas {id: ref, id2, ref2...}
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
widgets: [], // don't store the refs directly here, instead store it in widgetRef, store the widget type here
|
widgets: [], // stores the mapping to widgetRefs, stores id and WidgetType, later used for rendering [{id: , widgetType: WidgetClass}]
|
||||||
zoom: 1,
|
zoom: 1,
|
||||||
isPanning: false,
|
isPanning: false,
|
||||||
currentTranslate: { x: 0, y: 0 },
|
currentTranslate: { x: 0, y: 0 },
|
||||||
@@ -107,7 +109,7 @@ class Canvas extends React.Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.initEvents()
|
this.initEvents()
|
||||||
|
|
||||||
this.addWidget(Widget)
|
this.createWidget(Widget)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,13 +300,13 @@ class Canvas extends React.Component {
|
|||||||
|
|
||||||
}else{
|
}else{
|
||||||
// update the widgets position
|
// update the widgets position
|
||||||
this.state.selectedWidgets.forEach(widget => {
|
// this.state.selectedWidgets.forEach(widget => {
|
||||||
const {x, y} = widget.getPos()
|
// const {x, y} = widget.getPos()
|
||||||
|
|
||||||
const newPosX = x + (deltaX/this.state.zoom) // account for the zoom, since the widget is relative to canvas
|
// const newPosX = x + (deltaX/this.state.zoom) // account for the zoom, since the widget is relative to canvas
|
||||||
const newPosY = y + (deltaY/this.state.zoom) // account for the zoom, since the widget is relative to canvas
|
// const newPosY = y + (deltaY/this.state.zoom) // account for the zoom, since the widget is relative to canvas
|
||||||
// widget.setPos(newPosX, newPosY)
|
// widget.setPos(newPosX, newPosY)
|
||||||
})
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -450,9 +452,9 @@ class Canvas extends React.Component {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Widget} widgetComponentType - don't pass <Widget /> instead pass Widget object
|
* @param {Widget} widgetComponentType - don't pass <Widget /> instead pass Widget object/class
|
||||||
*/
|
*/
|
||||||
addWidget(widgetComponentType, callback){
|
createWidget(widgetComponentType, callback){
|
||||||
const widgetRef = React.createRef()
|
const widgetRef = React.createRef()
|
||||||
|
|
||||||
const id = `${widgetComponentType.widgetType}_${UID()}`
|
const id = `${widgetComponentType.widgetType}_${UID()}`
|
||||||
@@ -573,7 +575,7 @@ class Canvas extends React.Component {
|
|||||||
|
|
||||||
|
|
||||||
const container = draggedElement.getAttribute("data-container")
|
const container = draggedElement.getAttribute("data-container")
|
||||||
console.log("Dropped on canvas",)
|
// console.log("Dropped on canvas",)
|
||||||
|
|
||||||
// const canvasContainerRect = this.getCanvasContainerBoundingRect()
|
// const canvasContainerRect = this.getCanvasContainerBoundingRect()
|
||||||
const canvasRect = this.canvasRef.current.getBoundingClientRect()
|
const canvasRect = this.canvasRef.current.getBoundingClientRect()
|
||||||
@@ -586,7 +588,7 @@ class Canvas extends React.Component {
|
|||||||
|
|
||||||
if (container === "sidebar"){
|
if (container === "sidebar"){
|
||||||
// if the widget is being dropped from the sidebar, use the info to create the widget first
|
// if the widget is being dropped from the sidebar, use the info to create the widget first
|
||||||
this.addWidget(Widget, ({id, widgetRef}) => {
|
this.createWidget(Widget, ({id, widgetRef}) => {
|
||||||
widgetRef.current.setPos(finalPosition.x, finalPosition.y)
|
widgetRef.current.setPos(finalPosition.x, finalPosition.y)
|
||||||
})
|
})
|
||||||
}else if (container === "canvas"){
|
}else if (container === "canvas"){
|
||||||
@@ -633,12 +635,19 @@ class Canvas extends React.Component {
|
|||||||
ref={this.canvasContainerRef}
|
ref={this.canvasContainerRef}
|
||||||
style={{
|
style={{
|
||||||
transition: " transform 0.3s ease-in-out",
|
transition: " transform 0.3s ease-in-out",
|
||||||
backgroundImage: `url('${DotsBackground}')`,
|
backgroundImage: `url(${DotsBackground})`,
|
||||||
backgroundSize: 'cover', // Ensure proper sizing if needed
|
backgroundSize: 'cover', // Ensure proper sizing if needed
|
||||||
backgroundRepeat: 'no-repeat',
|
backgroundRepeat: 'no-repeat',
|
||||||
}}
|
}}
|
||||||
tabIndex={0} // allow focus
|
tabIndex={0} // allow focus
|
||||||
>
|
>
|
||||||
|
<DotsBackground
|
||||||
|
style={{
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
backgroundSize: 'cover'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
{/* Canvas */}
|
{/* Canvas */}
|
||||||
<div data-canvas className="tw-w-full tw-h-full tw-absolute tw-top-0 tw-select-none
|
<div data-canvas className="tw-w-full tw-h-full tw-absolute tw-top-0 tw-select-none
|
||||||
"
|
"
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useDragWidgetContext } from "./draggableWidgetContext"
|
|||||||
import { useDragContext } from "../../components/draggable/draggableContext"
|
import { useDragContext } from "../../components/draggable/draggableContext"
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: sometimes even after drag end the showDroppable is visible
|
||||||
/**
|
/**
|
||||||
* @param {} - widgetRef - the widget ref for your widget
|
* @param {} - widgetRef - the widget ref for your widget
|
||||||
* @param {boolean} - enableDraggable - should the widget be draggable
|
* @param {boolean} - enableDraggable - should the widget be draggable
|
||||||
|
|||||||
Reference in New Issue
Block a user