Add display components 041-065; move Icon into display; QR via rsc.io/qr

This commit is contained in:
ZacharyZhang-NY committed 2026-10-11 18:37:54 -04:00
1 parent 59fde4096d
commit 0247a130f5
41 files changed
+2152 -44

No files matched your search

+272
View File
@@ -0,0 +1,272 @@
package gallery
import (
"fmt"
"image"
"image/color"
"math"
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/display"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/icon"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
var displayEntries = []Entry{
{41, "Icon", "图标", "display", "A sprite in one ink slot at ×1 to ×4, named for screen readers or hidden.", demoIcon},
{42, "Sprite", "精灵", "display", "A multi-slot sprite that plays its frames and can face the other way.", demoSprite},
{43, "Picture", "像素图", "display", "Any image reduced to the palette with Bayer dither. Press P: it recolors.", demoPicture},
{44, "Avatar", "头像", "display", "A face built from a name: skin, hair, eyes, mouth and background.", demoAvatar},
{45, "AvatarGroup", "头像组", "display", "Overlapping faces and a chip for the rest.", demoAvatarGroup},
{46, "Badge", "徽标", "display", "A count or a word in a notched pill; counts stop at 99+.", demoBadge},
{47, "Tag", "标签", "display", "A chip with text, an icon and a remove box.", demoTag},
{48, "StatusDot", "状态点", "display", "Online, away, busy or offline; a live online dot blinks.", demoStatusDot},
{49, "Medal", "奖牌", "display", "Gold, silver and bronze on ribbons, rank on the face.", demoMedal},
{50, "Trophy", "奖杯", "display", "A gold cup over an engraved plaque.", demoTrophy},
{51, "Stat", "数据", "display", "A big value, its label and a change up or down.", demoStat},
{52, "KeyValue", "键值", "display", "A label and a value joined by a dotted leader.", demoKeyValue},
{53, "Portrait", "立绘框", "display", "A character in a frame over a nameplate.", demoPortrait},
{54, "Ribbon", "绶带", "display", "A title banner with folded, notched tails.", demoRibbon},
{55, "Stamp", "印章", "display", "A rubber stamp whose border wore unevenly.", demoStamp},
{56, "Emoji", "表情", "display", "Sixteen faces placed dot by dot.", demoEmoji},
{57, "Flag", "旗帜", "display", "A flag on a pole, waving in steps.", demoFlag},
{58, "Gem", "宝石", "display", "A cut gem for each rarity, with a stepped sparkle.", demoGem},
{59, "RarityFrame", "稀有度框", "display", "A border by rarity; a legendary one carries a running glint.", demoRarityFrame},
{60, "Bubble", "气泡", "display", "A speech bubble with its tail on any side.", demoBubble},
{61, "Swatch", "色板", "display", "The sixteen slots of the palette in use, by name.", demoSwatch},
{62, "Placeholder", "占位图", "display", "A dithered box with a cross and its size, for art to come.", demoPlaceholder},
{63, "Figure", "插图", "display", "Content over a caption in Faint.", demoFigure},
{64, "QRCode", "二维码", "display", "A scannable QR code in the darkest and lightest slots.", demoQRCode},
{65, "Signpost", "路牌", "display", "A post with up to three boards. Each board is a button.", demoSignpost},
}
// sunset is a smooth picture for Picture to reduce.
var sunset = func() image.Image {
img := image.NewRGBA(image.Rect(0, 0, 96, 64))
for y := range 64 {
for x := range 96 {
t := float64(y) / 63
c := color.RGBA{uint8(250 - 120*t), uint8(170 - 120*t), uint8(90 + 90*t), 255}
if dx, dy := float64(x-60), float64(y-34); dx*dx+dy*dy < 14*14 {
c = color.RGBA{255, 220, 120, 255}
}
if float64(y) > 44+6*math.Sin(float64(x)/9) {
c = color.RGBA{50, 40, 70, 255}
}
img.SetRGBA(x, y, c)
}
}
return img
}()
func demoIcon(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(8)).AlignItems(ui.End).Children(func() {
for sc := 1; sc <= 4; sc++ {
display.Icon(c, icon.Heart, display.IconOptions{Slot: pixel.Bad, Scale: sc, Label: fmt.Sprintf("heart ×%d", sc)})
}
})
}
func demoSprite(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(12)).Children(func() {
display.Sprite(c, slime, display.SpriteOptions{Scale: 3, FPS: 2, Label: "slime"})
display.Sprite(c, slime, display.SpriteOptions{Scale: 3, FPS: 2, Mirror: true, Label: "slime, mirrored"})
})
}
func demoPicture(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(8)).AlignItems(ui.End).Children(func() {
display.Picture(c, sunset, display.PictureOptions{Label: "sunset"})
display.Picture(c, sunset, display.PictureOptions{W: 48, H: 32, Label: "small sunset"})
})
}
var party = []string{"Aria", "Brom", "Cass", "Dax", "Eve", "Finn", "Gus"}
func demoAvatar(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(6)).Children(func() {
for _, n := range party[:5] {
display.Avatar(c, n, display.AvatarOptions{Scale: 2})
}
display.Avatar(c, "Sunny", display.AvatarOptions{Scale: 2, Picture: sunset})
})
}
func demoAvatarGroup(c *ui.Context, log func(string)) {
display.AvatarGroup(c, party, display.AvatarGroupOptions{Scale: 2})
}
func demoBadge(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(6)).AlignItems(ui.Center).Children(func() {
for _, n := range []int{3, 42, 128} {
display.Badge(c, n, display.BadgeOptions{})
}
display.Badge(c, 0, display.BadgeOptions{Text: "NEW", Slot: pixel.Good})
display.Badge(c, 0, display.BadgeOptions{Text: "HOT", Slot: pixel.Warn})
})
}
func demoTag(c *ui.Context, log func(string)) {
k := pixel.K(c)
tags := ui.Local(c.Root(), demoKey("tags"), func() []string { return []string{"fire", "ice", "thunder", "wind"} })
ui.Column(c).Gap(k.D(6)).Children(func() {
ui.Row(c).Wrap().Gap(k.D(4)).Children(func() {
for i, t := range *tags {
if display.Tag(c, t, display.TagOptions{Icon: icon.Sparkle, Removable: true}).Removed {
*tags = append((*tags)[:i:i], (*tags)[i+1:]...)
log("removed " + t)
}
}
display.Tag(c, "locked", display.TagOptions{Icon: icon.Lock, Removable: true, Disabled: true})
})
if button(c, "RESET") {
*tags = []string{"fire", "ice", "thunder", "wind"}
log("tags reset")
}
})
}
func demoStatusDot(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Column(c).Gap(k.D(4)).Children(func() {
for _, s := range []display.Status{display.Online, display.Away, display.Busy, display.Offline} {
ui.Row(c).Gap(k.D(4)).AlignItems(ui.Center).Children(func() {
display.StatusDot(c, s, display.StatusDotOptions{Live: true})
label(c, []string{"Player 1", "Player 2", "Player 3", "Player 4"}[s], pixel.Ink)
})
}
})
}
func demoMedal(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(10)).Children(func() {
for _, r := range []display.Rank{display.Gold, display.Silver, display.Bronze} {
display.Medal(c, r, display.MedalOptions{Scale: 2})
}
})
}
func demoTrophy(c *ui.Context, log func(string)) {
display.Trophy(c, "Champion 2026", display.TrophyOptions{Scale: 2})
}
func demoStat(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(24)).Children(func() {
display.Stat(c, "SCORE", "42,000", display.StatOptions{Delta: "12%"})
display.Stat(c, "LIVES", "2", display.StatOptions{Delta: "1", Down: true})
})
}
func demoKeyValue(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Column(c).Width(k.D(160)).Gap(k.D(2)).Children(func() {
for _, kv := range [][2]string{{"STR", "18"}, {"DEX", "12"}, {"INT", "7"}, {"LUCK", "99"}} {
display.KeyValue(c, kv[0], kv[1], display.KeyValueOptions{})
}
})
}
func demoPortrait(c *ui.Context, log func(string)) {
display.Portrait(c, "Sir Brom", display.PortraitOptions{Size: 48}, func() {
display.Avatar(c, "Brom", display.AvatarOptions{Scale: 3})
})
}
func demoRibbon(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Column(c).Gap(k.D(6)).Children(func() {
display.Ribbon(c, "STAGE 1-1", display.RibbonOptions{})
display.Ribbon(c, "BONUS ROUND", display.RibbonOptions{Slot: pixel.Info})
})
}
func demoStamp(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(10)).Children(func() {
display.Stamp(c, "APPROVED", display.StampOptions{Slot: pixel.Good, Seed: 3})
display.Stamp(c, "VOID", display.StampOptions{Seed: 9})
})
}
func demoEmoji(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Wrap().Gap(k.D(6)).Width(k.D(240)).Children(func() {
for _, name := range display.EmojiNames {
display.Emoji(c, name, display.EmojiOptions{Scale: 2})
}
})
}
func demoFlag(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(12)).Children(func() {
display.Flag(c, display.FlagOptions{Scale: 2, Label: "red flag"})
display.Flag(c, display.FlagOptions{Slot: pixel.Info, Scale: 2, Label: "blue flag"})
})
}
func demoGem(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(8)).Children(func() {
for r := display.Common; r <= display.Legendary; r++ {
display.Gem(c, r, display.GemOptions{Scale: 2})
}
})
}
func demoRarityFrame(c *ui.Context, log func(string)) {
k := pixel.K(c)
items := []string{"Stick", "Bow", "Rapier", "Dragon Lance", "Excalibur"}
ui.Row(c).Wrap().Gap(k.D(6)).Children(func() {
for r := display.Common; r <= display.Legendary; r++ {
display.RarityFrame(c, r, display.RarityFrameOptions{}, func() { label(c, items[r], pixel.Ink) })
}
})
}
func demoBubble(c *ui.Context, log func(string)) {
k := pixel.K(c)
lines := []string{"Hey!", "Look up.", "Psst.", "Over here."}
ui.Row(c).Wrap().Gap(k.D(8)).AlignItems(ui.Center).Children(func() {
for i, side := range []display.Side{display.Bottom, display.Top, display.Left, display.Right} {
display.Bubble(c, display.BubbleOptions{Tail: side}, func() { label(c, lines[i], pixel.Ink) })
}
})
}
func demoSwatch(c *ui.Context, log func(string)) {
display.Swatch(c, display.SwatchOptions{})
}
func demoPlaceholder(c *ui.Context, log func(string)) {
k := pixel.K(c)
ui.Row(c).Gap(k.D(8)).Children(func() {
display.Placeholder(c, display.PlaceholderOptions{})
display.Placeholder(c, display.PlaceholderOptions{W: 120, H: 40})
})
}
func demoFigure(c *ui.Context, log func(string)) {
display.Figure(c, "Fig. 1 — a slime, at rest", display.FigureOptions{}, func() {
display.Sprite(c, slime, display.SpriteOptions{Scale: 4, Label: "slime"})
})
}
func demoQRCode(c *ui.Context, log func(string)) {
display.QRCode(c, "https://mygo.egoist.dev/docs/ui", display.QRCodeOptions{})
}
func demoSignpost(c *ui.Context, log func(string)) {
boards := []string{"Town", "Dungeon", "Shop"}
if r := display.Signpost(c, boards, display.SignpostOptions{}); r.Clicked >= 0 {
log("to the " + boards[r.Clicked])
}
}
+4 -3
View File
@@ -5,6 +5,7 @@ import (
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/display"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/icon"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/layout"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
@@ -159,7 +160,7 @@ func demoGrid(c *ui.Context, log func(string)) {
ui.Row(c).Gap(k.D(12)).AlignItems(ui.Start).Children(func() {
for _, lines := range []layout.GridLines{layout.SolidLines, layout.DottedLines} {
layout.Grid(c, len(items), layout.GridOptions{Columns: 3, Lines: lines}, func(i int) {
pixel.Icon(c, items[i], pixel.IconOptions{Scale: 2})
display.Icon(c, items[i], display.IconOptions{Scale: 2})
})
}
})
@@ -171,7 +172,7 @@ func demoTiles(c *ui.Context, log func(string)) {
layout.Tiles(c, len(items), layout.TilesOptions{W: 28}, func(i int) {
ui.Box(c).Fill().Center().Draw(func(p *ui.Painter, r ui.Rect) {
k.Canvas(p, r).Frame(0, 0, 28, 28, pixel.Raised, pixel.Face)
}).Children(func() { pixel.Icon(c, items[i], pixel.IconOptions{}) })
}).Children(func() { display.Icon(c, items[i], display.IconOptions{}) })
}).Width(k.D(160))
}
@@ -211,7 +212,7 @@ func demoLayers(c *ui.Context, log func(string)) {
g.Dither(0, 0, g.W, g.H, pixel.Well, pixel.Info, 6)
})
}, func() {
ui.Box(c).Fill().Center().Children(func() { pixel.Icon(c, icon.Chest, pixel.IconOptions{Scale: 3}) })
ui.Box(c).Fill().Center().Children(func() { display.Icon(c, icon.Chest, display.IconOptions{Scale: 3}) })
}, func() {
ui.Box(c).Padding(k.D(3)).Children(func() { label(c, "LAYER 3", pixel.Ink) })
}).Size(k.D(120), k.D(64))
+2 -1
View File
@@ -6,6 +6,7 @@ import (
"github.com/egoist/mygo/ui"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/display"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/icon"
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
)
@@ -205,7 +206,7 @@ func GameOver(c *ui.Context, why string) bool {
shadowText(k.Canvas(p, r), 0, 0, k.Msg("game_over"), pixel.Bad, 3)
})
pixel.Text(c, why, pixel.TextOptions{Slot: pixel.Faint, Wrap: true, MaxLines: 6}).Width(k.D(min(pixel.Measure(why), 280)))
pixel.Icon(c, icon.Skull, pixel.IconOptions{Scale: 3})
display.Icon(c, icon.Skull, display.IconOptions{Scale: 3})
cont = button(c, k.Msg("continue"))
})
return cont
+1 -1
View File
@@ -56,7 +56,7 @@ var Categories = []Category{
{"tabletop", "Tabletop", "桌游", icon.Crown},
}
var entries = slices.Concat(foundationEntries, layoutEntries, textEntries)
var entries = slices.Concat(foundationEntries, layoutEntries, textEntries, displayEntries)
func Entries() []Entry { return entries }