Skip to content

updates for Cogent Canvas #1528

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

Open
wants to merge 80 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
b7acd48
canvas: use svg Geom.Pos offset, for direct rendering of svg at diffe…
rcoreilly May 19, 2025
acd1618
canvas: sprites have Locked versions of methods for batch-mode updati…
rcoreilly May 19, 2025
291a5a9
canvas: svg bounding boxes are math32.Vector2 not image.Rectangle -- …
rcoreilly May 20, 2025
334e6b6
canvas: move over some basic zoom logic from canvas -- should be usef…
rcoreilly May 20, 2025
0f6097d
canvas: ColorPicker sends both Input and Change events; updated Value…
rcoreilly May 20, 2025
7fb6212
add HandleValueOnInput for bind value updating on Input -- not good f…
rcoreilly May 21, 2025
680b6bf
canvas: add to the plan.md docs so I know how to restyle a sub-elemen…
rcoreilly May 21, 2025
dea969c
canvas:major update to docs, adding layout and scene to architecture,…
rcoreilly May 21, 2025
8103a54
canvas: add box model fig
rcoreilly May 21, 2025
22d071b
canvas: add box model fig to styles too
rcoreilly May 21, 2025
6bef5be
canvas: change gradient stop to color.RGBA instead of color.Color: al…
rcoreilly May 22, 2025
06b0a4d
canvas: key core.Tree fix: set root through the .This so it actually …
rcoreilly May 22, 2025
d3712d9
canvas: add core.Tree Updater to auto resync the tree on Update -- st…
rcoreilly May 22, 2025
7f9aa39
canvas: yeah that updater causes excessive updating during sync. addi…
rcoreilly May 22, 2025
a5c749b
canvas: tree export EditNode -- needed in canvas; svg use Paint.Displ…
rcoreilly May 22, 2025
e0af098
canvas: full implementation of IconSize as an inherited style propert…
rcoreilly May 23, 2025
83ad398
canvas: svg marshal xml gradient was saving completely the wrong data…
rcoreilly May 23, 2025
42ee847
canvas: svg marshal xml fixes for namedview metadata
rcoreilly May 23, 2025
4fef123
canvas: added tree.SetUniqueNameIfDuplicate and apply in core.tree to…
rcoreilly May 23, 2025
5cae18f
canvas: was not properly parsing color = "none" to nil; cannot skip s…
rcoreilly May 23, 2025
cfa6ca2
canvas: bidirectional setting of text, font properties from rich, tex…
rcoreilly May 23, 2025
5b9e81b
canvas: rich style returns nil for colors if flags not set, and flags…
rcoreilly May 24, 2025
08907cd
canvas: enumgen does not generate unexported enum values
rcoreilly May 24, 2025
a337dd5
canvas: yaegicore update
rcoreilly May 24, 2025
64a36b4
canvas: svg text bboxes in right place, and finally figured out right…
rcoreilly May 24, 2025
a54cea7
canvas: svg node tranform logic finally correct. todo: remove the mat…
rcoreilly May 24, 2025
461cd76
canvas: svg major update to ApplyTransform paradigm for dynamically t…
rcoreilly May 26, 2025
3bd8c74
canvas: svg gradient typo
rcoreilly May 26, 2025
69b3253
canvas: key fix to radial gradient transform logic: scale radii by sc…
rcoreilly May 26, 2025
b83cc63
canvas: actual key fix: need a different way of extracting angle usin…
rcoreilly May 26, 2025
7b7f879
canvas: new radial gradient fix is incompatible with updating direct …
rcoreilly May 26, 2025
3969e0a
canvas: have to init transform to identity when creating new gradient…
rcoreilly May 26, 2025
a2f2108
canvas: uncomment OpenFiles logic on mac: does not run in time for ma…
rcoreilly May 26, 2025
c89f2fb
canvas: handle OSOpenFiles events, generated on darwin by opening a d…
rcoreilly May 26, 2025
eccf8e0
canvas: crash in spell fixed
rcoreilly May 26, 2025
2977e70
canvas: fix js shaper crash -- canvas now working well on web.
rcoreilly May 26, 2025
123b1f8
canvas: major update to sprites; draw function instead of image-only.…
rcoreilly May 27, 2025
d10384b
canvas: sprite docs
rcoreilly May 27, 2025
87d364a
canvas: Sprites are Tiered to support rendering and event ordering in…
rcoreilly May 28, 2025
7011247
canvas: sprites process all lists and only default to Normal for add;…
rcoreilly May 29, 2025
225944e
canvas: overflow checks in rasterx/scan prevent fail on extreme svg z…
rcoreilly May 29, 2025
fd6d0b3
canvas: critical fix to FuncButton calling of methods from value butt…
rcoreilly May 29, 2025
bc578e3
canvas: rasterx scan fix needs to be more localized to actual for loo…
rcoreilly May 29, 2025
df2b7eb
canvas: new strategy for renderwindow async logic: atomic int counter…
rcoreilly May 30, 2025
971e3be
canvas: only one cursor sprite per type (TextField, texteditor), not …
rcoreilly May 30, 2025
a744b67
canvas: splits sends change when handles changed; svg strokewidth in px
rcoreilly May 30, 2025
13a3936
canvas: svg save image removes any position offset, add SaveImageSize…
rcoreilly May 30, 2025
bb40a78
canvas: reinstate sprite mobile render offset logic properly (cursors…
rcoreilly May 30, 2025
e862ed6
canvas: update xyz text build bug
rcoreilly May 30, 2025
4b7d2e5
canvas: close dialog needed an unlock if not closing. Last bug fixed!
rcoreilly May 31, 2025
5ca8712
Merge branch 'main' into canvas
rcoreilly May 31, 2025
007d44f
Merge branch 'main' into canvas
rcoreilly May 31, 2025
c294173
canvas: robustness for togglecursor in docs generate html destroy
rcoreilly May 31, 2025
8607e0b
canvas: box model fig made using canvas with screen grab from core bu…
rcoreilly May 31, 2025
a0eda8c
canvas: added test for editor in dialog -- requires screen off, now w…
rcoreilly May 31, 2025
89714ff
canvas: remove debug and drawpos is always 0,0 on all platforms for s…
rcoreilly May 31, 2025
95e9aef
core: improve use of IconSize on button
kkoreilly May 31, 2025
e77626a
docs: document button font and icon size
kkoreilly May 31, 2025
75cd585
add font size and icon size docs
kkoreilly May 31, 2025
76f4bdc
canvas: tiered Do needs to pass pointer -- otherwise doesn't work for…
rcoreilly May 31, 2025
4339fe4
canvas: remove non-standard min-width property from paint props. neve…
rcoreilly May 31, 2025
435d674
canvas: fix box-model.svg which had weird stuff in it
rcoreilly May 31, 2025
86425ca
canvas: updated box-model with layers and cleanup last part of min w…
rcoreilly May 31, 2025
b63f601
chooser: improve use of IconSize
kkoreilly May 31, 2025
998b59c
docs: document OnInput for color picker
kkoreilly May 31, 2025
8f33ece
canvas: fix copy-o in stroke properties
rcoreilly May 31, 2025
dfd4ff8
canvas: start and end marker directions are based on 2 proximal point…
rcoreilly Jun 1, 2025
7a7e716
canvas: enumgen only excludes unexported values for types that are ex…
rcoreilly Jun 1, 2025
bd3469e
canvas: rerun generate on everything -- enums ok, some types updated
rcoreilly Jun 1, 2025
70da254
canvas: use slices.Contains in events logic, update comments in render
rcoreilly Jun 1, 2025
417489b
canvas: use pointer for slicePainter
rcoreilly Jun 1, 2025
9757bc7
canvas: docs: add resources category with cursors and icons. Might al…
rcoreilly Jun 1, 2025
e612064
canvas: needed to pick a color too... and colors belong in resources.…
rcoreilly Jun 2, 2025
e18e515
canvas: todo about plotting cam space using a canvas in colors docs page
rcoreilly Jun 2, 2025
7900fda
canvas: SetTransformProperty method -- need to call this in canvas
rcoreilly Jun 2, 2025
b5cdac8
canvas: protect core.tree Duplicate from duplicate names
rcoreilly Jun 2, 2025
ae2f2c6
canvas: render overview diagram -- I wanted to make this figure but d…
rcoreilly Jun 2, 2025
70e73de
canvas: render overview size fix
rcoreilly Jun 2, 2025
09b1f00
canvas: fix cursor updating: was not setting cursor in many cases due…
rcoreilly Jun 2, 2025
e16118e
canvas: text props update to handle stroke-color and especially setti…
rcoreilly Jun 2, 2025
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
9 changes: 9 additions & 0 deletions base/keylist/keylist_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ func TestKeyList(t *testing.T) {
assert.Equal(t, 0, kl.Values[1])
assert.Equal(t, 2, kl.IndexByKey("key2"))

kl.DeleteByKey("new0")
assert.Equal(t, 0, kl.Values[0])
assert.Equal(t, 2, kl.Values[1])
assert.Equal(t, 1, kl.IndexByKey("key2"))

kl.Add("new0", 3)
assert.Equal(t, 3, kl.Values[2])
assert.Equal(t, 2, kl.IndexByKey("new0"))

// nm := Make([]KeyValue[string, int]{{"one", 1}, {"two", 2}, {"three", 3}})
// assert.Equal(t, 3, nm.Values[2])
// assert.Equal(t, 2, nm.Values[1])
Expand Down
8 changes: 4 additions & 4 deletions base/tiered/tiered.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ type Tiered[T any] struct {

// Do calls the given function for each tier,
// going through first, then normal, then final.
func (t *Tiered[T]) Do(f func(T)) {
f(t.First)
f(t.Normal)
f(t.Final)
func (t *Tiered[T]) Do(f func(*T)) {
f(&t.First)
f(&t.Normal)
f(&t.Final)
}

// DoWith calls the given function with each tier of this tiered
Expand Down
8 changes: 4 additions & 4 deletions colors/gradient/gradient.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ type Base struct { //types:add -setters
// Stop represents a single stop in a gradient
type Stop struct {

// the color of the stop. these should be fully opaque,
// Color of the stop. These should be fully opaque,
// with opacity specified separately, for best results, as is done in SVG etc.
Color color.Color
Color color.RGBA

// the position of the stop between 0 and 1
// Pos is the position of the stop in normalized units between 0 and 1.
Pos float32

// Opacity is the 0-1 level of opacity for this stop
// Opacity is the 0-1 level of opacity for this stop.
Opacity float32
}

Expand Down
29 changes: 20 additions & 9 deletions colors/gradient/gradient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,26 @@ func TestRenderRadial(t *testing.T) {
imagex.Assert(t, img, "radial-user-space")
}

// func matToRasterx(mat *math32.Matrix2) rasterx.Matrix2D {
// // A = XX
// // B = YX
// // C = XY
// // D = YY
// // E = X0
// // F = Y0
// return rasterx.Matrix2D{float64(mat.XX), float64(mat.YX), float64(mat.XY), float64(mat.YY), float64(mat.X0), float64(mat.Y0)}
// }
func TestRenderRadialRotate(t *testing.T) {
r := image.Rectangle{Max: image.Point{128, 128}}
b := math32.B2FromRect(r)
img := image.NewRGBA(r)
g := CopyOf(radialTransformTest)
// g.AsBase().Blend = colors.HCT
g.Update(1, b, math32.Identity2())
draw.Draw(img, img.Bounds(), g, image.Point{}, draw.Src)
imagex.Assert(t, img, "radial-rot")

xf := math32.Rotate2D(math32.DegToRad(-45))
ug := CopyOf(g).(*Radial)
ug.SetUnits(UserSpaceOnUse)
ug.Center.SetMul(ug.Box.Size())
ug.Focal.SetMul(ug.Box.Size())
ug.Radius.SetMul(ug.Box.Size())
ug.Update(1, b, xf)
draw.Draw(img, img.Bounds(), ug, image.Point{}, draw.Src)
imagex.Assert(t, img, "radial-rot-user-space")
}

func compareTol(t *testing.T, a, c float32) {
if math32.Abs(a-c) > 1.0e-5 {
Expand Down
11 changes: 7 additions & 4 deletions colors/gradient/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ func FromString(str string, ctx ...colors.Context) (image.Image, error) {
// TODO(kai): do we need to clone?
return img, nil
}

str = strings.TrimSpace(str)
if strings.HasPrefix(str, "url(") {
img := cc.ImageByURL(str)
Expand All @@ -69,6 +68,9 @@ func FromString(str string, ctx ...colors.Context) (image.Image, error) {
return img, nil
}
str = strings.ToLower(str)
if str == "none" || str == "" {
return nil, nil
}
grad := "-gradient"

gidx := strings.Index(str, grad)
Expand Down Expand Up @@ -126,10 +128,14 @@ func FromAny(val any, ctx ...colors.Context) (image.Image, error) {
switch v := val.(type) {
case color.Color:
return colors.Uniform(v), nil
case *color.Color:
return colors.Uniform(*v), nil
case image.Image:
return v, nil
case string:
return FromString(v, ctx...)
case *string:
return FromString(*v, ctx...)
}
return nil, fmt.Errorf("gradient.FromAny: got unsupported type %T", val)
}
Expand Down Expand Up @@ -498,9 +504,6 @@ func readFraction(v string) (float32, error) {
}
f := float32(f64)
f /= d
if f < 0 {
f = 0
}
return f, nil
}

Expand Down
18 changes: 11 additions & 7 deletions colors/gradient/radial.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type Radial struct { //types:add -setters
rCenter math32.Vector2
rFocal math32.Vector2
rRadius math32.Vector2

rotTrans math32.Matrix2
}

var _ Gradient = &Radial{}
Expand Down Expand Up @@ -62,6 +64,7 @@ func (r *Radial) Update(opacity float32, box math32.Box2, objTransform math32.Ma
r.Box = box
r.Opacity = opacity
r.updateBase()
r.rotTrans = math32.Identity2()

c, f, rs := r.Center, r.Focal, r.Radius
sz := r.Box.Size()
Expand All @@ -70,12 +73,12 @@ func (r *Radial) Update(opacity float32, box math32.Box2, objTransform math32.Ma
f = r.Box.Min.Add(sz.Mul(f))
rs.SetMul(sz)
} else {
c = r.Transform.MulVector2AsPoint(c)
f = r.Transform.MulVector2AsPoint(f)
rs = r.Transform.MulVector2AsVector(rs)
c = objTransform.MulVector2AsPoint(c)
f = objTransform.MulVector2AsPoint(f)
rs = objTransform.MulVector2AsVector(rs)
ct := objTransform.Mul(r.Transform)
c = ct.MulVector2AsPoint(c)
f = ct.MulVector2AsPoint(f)
_, _, phi, sx, sy, _ := ct.Decompose()
r.rotTrans = math32.Rotate2D(phi)
rs.SetMul(math32.Vec2(sx, sy))
}
if c != f {
f.SetDiv(rs)
Expand Down Expand Up @@ -111,7 +114,7 @@ func (r *Radial) At(x, y int) color.Color {
if r.Units == ObjectBoundingBox {
pt = r.boxTransform.MulVector2AsPoint(pt)
}
d := pt.Sub(r.rCenter)
d := r.rotTrans.MulVector2AsVector(pt.Sub(r.rCenter))
pos := math32.Sqrt(d.X*d.X/(r.rRadius.X*r.rRadius.X) + (d.Y*d.Y)/(r.rRadius.Y*r.rRadius.Y))
return r.getColor(pos)
}
Expand All @@ -123,6 +126,7 @@ func (r *Radial) At(x, y int) color.Color {
if r.Units == ObjectBoundingBox {
pt = r.boxTransform.MulVector2AsPoint(pt)
}
pt = r.rotTrans.MulVector2AsVector(pt)
e := pt.Div(r.rRadius)

t1, intersects := rayCircleIntersectionF(e, r.rFocal, r.rCenter, 1)
Expand Down
2 changes: 1 addition & 1 deletion colors/gradient/typegen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions colors/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import (
// Uniform returns a new [image.Uniform] filled completely with the given color.
// See [ToUniform] for the converse.
func Uniform(c color.Color) image.Image {
if c == nil {
return nil
}
return image.NewUniform(c)
}

Expand All @@ -24,6 +27,20 @@ func ToUniform(img image.Image) color.RGBA {
return AsRGBA(img.At(0, 0))
}

// CloneUniform returns a copy of a Uniform image color, if image is one.
// Otherwise just returns the image back. This is useful when modifying
// an image color, to ensure that it doesn't modify all users of this image.
func CloneUniform(img image.Image) image.Image {
if img == nil {
return nil
}
u, ok := img.(*image.Uniform)
if !ok {
return img
}
return image.NewUniform(AsRGBA(u.C))
}

// Pattern returns a new unbounded [image.Image] represented by the given pattern function.
func Pattern(f func(x, y int) color.Color) image.Image {
return &pattern{f}
Expand Down
8 changes: 7 additions & 1 deletion content/typegen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

94 changes: 0 additions & 94 deletions core/blinker.go

This file was deleted.

9 changes: 2 additions & 7 deletions core/button.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ func (bt *Button) Init() {
}
}
s.Font.Size.Dp(14) // Button font size is used for text font size
s.IconSize.Set(units.Em(18.0 / 14))
s.Gap.Zero()
s.CenterAll()

Expand Down Expand Up @@ -209,9 +210,6 @@ func (bt *Button) Init() {
}
if bt.Icon.IsSet() {
tree.AddAt(p, "icon", func(w *Icon) {
w.Styler(func(s *styles.Style) {
s.Font.Size.Dp(18)
})
w.Updater(func() {
w.SetIcon(bt.Icon)
})
Expand Down Expand Up @@ -251,10 +249,7 @@ func (bt *Button) Init() {
})
tree.AddAt(p, "indicator", func(w *Icon) {
w.Styler(func(s *styles.Style) {
s.Min.X.Dp(18)
s.Min.Y.Dp(18)
s.Margin.Zero()
s.Padding.Zero()
s.IconSize.Set(units.Dp(18)) // independent from Em
})
w.Updater(func() {
w.SetIcon(bt.Indicator)
Expand Down
Loading
Loading