Files
8bitMyGoUI/gallery/demos_display.go
T

274 lines
10 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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/input"
"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 input.Button(c, "RESET", input.ButtonOptions{}).Clicked {
*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})
pixel.Text(c, []string{"Player 1", "Player 2", "Player 3", "Player 4"}[s], pixel.TextOptions{})
})
}
})
}
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() { pixel.Text(c, items[r], pixel.TextOptions{}) })
}
})
}
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() { pixel.Text(c, lines[i], pixel.TextOptions{}) })
}
})
}
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])
}
}