Split into category packages; module github.com/ZacharyZhang-NY/MujicaUI
This commit is contained in:
1822 files changed
+24568
-21314
No files matched your search
@@ -0,0 +1,110 @@
|
||||
package chart
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/egoist/mygo/ui"
|
||||
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/core"
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/datetime"
|
||||
"github.com/ZacharyZhang-NY/MujicaUI/input"
|
||||
)
|
||||
|
||||
// RangePreset names a time range; zero selects Range1D.
|
||||
type RangePreset int
|
||||
|
||||
const (
|
||||
Range1D RangePreset = iota
|
||||
Range5D
|
||||
Range1M
|
||||
Range3M
|
||||
RangeYTD
|
||||
Range1Y
|
||||
Range5Y
|
||||
RangeCustom
|
||||
)
|
||||
|
||||
var rangePresetNames = []string{"1D", "5D", "1M", "3M", "YTD", "1Y", "5Y"}
|
||||
|
||||
// MarketRange stores a preset or custom date range.
|
||||
type MarketRange struct {
|
||||
Preset RangePreset
|
||||
// Custom holds the dates when Preset is RangeCustom.
|
||||
Custom datetime.DateRange
|
||||
}
|
||||
|
||||
// Bounds returns local boundaries, including the custom end date.
|
||||
func (r MarketRange) Bounds(now time.Time, loc *time.Location) (from, to time.Time) {
|
||||
now = now.In(loc)
|
||||
switch r.Preset {
|
||||
case Range1D:
|
||||
return now.AddDate(0, 0, -1), now
|
||||
case Range5D:
|
||||
return now.AddDate(0, 0, -5), now
|
||||
case Range1M:
|
||||
return now.AddDate(0, -1, 0), now
|
||||
case Range3M:
|
||||
return now.AddDate(0, -3, 0), now
|
||||
case RangeYTD:
|
||||
return time.Date(now.Year(), 1, 1, 0, 0, 0, 0, loc), now
|
||||
case Range1Y:
|
||||
return now.AddDate(-1, 0, 0), now
|
||||
case Range5Y:
|
||||
return now.AddDate(-5, 0, 0), now
|
||||
case RangeCustom:
|
||||
if r.Custom.IsZero() {
|
||||
panic("mujica: custom MarketRange without dates")
|
||||
}
|
||||
s, e := r.Custom.Start, r.Custom.End
|
||||
return time.Date(s.Year, s.Month, s.Day, 0, 0, 0, 0, loc), time.Date(e.Year, e.Month, e.Day, 0, 0, 0, 0, loc).AddDate(0, 0, 1)
|
||||
}
|
||||
panic(fmt.Sprintf("mujica: unknown RangePreset %d", r.Preset))
|
||||
}
|
||||
|
||||
// TimeRangeSelectorOptions configure a TimeRangeSelector.
|
||||
type TimeRangeSelectorOptions struct {
|
||||
Disabled bool
|
||||
// Today marks the calendar's today; zero uses the clock.
|
||||
Today core.Date
|
||||
}
|
||||
|
||||
// TimeRangeSelector chooses presets and custom dates through keyboard-accessible controls.
|
||||
func TimeRangeSelector(c *ui.Context, value *MarketRange, opts TimeRangeSelectorOptions) core.ChoiceResult {
|
||||
if value == nil {
|
||||
panic("mujica: TimeRangeSelector needs a value")
|
||||
}
|
||||
if value.Preset < Range1D || value.Preset > RangeCustom {
|
||||
panic(fmt.Sprintf("mujica: unknown RangePreset %d", value.Preset))
|
||||
}
|
||||
if value.Preset == RangeCustom && value.Custom.IsZero() {
|
||||
panic("mujica: custom MarketRange without dates")
|
||||
}
|
||||
items := make([]input.ToggleItem[RangePreset], len(rangePresetNames)+1)
|
||||
for i, n := range rangePresetNames {
|
||||
items[i] = input.ToggleItem[RangePreset]{Value: RangePreset(i), Label: n}
|
||||
}
|
||||
items[len(items)-1] = input.ToggleItem[RangePreset]{Value: RangeCustom, Label: core.Msg(c, "time_range_selector.custom")}
|
||||
changed := false
|
||||
row := ui.Row(c).Gap(core.Density(c).Unit() * 2).AlignItems(ui.Center).Wrap().Disabled(opts.Disabled)
|
||||
row.Children(func() {
|
||||
sel := []RangePreset{value.Preset}
|
||||
if input.ToggleGroup(c, &sel, items, input.ToggleGroupOptions{Label: core.Msg(c, "time_range_selector.label")}).Changed() && !row.IsDisabled() {
|
||||
if sel[0] == RangeCustom && value.Custom.IsZero() {
|
||||
today := core.DatetimeToday(c, opts.Today)
|
||||
value.Custom = datetime.DateRange{Start: today.AddMonths(-1), End: today}
|
||||
}
|
||||
value.Preset, changed = sel[0], true
|
||||
}
|
||||
if value.Preset == RangeCustom {
|
||||
if datetime.DateRangePicker(c, &value.Custom, datetime.DateRangePickerOptions{Today: opts.Today, Max: core.DatetimeToday(c, opts.Today)}).Changed() {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
})
|
||||
if changed {
|
||||
slog.Debug("mujica: time_range_selector changed", "preset", value.Preset, "custom", value.Custom)
|
||||
}
|
||||
return core.NewChoiceResult(row, changed)
|
||||
}
|
||||
Reference in new issue
Block a user