Add datetime components 196-215; Kit.At; inert stepper arrows
Calendars, date and time inputs, pickers, clocks, timers, a sun dial, a season wheel, an agenda and a day schedule. Kit.At rebuilds at a moment (relative times, midnight). Stepper and NumberInput arrows stop under Inert. DateInput parks a popup focus as its own.
This commit is contained in:
38 files changed
+2651
-5
No files matched your search
@@ -0,0 +1,126 @@
|
||||
package gallery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/egoist/mygo/ui"
|
||||
|
||||
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/datetime"
|
||||
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/input"
|
||||
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
|
||||
)
|
||||
|
||||
var datetimeEntries = []Entry{
|
||||
{196, "Calendar", "日历", "datetime", "Arrows walk the days, Page Up and Down the months. Today wears a line.", demoCalendar},
|
||||
{197, "DateInput", "日期框", "datetime", "YYYY-MM-DD. Click it and a calendar drops down.", demoDateInput},
|
||||
{198, "TimeInput", "时间框", "datetime", "HH:MM. Type 0730, or nudge with Up and Down.", demoTimeInput},
|
||||
{199, "DateRange", "日期区间", "datetime", "Pick a start, then an end. The days between dither.", demoDateRange},
|
||||
{200, "MonthPicker", "月份选择", "datetime", "A year of months; ◀ ▶ turn the year.", demoMonthPicker},
|
||||
{201, "YearPicker", "年份选择", "datetime", "A decade at a glance; ◀ ▶ turn decades.", demoYearPicker},
|
||||
{202, "AnalogClock", "指针钟", "datetime", "Hands drawn dot by dot with Bresenham lines. It ticks.", demoAnalogClock},
|
||||
{203, "DigitalClock", "数字钟", "datetime", "Seven-segment HH:MM:SS. The colons blink, like a VCR.", demoDigitalClock},
|
||||
{204, "Countdown", "倒计时", "datetime", "Time left; it turns red for the last ten seconds.", demoCountdown},
|
||||
{205, "Stopwatch", "秒表", "datetime", "START, STOP, LAP, RESET. Speedrunners, warm up.", demoStopwatch},
|
||||
}
|
||||
|
||||
type timeDemo struct {
|
||||
date, due, wake, from, to, month time.Time
|
||||
year, hour int
|
||||
season pixel.Season
|
||||
deadline time.Time
|
||||
week time.Time
|
||||
alarms []datetime.AlarmEntry
|
||||
egg time.Duration
|
||||
}
|
||||
|
||||
func timeState(c *ui.Context) *timeDemo {
|
||||
now := pixel.K(c).Now()
|
||||
return ui.Local(c.Root(), demoKey("datetime"), func() timeDemo {
|
||||
return timeDemo{date: now, due: now.AddDate(0, 0, 7), wake: time.Date(now.Year(), now.Month(), now.Day(), 7, 30, 0, 0, now.Location()),
|
||||
from: now, to: now.AddDate(0, 0, 4), month: now, year: now.Year(), hour: now.Hour(), season: pixel.Autumn,
|
||||
deadline: now.Add(30 * time.Second), week: now, egg: 3 * time.Minute,
|
||||
alarms: []datetime.AlarmEntry{{Hour: 7, Minute: 30, Days: [7]bool{1: true, 2: true, 3: true, 4: true, 5: true}, On: true}, {Hour: 10, Days: [7]bool{0: true, 6: true}}}}
|
||||
})
|
||||
}
|
||||
|
||||
func demoCalendar(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
r := datetime.Calendar(c, "Date", &s.date, datetime.CalendarOptions{})
|
||||
if r.Changed {
|
||||
log(s.date.Format("2006-01-02"))
|
||||
}
|
||||
if r.Picked {
|
||||
log("picked " + s.date.Format("2006-01-02"))
|
||||
}
|
||||
}
|
||||
|
||||
func demoDateInput(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.DateInput(c, "Quest due", &s.due, datetime.DateInputOptions{}).Changed {
|
||||
log("due " + s.due.Format("2006-01-02"))
|
||||
}
|
||||
}
|
||||
|
||||
func demoTimeInput(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.TimeInput(c, "Wake up", &s.wake, datetime.TimeInputOptions{}).Changed {
|
||||
log("wake at " + s.wake.Format("15:04"))
|
||||
}
|
||||
}
|
||||
|
||||
func demoDateRange(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.DateRange(c, "Vacation", &s.from, &s.to, datetime.DateRangeOptions{}).Changed {
|
||||
log(s.from.Format("01-02") + " to " + s.to.Format("01-02"))
|
||||
}
|
||||
}
|
||||
|
||||
func demoMonthPicker(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.MonthPicker(c, "Month", &s.month, datetime.MonthPickerOptions{}).Changed {
|
||||
log(s.month.Format("2006-01"))
|
||||
}
|
||||
}
|
||||
|
||||
func demoYearPicker(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.YearPicker(c, "Year", &s.year, datetime.YearPickerOptions{}).Changed {
|
||||
log(fmt.Sprint(s.year))
|
||||
}
|
||||
}
|
||||
|
||||
func demoAnalogClock(c *ui.Context, log func(string)) {
|
||||
k := pixel.K(c)
|
||||
ui.Row(c).Gap(k.D(8)).Children(func() {
|
||||
datetime.AnalogClock(c, datetime.AnalogClockOptions{Size: 64})
|
||||
datetime.AnalogClock(c, datetime.AnalogClockOptions{Size: 32})
|
||||
})
|
||||
}
|
||||
|
||||
func demoDigitalClock(c *ui.Context, log func(string)) {
|
||||
datetime.DigitalClock(c, datetime.DigitalClockOptions{})
|
||||
}
|
||||
|
||||
func demoCountdown(c *ui.Context, log func(string)) {
|
||||
k := pixel.K(c)
|
||||
s := timeState(c)
|
||||
ui.Row(c).Gap(k.D(8)).AlignItems(ui.Center).Children(func() {
|
||||
if datetime.Countdown(c, "Bomb", s.deadline, datetime.CountdownOptions{}).Done {
|
||||
log("boom")
|
||||
}
|
||||
if input.Button(c, "DEFUSE", input.ButtonOptions{Size: input.Small}).Clicked {
|
||||
s.deadline = k.Now().Add(30 * time.Second)
|
||||
log("thirty more seconds")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func demoStopwatch(c *ui.Context, log func(string)) {
|
||||
r := datetime.Stopwatch(c, "Speedrun", datetime.StopwatchOptions{})
|
||||
for name, on := range map[string]bool{"start": r.Started, "stop": r.Stopped, "lap": r.Lapped, "reset": r.Reset} {
|
||||
if on {
|
||||
log(name)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package gallery
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/egoist/mygo/ui"
|
||||
|
||||
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/datetime"
|
||||
"git.zacharyzhang.com/ZacharyZhang-NY/8bitMyGoUI/pixel"
|
||||
)
|
||||
|
||||
var timeEntries = []Entry{
|
||||
{206, "Timer", "定时器", "datetime", "Set minutes and seconds, START, PAUSE. Zero flashes.", demoTimer},
|
||||
{207, "SunDial", "日晷", "datetime", "Drag across the sky: the sun by day, the moon by night.", demoSunDial},
|
||||
{208, "SeasonWheel", "四季轮", "datetime", "Four seasons on a wheel. Click one, or turn it with the arrows.", demoSeasonWheel},
|
||||
{209, "WeekStrip", "周条", "datetime", "Seven days in a row. Left and Right walk into the next week.", demoWeekStrip},
|
||||
{210, "Agenda", "日程", "datetime", "Events under the day they fall on.", demoAgenda},
|
||||
{211, "EventChip", "事件块", "datetime", "A small chip: time, title, and a colored edge.", demoEventChip},
|
||||
{212, "RelativeTime", "相对时间", "datetime", "3 MIN AGO, IN 2 H, TOMORROW. It keeps itself up to date.", demoRelativeTime},
|
||||
{213, "Alarm", "闹钟", "datetime", "Alarm rows: time, days, and a lever to arm each one.", demoAlarm},
|
||||
{214, "YearView", "年视图", "datetime", "Twelve tiny months; today is lit.", demoYearView},
|
||||
{215, "DaySchedule", "日程表", "datetime", "Hour rows with blocks placed by start and length. Overlaps share.", demoDaySchedule},
|
||||
}
|
||||
|
||||
func demoTimer(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.Timer(c, "Egg timer", &s.egg, datetime.TimerOptions{}).Done {
|
||||
log("ding! the egg is ready")
|
||||
}
|
||||
}
|
||||
|
||||
func demoSunDial(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.SunDial(c, "Hour", &s.hour, datetime.SunDialOptions{}).Changed {
|
||||
log(fmt.Sprintf("%02d:00", s.hour))
|
||||
}
|
||||
}
|
||||
|
||||
func demoSeasonWheel(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.SeasonWheel(c, "Season", &s.season, datetime.SeasonWheelOptions{}).Changed {
|
||||
log([]string{"spring", "summer", "autumn", "winter"}[s.season])
|
||||
}
|
||||
}
|
||||
|
||||
func demoWeekStrip(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.WeekStrip(c, "Week", &s.week, datetime.WeekStripOptions{}).Changed {
|
||||
log(s.week.Format("Mon 2006-01-02"))
|
||||
}
|
||||
}
|
||||
|
||||
// today returns now's date at h:m.
|
||||
func today(c *ui.Context, h, m int) time.Time {
|
||||
n := pixel.K(c).Now()
|
||||
return time.Date(n.Year(), n.Month(), n.Day(), h, m, 0, 0, n.Location())
|
||||
}
|
||||
|
||||
func demoAgenda(c *ui.Context, log func(string)) {
|
||||
datetime.Agenda(c, []datetime.Event{
|
||||
{Start: today(c, 9, 0), Title: "Slime patrol"}, {Start: today(c, 13, 30), Title: "Lunch at the inn"},
|
||||
{Start: today(c, 10, 0).AddDate(0, 0, 1), Title: "Boss raid"}, {Start: today(c, 18, 0).AddDate(0, 0, 2), Title: "Fireworks"},
|
||||
}, datetime.AgendaOptions{})
|
||||
}
|
||||
|
||||
func demoEventChip(c *ui.Context, log func(string)) {
|
||||
k := pixel.K(c)
|
||||
ui.Column(c).Gap(k.D(4)).Children(func() {
|
||||
datetime.EventChip(c, datetime.Event{Start: today(c, 9, 0), Title: "Slime patrol"}, datetime.EventChipOptions{})
|
||||
datetime.EventChip(c, datetime.Event{Start: today(c, 20, 0), Title: "Boss raid"}, datetime.EventChipOptions{Slot: pixel.Bad})
|
||||
datetime.EventChip(c, datetime.Event{Start: today(c, 12, 0), Title: "Picnic"}, datetime.EventChipOptions{Slot: pixel.Good})
|
||||
})
|
||||
}
|
||||
|
||||
func demoRelativeTime(c *ui.Context, log func(string)) {
|
||||
k := pixel.K(c)
|
||||
now := k.Now()
|
||||
ui.Column(c).Gap(k.D(2)).Children(func() {
|
||||
for _, r := range []struct {
|
||||
what string
|
||||
at time.Time
|
||||
}{{"Saved", now.Add(-3 * time.Minute)}, {"Boss respawns", now.Add(2 * time.Hour)}, {"Last login", now.Add(-30 * time.Hour)}, {"Festival", now.Add(52 * time.Hour)}} {
|
||||
ui.Row(c).Gap(k.D(6)).Children(func() {
|
||||
pixel.Text(c, r.what, pixel.TextOptions{})
|
||||
datetime.RelativeTime(c, r.at, datetime.RelativeTimeOptions{})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func demoAlarm(c *ui.Context, log func(string)) {
|
||||
s := timeState(c)
|
||||
if datetime.Alarm(c, "Alarms", s.alarms, datetime.AlarmOptions{}).Changed {
|
||||
log(fmt.Sprintf("7:30 %v, 10:00 %v", s.alarms[0].On, s.alarms[1].On))
|
||||
}
|
||||
}
|
||||
|
||||
func demoYearView(c *ui.Context, log func(string)) {
|
||||
datetime.YearView(c, pixel.K(c).Now().Year(), datetime.YearViewOptions{})
|
||||
}
|
||||
|
||||
func demoDaySchedule(c *ui.Context, log func(string)) {
|
||||
ui.Box(c).Width(pixel.K(c).D(220)).Children(func() {
|
||||
datetime.DaySchedule(c, []datetime.Event{
|
||||
{Start: today(c, 9, 0), Length: 2 * time.Hour, Title: "Slime patrol"},
|
||||
{Start: today(c, 10, 0), Length: time.Hour, Title: "Call mom"},
|
||||
{Start: today(c, 13, 0), Length: 90 * time.Minute, Title: "Inn lunch"},
|
||||
{Start: today(c, 16, 30), Length: time.Hour, Title: "Training"},
|
||||
}, datetime.DayScheduleOptions{})
|
||||
})
|
||||
}
|
||||
+1
-1
@@ -56,7 +56,7 @@ var Categories = []Category{
|
||||
{"tabletop", "Tabletop", "桌游", icon.Crown},
|
||||
}
|
||||
|
||||
var entries = slices.Concat(foundationEntries, layoutEntries, textEntries, displayEntries, inputEntries, controlEntries, feedbackEntries, navigationEntries, dataEntries, recordEntries, overlayEntries, popupEntries)
|
||||
var entries = slices.Concat(foundationEntries, layoutEntries, textEntries, displayEntries, inputEntries, controlEntries, feedbackEntries, navigationEntries, dataEntries, recordEntries, overlayEntries, popupEntries, datetimeEntries, timeEntries)
|
||||
|
||||
func Entries() []Entry { return entries }
|
||||
|
||||
|
||||
Reference in new issue
Block a user