Add media components 346-365; input.SlideBase, guarded Pad
An audio player with transport, scrubber and volume; an equalizer and a visualizer; a playlist; a cassette, cartridge and record that turn while they play and hold where they stop; piano keys, a step sequencer and a tracker you can type into; a waveform, a 16:9 video frame, an image compare, a gallery, a filmstrip, a record button and an FM tuner. input exports SlideBase, the undrawn rail its sliders share; the gallery treats exported Bases as building blocks, not components. pixel's micro font gains '#' for notes like C#4. pixel.Pad and the slide rail read input only while their base is enabled, so Inert or a fresh Disabled stops a drag or a key already sent. AGENTS records why a drawn container keeps the DISABLED description: MyGo paints a disabled subtree at half opacity.
This commit is contained in:
39 files changed
+3066
-10
No files matched your search
@@ -0,0 +1,96 @@
|
||||
package media_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/egoist/mygo/ui"
|
||||
|
||||
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/media"
|
||||
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
|
||||
)
|
||||
|
||||
// solid is a w by h picture in one slot.
|
||||
func solid(w, h int, s pixel.Slot) *pixel.Sprite {
|
||||
return pixel.SpriteOf(w, h, func(x, y int) (pixel.Slot, bool) { return s, true })
|
||||
}
|
||||
|
||||
func TestImageCompareSplitsWhereDragged(t *testing.T) {
|
||||
wd := newWorld()
|
||||
split, changed := 0.5, false
|
||||
tt := view(300, 200, wd, func(c *ui.Context) {
|
||||
changed = media.ImageCompare(c, "Compare", solid(10, 6, pixel.Good), solid(10, 6, pixel.Bad), &split, media.ImageCompareOptions{Scale: 2}).Changed || changed
|
||||
})
|
||||
r := find(t, tt, "Compare")
|
||||
x, y, w, h := dots(r)
|
||||
img := tt.Image()
|
||||
// Row 0 is above the grip.
|
||||
if w != 20 || h != 12 || at(img, wd.pal, x+2, y) != pixel.Good || at(img, wd.pal, x+10, y) != pixel.Edge || at(img, wd.pal, x+15, y) != pixel.Bad {
|
||||
t.Fatal("before is not left of the split, after right")
|
||||
}
|
||||
tt.Press(r.X+r.W/4, r.Y+2)
|
||||
tt.Release(r.X+r.W/4, r.Y+2)
|
||||
if split != 0.25 || !changed || at(tt.Image(), wd.pal, x+7, y) != pixel.Bad {
|
||||
t.Fatalf("pressing a quarter in split at %v", split)
|
||||
}
|
||||
tt.Key(0, ui.KeyHome)
|
||||
if split != 0 || at(tt.Image(), wd.pal, x+2, y) != pixel.Bad || at(tt.Image(), wd.pal, x+6, y+h/2) != pixel.Edge {
|
||||
t.Fatal("at 0, all is after and the grip stays whole")
|
||||
}
|
||||
tt.Key(0, ui.KeyEnd)
|
||||
if split != 1 || at(tt.Image(), wd.pal, x+17, y) != pixel.Good {
|
||||
t.Fatal("at 1, all is before")
|
||||
}
|
||||
mustPanic(t, "pictures of two sizes", func() {
|
||||
view(300, 200, newWorld(), func(c *ui.Context) {
|
||||
s := 0.5
|
||||
media.ImageCompare(c, "C", solid(2, 2, pixel.Ink), solid(3, 2, pixel.Ink), &s, media.ImageCompareOptions{})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func TestGalleryChoosesByArrowsAndClicks(t *testing.T) {
|
||||
wd := newWorld()
|
||||
pics := []*pixel.Sprite{solid(4, 3, pixel.Good), solid(4, 3, pixel.Bad), solid(4, 3, pixel.Info)}
|
||||
chosen, changed := 0, false
|
||||
tt := view(300, 200, wd, func(c *ui.Context) {
|
||||
changed = media.Gallery(c, "Views", pics, []string{"Green", "Red", "Blue"}, &chosen, media.GalleryOptions{Scale: 2}).Changed || changed
|
||||
})
|
||||
big := func(name string) pixel.Slot {
|
||||
x, y, _, _ := dots(find(t, tt, name))
|
||||
return at(tt.Image(), wd.pal, x+4, y+4)
|
||||
}
|
||||
if big("Green") != pixel.Good {
|
||||
t.Fatal("the big picture is not the chosen one")
|
||||
}
|
||||
// The middle of the strip is the second thumbnail.
|
||||
click(t, tt, "Views")
|
||||
if chosen != 1 || !changed || big("Red") != pixel.Bad {
|
||||
t.Fatalf("clicking the middle chose %d", chosen)
|
||||
}
|
||||
tt.Key(0, ui.KeyRight)
|
||||
if chosen != 2 || big("Blue") != pixel.Info {
|
||||
t.Fatalf("Right chose %d", chosen)
|
||||
}
|
||||
changed = false
|
||||
tt.Key(0, ui.KeyRight)
|
||||
if chosen != 2 || changed {
|
||||
t.Fatalf("Right at the end: %d, changed %v", chosen, changed)
|
||||
}
|
||||
// The chosen thumbnail wears the cursor ring.
|
||||
x, y, _, _ := dots(find(t, tt, "Views"))
|
||||
if at(tt.Image(), wd.pal, x+2*10, y) != pixel.Accent || at(tt.Image(), wd.pal, x, y) == pixel.Accent {
|
||||
t.Fatal("the ring is not on the chosen thumbnail")
|
||||
}
|
||||
for name, fn := range map[string]func(c *ui.Context){
|
||||
"names short of pictures": func(c *ui.Context) {
|
||||
n := 0
|
||||
media.Gallery(c, "V", pics, []string{"Green"}, &n, media.GalleryOptions{})
|
||||
},
|
||||
"a choice past the end": func(c *ui.Context) {
|
||||
n := 3
|
||||
media.Gallery(c, "V", pics, []string{"Green", "Red", "Blue"}, &n, media.GalleryOptions{})
|
||||
},
|
||||
} {
|
||||
mustPanic(t, name, func() { view(300, 200, newWorld(), fn) })
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user