style

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2026 License: GPL-3.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

View Source
const (
	NavInitialDelay  = 400 * time.Millisecond // Delay before repeat starts
	NavStartInterval = 200 * time.Millisecond // Initial repeat interval
	NavMinInterval   = 25 * time.Millisecond  // Fastest repeat (cap)
	NavAcceleration  = 20 * time.Millisecond  // Speed increase per repeat
)

Gamepad navigation timing constants

View Source
const (
	AutoSaveInterval = 5 * time.Second
)

Auto-save timing constant

View Source
const (
	ScrollWheelSensitivity = 0.05
)

Mouse wheel scroll sensitivity

Variables

View Source
var (
	// Standard spacing and padding values
	DefaultPadding = baseDefaultPadding
	DefaultSpacing = baseDefaultSpacing
	SmallSpacing   = baseSmallSpacing
	TinySpacing    = baseTinySpacing
	LargeSpacing   = baseLargeSpacing

	// Scrollbar dimensions
	ScrollbarWidth = baseScrollbarWidth

	// Button padding
	ButtonPaddingSmall  = baseButtonPaddingSmall
	ButtonPaddingMedium = baseButtonPaddingMedium
)

Layout vars used across screens — DPI-scaled at runtime via SetDPIScale.

View Source
var (
	ListRowHeight    = baseListRowHeight
	ListHeaderHeight = baseListHeaderHeight

	// Column widths for library list view
	ListColFavorite   = baseListColFavorite
	ListColGenre      = baseListColGenre
	ListColRegion     = baseListColRegion
	ListColPlayTime   = baseListColPlayTime
	ListColLastPlayed = baseListColLastPlayed

	// Icon view
	IconCardTextHeight = baseIconCardTextHeight
)

Font-dependent layout values (updated by ApplyFontSize)

View Source
var (
	IconMinCardWidth       = baseIconMinCardWidth
	IconDefaultWindowWidth = baseIconDefaultWinWidth
	IconUnfocusedScale     = baseIconUnfocusedScale
	IconUnfocusedDim       = baseIconUnfocusedDim
)

Icon view vars for grid layouts

View Source
var (
	DetailArtWidthSmall = baseDetailArtSmall
	DetailArtWidthLarge = baseDetailArtLarge
)

Detail screen vars

View Source
var (
	SettingsSidebarMinWidth     = baseSidebarMinWidth
	SettingsFolderListMinHeight = baseFolderListMinHeight
)

Settings screen vars

View Source
var (
	ProgressBarWidth  = baseProgressBarWidth
	ProgressBarHeight = baseProgressBarHeight
)

Progress bar vars

View Source
var (
	OverlayPadding = baseOverlayPadding
	OverlayMargin  = baseOverlayMargin
)

Overlay vars (shared by notification/search)

View Source
var (
	PauseMenuMinWidth     = basePauseMinWidth
	PauseMenuMaxWidth     = basePauseMaxWidth
	PauseMenuMinBtnHeight = basePauseMinBtnH
	PauseMenuMaxBtnHeight = basePauseMaxBtnH
)

Pause menu vars

View Source
var (
	AchievementRowSpacing      = baseAchievementRowSpac
	AchievementPanelMargin     = baseAchievementPanelMargin
	AchievementMinPanelHeight  = baseAchievementMinPanelH
	AchievementNotifyMargin    = baseAchNotifyMargin
	AchievementNotifyBadgeSize = baseAchNotifyBadge
	AchievementNotifyPaddingH  = baseAchNotifyPaddingH
	AchievementNotifyPaddingV  = baseAchNotifyPaddingV
	AchievementNotifySpacing   = baseAchNotifySpacing
	AchievementNotifyBorder    = baseAchNotifyBorder
)

Achievement UI vars

View Source
var (
	AchievementBadgeSize      = baseAchievementBadgeSize
	AchievementRowHeight      = baseAchievementRowHeight
	AchievementOverlayWidth   = baseAchievementOverlayW
	AchievementOverlayPadding = baseAchievementOverlayPad
)

Font-dependent achievement values (updated by ApplyFontSize)

View Source
var (
	Background        = color.NRGBA{0x1a, 0x1a, 0x2e, 0xff} // Dark blue-gray
	Surface           = color.NRGBA{0x25, 0x25, 0x3a, 0xff} // Slightly lighter
	Primary           = color.NRGBA{0x4a, 0x4a, 0x8a, 0xff} // Muted purple
	PrimaryHover      = color.NRGBA{0x5a, 0x5a, 0x9a, 0xff}
	Text              = color.NRGBA{0xff, 0xff, 0xff, 0xff}
	TextSecondary     = color.NRGBA{0xaa, 0xaa, 0xaa, 0xff}
	Accent            = color.NRGBA{0xff, 0xd7, 0x00, 0xff} // Gold for favorites
	Border            = color.NRGBA{0x3a, 0x3a, 0x5a, 0xff}
	Black             = color.NRGBA{0x00, 0x00, 0x00, 0xff}
	DimOverlay        = color.NRGBA{0x00, 0x00, 0x00, 0xff} // Base color for screen-dimming overlays (alpha applied per use)
	OverlayBackground = color.NRGBA{0x1a, 0x1a, 0x2e, 0xff} // Base color for floating element backgrounds (alpha applied per use)
)

Theme colors (package-level variables updated by ApplyTheme)

View Source
var (
	ThemeDefault = Theme{
		Name:              "Default",
		Background:        color.NRGBA{0x1a, 0x1a, 0x2e, 0xff},
		Surface:           color.NRGBA{0x25, 0x25, 0x3a, 0xff},
		Primary:           color.NRGBA{0x4a, 0x4a, 0x8a, 0xff},
		PrimaryHover:      color.NRGBA{0x5a, 0x5a, 0x9a, 0xff},
		Text:              color.NRGBA{0xff, 0xff, 0xff, 0xff},
		TextSecondary:     color.NRGBA{0xaa, 0xaa, 0xaa, 0xff},
		Accent:            color.NRGBA{0xff, 0xd7, 0x00, 0xff},
		Border:            color.NRGBA{0x3a, 0x3a, 0x5a, 0xff},
		Black:             color.NRGBA{0x00, 0x00, 0x00, 0xff},
		DimOverlay:        color.NRGBA{0x00, 0x00, 0x00, 0xff},
		OverlayBackground: color.NRGBA{0x1a, 0x1a, 0x2e, 0xff},
	}

	ThemeDark = Theme{
		Name:              "Dark",
		Background:        color.NRGBA{0x0a, 0x0a, 0x0a, 0xff},
		Surface:           color.NRGBA{0x1a, 0x1a, 0x1a, 0xff},
		Primary:           color.NRGBA{0x1e, 0x40, 0x7a, 0xff},
		PrimaryHover:      color.NRGBA{0x2a, 0x50, 0x8a, 0xff},
		Text:              color.NRGBA{0xff, 0xff, 0xff, 0xff},
		TextSecondary:     color.NRGBA{0x88, 0x88, 0x88, 0xff},
		Accent:            color.NRGBA{0x00, 0xc8, 0x53, 0xff},
		Border:            color.NRGBA{0x2a, 0x2a, 0x2a, 0xff},
		Black:             color.NRGBA{0x00, 0x00, 0x00, 0xff},
		DimOverlay:        color.NRGBA{0x00, 0x00, 0x00, 0xff},
		OverlayBackground: color.NRGBA{0x0a, 0x0a, 0x0a, 0xff},
	}

	ThemeLight = Theme{
		Name:              "Light",
		Background:        color.NRGBA{0xe8, 0xe8, 0xe8, 0xff},
		Surface:           color.NRGBA{0xf5, 0xf5, 0xf5, 0xff},
		Primary:           color.NRGBA{0x1a, 0x56, 0xdb, 0xff},
		PrimaryHover:      color.NRGBA{0x2a, 0x66, 0xeb, 0xff},
		Text:              color.NRGBA{0x1a, 0x1a, 0x1a, 0xff},
		TextSecondary:     color.NRGBA{0x66, 0x66, 0x66, 0xff},
		Accent:            color.NRGBA{0xe6, 0x5c, 0x00, 0xff},
		Border:            color.NRGBA{0xcc, 0xcc, 0xcc, 0xff},
		Black:             color.NRGBA{0x00, 0x00, 0x00, 0xff},
		DimOverlay:        color.NRGBA{0x00, 0x00, 0x00, 0xff},
		OverlayBackground: color.NRGBA{0xe8, 0xe8, 0xe8, 0xff},
	}

	ThemeRetro = Theme{
		Name:              "Retro",
		Background:        color.NRGBA{0x1c, 0x1c, 0x1c, 0xff},
		Surface:           color.NRGBA{0x28, 0x28, 0x28, 0xff},
		Primary:           color.NRGBA{0x8b, 0x00, 0x00, 0xff},
		PrimaryHover:      color.NRGBA{0xab, 0x20, 0x20, 0xff},
		Text:              color.NRGBA{0xd0, 0xd0, 0xd0, 0xff},
		TextSecondary:     color.NRGBA{0x80, 0x80, 0x80, 0xff},
		Accent:            color.NRGBA{0x00, 0xaa, 0x00, 0xff},
		Border:            color.NRGBA{0x3c, 0x3c, 0x3c, 0xff},
		Black:             color.NRGBA{0x00, 0x00, 0x00, 0xff},
		DimOverlay:        color.NRGBA{0x00, 0x00, 0x00, 0xff},
		OverlayBackground: color.NRGBA{0x1c, 0x1c, 0x1c, 0xff},
	}

	ThemePink = Theme{
		Name:              "Pink",
		Background:        color.NRGBA{0x1a, 0x0a, 0x1a, 0xff},
		Surface:           color.NRGBA{0x3a, 0x1a, 0x3a, 0xff},
		Primary:           color.NRGBA{0xc0, 0x10, 0x70, 0xff},
		PrimaryHover:      color.NRGBA{0xff, 0x14, 0x93, 0xff},
		Text:              color.NRGBA{0xff, 0xfa, 0xfc, 0xff},
		TextSecondary:     color.NRGBA{0xff, 0x99, 0xcc, 0xff},
		Accent:            color.NRGBA{0xff, 0x00, 0xff, 0xff},
		Border:            color.NRGBA{0x5a, 0x2a, 0x5a, 0xff},
		Black:             color.NRGBA{0x00, 0x00, 0x00, 0xff},
		DimOverlay:        color.NRGBA{0x00, 0x00, 0x00, 0xff},
		OverlayBackground: color.NRGBA{0x1a, 0x0a, 0x1a, 0xff},
	}

	ThemeHotPink = Theme{
		Name:              "Hot Pink",
		Background:        color.NRGBA{0x4d, 0x15, 0x3d, 0xff},
		Surface:           color.NRGBA{0x70, 0x25, 0x58, 0xff},
		Primary:           color.NRGBA{0xff, 0x33, 0x99, 0xff},
		PrimaryHover:      color.NRGBA{0xff, 0x66, 0xb2, 0xff},
		Text:              color.NRGBA{0xff, 0xff, 0xff, 0xff},
		TextSecondary:     color.NRGBA{0xff, 0xb3, 0xda, 0xff},
		Accent:            color.NRGBA{0xff, 0x44, 0xff, 0xff},
		Border:            color.NRGBA{0x99, 0x33, 0x77, 0xff},
		Black:             color.NRGBA{0x00, 0x00, 0x00, 0xff},
		DimOverlay:        color.NRGBA{0x00, 0x00, 0x00, 0xff},
		OverlayBackground: color.NRGBA{0x4d, 0x15, 0x3d, 0xff},
	}

	ThemeGreenLCD = Theme{
		Name:              "Green LCD",
		Background:        color.NRGBA{0x07, 0x20, 0x07, 0xff},
		Surface:           color.NRGBA{0x0f, 0x38, 0x0f, 0xff},
		Primary:           color.NRGBA{0x30, 0x62, 0x30, 0xff},
		PrimaryHover:      color.NRGBA{0x4a, 0x7c, 0x4a, 0xff},
		Text:              color.NRGBA{0x9b, 0xbc, 0x0f, 0xff},
		TextSecondary:     color.NRGBA{0x5a, 0x7a, 0x0f, 0xff},
		Accent:            color.NRGBA{0xc0, 0xe0, 0x30, 0xff},
		Border:            color.NRGBA{0x20, 0x50, 0x20, 0xff},
		Black:             color.NRGBA{0x07, 0x20, 0x07, 0xff},
		DimOverlay:        color.NRGBA{0x07, 0x20, 0x07, 0xff},
		OverlayBackground: color.NRGBA{0x07, 0x20, 0x07, 0xff},
	}

	ThemeHighContrast = Theme{
		Name:              "High Contrast",
		Background:        color.NRGBA{0x00, 0x00, 0x00, 0xff},
		Surface:           color.NRGBA{0x40, 0x40, 0x40, 0xff},
		Primary:           color.NRGBA{0x00, 0x80, 0xff, 0xff},
		PrimaryHover:      color.NRGBA{0x40, 0xa0, 0xff, 0xff},
		Text:              color.NRGBA{0xff, 0xff, 0xff, 0xff},
		TextSecondary:     color.NRGBA{0xcc, 0xcc, 0xcc, 0xff},
		Accent:            color.NRGBA{0xff, 0xff, 0x00, 0xff},
		Border:            color.NRGBA{0x66, 0x66, 0x66, 0xff},
		Black:             color.NRGBA{0x00, 0x00, 0x00, 0xff},
		DimOverlay:        color.NRGBA{0x00, 0x00, 0x00, 0xff},
		OverlayBackground: color.NRGBA{0x00, 0x00, 0x00, 0xff},
	}

	// AvailableThemes lists all themes for UI selection
	AvailableThemes = []Theme{ThemeDefault, ThemeDark, ThemeLight, ThemeRetro, ThemePink, ThemeHotPink, ThemeGreenLCD, ThemeHighContrast}

	// CurrentThemeName tracks the active theme name
	CurrentThemeName = "Default"
)

Predefined themes

View Source
var EstimatedViewportHeight = baseEstimatedViewportHeight

Font-dependent scroll estimation (updated by ApplyFontSize)

View Source
var (
	ListMinTitleWidth = baseListMinTitleWidth
)

Library list view vars

View Source
var SettingsRowHeight = baseSettingsRowHeight

Font-dependent settings layout value (updated by ApplyFontSize)

Functions

func ActiveButtonImage

func ActiveButtonImage(active bool) *widget.ButtonImage

ActiveButtonImage returns a button image based on active state. Used for toggle buttons like view mode selectors and sidebar items.

func ApplyFontSize

func ApplyFontSize(size int)

ApplyFontSize sets the font size and recalculates all font-dependent layout values.

func ApplyGrayscale

func ApplyGrayscale(src *ebiten.Image) *ebiten.Image

ApplyGrayscale converts an ebiten image to grayscale. Returns a new image with grayscale applied.

func ApplyTheme

func ApplyTheme(theme Theme)

ApplyTheme updates package-level color variables from a theme

func ApplyThemeByName

func ApplyThemeByName(name string)

ApplyThemeByName applies theme by name with fallback to Default

func ButtonImage

func ButtonImage() *widget.ButtonImage

ButtonImage creates a standard button image set

func ButtonTextColor

func ButtonTextColor() *widget.ButtonTextColor

ButtonTextColor returns the standard button text colors

func DPIScale

func DPIScale() float64

DPIScale returns the current device scale factor.

func DisabledButtonImage

func DisabledButtonImage() *widget.ButtonImage

DisabledButtonImage creates a disabled-looking button image set

func FontFace

func FontFace() *text.Face

FontFace returns the font face to use for UI text

func FontScale

func FontScale() float64

FontScale returns the current font scale factor relative to the base size (14pt).

func FormatDate

func FormatDate(timestamp int64) string

FormatDate formats a Unix timestamp as a date string. Returns "Unknown" for 0, otherwise "Jan 2, 2006".

func FormatLastPlayed

func FormatLastPlayed(timestamp int64) string

FormatLastPlayed formats a Unix timestamp into a relative or absolute date string. Returns "Never" for 0, "Today"/"Yesterday" for recent dates, "Jan 2" for this year, or "Jan 2, 2006" for previous years.

func FormatPlayTime

func FormatPlayTime(seconds int64) string

FormatPlayTime formats a duration in seconds into a human-readable string. Returns "—" for 0 seconds, "< 1m" for under a minute, or a formatted string like "2h 30m" or "45m".

func IsValidThemeName

func IsValidThemeName(name string) bool

IsValidThemeName returns true if the name matches a known theme

func LargeFontFace

func LargeFontFace() *text.GoTextFace

LargeFontFace returns a larger font face for prominent displays like achievements

func MeasureWidth

func MeasureWidth(s string) float64

MeasureWidth returns the pixel width of s rendered at the current font size.

func PrimaryButtonImage

func PrimaryButtonImage() *widget.ButtonImage

PrimaryButtonImage creates a prominent button image set

func Px

func Px(logical int) int

Px converts a logical pixel value to physical pixels using the current DPI scale.

func PxFont

func PxFont(logical int) int

PxFont converts a logical pixel value to physical pixels scaled by both DPI and font size.

func ScaleImage

func ScaleImage(src goimage.Image, maxWidth, maxHeight int) *ebiten.Image

ScaleImage scales an image to fit within maxWidth x maxHeight while preserving aspect ratio. The result is a managed (atlased) ebiten.Image, suitable for small, long-lived images that benefit from draw-call batching.

func ScaleImageUnmanaged added in v0.4.5

func ScaleImageUnmanaged(src goimage.Image, maxWidth, maxHeight int) *ebiten.Image

ScaleImageUnmanaged is like ScaleImage but returns an unmanaged (off-atlas) ebiten.Image. Each unmanaged image is its own right-sized GPU texture that is freed immediately on Deallocate, rather than being packed onto a large shared atlas page that is only released once every image on it is gone. This is the right choice for numerous or frequently rebuilt artwork (cover art, box art) where atlas packing wastes memory and fragments. The trade-off is that these images are not batched with others when drawn, which is immaterial for the handful of static artwork images on a UI screen.

func SetDPIScale

func SetDPIScale(scale float64)

SetDPIScale sets the DPI scale factor and recalculates all spatial vars.

func SliderButtonImage

func SliderButtonImage() *widget.ButtonImage

SliderButtonImage creates a slider handle button image

func SliderTrackImage

func SliderTrackImage() *widget.SliderTrackImage

SliderTrackImage creates a slider track image

func ThemeNames

func ThemeNames() []string

ThemeNames returns the list of valid theme name strings.

func TruncateEnd

func TruncateEnd(s string, maxLen int) (string, bool)

TruncateEnd truncates a string from the end, keeping the start portion. Returns the truncated string and whether truncation occurred. Useful for titles where the beginning is most relevant.

func TruncateStart

func TruncateStart(s string, maxLen int) (string, bool)

TruncateStart truncates a string from the start, keeping the end portion. Returns the truncated string and whether truncation occurred. Useful for file paths where the end (filename) is most relevant.

func TruncateToWidth

func TruncateToWidth(s string, face text.Face, maxWidth float64) (string, bool)

TruncateToWidth truncates a string to fit within a given pixel width using actual font measurement. Returns the truncated string (with "..." suffix if truncated) and whether truncation occurred. Uses binary search on rune boundaries for efficiency with proportional fonts.

func WrapToBox added in v0.3.0

func WrapToBox(s string, face text.Face, maxWidth, maxHeight float64) string

WrapToBox lays s out as word-wrapped lines that fit within maxWidth pixels, keeping only as many lines as fit in maxHeight and ending the last visible line with an ellipsis when text is dropped. A single word wider than maxWidth is itself truncated with an ellipsis. The returned newline-joined string never exceeds the maxWidth x maxHeight box, so a fixed-size container holding it does not grow to fit.

Types

type Theme

type Theme struct {
	Name              string
	Background        color.NRGBA
	Surface           color.NRGBA
	Primary           color.NRGBA
	PrimaryHover      color.NRGBA
	Text              color.NRGBA
	TextSecondary     color.NRGBA
	Accent            color.NRGBA
	Border            color.NRGBA
	Black             color.NRGBA
	DimOverlay        color.NRGBA
	OverlayBackground color.NRGBA
}

Theme holds all color values for a UI theme

func GetThemeByName

func GetThemeByName(name string) Theme

GetThemeByName returns theme by name, or ThemeDefault if not found

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL