style

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2026 License: GPL-3.0 Imports: 17 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 AlternatingRowColor

func AlternatingRowColor(index int) color.Color

AlternatingRowColor returns the appropriate background color for alternating rows. Even indices (0, 2, 4...) return Background, odd indices return Surface.

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 ButtonRow

func ButtonRow() *widget.Container

ButtonRow creates a horizontal container for buttons with standard spacing.

func ButtonTextColor

func ButtonTextColor() *widget.ButtonTextColor

ButtonTextColor returns the standard button text colors

func CenteredContainer

func CenteredContainer(spacing int) *widget.Container

CenteredContainer creates a container with vertical layout, centered in its parent. Use for modal dialogs, status screens, and centered content. The spacing parameter controls vertical spacing between children.

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 DisabledSidebarItem

func DisabledSidebarItem(label string) *widget.Container

DisabledSidebarItem creates a non-focusable sidebar item with the given label. Used for future/coming-soon menu items.

func EmptyState

func EmptyState(title, subtitle string, button *widget.Button) *widget.Container

EmptyState creates a centered empty state display with title, optional subtitle, and optional button. The returned container has RowLayoutData{Stretch: true} for use in row layouts. Pass empty string for subtitle to omit it. Pass nil for button to omit it.

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 LabeledText

func LabeledText(label, subtext string) *widget.Container

LabeledText creates a vertical container with a primary label and optional secondary subtext. Text is vertically centered within the grid cell.

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 PrimaryTextButton

func PrimaryTextButton(text string, padding int, handler func(*widget.ButtonClickedEventArgs)) *widget.Button

PrimaryTextButton creates a prominent text button with primary styling. Use for main actions like "Play", "Save", "Scan Library".

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. Returns an ebiten.Image suitable for display. Scaling is done on CPU to avoid creating large temporary GPU textures.

func ScreenContainer

func ScreenContainer() *widget.Container

ScreenContainer creates a full-screen root container with background. The container uses AnchorLayout so children can stretch to fill.

func ScreenContentContainer

func ScreenContentContainer(rowStretch []bool) *widget.Container

ScreenContentContainer creates an inner container for screen content. Uses a single-column GridLayout with default padding and spacing. The stretch parameter controls which rows stretch vertically.

func ScrollContainerImage

func ScrollContainerImage() *widget.ScrollContainerImage

ScrollContainerImage creates a scroll container image

func ScrollSlider

func ScrollSlider(scrollContainer *widget.ScrollContainer, needsScroll func() bool) *widget.Slider

ScrollSlider creates a vertical scroll slider bound to a scroll container. The needsScroll function should return true when content exceeds view height. Returns the slider widget.

func ScrollableContainer

ScrollableContainer creates a scrollable container with a vertical slider. Returns the scroll container, slider, and wrapper widget for embedding in layouts. The scroll container and slider references can be used for scroll position preservation.

func SetDPIScale

func SetDPIScale(scale float64)

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

func SettingsRow

func SettingsRow(columns int) *widget.Container

SettingsRow creates a standard settings row container with Surface background, N-column grid layout, and RowLayoutData stretch.

func SetupScrollHandler

func SetupScrollHandler(scrollContainer *widget.ScrollContainer, vSlider *widget.Slider, needsScroll func() bool)

SetupScrollHandler adds mouse wheel scroll support to a scroll container. The slider's Current value is kept in sync with scroll position.

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 StyledTextInput

func StyledTextInput(placeholder string, secure bool, minWidth int) *widget.TextInput

StyledTextInput creates a text input with consistent styling.

func TableCell

func TableCell(text string, width, height int, textColor color.Color) *widget.Container

TableCell creates a table cell with text content. Use for data cells in list/table views.

func TableHeaderCell

func TableHeaderCell(text string, width, height int) *widget.Container

TableHeaderCell creates a table header cell with secondary text color. Use for column headers in list/table views.

func TextButton

func TextButton(text string, padding int, handler func(*widget.ButtonClickedEventArgs)) *widget.Button

TextButton creates a standard text button with consistent styling. Use for regular actions like "Back", "Cancel", "Settings".

func ThemeNames

func ThemeNames() []string

ThemeNames returns the list of valid theme name strings.

func ToggleButton

func ToggleButton(text string, active bool, handler func(*widget.ButtonClickedEventArgs)) *widget.Button

ToggleButton creates a button that visually indicates an active/inactive state. Use for view mode toggles, filters, and other binary state buttons.

func TooltipContent

func TooltipContent(text string) *widget.Container

TooltipContent creates a tooltip container with consistent styling. Use for showing full text when content is truncated.

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.

Types

type ScrollableOpts

type ScrollableOpts struct {
	Content     *widget.Container // Required: content to scroll
	BgColor     color.Color       // Background color for scroll area (default: Background)
	BorderColor color.Color       // Border color for wrapper (nil = no border)
	Spacing     int               // Spacing between scroll area and slider (default: 4)
	Padding     int               // Padding inside wrapper, used with BorderColor (default: 0)
}

ScrollableOpts configures a scrollable container.

type TextInputGroup

type TextInputGroup struct {
	// contains filtered or unexported fields
}

TextInputGroup manages a group of text inputs with clipboard support. Call Update() each frame to handle Ctrl/Cmd+A/C/V/X shortcuts.

func NewTextInputGroup

func NewTextInputGroup() *TextInputGroup

NewTextInputGroup creates a new text input group for clipboard handling.

func (*TextInputGroup) Add

func (g *TextInputGroup) Add(input *widget.TextInput)

Add registers a text input with the group for clipboard handling.

func (*TextInputGroup) Update

func (g *TextInputGroup) Update()

Update handles clipboard shortcuts (Ctrl/Cmd+A/C/V/X) for the focused input. Call this each frame from your screen's Update method.

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