restructure-config #8
| @ -1,5 +1,6 @@ | ||||
| package config | ||||
| 
 | ||||
| // Config can return global configuration parameters. | ||||
| type Config interface { | ||||
| 	// Padding returns the amount of internal padding elements should have. | ||||
| 	// An element's inner content (such as text) should be inset by this | ||||
|  | ||||
| @ -1,48 +0,0 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| 
 | ||||
| var buttonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var selectedButtonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var pressedButtonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 			artist.NewUniform(hex(0x8D9894FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var pressedSelectedButtonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 			artist.NewUniform(hex(0x8D9894FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var disabledButtonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: weakForegroundPattern }, | ||||
| 	artist.Stroke { Pattern: backgroundPattern }) | ||||
							
								
								
									
										167
									
								
								theme/default.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								theme/default.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,167 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "image" | ||||
| import "golang.org/x/image/font" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/defaultfont" | ||||
| 
 | ||||
| // Default is the default theme. | ||||
| type Default struct { } | ||||
| 
 | ||||
| // FontFace returns the default font face. | ||||
| func (Default) FontFace (style FontStyle, size FontSize, c Case) font.Face { | ||||
| 	switch style { | ||||
| 	case FontStyleBold: | ||||
| 		return defaultfont.FaceBold | ||||
| 	case FontStyleItalic: | ||||
| 		return defaultfont.FaceItalic | ||||
| 	case FontStyleBoldItalic: | ||||
| 		return defaultfont.FaceBoldItalic | ||||
| 	default: | ||||
| 		return defaultfont.FaceRegular | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Icon returns an icon from the default set corresponding to the given name. | ||||
| func (Default) Icon (string, Case) artist.Pattern { | ||||
| 	// TODO | ||||
| 	return uhex(0) | ||||
| } | ||||
| 
 | ||||
| // Pattern returns a pattern from the default theme corresponding to the given | ||||
| // pattern ID. | ||||
| func (Default) Pattern ( | ||||
| 	pattern Pattern, | ||||
| 	c Case, | ||||
| 	state PatternState, | ||||
| ) artist.Pattern { | ||||
| 	switch pattern { | ||||
| 	case PatternAccent: | ||||
| 		return accentPattern | ||||
| 	case PatternBackground: | ||||
| 		return backgroundPattern | ||||
| 	case PatternForeground: | ||||
| 		if state.Disabled { | ||||
| 			return weakForegroundPattern | ||||
| 		} else { | ||||
| 			return foregroundPattern | ||||
| 		} | ||||
| 	case PatternDead: | ||||
| 		return deadPattern | ||||
| 	case PatternRaised: | ||||
| 		if c == C("basic", "listEntry") { | ||||
| 			if state.Focused { | ||||
| 				if state.On { | ||||
| 					return focusedOnListEntryPattern | ||||
| 				} else { | ||||
| 					return focusedListEntryPattern | ||||
| 				} | ||||
| 			} else { | ||||
| 				if state.On { | ||||
| 					return onListEntryPattern | ||||
| 				} else { | ||||
| 					return listEntryPattern | ||||
| 				} | ||||
| 			} | ||||
| 		} else { | ||||
| 			if state.Focused { | ||||
| 				return selectedRaisedPattern | ||||
| 			} else { | ||||
| 				return raisedPattern | ||||
| 			} | ||||
| 		} | ||||
| 	case PatternSunken: | ||||
| 		if c == C("basic", "list") { | ||||
| 			if state.Focused { | ||||
| 				return focusedListPattern | ||||
| 			} else { | ||||
| 				return listPattern | ||||
| 			} | ||||
| 		} else { | ||||
| 			return sunkenPattern | ||||
| 		} | ||||
| 	case PatternPinboard: | ||||
| 		return texturedSunkenPattern | ||||
| 	case PatternButton: | ||||
| 		if state.Disabled { | ||||
| 			return disabledButtonPattern | ||||
| 		} else { | ||||
| 			if state.Pressed { | ||||
| 				if state.Focused { | ||||
| 					return pressedSelectedButtonPattern | ||||
| 				} else { | ||||
| 					return pressedButtonPattern | ||||
| 				} | ||||
| 			} else { | ||||
| 				if state.Focused { | ||||
| 					return selectedButtonPattern | ||||
| 				} else { | ||||
| 					return buttonPattern | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	case PatternInput: | ||||
| 		if state.Disabled { | ||||
| 			return disabledInputPattern | ||||
| 		} else { | ||||
| 			if state.Focused { | ||||
| 				return selectedInputPattern | ||||
| 			} else { | ||||
| 				return inputPattern | ||||
| 			} | ||||
| 		} | ||||
| 	case PatternGutter: | ||||
| 		if state.Disabled { | ||||
| 			return disabledScrollGutterPattern | ||||
| 		} else { | ||||
| 			return scrollGutterPattern | ||||
| 		} | ||||
| 	case PatternHandle: | ||||
| 		if state.Disabled { | ||||
| 			return disabledScrollBarPattern | ||||
| 		} else { | ||||
| 			if state.Focused { | ||||
| 				if state.Pressed { | ||||
| 					return pressedSelectedScrollBarPattern | ||||
| 				} else { | ||||
| 					return selectedScrollBarPattern | ||||
| 				} | ||||
| 			} else { | ||||
| 				if state.Pressed { | ||||
| 					return pressedScrollBarPattern | ||||
| 				} else { | ||||
| 					return scrollBarPattern | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	default: | ||||
| 		return uhex(0) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Inset returns the default inset value for the given pattern. | ||||
| func (Default) Inset (pattern Pattern, c Case) Inset { | ||||
| 	switch pattern { | ||||
| 	case PatternRaised: | ||||
| 		if c == C("basic", "listEntry") { | ||||
| 			return Inset { 2, 1, 2, 1 } | ||||
| 		} else { | ||||
| 			return Inset { 1, 1, 1, 1 } | ||||
| 		} | ||||
| 	case PatternSunken: | ||||
| 		if c == C("basic", "list") { | ||||
| 			return Inset { 4, 6, 4, 6 } | ||||
| 		} else { | ||||
| 			return Inset { 1, 1, 1, 1 } | ||||
| 		} | ||||
| 	 | ||||
| 	case PatternInput, PatternButton, PatternHandle, PatternPinboard: | ||||
| 		return Inset { 1, 1, 1, 1} | ||||
| 	default: return Inset { } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Sink returns the default sink vector for the given pattern. | ||||
| func (Default) Sink (pattern Pattern, c Case) image.Point { | ||||
| 	return image.Point { 1, 1 } | ||||
| } | ||||
							
								
								
									
										237
									
								
								theme/defaultpatterns.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								theme/defaultpatterns.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,237 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "image/color" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| 
 | ||||
| var accentPattern         = artist.NewUniform(hex(0x408090FF)) | ||||
| var backgroundPattern     = artist.NewUniform(color.Gray16 { 0xAAAA }) | ||||
| var foregroundPattern     = artist.NewUniform(color.Gray16 { 0x0000 }) | ||||
| var weakForegroundPattern = artist.NewUniform(color.Gray16 { 0x4444 }) | ||||
| var strokePattern         = artist.NewUniform(color.Gray16 { 0x0000 }) | ||||
| 
 | ||||
| var sunkenPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x3b534eFF)), | ||||
| 			artist.NewUniform(hex(0x97a09cFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) }) | ||||
| 
 | ||||
| var texturedSunkenPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x3b534eFF)), | ||||
| 			artist.NewUniform(hex(0x97a09cFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	// artist.Stroke { Pattern: artist.Striped { | ||||
| 		// First: artist.Stroke { | ||||
| 			// Weight: 2, | ||||
| 			// Pattern: artist.NewUniform(hex(0x97a09cFF)), | ||||
| 		// }, | ||||
| 		// Second: artist.Stroke { | ||||
| 			// Weight: 1, | ||||
| 			// Pattern: artist.NewUniform(hex(0x6e8079FF)), | ||||
| 		// }, | ||||
| 	// }}) | ||||
| 	 | ||||
| 	artist.Stroke { Pattern: artist.Noisy { | ||||
| 		Low:  artist.NewUniform(hex(0x97a09cFF)), | ||||
| 		High: artist.NewUniform(hex(0x6e8079FF)), | ||||
| 	}}) | ||||
| 
 | ||||
| var raisedPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xDBDBDBFF)), | ||||
| 			artist.NewUniform(hex(0x383C3AFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0xAAAAAAFF)) }) | ||||
| 
 | ||||
| var selectedRaisedPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xDBDBDBFF)), | ||||
| 			artist.NewUniform(hex(0x383C3AFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0xAAAAAAFF)) }) | ||||
| 
 | ||||
| var deadPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) }) | ||||
| 
 | ||||
| var buttonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var selectedButtonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| 
 | ||||
| var pressedButtonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 			artist.NewUniform(hex(0x8D9894FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var pressedSelectedButtonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 			artist.NewUniform(hex(0x8D9894FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var disabledButtonPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: weakForegroundPattern }, | ||||
| 	artist.Stroke { Pattern: backgroundPattern }) | ||||
| 
 | ||||
| var inputPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x89925AFF)), | ||||
| 			artist.NewUniform(hex(0xD2CB9AFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0xD2CB9AFF)) }) | ||||
| var selectedInputPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0xD2CB9AFF)) }) | ||||
| var disabledInputPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: weakForegroundPattern }, | ||||
| 	artist.Stroke { Pattern: backgroundPattern }) | ||||
| 
 | ||||
| var listPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			uhex(0x383C3AFF), | ||||
| 			uhex(0x999C99FF), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: uhex(0x999C99FF) }) | ||||
| 
 | ||||
| var focusedListPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: uhex(0x999C99FF) }) | ||||
| 
 | ||||
| var listEntryPattern = artist.Padded { | ||||
| 	Stroke: uhex(0x383C3AFF), | ||||
| 	Fill:   uhex(0x999C99FF), | ||||
| 	Sides:  []int { 0, 0, 0, 1 }, | ||||
| } | ||||
| 
 | ||||
| var onListEntryPattern = artist.Padded { | ||||
| 	Stroke: uhex(0x383C3AFF), | ||||
| 	Fill:   uhex(0x6e8079FF), | ||||
| 	Sides:  []int { 0, 0, 0, 1 }, | ||||
| } | ||||
| 
 | ||||
| var focusedListEntryPattern = artist.Padded { | ||||
| 	Stroke: accentPattern, | ||||
| 	Fill:   uhex(0x999C99FF), | ||||
| 	Sides:  []int { 0, 1, 0, 1 }, | ||||
| } | ||||
| 
 | ||||
| var focusedOnListEntryPattern = artist.Padded { | ||||
| 	Stroke: accentPattern, | ||||
| 	Fill:   uhex(0x6e8079FF), | ||||
| 	Sides:  []int { 0, 1, 0, 1 }, | ||||
| } | ||||
| 
 | ||||
| var scrollGutterPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x3b534eFF)), | ||||
| 			artist.NewUniform(hex(0x6e8079FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x6e8079FF)) }) | ||||
| var disabledScrollGutterPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: weakForegroundPattern }, | ||||
| 	artist.Stroke { Pattern: backgroundPattern }) | ||||
| var scrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var selectedScrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var pressedScrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: artist.NewUniform(hex(0x8D9894FF)) }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x7f8c89FF)) }) | ||||
| var pressedSelectedScrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x7f8c89FF)) }) | ||||
| var disabledScrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: weakForegroundPattern }, | ||||
| 	artist.Stroke { Pattern: backgroundPattern }) | ||||
| @ -1,21 +0,0 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| 
 | ||||
| var inputPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x89925AFF)), | ||||
| 			artist.NewUniform(hex(0xD2CB9AFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0xD2CB9AFF)) }) | ||||
| var selectedInputPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0xD2CB9AFF)) }) | ||||
| var disabledInputPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: weakForegroundPattern }, | ||||
| 	artist.Stroke { Pattern: backgroundPattern }) | ||||
							
								
								
									
										42
									
								
								theme/inset.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								theme/inset.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "image" | ||||
| 
 | ||||
| // Inset represents an inset amount for all four sides of a rectangle. The top | ||||
| // side is at index zero, the right at index one, the bottom at index two, and | ||||
| // the left at index three. These values may be negative. | ||||
| type Inset [4]int | ||||
| 
 | ||||
| // Apply returns the given rectangle, shrunk on all four sides by the given | ||||
| // inset. If a measurment of the inset is negative, that side will instead be | ||||
| // expanded outward. If the rectangle's dimensions cannot be reduced any | ||||
| // further, an empty rectangle near its center will be returned. | ||||
| func (inset Inset) Apply (bigger image.Rectangle) (smaller image.Rectangle) { | ||||
| 	smaller = bigger | ||||
| 	if smaller.Dx() < inset[3] + inset[1] { | ||||
| 		smaller.Min.X = (smaller.Min.X + smaller.Max.X) / 2 | ||||
| 		smaller.Max.X = smaller.Min.X | ||||
| 	} else { | ||||
| 		smaller.Min.X += inset[3] | ||||
| 		smaller.Max.X -= inset[1] | ||||
| 	} | ||||
| 
 | ||||
| 	if smaller.Dy() < inset[0] + inset[2] { | ||||
| 		smaller.Min.Y = (smaller.Min.Y + smaller.Max.Y) / 2 | ||||
| 		smaller.Max.Y = smaller.Min.Y | ||||
| 	} else { | ||||
| 		smaller.Min.Y += inset[0] | ||||
| 		smaller.Max.Y -= inset[2] | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Inverse returns a negated version of the inset. | ||||
| func (inset Inset) Inverse () (prime Inset) { | ||||
| 	return Inset { | ||||
| 		inset[0] * -1, | ||||
| 		inset[1] * -1, | ||||
| 		inset[2] * -1, | ||||
| 		inset[3] * -1, | ||||
| 	} | ||||
| } | ||||
| @ -1,43 +0,0 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| 
 | ||||
| var listPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			uhex(0x383C3AFF), | ||||
| 			uhex(0x999C99FF), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: uhex(0x999C99FF) }) | ||||
| 
 | ||||
| var focusedListPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: uhex(0x999C99FF) }) | ||||
| 
 | ||||
| var listEntryPattern = artist.Padded { | ||||
| 	Stroke: uhex(0x383C3AFF), | ||||
| 	Fill:   uhex(0x999C99FF), | ||||
| 	Sides:  []int { 0, 0, 0, 1 }, | ||||
| } | ||||
| 
 | ||||
| var onListEntryPattern = artist.Padded { | ||||
| 	Stroke: uhex(0x383C3AFF), | ||||
| 	Fill:   uhex(0x6e8079FF), | ||||
| 	Sides:  []int { 0, 0, 0, 1 }, | ||||
| } | ||||
| 
 | ||||
| var focusedListEntryPattern = artist.Padded { | ||||
| 	Stroke: accentPattern, | ||||
| 	Fill:   uhex(0x999C99FF), | ||||
| 	Sides:  []int { 0, 1, 0, 1 }, | ||||
| } | ||||
| 
 | ||||
| var focusedOnListEntryPattern = artist.Padded { | ||||
| 	Stroke: accentPattern, | ||||
| 	Fill:   uhex(0x6e8079FF), | ||||
| 	Sides:  []int { 0, 1, 0, 1 }, | ||||
| } | ||||
							
								
								
									
										9
									
								
								theme/parse.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								theme/parse.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,9 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "io" | ||||
| 
 | ||||
| // Parse parses a theme file and returns it as a Theme. | ||||
| func Parse (io.Reader) (Theme) { | ||||
| 	// TODO | ||||
| 	return Default { } | ||||
| } | ||||
| @ -1,239 +0,0 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "image" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| 
 | ||||
| // Case sepecifies what kind of element is using a pattern. It contains a | ||||
| // namespace parameter and an element parameter. The element parameter does not | ||||
| // necissarily need to match an element name, but if it can, it should. Both | ||||
| // parameters should be written in camel case. Themes can change their styling | ||||
| // based on this parameter for fine-grained control over the look and feel of | ||||
| // specific elements. | ||||
| type Case struct { Namespace, Element string }  | ||||
|   | ||||
| // C can be used as shorthand to generate a case struct as used in PatternState. | ||||
| func C (namespace, element string) (c Case) { | ||||
| 	return Case { | ||||
| 		Namespace: namespace, | ||||
| 		Element: element, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // PatternState lists parameters which can change the appearance of some | ||||
| // patterns. For example, passing a PatternState with Selected set to true may | ||||
| // result in a pattern that has a colored border within it. | ||||
| type PatternState struct { | ||||
| 	Case | ||||
| 
 | ||||
| 	// On should be set to true if the element that is using this pattern is | ||||
| 	// in some sort of "on" state, such as if a checkbox is checked or a | ||||
| 	// switch is toggled on. This is only necessary if the element in | ||||
| 	// question is capable of being toggled. | ||||
| 	On bool | ||||
| 
 | ||||
| 	// Focused should be set to true if the element that is using this | ||||
| 	// pattern is currently focused. | ||||
| 	Focused bool | ||||
| 
 | ||||
| 	// Pressed should be set to true if the element that is using this | ||||
| 	// pattern is being pressed down by the mouse. This is only necessary if | ||||
| 	// the element in question processes mouse button events. | ||||
| 	Pressed bool | ||||
| 
 | ||||
| 	// Disabled should be set to true if the element that is using this | ||||
| 	// pattern is locked and cannot be interacted with. Disabled variations | ||||
| 	// of patterns are typically flattened and greyed-out. | ||||
| 	Disabled bool | ||||
| 
 | ||||
| 	// Invalid should be set to true if th element that is using this | ||||
| 	// pattern wants to warn the user of an invalid interaction or data | ||||
| 	// entry. Invalid variations typically have some sort of reddish tint | ||||
| 	// or outline. | ||||
| 	Invalid bool | ||||
| } | ||||
| 
 | ||||
| // Inset represents an inset amount for all four sides of a rectangle. The top | ||||
| // side is at index zero, the right at index one, the bottom at index two, and | ||||
| // the left at index three. These values may be negative. | ||||
| type Inset [4]int | ||||
| 
 | ||||
| // Apply returns the given rectangle, shrunk on all four sides by the given | ||||
| // inset. If a measurment of the inset is negative, that side will instead be | ||||
| // expanded outward. If the rectangle's dimensions cannot be reduced any | ||||
| // further, an empty rectangle near its center will be returned. | ||||
| func (inset Inset) Apply (bigger image.Rectangle) (smaller image.Rectangle) { | ||||
| 	smaller = bigger | ||||
| 	if smaller.Dx() < inset[3] + inset[1] { | ||||
| 		smaller.Min.X = (smaller.Min.X + smaller.Max.X) / 2 | ||||
| 		smaller.Max.X = smaller.Min.X | ||||
| 	} else { | ||||
| 		smaller.Min.X += inset[3] | ||||
| 		smaller.Max.X -= inset[1] | ||||
| 	} | ||||
| 
 | ||||
| 	if smaller.Dy() < inset[0] + inset[2] { | ||||
| 		smaller.Min.Y = (smaller.Min.Y + smaller.Max.Y) / 2 | ||||
| 		smaller.Max.Y = smaller.Min.Y | ||||
| 	} else { | ||||
| 		smaller.Min.Y += inset[0] | ||||
| 		smaller.Max.Y -= inset[2] | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // Inverse returns a negated version of the inset. | ||||
| func (inset Inset) Inverse () (prime Inset) { | ||||
| 	return Inset { | ||||
| 		inset[0] * -1, | ||||
| 		inset[1] * -1, | ||||
| 		inset[2] * -1, | ||||
| 		inset[3] * -1, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // AccentPattern returns the accent pattern, which is usually just a solid | ||||
| // color. | ||||
| func AccentPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	return accentPattern, Inset { } | ||||
| } | ||||
| 
 | ||||
| // BackgroundPattern returns the main background pattern. | ||||
| func BackgroundPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	return backgroundPattern, Inset { } | ||||
| } | ||||
| 
 | ||||
| // DeadPattern returns a pattern that can be used to mark an area or gap that | ||||
| // serves no purpose, but still needs aesthetic structure. | ||||
| func DeadPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	return deadPattern, Inset { } | ||||
| } | ||||
| 
 | ||||
| // ForegroundPattern returns the color text should be. | ||||
| func ForegroundPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	if state.Disabled { | ||||
| 		return weakForegroundPattern, Inset { } | ||||
| 	} else { | ||||
| 		return foregroundPattern, Inset { } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // InputPattern returns a background pattern for any input field that can be | ||||
| // edited by typing with the keyboard. | ||||
| func InputPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	if state.Disabled { | ||||
| 		return disabledInputPattern, Inset { 1, 1, 1, 1 } | ||||
| 	} else { | ||||
| 		if state.Focused { | ||||
| 			return selectedInputPattern, Inset { 1, 1, 1, 1 } | ||||
| 		} else { | ||||
| 			return inputPattern, Inset { 1, 1, 1, 1 } | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // ListPattern returns a background pattern for a list of things. | ||||
| func ListPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	if state.Focused { | ||||
| 		pattern = focusedListPattern | ||||
| 		inset = Inset { 2, 1, 2, 1 } | ||||
| 	} else { | ||||
| 		pattern = listPattern | ||||
| 		inset = Inset { 2, 1, 1, 1 } | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // ItemPattern returns a background pattern for a list item. | ||||
| func ItemPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	if state.Focused { | ||||
| 		if state.On { | ||||
| 			pattern = focusedOnListEntryPattern | ||||
| 		} else { | ||||
| 			pattern = focusedListEntryPattern | ||||
| 		} | ||||
| 	} else { | ||||
| 		if state.On { | ||||
| 			pattern = onListEntryPattern | ||||
| 		} else { | ||||
| 			pattern = listEntryPattern | ||||
| 		} | ||||
| 	} | ||||
| 	inset = Inset { 4, 6, 4, 6 } | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| // ButtonPattern returns a pattern to be displayed on buttons. | ||||
| func ButtonPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	if state.Disabled { | ||||
| 		return disabledButtonPattern, Inset { 1, 1, 1, 1 } | ||||
| 	} else { | ||||
| 		if state.Pressed { | ||||
| 			if state.Focused { | ||||
| 				return pressedSelectedButtonPattern, Inset { | ||||
| 					2, 0, 0, 2 } | ||||
| 			} else { | ||||
| 				return pressedButtonPattern, Inset { 2, 0, 0, 2 } | ||||
| 			} | ||||
| 		} else { | ||||
| 			if state.Focused { | ||||
| 				return selectedButtonPattern, Inset { 1, 1, 1, 1 } | ||||
| 			} else { | ||||
| 				return buttonPattern, Inset { 1, 1, 1, 1 } | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GutterPattern returns a pattern to be used to mark a track along which | ||||
| // something slides. | ||||
| func GutterPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	if state.Disabled { | ||||
| 		return disabledScrollGutterPattern, Inset { 0, 0, 0, 0 } | ||||
| 	} else { | ||||
| 		return scrollGutterPattern, Inset { 0, 0, 0, 0 } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // HandlePattern returns a pattern to be displayed on a grab handle that slides | ||||
| // along a gutter. | ||||
| func HandlePattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	if state.Disabled { | ||||
| 		return disabledScrollBarPattern, Inset { 1, 1, 1, 1 } | ||||
| 	} else { | ||||
| 		if state.Focused { | ||||
| 			if state.Pressed { | ||||
| 				return pressedSelectedScrollBarPattern, Inset { 1, 1, 1, 1 } | ||||
| 			} else { | ||||
| 				return selectedScrollBarPattern, Inset { 1, 1, 1, 1 } | ||||
| 			} | ||||
| 		} else { | ||||
| 			if state.Pressed { | ||||
| 				return pressedScrollBarPattern, Inset { 1, 1, 1, 1 } | ||||
| 			} else { | ||||
| 				return scrollBarPattern, Inset { 1, 1, 1, 1 } | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // SunkenPattern returns a general purpose pattern that is sunken/engraved into | ||||
| // the background. | ||||
| func SunkenPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	return sunkenPattern, Inset { 1, 1, 1, 1 } | ||||
| } | ||||
| 
 | ||||
| // RaisedPattern returns a general purpose pattern that is raised up out of the | ||||
| // background. | ||||
| func RaisedPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	if state.Focused { | ||||
| 		return selectedRaisedPattern, Inset { 1, 1, 1, 1 } | ||||
| 	} else { | ||||
| 		return raisedPattern, Inset { 1, 1, 1, 1 } | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // PinboardPattern returns a textured backdrop pattern. Anything drawn within it | ||||
| // should have its own background pattern. | ||||
| func PinboardPattern (state PatternState) (pattern artist.Pattern, inset Inset) { | ||||
| 	return texturedSunkenPattern, Inset { 1, 1, 1, 1 } | ||||
| } | ||||
| @ -1,63 +0,0 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| 
 | ||||
| var scrollGutterPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x3b534eFF)), | ||||
| 			artist.NewUniform(hex(0x6e8079FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x6e8079FF)) }) | ||||
| var disabledScrollGutterPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: weakForegroundPattern }, | ||||
| 	artist.Stroke { Pattern: backgroundPattern }) | ||||
| var scrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var selectedScrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x8D9894FF)) }) | ||||
| var pressedScrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: artist.NewUniform(hex(0x8D9894FF)) }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x7f8c89FF)) }) | ||||
| var pressedSelectedScrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xCCD5D2FF)), | ||||
| 			artist.NewUniform(hex(0x4B5B59FF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x7f8c89FF)) }) | ||||
| var disabledScrollBarPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: weakForegroundPattern }, | ||||
| 	artist.Stroke { Pattern: backgroundPattern }) | ||||
							
								
								
									
										48
									
								
								theme/state.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								theme/state.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| package theme | ||||
| 
 | ||||
| // Case sepecifies what kind of element is using a pattern. It contains a | ||||
| // namespace parameter and an element parameter. The element parameter does not | ||||
| // necissarily need to match an element name, but if it can, it should. Both | ||||
| // parameters should be written in camel case. Themes can change their styling | ||||
| // based on this parameter for fine-grained control over the look and feel of | ||||
| // specific elements. | ||||
| type Case struct { Namespace, Element string }  | ||||
|   | ||||
| // C can be used as shorthand to generate a case struct as used in PatternState. | ||||
| func C (namespace, element string) (c Case) { | ||||
| 	return Case { | ||||
| 		Namespace: namespace, | ||||
| 		Element: element, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // PatternState lists parameters which can change the appearance of some | ||||
| // patterns. For example, passing a PatternState with Selected set to true may | ||||
| // result in a pattern that has a colored border within it. | ||||
| type PatternState struct { | ||||
| 	// On should be set to true if the element that is using this pattern is | ||||
| 	// in some sort of "on" state, such as if a checkbox is checked or a | ||||
| 	// switch is toggled on. This is only necessary if the element in | ||||
| 	// question is capable of being toggled. | ||||
| 	On bool | ||||
| 
 | ||||
| 	// Focused should be set to true if the element that is using this | ||||
| 	// pattern is currently focused. | ||||
| 	Focused bool | ||||
| 
 | ||||
| 	// Pressed should be set to true if the element that is using this | ||||
| 	// pattern is being pressed down by the mouse. This is only necessary if | ||||
| 	// the element in question processes mouse button events. | ||||
| 	Pressed bool | ||||
| 
 | ||||
| 	// Disabled should be set to true if the element that is using this | ||||
| 	// pattern is locked and cannot be interacted with. Disabled variations | ||||
| 	// of patterns are typically flattened and greyed-out. | ||||
| 	Disabled bool | ||||
| 
 | ||||
| 	// Invalid should be set to true if th element that is using this | ||||
| 	// pattern wants to warn the user of an invalid interaction or data | ||||
| 	// entry. Invalid variations typically have some sort of reddish tint | ||||
| 	// or outline. | ||||
| 	Invalid bool | ||||
| } | ||||
							
								
								
									
										199
									
								
								theme/theme.go
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								theme/theme.go
									
									
									
									
									
								
							| @ -1,113 +1,100 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "image/color" | ||||
| import "image" | ||||
| import "golang.org/x/image/font" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/defaultfont" | ||||
| 
 | ||||
| // none of these colors are final! TODO: generate these values from a theme | ||||
| // file at startup. | ||||
| // FontStyle specifies stylistic alterations to a font face. | ||||
| type FontStyle int; const ( | ||||
| 	FontStyleRegular    FontStyle = 0 | ||||
| 	FontStyleBold       FontStyle = 1 | ||||
| 	FontStyleItalic     FontStyle = 2 | ||||
| 	FontStyleBoldItalic FontStyle = 1 | 2 | ||||
| ) | ||||
| 
 | ||||
| func hex (color uint32) (c color.RGBA) { | ||||
| 	c.A = uint8(color) | ||||
| 	c.B = uint8(color >>  8) | ||||
| 	c.G = uint8(color >> 16) | ||||
| 	c.R = uint8(color >> 24) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func uhex (color uint32) (pattern artist.Pattern) { | ||||
| 	return artist.NewUniform(hex(color)) | ||||
| } | ||||
| 
 | ||||
| var accentPattern         = artist.NewUniform(hex(0x408090FF)) | ||||
| var backgroundPattern     = artist.NewUniform(color.Gray16 { 0xAAAA }) | ||||
| var foregroundPattern     = artist.NewUniform(color.Gray16 { 0x0000 }) | ||||
| var weakForegroundPattern = artist.NewUniform(color.Gray16 { 0x4444 }) | ||||
| var strokePattern         = artist.NewUniform(color.Gray16 { 0x0000 }) | ||||
| 
 | ||||
| var sunkenPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x3b534eFF)), | ||||
| 			artist.NewUniform(hex(0x97a09cFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) }) | ||||
| 
 | ||||
| var texturedSunkenPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0x3b534eFF)), | ||||
| 			artist.NewUniform(hex(0x97a09cFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	// artist.Stroke { Pattern: artist.Striped { | ||||
| 		// First: artist.Stroke { | ||||
| 			// Weight: 2, | ||||
| 			// Pattern: artist.NewUniform(hex(0x97a09cFF)), | ||||
| 		// }, | ||||
| 		// Second: artist.Stroke { | ||||
| 			// Weight: 1, | ||||
| 			// Pattern: artist.NewUniform(hex(0x6e8079FF)), | ||||
| 		// }, | ||||
| 	// }}) | ||||
| 	 | ||||
| 	artist.Stroke { Pattern: artist.Noisy { | ||||
| 		Low:  artist.NewUniform(hex(0x97a09cFF)), | ||||
| 		High: artist.NewUniform(hex(0x6e8079FF)), | ||||
| 	}}) | ||||
| 
 | ||||
| var raisedPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xDBDBDBFF)), | ||||
| 			artist.NewUniform(hex(0x383C3AFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0xAAAAAAFF)) }) | ||||
| 
 | ||||
| var selectedRaisedPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { | ||||
| 		Weight: 1, | ||||
| 		Pattern: artist.Beveled { | ||||
| 			artist.NewUniform(hex(0xDBDBDBFF)), | ||||
| 			artist.NewUniform(hex(0x383C3AFF)), | ||||
| 		}, | ||||
| 	}, | ||||
| 	artist.Stroke { Weight: 1, Pattern: accentPattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0xAAAAAAFF)) }) | ||||
| 
 | ||||
| var deadPattern = artist.NewMultiBordered ( | ||||
| 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) }) | ||||
| 
 | ||||
| // TODO: load fonts from an actual source instead of using defaultfont | ||||
| 
 | ||||
| // FontFaceRegular returns the font face to be used for normal text. | ||||
| func FontFaceRegular () font.Face { | ||||
| 	return defaultfont.FaceRegular | ||||
| } | ||||
| 
 | ||||
| // FontFaceBold returns the font face to be used for bolded text. | ||||
| func FontFaceBold () font.Face { | ||||
| 	return defaultfont.FaceBold | ||||
| } | ||||
| 
 | ||||
| // FontFaceItalic returns the font face to be used for italicized text. | ||||
| func FontFaceItalic () font.Face { | ||||
| 	return defaultfont.FaceItalic | ||||
| } | ||||
| 
 | ||||
| // FontFaceBoldItalic returns the font face to be used for text that is both | ||||
| // bolded and italicized. | ||||
| func FontFaceBoldItalic () font.Face { | ||||
| 	return defaultfont.FaceBoldItalic | ||||
| // FontSize specifies the general size of a font face in a semantic way. | ||||
| type FontSize int; const ( | ||||
| 	// FontSizeNormal is the default font size that should be used for most | ||||
| 	// things. | ||||
| 	FontSizeNormal FontSize = iota | ||||
| 
 | ||||
| 	// FontSizeLarge is a larger font size suitable for things like section | ||||
| 	// headings. | ||||
| 	FontSizeLarge | ||||
| 
 | ||||
| 	// FontSizeHuge is a very large font size suitable for things like | ||||
| 	// titles, wizard step names, digital clocks, etc. | ||||
| 	FontSizeHuge | ||||
| 
 | ||||
| 	// FontSizeSmall is a smaller font size. Try not to use this unless it | ||||
| 	// makes a lot of sense to do so, because it can negatively impact | ||||
| 	// accessibility. It is useful for things like copyright notices at the | ||||
| 	// bottom of some window that the average user doesn't actually care | ||||
| 	// about. | ||||
| 	FontSizeSmall | ||||
| ) | ||||
| 
 | ||||
| // Pattern lists a number of cannonical pattern types, each with its own ID. | ||||
| // This allows custom elements to follow themes, even those that do not | ||||
| // explicitly support them. | ||||
| type Pattern int; const ( | ||||
| 	// PatternAccent is the accent color of the theme. It is safe to assume | ||||
| 	// that this is, by default, a solid color. | ||||
| 	PatternAccent Pattern = iota | ||||
| 
 | ||||
| 	// PatternBackground is the background color of the theme. It is safe to | ||||
| 	// assume that this is, by default, a solid color. | ||||
| 	PatternBackground | ||||
| 
 | ||||
| 	// PatternForeground is the foreground text color of the theme. It is | ||||
| 	// safe to assume that this is, by default, a solid color. | ||||
| 	PatternForeground | ||||
| 
 | ||||
| 	// PatternDead is a pattern that is displayed on a "dead area" where no | ||||
| 	// controls exist, but there still must be some indication of visual | ||||
| 	// structure (such as in the corner between two scroll bars). | ||||
| 	PatternDead | ||||
| 
 | ||||
| 	// PatternRaised is a generic raised pattern. | ||||
| 	PatternRaised | ||||
| 
 | ||||
| 	// PatternSunken is a generic sunken pattern. | ||||
| 	PatternSunken | ||||
| 
 | ||||
| 	// PatternPinboard is similar to PatternSunken, but it is textured. | ||||
| 	PatternPinboard | ||||
| 
 | ||||
| 	// PatternButton is a button pattern. | ||||
| 	PatternButton | ||||
| 
 | ||||
| 	// PatternInput is a pattern for input fields, editable text areas, etc. | ||||
| 	PatternInput | ||||
| 
 | ||||
| 	// PatternGutter is a track for things to slide on. | ||||
| 	PatternGutter | ||||
| 
 | ||||
| 	// PatternHandle is a handle that slides along a gutter. | ||||
| 	PatternHandle | ||||
| ) | ||||
| 
 | ||||
| // Theme represents a visual style configuration, | ||||
| type Theme interface { | ||||
| 	// FontFace returns the proper font for a given style, size, and case. | ||||
| 	FontFace (FontStyle, FontSize, Case) font.Face | ||||
| 
 | ||||
| 	// Icon returns an appropriate icon given an icon name and case. | ||||
| 	Icon (string, Case) artist.Pattern | ||||
| 
 | ||||
| 	// Pattern returns an appropriate pattern given a pattern name, case, | ||||
| 	// and state. | ||||
| 	Pattern (Pattern, Case, PatternState) artist.Pattern | ||||
| 
 | ||||
| 	// Inset returns the area on all sides of a given pattern that is not | ||||
| 	// meant to be drawn on. | ||||
| 	Inset (Pattern, Case) Inset | ||||
| 
 | ||||
| 	// Sink returns a vector that should be added to an element's inner | ||||
| 	// content when it is pressed down (if applicable) to simulate a 3D | ||||
| 	// sinking effect. | ||||
| 	Sink (Pattern, Case) image.Point | ||||
| } | ||||
|  | ||||
							
								
								
									
										16
									
								
								theme/util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								theme/util.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| package theme | ||||
| 
 | ||||
| import "image/color" | ||||
| import "git.tebibyte.media/sashakoshka/tomo/artist" | ||||
| 
 | ||||
| func hex (color uint32) (c color.RGBA) { | ||||
| 	c.A = uint8(color) | ||||
| 	c.B = uint8(color >>  8) | ||||
| 	c.G = uint8(color >> 16) | ||||
| 	c.R = uint8(color >> 24) | ||||
| 	return | ||||
| } | ||||
| 
 | ||||
| func uhex (color uint32) (pattern artist.Pattern) { | ||||
| 	return artist.NewUniform(hex(color)) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user