Skip to content

Commit a4b702d

Browse files
author
Randall C. O'Reilly
committed
initial plans -- seems pretty straightforward..
1 parent eaa04ba commit a4b702d

File tree

8 files changed

+680
-1
lines changed

8 files changed

+680
-1
lines changed

Makefile

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Basic Go makefile
2+
3+
GOCMD=go
4+
GOBUILD=$(GOCMD) build
5+
GOCLEAN=$(GOCMD) clean
6+
GOTEST=$(GOCMD) test
7+
GOGET=$(GOCMD) get
8+
9+
# exclude python from std builds
10+
DIRS=`go list ./... | grep -v python`
11+
12+
all: build
13+
14+
install:
15+
cd cmd/grid; pwd; go build
16+
17+
build:
18+
@echo "GO111MODULE = $(value GO111MODULE)"
19+
$(GOBUILD) -v $(DIRS)
20+
21+
test:
22+
@echo "GO111MODULE = $(value GO111MODULE)"
23+
$(GOTEST) -v $(DIRS)
24+
25+
clean:
26+
@echo "GO111MODULE = $(value GO111MODULE)"
27+
$(GOCLEAN) ./...
28+
29+
fmts:
30+
gofmt -s -w .
31+
32+
vet:
33+
@echo "GO111MODULE = $(value GO111MODULE)"
34+
$(GOCMD) vet $(DIRS) | grep -v unkeyed
35+
36+
tidy: export GO111MODULE = on
37+
tidy:
38+
@echo "GO111MODULE = $(value GO111MODULE)"
39+
go mod tidy
40+
41+
# updates go.mod to master for all of the goki dependencies
42+
# note: must somehow remember to do this for any other depend
43+
# that we need to update at any point!
44+
master: export GO111MODULE = on
45+
master:
46+
@echo "GO111MODULE = $(value GO111MODULE)"
47+
go get -u github.com/goki/ki@master
48+
go get -u github.com/goki/pi@master
49+
go get -u github.com/goki/gi@master
50+
go list -m all | grep goki
51+
52+
old:
53+
@echo "GO111MODULE = $(value GO111MODULE)"
54+
go list -u -m all | grep '\['
55+
56+
mod-update: export GO111MODULE = on
57+
mod-update:
58+
@echo "GO111MODULE = $(value GO111MODULE)"
59+
go get -u ./...
60+
go mod tidy
61+
62+
# gopath-update is for GOPATH to get most things updated.
63+
# need to call it in a target executable directory
64+
gopath-update: export GO111MODULE = off
65+
gopath-update:
66+
@echo "GO111MODULE = $(value GO111MODULE)"
67+
cd cmd/grid; go get -u ./...
68+
69+
release: export GO111MODULE = on
70+
release:
71+
@echo "GO111MODULE = $(value GO111MODULE)"
72+
$(MAKE) -C grid release
73+

README.md

+23-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,24 @@
11
# grid
2-
GoGi SVG vector drawing program
2+
3+
Grid is a GoGi-based SVG vector drawing program, with design based on Inkscape.
4+
5+
# plans
6+
7+
Similar to inkscape in overall layout, and read / write inkscape compatible SVG files.
8+
9+
* Main horiz toolbar(s) across top -- top one is static, bottom one is dynamic based on selection / tool mode.
10+
11+
* Left vert toolbar with drawing tools
12+
13+
* Left panel with drawing structure. This is just like GiEditor tree -- should be trivial, and provides direct access as needed. In particular this provides layer-level organization -- always have a layer group by default, and can drag items into different layers, and also have view and freeze flags on layers. usu only show layer level, and selection there determines which layer things are added to!
14+
15+
* Main middle panel with drawing. Have an optional grid underlay? Need to figure out good gpu-based way to do that -- texture is required, similar to scene? do this later.
16+
17+
* Right tab panel with all the controls, just like gide in terms of tab & Inkscape overall. tabs are easier to find vs. inkscape.
18+
19+
* code in main grid package provides all the editors for right tabs.
20+
21+
* control knobs are sprites, need to add sprite events in gi so we can get mouse events on them.
22+
23+
* figure out clipping eventually.
24+

cmd/grid/grid.go

+226
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
// Copyright (c) 2021, The Grid Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package main
6+
7+
import (
8+
"fmt"
9+
10+
"github.com/goki/gi/gi"
11+
"github.com/goki/gi/gimain"
12+
"github.com/goki/gi/gist"
13+
"github.com/goki/gi/giv"
14+
"github.com/goki/gi/svg"
15+
"github.com/goki/gi/units"
16+
"github.com/goki/grid/grid"
17+
"github.com/goki/ki/ki"
18+
"github.com/mitchellh/go-homedir"
19+
)
20+
21+
func main() {
22+
gimain.Main(func() {
23+
mainrun()
24+
})
25+
}
26+
27+
var CurFilename = ""
28+
var TheSVG *grid.GridView
29+
var TheZoom *gi.SpinBox
30+
var TheTransX *gi.SpinBox
31+
var TheTransY *gi.SpinBox
32+
var TheFile *gi.TextField
33+
34+
func SetZoom(zf float32) {
35+
TheSVG.Scale = zf
36+
TheZoom.SetValue(zf)
37+
TheSVG.SetTransform()
38+
}
39+
40+
func SetTrans(xt, yt float32) {
41+
TheSVG.Trans.Set(xt, yt)
42+
TheTransX.SetValue(xt)
43+
TheTransY.SetValue(yt)
44+
TheSVG.SetTransform()
45+
}
46+
47+
func OpenSVG(fnm string) {
48+
CurFilename = fnm
49+
TheFile.SetText(CurFilename)
50+
updt := TheSVG.UpdateStart()
51+
TheSVG.SetFullReRender()
52+
fmt.Printf("Opening: %v\n", CurFilename)
53+
TheSVG.OpenXML(CurFilename)
54+
SetZoom(TheSVG.ParentWindow().LogicalDPI() / 96.0)
55+
SetTrans(0, 0)
56+
TheSVG.UpdateEnd(updt)
57+
}
58+
59+
func FileViewOpenSVG(vp *gi.Viewport2D) {
60+
giv.FileViewDialog(vp, CurFilename, ".svg", giv.DlgOpts{Title: "Open SVG"}, nil,
61+
vp.Win, func(recv, send ki.Ki, sig int64, data interface{}) {
62+
if sig == int64(gi.DialogAccepted) {
63+
dlg, _ := send.(*gi.Dialog)
64+
OpenSVG(giv.FileViewDialogValue(dlg))
65+
}
66+
})
67+
}
68+
69+
func mainrun() {
70+
width := 1600
71+
height := 1200
72+
73+
gi.SetAppName("svg")
74+
gi.SetAppAbout(`This is a demo of the SVG rendering (and start on editing) in the <b>GoGi</b> graphical interface system, within the <b>GoKi</b> tree framework. See <a href="https://github.com/goki">GoKi on GitHub</a>
75+
<p>You can drag the image around and use the scroll wheel to zoom.</p>`)
76+
77+
win := gi.NewMainWindow("gogi-svg-viewer", "GoGi SVG Viewer", width, height)
78+
79+
vp := win.WinViewport2D()
80+
updt := vp.UpdateStart()
81+
82+
mfr := win.SetMainFrame()
83+
84+
tbar := gi.AddNewToolBar(mfr, "tbar")
85+
tbar.SetStretchMaxWidth()
86+
87+
svgrow := gi.AddNewLayout(mfr, "svgrow", gi.LayoutHoriz)
88+
svgrow.SetProp("horizontal-align", "center")
89+
svgrow.SetProp("margin", 2.0) // raw numbers = px = 96 dpi pixels
90+
svgrow.SetStretchMaxWidth()
91+
svgrow.SetStretchMaxHeight()
92+
93+
svge := grid.AddNewGridView(svgrow, "svg")
94+
TheSVG = svge
95+
svge.InitScale()
96+
svge.Fill = true
97+
svge.SetProp("background-color", "white")
98+
svge.SetProp("width", units.NewPx(float32(width-20)))
99+
svge.SetProp("height", units.NewPx(float32(height-100)))
100+
svge.SetStretchMaxWidth()
101+
svge.SetStretchMaxHeight()
102+
103+
loads := tbar.AddAction(gi.ActOpts{Label: "Open SVG", Icon: "file-open"}, win.This(),
104+
func(recv, send ki.Ki, sig int64, data interface{}) {
105+
FileViewOpenSVG(vp)
106+
})
107+
loads.StartFocus()
108+
109+
fnm := gi.AddNewTextField(tbar, "cur-fname")
110+
TheFile = fnm
111+
fnm.SetMinPrefWidth(units.NewCh(60))
112+
113+
zmlb := gi.AddNewLabel(tbar, "zmlb", "Zoom: ")
114+
zmlb.SetProp("vertical-align", gist.AlignMiddle)
115+
zmlb.Tooltip = "zoom scaling factor -- can use mouse scrollwheel to zoom as well"
116+
117+
zoomout := tbar.AddAction(gi.ActOpts{Icon: "zoom-out", Name: "zoomout", Tooltip: "zoom out"},
118+
win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
119+
SetZoom(svge.Scale * 0.9)
120+
win.FullReRender()
121+
})
122+
zoomout.SetProp("margin", 0)
123+
zoomout.SetProp("padding", 0)
124+
zoomout.SetProp("#icon", ki.Props{
125+
"width": units.NewEm(1.5),
126+
"height": units.NewEm(1.5),
127+
})
128+
zoom := gi.AddNewSpinBox(tbar, "zoom")
129+
// zoom.SetMinPrefWidth(units.NewEm(10))
130+
zoom.SetValue(svge.Scale)
131+
zoom.Tooltip = "zoom scaling factor -- can use mouse scrollwheel to zoom as well"
132+
TheZoom = zoom
133+
zoom.SpinBoxSig.Connect(win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
134+
sp := send.(*gi.SpinBox)
135+
SetZoom(sp.Value)
136+
win.FullReRender()
137+
})
138+
139+
zoomin := tbar.AddAction(gi.ActOpts{Icon: "zoom-in", Name: "zoomin", Tooltip: " zoom in"},
140+
win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
141+
SetZoom(svge.Scale * 1.1)
142+
win.FullReRender()
143+
})
144+
zoomin.SetProp("margin", 0)
145+
zoomin.SetProp("padding", 0)
146+
zoomin.SetProp("#icon", ki.Props{
147+
"width": units.NewEm(1.5),
148+
"height": units.NewEm(1.5),
149+
})
150+
151+
gi.AddNewSpace(tbar, "spctr")
152+
trlb := gi.AddNewLabel(tbar, "trlb", "Translate: ")
153+
trlb.Tooltip = "Translation of overall image -- can use mouse drag to move as well"
154+
trlb.SetProp("vertical-align", gist.AlignMiddle)
155+
156+
trx := gi.AddNewSpinBox(tbar, "trx")
157+
// zoom.SetMinPrefWidth(units.NewEm(10))
158+
trx.SetValue(svge.Trans.X)
159+
TheTransX = trx
160+
trx.SpinBoxSig.Connect(win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
161+
SetTrans(trx.Value, svge.Trans.Y)
162+
win.FullReRender()
163+
})
164+
165+
try := gi.AddNewSpinBox(tbar, "try")
166+
// zoom.SetMinPrefWidth(units.NewEm(10))
167+
try.SetValue(svge.Trans.Y)
168+
TheTransY = try
169+
try.SpinBoxSig.Connect(win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
170+
SetTrans(svge.Trans.X, try.Value)
171+
win.FullReRender()
172+
})
173+
174+
fnm.TextFieldSig.Connect(win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
175+
if sig == int64(gi.TextFieldDone) {
176+
tf := send.(*gi.TextField)
177+
fn, _ := homedir.Expand(tf.Text())
178+
OpenSVG(fn)
179+
}
180+
})
181+
182+
svge.NodeSig.Connect(win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
183+
ssvg := send.Embed(svg.KiT_Editor).(*grid.GridView)
184+
SetZoom(ssvg.Scale)
185+
SetTrans(ssvg.Trans.X, ssvg.Trans.Y)
186+
})
187+
188+
vp.UpdateEndNoSig(updt)
189+
190+
// main menu
191+
appnm := gi.AppName()
192+
mmen := win.MainMenu
193+
mmen.ConfigMenus([]string{appnm, "File", "Edit", "Window"})
194+
195+
amen := win.MainMenu.ChildByName(appnm, 0).(*gi.Action)
196+
amen.Menu = make(gi.Menu, 0, 10)
197+
amen.Menu.AddAppMenu(win)
198+
199+
emen := win.MainMenu.ChildByName("Edit", 1).(*gi.Action)
200+
emen.Menu = make(gi.Menu, 0, 10)
201+
emen.Menu.AddCopyCutPaste(win)
202+
203+
// note: Command in shortcuts is automatically translated into Control for
204+
// Linux, Windows or Meta for MacOS
205+
fmen := win.MainMenu.ChildByName("File", 0).(*gi.Action)
206+
fmen.Menu = make(gi.Menu, 0, 10)
207+
fmen.Menu.AddAction(gi.ActOpts{Label: "Open", Shortcut: "Command+O"},
208+
win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
209+
FileViewOpenSVG(vp)
210+
})
211+
fmen.Menu.AddSeparator("csep")
212+
fmen.Menu.AddAction(gi.ActOpts{Label: "Close Window", Shortcut: "Command+W"},
213+
win.This(), func(recv, send ki.Ki, sig int64, data interface{}) {
214+
win.OSWin.Close()
215+
})
216+
217+
win.SetCloseCleanFunc(func(w *gi.Window) {
218+
go gi.Quit() // once main window is closed, quit
219+
})
220+
221+
// todo: when saving works, add option to save, and change above to CloseReq
222+
223+
win.MainMenuUpdated()
224+
225+
win.StartEventLoop()
226+
}

doc.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) 2021, The Grid Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
/*
6+
Package grid is the top-level repository for the Grid Go SVG vector drawing program
7+
the GoGi GUI framework.
8+
9+
The following sub-packages provide all the code:
10+
11+
* grid: is the main codebase, in library form which can be
12+
used in different contexts.
13+
14+
* cmd: is where the actual command tool is built.
15+
*/
16+
package grid

go.mod

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module github.com/goki/grid
2+
3+
require (
4+
github.com/goki/gi v1.1.6
5+
github.com/goki/ki v1.0.8
6+
github.com/goki/mat32 v1.0.2
7+
github.com/mitchellh/go-homedir v1.1.0
8+
)
9+
10+
go 1.13

0 commit comments

Comments
 (0)