Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DiagramWidget #55

Merged
merged 56 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from 55 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
931b139
Added diagramwidget, updated terminology
pbrown12303 Mar 13, 2023
55d7445
Fixed arrowhead direction
pbrown12303 Mar 15, 2023
daeaa67
Arrow decorations working at three locations
pbrown12303 Mar 17, 2023
21033d4
Stacked Decorations working
pbrown12303 Mar 17, 2023
d00df3b
Anchored Text working
pbrown12303 Mar 21, 2023
3e63240
Node handles working
pbrown12303 Mar 23, 2023
4e99290
Added connectionPads, identifiers
pbrown12303 Mar 24, 2023
6b3f337
All basic functionality in place
pbrown12303 Mar 29, 2023
5b99519
Added documentation to AnchoredText
pbrown12303 Apr 14, 2023
d8e92c8
Updated Readme.md and DiagramWidget documentation
pbrown12303 Apr 14, 2023
cbe3545
Fixed Readme.md formatting
pbrown12303 Apr 14, 2023
a072838
Update README.md
pbrown12303 Apr 14, 2023
5e96093
Update README.md
pbrown12303 Apr 14, 2023
bd3d70f
Documented ForceRepaint
pbrown12303 Apr 17, 2023
f7a8fe3
Removed .gitarchive, table and viewport widgets
pbrown12303 Apr 18, 2023
d412f53
Polygon decoration implemented
pbrown12303 Apr 23, 2023
9b5449b
Made refresh workaround private; go.mod image version
pbrown12303 Apr 27, 2023
562448b
Scrolling; ForceRefresh; factored out StringForceLayout
pbrown12303 Apr 27, 2023
2d17ea6
Delete explicitlayout
pbrown12303 Apr 27, 2023
f408904
Refined Polygon point positioning; Added pad interfaces.
pbrown12303 Apr 28, 2023
34cd696
Added documentation
pbrown12303 Apr 30, 2023
5b4c073
Handling of DiagramElement deletion
pbrown12303 May 2, 2023
456a9ce
Interaction Work
pbrown12303 May 17, 2023
b2f00fc
Link end movement implemented
pbrown12303 May 23, 2023
9f4ef1c
Added primarySelection
pbrown12303 May 24, 2023
6001e0a
Added selection functions
pbrown12303 May 25, 2023
c40991f
Added Tapped override
pbrown12303 May 26, 2023
2d5e9f3
Dynamic Link Creation; DiaagramElement kind checking
pbrown12303 Jun 8, 2023
16afb1f
Added mouse callbacks; made ConnectionTransaction public
pbrown12303 Jun 16, 2023
d45d1fb
Removed debug log entries
pbrown12303 Jun 26, 2023
9a29be0
Removed ForceRepaint workaround; consolidated properties
pbrown12303 Jul 12, 2023
25ae4e7
Added link mouse callbacks
pbrown12303 Jul 13, 2023
820beec
Ignore all executables
pbrown12303 Jul 18, 2023
03d72df
Fixed Refresh() bugs
pbrown12303 Jul 25, 2023
db73a10
Removed replace directive
pbrown12303 Jul 26, 2023
b19c2e6
Merge branch 'master' into diagramwidget
pbrown12303 Jul 26, 2023
c6ee81f
Merge changes
pbrown12303 Jul 26, 2023
bc24ccd
Changed diagram drag behavior; fixed dependencies
pbrown12303 Jul 28, 2023
f9c6702
Added comments
pbrown12303 Jul 28, 2023
58634eb
Fixed lint errors
pbrown12303 Jul 28, 2023
9130c23
Update box.go
pbrown12303 Jul 29, 2023
c2b4174
Addressed Jacob's feedback.
pbrown12303 Aug 15, 2023
6f11e6d
Fixed display flickering
pbrown12303 Sep 6, 2023
91eebaa
Added scrolling
pbrown12303 Sep 7, 2023
58a0e64
Improved link selection; Added bring to front/send to back
pbrown12303 Sep 7, 2023
3be0276
Fixed review feedback
pbrown12303 Sep 11, 2023
298d96f
Revert "Fixed review feedback"
pbrown12303 Sep 12, 2023
efe6454
Addressed review feedback
pbrown12303 Sep 12, 2023
6e5f359
Fixed static error in node.go line 55
pbrown12303 Sep 12, 2023
ba26990
Removed go.work.sum
pbrown12303 Sep 13, 2023
2a8813f
Made drawingArea private, added simulation events
pbrown12303 Sep 14, 2023
846dd70
Removed DiagramWidget.SimulateMouse... functions
pbrown12303 Sep 18, 2023
40bc5e2
Merge branch 'fyne-io:master' into diagramwidget
pbrown12303 Oct 13, 2023
a8defda
Upgrade to fyne 2.4.1
pbrown12303 Oct 17, 2023
57f5855
Merge branch 'master' into diagramwidget
pbrown12303 Oct 17, 2023
bc06b79
Renamed screenshot, removed TODO comment, edited README
pbrown12303 Oct 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ Session.vim
tags
# Persistent undo
[._]*.un~
*.exe
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Diagram Widget: Charles Daniels and Paul C. Brown
54 changes: 43 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,33 @@ layout := NewResponsiveLayout(

## Widgets

Community contributed widgets.
This package contains a collection of community-contributed widgets for the [Fyne](https://fyne.io/)
toolkit. The code here is intended to be production ready, but may be lacking
some desirable functional features. If you have suggestions for changes to
existing functionality or addition of new functionality, please look at the existing
issues in the repository to see if your idea is already on the table. If it is not,
feel free to open an issue.

This collection should be considered a work in progress. When changes are made,
serious consideration will be given to backward compatibility, but compatibility
is not guaranteed.

`import "fyne.io/x/fyne/widget"`

### Calendar
### Animated Gif


A widget that will run animated gifs.

<p align="center" class="align:center;margin:auto" markdown="1">
<img src="img/gifwidget.gif" />
</p>

```go
gif, err := NewAnimatedGif(storage.NewFileURI("./testdata/gif/earth.gif"))
gif.Start()
```

### Calendar

A date picker which returns a [time](https://pkg.go.dev/time) object with the selected date.

Expand All @@ -80,18 +100,30 @@ calendar := widget.NewCalendar(time.Now(), onSelected, cellSize, padding)
```
[Demo](./cmd/hexwidget_demo/main.go) available for example usage

### Animated Gif
### DiagramWidget

A widget that will run animated gifs.
The DiagramWidget provides a drawing area within which a diagram can be created. The diagram itself is a collection of
DiagramElement widgets (an interface). There are two types of DiagramElements: DiagramNode widgets and DiagramLink widgets.
DiagramNode widgets are thin wrappers around a user-supplied CanvasObject.
Any valid CanvasObject can be used. DiagramLinks are line-based connections between DiagramElements.
Note that links can connect to other links as well as nodes.

<p align="center" class="align:center;margin:auto" markdown="1">
<img src="img/gifwidget.gif" />
While some provisions have been made for automatic layout, layouts are for the convenience
of the author and are on-demand only. The design intent is that users will place the diagram elements for human readability.

DiagramElements are managed by the DiagramWidget from a layout perspective. DiagramNodes have no size
constraints imposed by the DiagramWidget and can be placed anywhere. DiagramLinks connect
DiagramElements. The DiagramWidget keeps track of the DiagramElements to which each DiagramLink
is connected and calls the Refresh() method on the link when the connected diagram element is moved
or resized.

* [demo](./cmd/diagramdemo/main.go)
* [More Detail](./widget/diagramwidget/README.md)

<p align="center" markdown="1" style="max-width: 100%">
<img src="img/DiagramWidget.png" width="1024" height="880" alt="Diagram Widget" style="max-width: 100%" />
</p>

```go
gif, err := NewAnimatedGif(storage.NewFileURI("./testdata/gif/earth.gif"))
gif.Start()
```

### FileTree

Expand Down
184 changes: 184 additions & 0 deletions cmd/diagramdemo/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package main

import (
"fmt"
"image/color"
"time"

"fyne.io/x/fyne/widget/diagramwidget"

"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
)

var forceticks int = 0

func forceanim(diagramWidget *diagramwidget.DiagramWidget) {

for {
if forceticks > 0 {
diagramwidget.StepForceLayout(diagramWidget, 300)
diagramWidget.Refresh()
forceticks--
fmt.Printf("forceticks=%d\n", forceticks)
}

time.Sleep(time.Millisecond * (1000 / 30))
}
}

func main() {
app := app.New()
w := app.NewWindow("Diagram Demo")

w.SetMaster()

diagramWidget := diagramwidget.NewDiagramWidget("Diagram1")

scrollContainer := container.NewScroll(diagramWidget)

go forceanim(diagramWidget)

// Node 0
node0Label := widget.NewLabel("Node0")
node0 := diagramwidget.NewDiagramNode(diagramWidget, node0Label, "Node0")
node0.Move(fyne.NewPos(300, 0))

// Node 1
node1Button := widget.NewButton("Node1 Button", func() { fmt.Printf("tapped Node1!\n") })
node1 := diagramwidget.NewDiagramNode(diagramWidget, node1Button, "Node1")
node1.Move(fyne.Position{X: 100, Y: 100})

// Node 2
node2 := diagramwidget.NewDiagramNode(diagramWidget, nil, "Node2")
node2Container := container.NewVBox(
widget.NewLabel("Node2 - with structure"),
widget.NewButton("Up", func() {
node2.GetDiagram().DisplaceNode(node2, fyne.Position{X: 0, Y: -10})
node2.Refresh()
}),
widget.NewButton("Down", func() {
node2.GetDiagram().DisplaceNode(node2, fyne.Position{X: 0, Y: 10})
node2.Refresh()
}),
container.NewHBox(
widget.NewButton("Left", func() {
node2.GetDiagram().DisplaceNode(node2, fyne.Position{X: -10, Y: 0})
node2.Refresh()
}),
widget.NewButton("Right", func() {
node2.GetDiagram().DisplaceNode(node2, fyne.Position{X: 10, Y: 0})
node2.Refresh()
}),
),
)
node2.SetInnerObject(node2Container)
node2.Move(fyne.Position{X: 100, Y: 300})

// Node 3
node3 := diagramwidget.NewDiagramNode(diagramWidget, widget.NewButton("Node3: Force layout step", func() {
diagramwidget.StepForceLayout(diagramWidget, 300)
diagramWidget.Refresh()
}), "Node3")
node3.Move(fyne.Position{X: 400, Y: 100})

// Node 4
node4 := diagramwidget.NewDiagramNode(diagramWidget, widget.NewButton("Node4: auto layout", func() {
forceticks += 100
diagramWidget.Refresh()
}), "Node4")
node4.Move(fyne.Position{X: 400, Y: 400})

node5 := diagramwidget.NewDiagramNode(diagramWidget, widget.NewLabel("Node5"), "Node5")
node5.Move(fyne.NewPos(600, 200))

// Link0
link0 := diagramwidget.NewDiagramLink(diagramWidget, "Link0")
link0.SetSourcePad(node0.GetEdgePad())
link0.SetTargetPad(node1.GetEdgePad())
link0.AddSourceAnchoredText("sourceRole", "sourceRole")
link0.AddMidpointAnchoredText("linkName", "Link 0")
solidDiamond := createDiamondDecoration()
solidDiamond.SetSolid(true)
link0.AddSourceDecoration(solidDiamond)

// Link1
link1 := diagramwidget.NewDiagramLink(diagramWidget, "Link1")
link1.SetSourcePad(node2.GetEdgePad())
link1.SetTargetPad(node1.GetEdgePad())
link1.SetForegroundColor(color.RGBA{255, 64, 64, 255})
link1.AddTargetDecoration(diagramwidget.NewArrowhead())
link1.AddTargetDecoration(diagramwidget.NewArrowhead())
link1.AddMidpointDecoration(diagramwidget.NewArrowhead())
link1.AddMidpointDecoration(diagramwidget.NewArrowhead())
link1.AddMidpointAnchoredText("linkName", "Link 1")
link1.AddSourceDecoration(diagramwidget.NewArrowhead())
link1.AddSourceDecoration(diagramwidget.NewArrowhead())

// Link2
link2 := diagramwidget.NewDiagramLink(diagramWidget, "Link2")
link2.SetSourcePad(node0.GetEdgePad())
link2.SetTargetPad(node3.GetEdgePad())
link2.AddMidpointAnchoredText("linkName", "Link 2")
link2.AddSourceDecoration(createHalfArrowDecoration())

// Link3
link3 := diagramwidget.NewDiagramLink(diagramWidget, "Link3")
link3.SetSourcePad(node2.GetEdgePad())
link3.SetTargetPad(node3.GetEdgePad())
link3.AddSourceAnchoredText("sourceRole", "sourceRole")
link3.AddMidpointAnchoredText("linkName", "Link 3")
link3.AddTargetAnchoredText("targetRole", "targetRole")
link3.AddMidpointDecoration(createTriangleDecoration())

// Link4
link4 := diagramwidget.NewDiagramLink(diagramWidget, "Link4")
link4.SetSourcePad(node4.GetEdgePad())
link4.SetTargetPad(node3.GetEdgePad())
link4.AddMidpointAnchoredText("linkName", "Link 4")

// Link5
link5 := diagramwidget.NewDiagramLink(diagramWidget, "Link5")
link5.SetSourcePad(link4.GetMidPad())
link5.SetTargetPad(node5.GetEdgePad())
link5.AddMidpointAnchoredText("linkName", "Link 5")
link5.AddTargetDecoration(diagramwidget.NewArrowhead())

w.SetContent(scrollContainer)

w.Resize(fyne.NewSize(600, 400))
w.ShowAndRun()
}

func createTriangleDecoration() diagramwidget.Decoration {
points := []fyne.Position{
{X: 0, Y: 15},
{X: 15, Y: 0},
{X: 0, Y: -15},
}
polygon := diagramwidget.NewPolygon(points)
return polygon
}

func createDiamondDecoration() diagramwidget.Decoration {
points := []fyne.Position{
{X: 0, Y: 0},
{X: 8, Y: 4},
{X: 16, Y: 0},
{X: 8, Y: -4},
}
polygon := diagramwidget.NewPolygon(points)
return polygon
}

func createHalfArrowDecoration() diagramwidget.Decoration {
points := []fyne.Position{
{X: 0, Y: 0},
{X: 16, Y: 8},
{X: 16, Y: 0},
}
polygon := diagramwidget.NewPolygon(points)
return polygon
}
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ require (
github.com/eclipse/paho.mqtt.golang v1.3.5
github.com/gorilla/websocket v1.4.2
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef
github.com/stretchr/testify v1.8.4
github.com/twpayne/go-geom v1.0.0
github.com/wagslane/go-password-validator v0.3.0
golang.org/x/image v0.11.0
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,10 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA=
github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg=
github.com/twpayne/go-geom v1.0.0 h1:ARrRnN4+rBX3LZFZQy9NFeXXlgQqVL4OOvAcnLdgy2g=
github.com/twpayne/go-geom v1.0.0/go.mod h1:RWsl+e3XSahOul/KH2BHCfF0QxSL4RMnMlFw/TNmET0=
github.com/twpayne/go-kml v1.0.0/go.mod h1:LlvLIQSfMqYk2O7Nx8vYAbSLv4K9rjMvLlEdUKWdjq0=
github.com/twpayne/go-polyline v1.0.0/go.mod h1:ICh24bcLYBX8CknfvNPKqoTbe+eg+MX1NPyJmSBo7pU=
github.com/urfave/cli/v2 v2.4.0/go.mod h1:NX9W0zmTvedE5oDoOMs2RTC8RvdK98NTYZE5LbaEYPg=
github.com/wagslane/go-password-validator v0.3.0 h1:vfxOPzGHkz5S146HDpavl0cw1DSVP061Ry2PX0/ON6I=
github.com/wagslane/go-password-validator v0.3.0/go.mod h1:TI1XJ6T5fRdRnHqHt14pvy1tNVnrwe7m3/f1f2fDphQ=
Expand Down
Binary file added img/DiagramWidget.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/Screenshot 2023-10-07 102222.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading