160 lines
5.9 KiB
Odin
160 lines
5.9 KiB
Odin
package main
|
|||
|
|
|
||
|
|
import engine "../zephr"
|
||
|
|
|
||
|
|
// Material 3 design tokens.
|
||
|
|
//
|
||
|
|
// Baseline dark scheme, verbatim from the M3 spec. Sizes are dp and type sizes
|
||
|
|
// are sp, which are the same thing here because layout points are dp.
|
||
|
|
//
|
||
|
|
// Two spec notes that shape everything below:
|
||
|
|
// - M3 conveys elevation with surface *colour*, not shadow. The engine draws
|
||
|
|
// no shadows, and it does not need to: the container roles below are the
|
||
|
|
// real mechanism.
|
||
|
|
// - Corner radii are uniform. The engine's border_radius is a single float,
|
||
|
|
// so shapes needing per-corner radii (segmented button ends) are noted.
|
||
|
|
|
||
|
|
// -- Colour roles ------------------------------------------------------------
|
||
|
|
|
||
|
|
hex :: proc(v: u32, a: f32 = 1) -> engine.Color {
|
||
|
|
return {
|
||
|
|
f32((v >> 16) & 0xFF) / 255,
|
||
|
|
f32((v >> 8) & 0xFF) / 255,
|
||
|
|
f32(v & 0xFF) / 255,
|
||
|
|
a,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
M3 :: struct {
|
||
|
|
primary, on_primary, primary_container, on_primary_container: engine.Color,
|
||
|
|
secondary, on_secondary, secondary_container, on_secondary_container: engine.Color,
|
||
|
|
tertiary, on_tertiary, tertiary_container, on_tertiary_container: engine.Color,
|
||
|
|
error, on_error, error_container, on_error_container: engine.Color,
|
||
|
|
surface, on_surface, surface_variant, on_surface_variant: engine.Color,
|
||
|
|
surface_c_lowest, surface_c_low, surface_c, surface_c_high, surface_c_highest: engine.Color,
|
||
|
|
outline, outline_variant: engine.Color,
|
||
|
|
inverse_surface, inverse_on_surface, inverse_primary: engine.Color,
|
||
|
|
scrim: engine.Color,
|
||
|
|
}
|
||
|
|
|
||
|
|
m3: M3
|
||
|
|
|
||
|
|
m3_init_dark :: proc() {
|
||
|
|
m3.primary = hex(0xD0BCFF)
|
||
|
|
m3.on_primary = hex(0x381E72)
|
||
|
|
m3.primary_container = hex(0x4F378B)
|
||
|
|
m3.on_primary_container = hex(0xEADDFF)
|
||
|
|
|
||
|
|
m3.secondary = hex(0xCCC2DC)
|
||
|
|
m3.on_secondary = hex(0x332D41)
|
||
|
|
m3.secondary_container = hex(0x4A4458)
|
||
|
|
m3.on_secondary_container = hex(0xE8DEF8)
|
||
|
|
|
||
|
|
m3.tertiary = hex(0xEFB8C8)
|
||
|
|
m3.on_tertiary = hex(0x492532)
|
||
|
|
m3.tertiary_container = hex(0x633B48)
|
||
|
|
m3.on_tertiary_container = hex(0xFFD8E4)
|
||
|
|
|
||
|
|
m3.error = hex(0xF2B8B5)
|
||
|
|
m3.on_error = hex(0x601410)
|
||
|
|
m3.error_container = hex(0x8C1D18)
|
||
|
|
m3.on_error_container = hex(0xF9DEDC)
|
||
|
|
|
||
|
|
m3.surface = hex(0x141218)
|
||
|
|
m3.on_surface = hex(0xE6E0E9)
|
||
|
|
m3.surface_variant = hex(0x49454F)
|
||
|
|
m3.on_surface_variant = hex(0xCAC4D0)
|
||
|
|
|
||
|
|
// The elevation ladder. Higher role == "further from the surface".
|
||
|
|
m3.surface_c_lowest = hex(0x0F0D13)
|
||
|
|
m3.surface_c_low = hex(0x1D1B20)
|
||
|
|
m3.surface_c = hex(0x211F26)
|
||
|
|
m3.surface_c_high = hex(0x2B2930)
|
||
|
|
m3.surface_c_highest = hex(0x36343B)
|
||
|
|
|
||
|
|
m3.outline = hex(0x938F99)
|
||
|
|
m3.outline_variant = hex(0x49454F)
|
||
|
|
|
||
|
|
m3.inverse_surface = hex(0xE6E0E9)
|
||
|
|
m3.inverse_on_surface = hex(0x322F35)
|
||
|
|
m3.inverse_primary = hex(0x6750A4)
|
||
|
|
m3.scrim = hex(0x000000)
|
||
|
|
}
|
||
|
|
|
||
|
|
// State layer opacities, applied over a container colour.
|
||
|
|
M3_STATE_HOVER :: f32(0.08)
|
||
|
|
M3_STATE_FOCUS :: f32(0.10)
|
||
|
|
M3_STATE_PRESSED :: f32(0.10)
|
||
|
|
M3_DISABLED_FG :: f32(0.38)
|
||
|
|
M3_DISABLED_BG :: f32(0.12)
|
||
|
|
|
||
|
|
// Composites a state layer over a base colour, which is how M3 defines every
|
||
|
|
// hover/press appearance rather than by naming separate colours.
|
||
|
|
m3_state_layer :: proc(base: engine.Color, layer: engine.Color, opacity: f32) -> engine.Color {
|
||
|
|
return {
|
||
|
|
base.r + (layer.r - base.r) * opacity,
|
||
|
|
base.g + (layer.g - base.g) * opacity,
|
||
|
|
base.b + (layer.b - base.b) * opacity,
|
||
|
|
base.a,
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
m3_alpha :: proc(c: engine.Color, a: f32) -> engine.Color {
|
||
|
|
return {c.r, c.g, c.b, a}
|
||
|
|
}
|
||
|
|
|
||
|
|
// -- Type scale (sp) ---------------------------------------------------------
|
||
|
|
|
||
|
|
M3_DISPLAY_SMALL :: 36
|
||
|
|
M3_HEADLINE_MEDIUM :: 28
|
||
|
|
M3_HEADLINE_SMALL :: 24
|
||
|
|
M3_TITLE_LARGE :: 22
|
||
|
|
M3_TITLE_MEDIUM :: 16
|
||
|
|
M3_TITLE_SMALL :: 14
|
||
|
|
M3_BODY_LARGE :: 16
|
||
|
|
M3_BODY_MEDIUM :: 14
|
||
|
|
M3_BODY_SMALL :: 12
|
||
|
|
M3_LABEL_LARGE :: 14
|
||
|
|
M3_LABEL_MEDIUM :: 12
|
||
|
|
M3_LABEL_SMALL :: 11
|
||
|
|
|
||
|
|
// Roboto weights the M3 type scale uses. Title/label roles are medium (500).
|
||
|
|
M3_WEIGHT_REGULAR :: f32(400)
|
||
|
|
M3_WEIGHT_MEDIUM :: f32(500)
|
||
|
|
|
||
|
|
// -- Shape scale (dp) --------------------------------------------------------
|
||
|
|
|
||
|
|
M3_SHAPE_XS :: 4
|
||
|
|
M3_SHAPE_SM :: 8
|
||
|
|
M3_SHAPE_MD :: 12
|
||
|
|
M3_SHAPE_LG :: 16
|
||
|
|
M3_SHAPE_XL :: 28
|
||
|
|
M3_SHAPE_FULL :: 9999 // clamped by the widget's half-height
|
||
|
|
|
||
|
|
// -- Icon codepoints ---------------------------------------------------------
|
||
|
|
//
|
||
|
|
// Written as byte escapes rather than literal glyphs: these live in the Private
|
||
|
|
// Use Area, so they are invisible in an editor and are silently lost by tools
|
||
|
|
// that do not round-trip them. The codepoint in each comment is the source of
|
||
|
|
// truth, and must stay in step with the pyftsubset --unicodes list.
|
||
|
|
|
||
|
|
ICON_ARROW_BACK :: "\xEE\x97\x84" // U+E5C4 arrow_back
|
||
|
|
ICON_MENU :: "\xEE\x97\x92" // U+E5D2 menu
|
||
|
|
ICON_MORE_VERT :: "\xEE\x97\x94" // U+E5D4 more_vert
|
||
|
|
ICON_SEARCH :: "\xEE\xA2\xB6" // U+E8B6 search
|
||
|
|
ICON_CHECK :: "\xEE\x97\x8A" // U+E5CA check
|
||
|
|
ICON_CLOSE :: "\xEE\x97\x8D" // U+E5CD close
|
||
|
|
ICON_ADD :: "\xEE\x85\x85" // U+E145 add
|
||
|
|
ICON_HOME :: "\xEE\xA2\x8A" // U+E88A home
|
||
|
|
ICON_FAVORITE :: "\xEE\xA1\xBD" // U+E87D favorite
|
||
|
|
ICON_SETTINGS :: "\xEE\xA2\xB8" // U+E8B8 settings
|
||
|
|
ICON_EDIT :: "\xEE\x8F\x89" // U+E3C9 edit
|
||
|
|
ICON_DELETE :: "\xEE\xA1\xB2" // U+E872 delete
|
||
|
|
ICON_PERSON :: "\xEE\x9F\xBD" // U+E7FD person
|
||
|
|
ICON_STAR :: "\xEE\xA0\xB8" // U+E838 star
|
||
|
|
ICON_SHARE :: "\xEE\xA0\x8D" // U+E80D share
|
||
|
|
ICON_DOWNLOAD :: "\xEE\x8B\x84" // U+E2C4 download
|
||
|
|
ICON_BOOKMARK :: "\xEE\xA1\xA6" // U+E866 bookmark
|
||
|
|
ICON_NOTIFICATIONS :: "\xEE\x9F\xB4" // U+E7F4 notifications
|
||
|
|
ICON_EXPAND_MORE :: "\xEE\x97\x8F" // U+E5CF expand_more
|