theme.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. // Package theme defines how a Fyne app should look when rendered.
  2. package theme // import "fyne.io/fyne/v2/theme"
  3. import (
  4. "image/color"
  5. "os"
  6. "strings"
  7. "fyne.io/fyne/v2"
  8. )
  9. const (
  10. // ColorRed is the red primary color name.
  11. //
  12. // Since: 1.4
  13. ColorRed = "red"
  14. // ColorOrange is the orange primary color name.
  15. //
  16. // Since: 1.4
  17. ColorOrange = "orange"
  18. // ColorYellow is the yellow primary color name.
  19. //
  20. // Since: 1.4
  21. ColorYellow = "yellow"
  22. // ColorGreen is the green primary color name.
  23. //
  24. // Since: 1.4
  25. ColorGreen = "green"
  26. // ColorBlue is the blue primary color name.
  27. //
  28. // Since: 1.4
  29. ColorBlue = "blue"
  30. // ColorPurple is the purple primary color name.
  31. //
  32. // Since: 1.4
  33. ColorPurple = "purple"
  34. // ColorBrown is the brown primary color name.
  35. //
  36. // Since: 1.4
  37. ColorBrown = "brown"
  38. // ColorGray is the gray primary color name.
  39. //
  40. // Since: 1.4
  41. ColorGray = "gray"
  42. // ColorNameBackground is the name of theme lookup for background color.
  43. //
  44. // Since: 2.0
  45. ColorNameBackground fyne.ThemeColorName = "background"
  46. // ColorNameButton is the name of theme lookup for button color.
  47. //
  48. // Since: 2.0
  49. ColorNameButton fyne.ThemeColorName = "button"
  50. // ColorNameDisabledButton is the name of theme lookup for disabled button color.
  51. //
  52. // Since: 2.0
  53. ColorNameDisabledButton fyne.ThemeColorName = "disabledButton"
  54. // ColorNameDisabled is the name of theme lookup for disabled foreground color.
  55. //
  56. // Since: 2.0
  57. ColorNameDisabled fyne.ThemeColorName = "disabled"
  58. // ColorNameError is the name of theme lookup for foreground error color.
  59. //
  60. // Since: 2.0
  61. ColorNameError fyne.ThemeColorName = "error"
  62. // ColorNameFocus is the name of theme lookup for focus color.
  63. //
  64. // Since: 2.0
  65. ColorNameFocus fyne.ThemeColorName = "focus"
  66. // ColorNameForeground is the name of theme lookup for foreground color.
  67. //
  68. // Since: 2.0
  69. ColorNameForeground fyne.ThemeColorName = "foreground"
  70. // ColorNameHover is the name of theme lookup for hover color.
  71. //
  72. // Since: 2.0
  73. ColorNameHover fyne.ThemeColorName = "hover"
  74. // ColorNameInputBackground is the name of theme lookup for background color of an input field.
  75. //
  76. // Since: 2.0
  77. ColorNameInputBackground fyne.ThemeColorName = "inputBackground"
  78. // ColorNameInputBorder is the name of theme lookup for border color of an input field.
  79. //
  80. // Since: 2.3
  81. ColorNameInputBorder fyne.ThemeColorName = "inputBorder"
  82. // ColorNameMenuBackground is the name of theme lookup for background color of menus.
  83. //
  84. // Since: 2.3
  85. ColorNameMenuBackground fyne.ThemeColorName = "menuBackground"
  86. // ColorNameOverlayBackground is the name of theme lookup for background color of overlays like dialogs.
  87. //
  88. // Since: 2.3
  89. ColorNameOverlayBackground fyne.ThemeColorName = "overlayBackground"
  90. // ColorNamePlaceHolder is the name of theme lookup for placeholder text color.
  91. //
  92. // Since: 2.0
  93. ColorNamePlaceHolder fyne.ThemeColorName = "placeholder"
  94. // ColorNamePressed is the name of theme lookup for the tap overlay color.
  95. //
  96. // Since: 2.0
  97. ColorNamePressed fyne.ThemeColorName = "pressed"
  98. // ColorNamePrimary is the name of theme lookup for primary color.
  99. //
  100. // Since: 2.0
  101. ColorNamePrimary fyne.ThemeColorName = "primary"
  102. // ColorNameScrollBar is the name of theme lookup for scrollbar color.
  103. //
  104. // Since: 2.0
  105. ColorNameScrollBar fyne.ThemeColorName = "scrollBar"
  106. // ColorNameSelection is the name of theme lookup for selection color.
  107. //
  108. // Since: 2.1
  109. ColorNameSelection fyne.ThemeColorName = "selection"
  110. // ColorNameSeparator is the name of theme lookup for separator bars.
  111. //
  112. // Since: 2.3
  113. ColorNameSeparator fyne.ThemeColorName = "separator"
  114. // ColorNameShadow is the name of theme lookup for shadow color.
  115. //
  116. // Since: 2.0
  117. ColorNameShadow fyne.ThemeColorName = "shadow"
  118. // ColorNameSuccess is the name of theme lookup for foreground success color.
  119. //
  120. // Since: 2.3
  121. ColorNameSuccess fyne.ThemeColorName = "success"
  122. // ColorNameWarning is the name of theme lookup for foreground warning color.
  123. //
  124. // Since: 2.3
  125. ColorNameWarning fyne.ThemeColorName = "warning"
  126. // SizeNameCaptionText is the name of theme lookup for helper text size, normally smaller than regular text size.
  127. //
  128. // Since: 2.0
  129. SizeNameCaptionText fyne.ThemeSizeName = "helperText"
  130. // SizeNameInlineIcon is the name of theme lookup for inline icons size.
  131. //
  132. // Since: 2.0
  133. SizeNameInlineIcon fyne.ThemeSizeName = "iconInline"
  134. // SizeNameInnerPadding is the name of theme lookup for internal widget padding size.
  135. //
  136. // Since: 2.3
  137. SizeNameInnerPadding fyne.ThemeSizeName = "innerPadding"
  138. // SizeNameLineSpacing is the name of theme lookup for between text line spacing.
  139. //
  140. // Since: 2.3
  141. SizeNameLineSpacing fyne.ThemeSizeName = "lineSpacing"
  142. // SizeNamePadding is the name of theme lookup for padding size.
  143. //
  144. // Since: 2.0
  145. SizeNamePadding fyne.ThemeSizeName = "padding"
  146. // SizeNameScrollBar is the name of theme lookup for the scrollbar size.
  147. //
  148. // Since: 2.0
  149. SizeNameScrollBar fyne.ThemeSizeName = "scrollBar"
  150. // SizeNameScrollBarSmall is the name of theme lookup for the shrunk scrollbar size.
  151. //
  152. // Since: 2.0
  153. SizeNameScrollBarSmall fyne.ThemeSizeName = "scrollBarSmall"
  154. // SizeNameSeparatorThickness is the name of theme lookup for the thickness of a separator.
  155. //
  156. // Since: 2.0
  157. SizeNameSeparatorThickness fyne.ThemeSizeName = "separator"
  158. // SizeNameText is the name of theme lookup for text size.
  159. //
  160. // Since: 2.0
  161. SizeNameText fyne.ThemeSizeName = "text"
  162. // SizeNameHeadingText is the name of theme lookup for text size of a heading.
  163. //
  164. // Since: 2.1
  165. SizeNameHeadingText fyne.ThemeSizeName = "headingText"
  166. // SizeNameSubHeadingText is the name of theme lookup for text size of a sub-heading.
  167. //
  168. // Since: 2.1
  169. SizeNameSubHeadingText fyne.ThemeSizeName = "subHeadingText"
  170. // SizeNameInputBorder is the name of theme lookup for input border size.
  171. //
  172. // Since: 2.0
  173. SizeNameInputBorder fyne.ThemeSizeName = "inputBorder"
  174. // VariantDark is the version of a theme that satisfies a user preference for a light look.
  175. //
  176. // Since: 2.0
  177. VariantDark fyne.ThemeVariant = 0
  178. // VariantLight is the version of a theme that satisfies a user preference for a dark look.
  179. //
  180. // Since: 2.0
  181. VariantLight fyne.ThemeVariant = 1
  182. // potential for adding theme types such as high visibility or monochrome...
  183. variantNameUserPreference fyne.ThemeVariant = 2 // locally used in builtinTheme for backward compatibility
  184. )
  185. // BackgroundColor returns the theme's background color.
  186. func BackgroundColor() color.Color {
  187. return safeColorLookup(ColorNameBackground, currentVariant())
  188. }
  189. // ButtonColor returns the theme's standard button color.
  190. func ButtonColor() color.Color {
  191. return safeColorLookup(ColorNameButton, currentVariant())
  192. }
  193. // CaptionTextSize returns the size for caption text.
  194. func CaptionTextSize() float32 {
  195. return current().Size(SizeNameCaptionText)
  196. }
  197. // DarkTheme defines the built-in dark theme colors and sizes.
  198. //
  199. // Deprecated: This method ignores user preference and should not be used, it will be removed in v3.0.
  200. func DarkTheme() fyne.Theme {
  201. theme := &builtinTheme{variant: VariantDark}
  202. theme.initFonts()
  203. return theme
  204. }
  205. // DefaultTextBoldFont returns the font resource for the built-in bold font style.
  206. func DefaultTextBoldFont() fyne.Resource {
  207. return bold
  208. }
  209. // DefaultTextBoldItalicFont returns the font resource for the built-in bold and italic font style.
  210. func DefaultTextBoldItalicFont() fyne.Resource {
  211. return bolditalic
  212. }
  213. // DefaultTextFont returns the font resource for the built-in regular font style.
  214. func DefaultTextFont() fyne.Resource {
  215. return regular
  216. }
  217. // DefaultTextItalicFont returns the font resource for the built-in italic font style.
  218. func DefaultTextItalicFont() fyne.Resource {
  219. return italic
  220. }
  221. // DefaultTextMonospaceFont returns the font resource for the built-in monospace font face.
  222. func DefaultTextMonospaceFont() fyne.Resource {
  223. return monospace
  224. }
  225. // DefaultSymbolFont returns the font resource for the built-in symbol font.
  226. //
  227. // Since: 2.2
  228. func DefaultSymbolFont() fyne.Resource {
  229. return symbol
  230. }
  231. // DefaultTheme returns a built-in theme that can adapt to the user preference of light or dark colors.
  232. //
  233. // Since: 2.0
  234. func DefaultTheme() fyne.Theme {
  235. if defaultTheme == nil {
  236. defaultTheme = setupDefaultTheme()
  237. }
  238. return defaultTheme
  239. }
  240. // DisabledButtonColor returns the theme's disabled button color.
  241. func DisabledButtonColor() color.Color {
  242. return safeColorLookup(ColorNameDisabledButton, currentVariant())
  243. }
  244. // DisabledColor returns the foreground color for a disabled UI element.
  245. //
  246. // Since: 2.0
  247. func DisabledColor() color.Color {
  248. return safeColorLookup(ColorNameDisabled, currentVariant())
  249. }
  250. // DisabledTextColor returns the theme's disabled text color - this is actually the disabled color since 1.4.
  251. //
  252. // Deprecated: Use theme.DisabledColor() colour instead.
  253. func DisabledTextColor() color.Color {
  254. return DisabledColor()
  255. }
  256. // ErrorColor returns the theme's error foreground color.
  257. //
  258. // Since: 2.0
  259. func ErrorColor() color.Color {
  260. return safeColorLookup(ColorNameError, currentVariant())
  261. }
  262. // FocusColor returns the color used to highlight a focused widget.
  263. func FocusColor() color.Color {
  264. return safeColorLookup(ColorNameFocus, currentVariant())
  265. }
  266. // ForegroundColor returns the theme's standard foreground color for text and icons.
  267. //
  268. // Since: 2.0
  269. func ForegroundColor() color.Color {
  270. return safeColorLookup(ColorNameForeground, currentVariant())
  271. }
  272. // HoverColor returns the color used to highlight interactive elements currently under a cursor.
  273. func HoverColor() color.Color {
  274. return safeColorLookup(ColorNameHover, currentVariant())
  275. }
  276. // IconInlineSize is the standard size of icons which appear within buttons, labels etc.
  277. func IconInlineSize() float32 {
  278. return current().Size(SizeNameInlineIcon)
  279. }
  280. // InnerPadding is the standard gap between element content and the outside edge of a widget.
  281. //
  282. // Since: 2.3
  283. func InnerPadding() float32 {
  284. return current().Size(SizeNameInnerPadding)
  285. }
  286. // InputBackgroundColor returns the color used to draw underneath input elements.
  287. func InputBackgroundColor() color.Color {
  288. return current().Color(ColorNameInputBackground, currentVariant())
  289. }
  290. // InputBorderColor returns the color used to draw underneath input elements.
  291. //
  292. // Since: 2.3
  293. func InputBorderColor() color.Color {
  294. return current().Color(ColorNameInputBorder, currentVariant())
  295. }
  296. // InputBorderSize returns the input border size (or underline size for an entry).
  297. //
  298. // Since: 2.0
  299. func InputBorderSize() float32 {
  300. return current().Size(SizeNameInputBorder)
  301. }
  302. // LightTheme defines the built-in light theme colors and sizes.
  303. //
  304. // Deprecated: This method ignores user preference and should not be used, it will be removed in v3.0.
  305. func LightTheme() fyne.Theme {
  306. theme := &builtinTheme{variant: VariantLight}
  307. theme.initFonts()
  308. return theme
  309. }
  310. // LineSpacing is the default gap between multiple lines of text.
  311. //
  312. // Since: 2.3
  313. func LineSpacing() float32 {
  314. return current().Size(SizeNameLineSpacing)
  315. }
  316. // MenuBackgroundColor returns the theme's background color for menus.
  317. //
  318. // Since: 2.3
  319. func MenuBackgroundColor() color.Color {
  320. return safeColorLookup(ColorNameMenuBackground, currentVariant())
  321. }
  322. // OverlayBackgroundColor returns the theme's background color for overlays like dialogs.
  323. //
  324. // Since: 2.3
  325. func OverlayBackgroundColor() color.Color {
  326. return safeColorLookup(ColorNameOverlayBackground, currentVariant())
  327. }
  328. // Padding is the standard gap between elements and the border around interface elements.
  329. func Padding() float32 {
  330. return current().Size(SizeNamePadding)
  331. }
  332. // PlaceHolderColor returns the theme's standard text color.
  333. func PlaceHolderColor() color.Color {
  334. return safeColorLookup(ColorNamePlaceHolder, currentVariant())
  335. }
  336. // PressedColor returns the color used to overlap tapped features.
  337. //
  338. // Since: 2.0
  339. func PressedColor() color.Color {
  340. return safeColorLookup(ColorNamePressed, currentVariant())
  341. }
  342. // PrimaryColor returns the color used to highlight primary features.
  343. func PrimaryColor() color.Color {
  344. return safeColorLookup(ColorNamePrimary, currentVariant())
  345. }
  346. // PrimaryColorNamed returns a theme specific color value for a named primary color.
  347. //
  348. // Since: 1.4
  349. func PrimaryColorNamed(name string) color.Color {
  350. return primaryColorNamed(name)
  351. }
  352. // PrimaryColorNames returns a list of the standard primary color options.
  353. //
  354. // Since: 1.4
  355. func PrimaryColorNames() []string {
  356. return []string{ColorRed, ColorOrange, ColorYellow, ColorGreen, ColorBlue, ColorPurple, ColorBrown, ColorGray}
  357. }
  358. // ScrollBarColor returns the color (and translucency) for a scrollBar.
  359. func ScrollBarColor() color.Color {
  360. return safeColorLookup(ColorNameScrollBar, currentVariant())
  361. }
  362. // ScrollBarSize is the width (or height) of the bars on a ScrollContainer.
  363. func ScrollBarSize() float32 {
  364. return current().Size(SizeNameScrollBar)
  365. }
  366. // ScrollBarSmallSize is the width (or height) of the minimized bars on a ScrollContainer.
  367. func ScrollBarSmallSize() float32 {
  368. return current().Size(SizeNameScrollBarSmall)
  369. }
  370. // SelectionColor returns the color for a selected element.
  371. //
  372. // Since: 2.1
  373. func SelectionColor() color.Color {
  374. return safeColorLookup(ColorNameSelection, currentVariant())
  375. }
  376. // SeparatorColor returns the color for the separator element.
  377. //
  378. // Since: 2.3
  379. func SeparatorColor() color.Color {
  380. return safeColorLookup(ColorNameSeparator, currentVariant())
  381. }
  382. // SeparatorThicknessSize is the standard thickness of the separator widget.
  383. //
  384. // Since: 2.0
  385. func SeparatorThicknessSize() float32 {
  386. return current().Size(SizeNameSeparatorThickness)
  387. }
  388. // ShadowColor returns the color (and translucency) for shadows used for indicating elevation.
  389. func ShadowColor() color.Color {
  390. return safeColorLookup(ColorNameShadow, currentVariant())
  391. }
  392. // SuccessColor returns the theme's success foreground color.
  393. //
  394. // Since: 2.3
  395. func SuccessColor() color.Color {
  396. return safeColorLookup(ColorNameSuccess, currentVariant())
  397. }
  398. // TextBoldFont returns the font resource for the bold font style.
  399. func TextBoldFont() fyne.Resource {
  400. return safeFontLookup(fyne.TextStyle{Bold: true})
  401. }
  402. // TextBoldItalicFont returns the font resource for the bold and italic font style.
  403. func TextBoldItalicFont() fyne.Resource {
  404. return safeFontLookup(fyne.TextStyle{Bold: true, Italic: true})
  405. }
  406. // TextColor returns the theme's standard text color - this is actually the foreground color since 1.4.
  407. //
  408. // Deprecated: Use theme.ForegroundColor() colour instead.
  409. func TextColor() color.Color {
  410. return safeColorLookup(ColorNameForeground, currentVariant())
  411. }
  412. // TextFont returns the font resource for the regular font style.
  413. func TextFont() fyne.Resource {
  414. return safeFontLookup(fyne.TextStyle{})
  415. }
  416. // TextHeadingSize returns the text size for header text.
  417. //
  418. // Since: 2.1
  419. func TextHeadingSize() float32 {
  420. return current().Size(SizeNameHeadingText)
  421. }
  422. // TextItalicFont returns the font resource for the italic font style.
  423. func TextItalicFont() fyne.Resource {
  424. return safeFontLookup(fyne.TextStyle{Italic: true})
  425. }
  426. // TextMonospaceFont returns the font resource for the monospace font face.
  427. func TextMonospaceFont() fyne.Resource {
  428. return safeFontLookup(fyne.TextStyle{Monospace: true})
  429. }
  430. // TextSize returns the standard text size.
  431. func TextSize() float32 {
  432. return current().Size(SizeNameText)
  433. }
  434. // TextSubHeadingSize returns the text size for sub-header text.
  435. //
  436. // Since: 2.1
  437. func TextSubHeadingSize() float32 {
  438. return current().Size(SizeNameSubHeadingText)
  439. }
  440. // WarningColor returns the theme's warning foreground color.
  441. //
  442. // Since: 2.3
  443. func WarningColor() color.Color {
  444. return safeColorLookup(ColorNameWarning, currentVariant())
  445. }
  446. var (
  447. defaultTheme fyne.Theme
  448. errorColor = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff}
  449. successColor = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff}
  450. warningColor = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff}
  451. )
  452. type builtinTheme struct {
  453. variant fyne.ThemeVariant
  454. regular, bold, italic, boldItalic, monospace fyne.Resource
  455. }
  456. func (t *builtinTheme) initFonts() {
  457. t.regular = regular
  458. t.bold = bold
  459. t.italic = italic
  460. t.boldItalic = bolditalic
  461. t.monospace = monospace
  462. font := os.Getenv("FYNE_FONT")
  463. if font != "" {
  464. t.regular = loadCustomFont(font, "Regular", regular)
  465. if t.regular == regular { // failed to load
  466. t.bold = loadCustomFont(font, "Bold", bold)
  467. t.italic = loadCustomFont(font, "Italic", italic)
  468. t.boldItalic = loadCustomFont(font, "BoldItalic", bolditalic)
  469. } else { // first custom font loaded, fall back to that
  470. t.bold = loadCustomFont(font, "Bold", t.regular)
  471. t.italic = loadCustomFont(font, "Italic", t.regular)
  472. t.boldItalic = loadCustomFont(font, "BoldItalic", t.regular)
  473. }
  474. }
  475. font = os.Getenv("FYNE_FONT_MONOSPACE")
  476. if font != "" {
  477. t.monospace = loadCustomFont(font, "Regular", monospace)
  478. }
  479. }
  480. func (t *builtinTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
  481. if t.variant != variantNameUserPreference {
  482. v = t.variant
  483. }
  484. primary := fyne.CurrentApp().Settings().PrimaryColor()
  485. if n == ColorNamePrimary {
  486. return primaryColorNamed(primary)
  487. } else if n == ColorNameFocus {
  488. return focusColorNamed(primary)
  489. } else if n == ColorNameSelection {
  490. return selectionColorNamed(primary)
  491. }
  492. if v == VariantLight {
  493. return lightPaletColorNamed(n)
  494. }
  495. return darkPaletColorNamed(n)
  496. }
  497. func (t *builtinTheme) Font(style fyne.TextStyle) fyne.Resource {
  498. if style.Monospace {
  499. return t.monospace
  500. }
  501. if style.Bold {
  502. if style.Italic {
  503. return t.boldItalic
  504. }
  505. return t.bold
  506. }
  507. if style.Italic {
  508. return t.italic
  509. }
  510. return t.regular
  511. }
  512. func (t *builtinTheme) Size(s fyne.ThemeSizeName) float32 {
  513. switch s {
  514. case SizeNameSeparatorThickness:
  515. return 1
  516. case SizeNameInlineIcon:
  517. return 20
  518. case SizeNameInnerPadding:
  519. return 8
  520. case SizeNameLineSpacing:
  521. return 4
  522. case SizeNamePadding:
  523. return 6
  524. case SizeNameScrollBar:
  525. return 16
  526. case SizeNameScrollBarSmall:
  527. return 3
  528. case SizeNameText:
  529. return 13
  530. case SizeNameHeadingText:
  531. return 24
  532. case SizeNameSubHeadingText:
  533. return 18
  534. case SizeNameCaptionText:
  535. return 11
  536. case SizeNameInputBorder:
  537. return 1
  538. default:
  539. return 0
  540. }
  541. }
  542. func current() fyne.Theme {
  543. if fyne.CurrentApp() == nil || fyne.CurrentApp().Settings().Theme() == nil {
  544. return DarkTheme()
  545. }
  546. return fyne.CurrentApp().Settings().Theme()
  547. }
  548. func currentVariant() fyne.ThemeVariant {
  549. if std, ok := current().(*builtinTheme); ok {
  550. if std.variant != variantNameUserPreference {
  551. return std.variant // override if using the old LightTheme() or DarkTheme() constructor
  552. }
  553. }
  554. return fyne.CurrentApp().Settings().ThemeVariant()
  555. }
  556. func darkPaletColorNamed(name fyne.ThemeColorName) color.Color {
  557. switch name {
  558. case ColorNameBackground:
  559. return color.NRGBA{R: 0x14, G: 0x14, B: 0x15, A: 0xff}
  560. case ColorNameButton:
  561. return color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff}
  562. case ColorNameDisabled:
  563. return color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff}
  564. case ColorNameDisabledButton:
  565. return color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff}
  566. case ColorNameError:
  567. return errorColor
  568. case ColorNameForeground:
  569. return color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff}
  570. case ColorNameHover:
  571. return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x0f}
  572. case ColorNameInputBackground:
  573. return color.NRGBA{R: 0x20, G: 0x20, B: 0x23, A: 0xff}
  574. case ColorNameInputBorder:
  575. return color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff}
  576. case ColorNameMenuBackground:
  577. return color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff}
  578. case ColorNameOverlayBackground:
  579. return color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff}
  580. case ColorNamePlaceHolder:
  581. return color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff}
  582. case ColorNamePressed:
  583. return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66}
  584. case ColorNameScrollBar:
  585. return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x99}
  586. case ColorNameSeparator:
  587. return color.NRGBA{R: 0x0, G: 0x0, B: 0x0, A: 0xff}
  588. case ColorNameShadow:
  589. return color.NRGBA{A: 0x66}
  590. case ColorNameSuccess:
  591. return successColor
  592. case ColorNameWarning:
  593. return warningColor
  594. }
  595. return color.Transparent
  596. }
  597. func focusColorNamed(name string) color.NRGBA {
  598. switch name {
  599. case ColorRed:
  600. return color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0x7f}
  601. case ColorOrange:
  602. return color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0x7f}
  603. case ColorYellow:
  604. return color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0x7f}
  605. case ColorGreen:
  606. return color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0x7f}
  607. case ColorPurple:
  608. return color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0x7f}
  609. case ColorBrown:
  610. return color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0x7f}
  611. case ColorGray:
  612. return color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0x7f}
  613. }
  614. // We return the value for ColorBlue for every other value.
  615. // There is no need to have it in the switch above.
  616. return color.NRGBA{R: 0x00, G: 0x6C, B: 0xff, A: 0x2a}
  617. }
  618. func lightPaletColorNamed(name fyne.ThemeColorName) color.Color {
  619. switch name {
  620. case ColorNameBackground:
  621. return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}
  622. case ColorNameButton:
  623. return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff}
  624. case ColorNameDisabled:
  625. return color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff}
  626. case ColorNameDisabledButton:
  627. return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff}
  628. case ColorNameError:
  629. return errorColor
  630. case ColorNameForeground:
  631. return color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff}
  632. case ColorNameHover:
  633. return color.NRGBA{A: 0x0f}
  634. case ColorNameInputBackground:
  635. return color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff}
  636. case ColorNameInputBorder:
  637. return color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff}
  638. case ColorNameMenuBackground:
  639. return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff}
  640. case ColorNameOverlayBackground:
  641. return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}
  642. case ColorNamePlaceHolder:
  643. return color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff}
  644. case ColorNamePressed:
  645. return color.NRGBA{A: 0x19}
  646. case ColorNameScrollBar:
  647. return color.NRGBA{A: 0x99}
  648. case ColorNameSeparator:
  649. return color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff}
  650. case ColorNameShadow:
  651. return color.NRGBA{A: 0x33}
  652. case ColorNameSuccess:
  653. return successColor
  654. case ColorNameWarning:
  655. return warningColor
  656. }
  657. return color.Transparent
  658. }
  659. func loadCustomFont(env, variant string, fallback fyne.Resource) fyne.Resource {
  660. variantPath := strings.Replace(env, "Regular", variant, -1)
  661. res, err := fyne.LoadResourceFromPath(variantPath)
  662. if err != nil {
  663. fyne.LogError("Error loading specified font", err)
  664. return fallback
  665. }
  666. return res
  667. }
  668. func primaryColorNamed(name string) color.NRGBA {
  669. switch name {
  670. case ColorRed:
  671. return color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff}
  672. case ColorOrange:
  673. return color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff}
  674. case ColorYellow:
  675. return color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0xff}
  676. case ColorGreen:
  677. return color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0xff}
  678. case ColorPurple:
  679. return color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0xff}
  680. case ColorBrown:
  681. return color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0xff}
  682. case ColorGray:
  683. return color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0xff}
  684. }
  685. // We return the value for ColorBlue for every other value.
  686. // There is no need to have it in the switch above.
  687. return color.NRGBA{R: 0x29, G: 0x6f, B: 0xf6, A: 0xff}
  688. }
  689. func safeColorLookup(n fyne.ThemeColorName, v fyne.ThemeVariant) color.Color {
  690. col := current().Color(n, v)
  691. if col == nil {
  692. fyne.LogError("Loaded theme returned nil color", nil)
  693. return fallbackColor
  694. }
  695. return col
  696. }
  697. func safeFontLookup(s fyne.TextStyle) fyne.Resource {
  698. font := current().Font(s)
  699. if font != nil {
  700. return font
  701. }
  702. fyne.LogError("Loaded theme returned nil font", nil)
  703. if s.Monospace {
  704. return DefaultTextMonospaceFont()
  705. }
  706. if s.Bold {
  707. if s.Italic {
  708. return DefaultTextBoldItalicFont()
  709. }
  710. return DefaultTextBoldFont()
  711. }
  712. if s.Italic {
  713. return DefaultTextItalicFont()
  714. }
  715. return DefaultTextFont()
  716. }
  717. func selectionColorNamed(name string) color.NRGBA {
  718. switch name {
  719. case ColorRed:
  720. return color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0x3f}
  721. case ColorOrange:
  722. return color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0x3f}
  723. case ColorYellow:
  724. return color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0x3f}
  725. case ColorGreen:
  726. return color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0x3f}
  727. case ColorPurple:
  728. return color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0x3f}
  729. case ColorBrown:
  730. return color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0x3f}
  731. case ColorGray:
  732. return color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0x3f}
  733. }
  734. // We return the value for ColorBlue for every other value.
  735. // There is no need to have it in the switch above.
  736. return color.NRGBA{R: 0x00, G: 0x6C, B: 0xff, A: 0x40}
  737. }
  738. func setupDefaultTheme() fyne.Theme {
  739. theme := &builtinTheme{variant: variantNameUserPreference}
  740. theme.initFonts()
  741. return theme
  742. }