Various improvements to list
This commit is contained in:
		
							parent
							
								
									24bcd6977a
								
							
						
					
					
						commit
						468d4e9dab
					
				| @ -11,11 +11,15 @@ import "git.tebibyte.media/sashakoshka/tomo/elements/core" | |||||||
| type List struct { | type List struct { | ||||||
| 	*core.Core | 	*core.Core | ||||||
| 	core core.CoreControl | 	core core.CoreControl | ||||||
|  | 	 | ||||||
| 	enabled bool | 	enabled bool | ||||||
| 	selected bool | 	selected bool | ||||||
|  | 	pressed bool | ||||||
|  | 	 | ||||||
| 	contentHeight int | 	contentHeight int | ||||||
| 	forcedMinimumWidth  int | 	forcedMinimumWidth  int | ||||||
| 	forcedMinimumHeight int | 	forcedMinimumHeight int | ||||||
|  | 	 | ||||||
| 	selectedEntry int | 	selectedEntry int | ||||||
| 	scroll int | 	scroll int | ||||||
| 	entries []ListEntry | 	entries []ListEntry | ||||||
| @ -28,7 +32,7 @@ type List struct { | |||||||
| 
 | 
 | ||||||
| // NewList creates a new list element with the specified entries. | // NewList creates a new list element with the specified entries. | ||||||
| func NewList (entries ...ListEntry) (element *List) { | func NewList (entries ...ListEntry) (element *List) { | ||||||
| 	element = &List { } | 	element = &List { enabled: true, selectedEntry: -1 } | ||||||
| 	element.Core, element.core = core.NewCore(element) | 	element.Core, element.core = core.NewCore(element) | ||||||
| 	 | 	 | ||||||
| 	element.entries = make([]ListEntry, len(entries)) | 	element.entries = make([]ListEntry, len(entries)) | ||||||
| @ -71,16 +75,16 @@ func (element *List) HandleMouseDown (x, y int, button tomo.Button) { | |||||||
| 	if !element.enabled  { return } | 	if !element.enabled  { return } | ||||||
| 	if !element.selected { element.Select() } | 	if !element.selected { element.Select() } | ||||||
| 	if button != tomo.ButtonLeft { return } | 	if button != tomo.ButtonLeft { return } | ||||||
| 	 | 	element.pressed = true | ||||||
| 	// if element.core.HasImage() { | 	if element.selectUnderMouse(x, y) && element.core.HasImage() { | ||||||
| 		// element.draw() | 		element.draw() | ||||||
| 		// element.core.DamageAll() | 		element.core.DamageAll() | ||||||
| 	// } | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (element *List) HandleMouseUp (x, y int, button tomo.Button) { | func (element *List) HandleMouseUp (x, y int, button tomo.Button) { | ||||||
| 	if button != tomo.ButtonLeft { return } | 	if button != tomo.ButtonLeft { return } | ||||||
| 	// element.pressed = false | 	element.pressed = false | ||||||
| 	// if element.core.HasImage() { | 	// if element.core.HasImage() { | ||||||
| 		// element.draw() | 		// element.draw() | ||||||
| 		// element.core.DamageAll() | 		// element.core.DamageAll() | ||||||
| @ -95,7 +99,15 @@ func (element *List) HandleMouseUp (x, y int, button tomo.Button) { | |||||||
| 	// } | 	// } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (element *List) HandleMouseMove (x, y int) { } | func (element *List) HandleMouseMove (x, y int) { | ||||||
|  | 	if element.pressed { | ||||||
|  | 		if element.selectUnderMouse(x, y) && element.core.HasImage() { | ||||||
|  | 			element.draw() | ||||||
|  | 			element.core.DamageAll() | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (element *List) HandleMouseScroll (x, y int, deltaX, deltaY float64) { } | func (element *List) HandleMouseScroll (x, y int, deltaX, deltaY float64) { } | ||||||
| 
 | 
 | ||||||
| func (element *List) HandleKeyDown (key tomo.Key, modifiers tomo.Modifiers) { | func (element *List) HandleKeyDown (key tomo.Key, modifiers tomo.Modifiers) { | ||||||
| @ -324,6 +336,32 @@ func (element *List) Replace (index int, entry ListEntry) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (element *List) selectUnderMouse (x, y int) (updated bool) { | ||||||
|  | 	bounds := element.Bounds() | ||||||
|  | 	mousePoint := image.Pt(x, y) | ||||||
|  | 	dot := image.Pt ( | ||||||
|  | 		bounds.Min.X + theme.Padding() / 2, | ||||||
|  | 		bounds.Min.Y - element.scroll + theme.Padding() / 2) | ||||||
|  | 	 | ||||||
|  | 	newlySelectedEntryIndex := -1 | ||||||
|  | 	for index, entry := range element.entries { | ||||||
|  | 		entryPosition := dot | ||||||
|  | 		dot.Y += entry.Bounds().Dy() | ||||||
|  | 		if entryPosition.Y > bounds.Max.Y { break } | ||||||
|  | 		if mousePoint.In(entry.Bounds().Add(entryPosition)) { | ||||||
|  | 			newlySelectedEntryIndex = index | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if element.selectedEntry == newlySelectedEntryIndex { return false } | ||||||
|  | 	element.selectedEntry = newlySelectedEntryIndex | ||||||
|  | 	if element.onSelectedEntryChange != nil { | ||||||
|  | 		element.onSelectedEntryChange(element.selectedEntry) | ||||||
|  | 	} | ||||||
|  | 	return true | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (element *List) resizeEntryToFit (entry ListEntry) (resized ListEntry) { | func (element *List) resizeEntryToFit (entry ListEntry) (resized ListEntry) { | ||||||
| 	entry.Collapse(element.forcedMinimumWidth) | 	entry.Collapse(element.forcedMinimumWidth) | ||||||
| 	return entry | 	return entry | ||||||
| @ -332,7 +370,6 @@ func (element *List) resizeEntryToFit (entry ListEntry) (resized ListEntry) { | |||||||
| func (element *List) updateMinimumSize () { | func (element *List) updateMinimumSize () { | ||||||
| 	element.contentHeight = 0 | 	element.contentHeight = 0 | ||||||
| 	for _, entry := range element.entries { | 	for _, entry := range element.entries { | ||||||
| 		element.contentHeight += theme.Padding() |  | ||||||
| 		element.contentHeight += entry.Bounds().Dy() | 		element.contentHeight += entry.Bounds().Dy() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -340,11 +377,18 @@ func (element *List) updateMinimumSize () { | |||||||
| 	minimumHeight := element.forcedMinimumHeight | 	minimumHeight := element.forcedMinimumHeight | ||||||
| 
 | 
 | ||||||
| 	if minimumWidth == 0 { | 	if minimumWidth == 0 { | ||||||
| 		 | 		minimumWidth = theme.Padding() | ||||||
|  | 		for _, entry := range element.entries { | ||||||
|  | 			entryWidth := entry.Bounds().Dx() | ||||||
|  | 			if entryWidth > minimumWidth { | ||||||
|  | 				minimumWidth = entryWidth | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		minimumWidth += theme.Padding() | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if minimumHeight == 0 { | 	if minimumHeight == 0 { | ||||||
| 		minimumHeight = element.contentHeight | 		minimumHeight = element.contentHeight + theme.Padding() * 2 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	element.core.SetMinimumSize(minimumWidth, minimumHeight) | 	element.core.SetMinimumSize(minimumWidth, minimumHeight) | ||||||
| @ -359,27 +403,21 @@ func (element *List) draw () { | |||||||
| 		bounds) | 		bounds) | ||||||
| 
 | 
 | ||||||
| 	dot := image.Point { | 	dot := image.Point { | ||||||
| 		bounds.Min.X + theme.Padding(), | 		bounds.Min.X, | ||||||
| 		bounds.Min.Y - element.scroll, | 		bounds.Min.Y - element.scroll + theme.Padding() / 2, | ||||||
| 	} | 	} | ||||||
| 	for index, entry := range element.entries { | 	for index, entry := range element.entries { | ||||||
| 		dot.Y += theme.Padding() |  | ||||||
| 		entryPosition := dot | 		entryPosition := dot | ||||||
| 		dot.Y += entry.Bounds().Dy() | 		dot.Y += entry.Bounds().Dy() | ||||||
| 		if dot.Y < bounds.Min.Y { continue } | 		if dot.Y < bounds.Min.Y { continue } | ||||||
| 		if entryPosition.Y > bounds.Max.Y { break } | 		if entryPosition.Y > bounds.Max.Y { break } | ||||||
| 
 | 
 | ||||||
| 		selectionMarkerBounds := image.Rect ( | 		if element.selectedEntry == index { | ||||||
| 			theme.Padding() / 2, |  | ||||||
| 			entryPosition.Y - theme.Padding() / 2, |  | ||||||
| 			bounds.Dx() - theme.Padding() / 2, |  | ||||||
| 			entryPosition.Y + entry.Bounds().Dy() + |  | ||||||
| 			theme.Padding() / 2) |  | ||||||
| 			artist.FillRectangle ( | 			artist.FillRectangle ( | ||||||
| 				element, | 				element, | ||||||
| 			theme.ListEntryPattern(element.selectedEntry == index), | 				theme.ListEntryPattern(true), | ||||||
| 			selectionMarkerBounds) | 				entry.Bounds().Add(entryPosition)) | ||||||
| 		 | 		} | ||||||
| 		entry.Draw ( | 		entry.Draw ( | ||||||
| 			element, entryPosition, | 			element, entryPosition, | ||||||
| 			element.selectedEntry == index && element.selected) | 			element.selectedEntry == index && element.selected) | ||||||
|  | |||||||
| @ -33,13 +33,20 @@ func (entry *ListEntry) Collapse (width int) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (entry *ListEntry) updateBounds () { | func (entry *ListEntry) updateBounds () { | ||||||
|  | 	padding := theme.Padding() | ||||||
|  | 	 | ||||||
| 	entry.bounds = image.Rectangle { } | 	entry.bounds = image.Rectangle { } | ||||||
| 	entry.bounds.Max.Y = entry.drawer.LineHeight().Round() | 	entry.bounds.Max.Y = entry.drawer.LineHeight().Round() + padding | ||||||
| 	if entry.forcedMinimumWidth > 0 { | 	if entry.forcedMinimumWidth > 0 { | ||||||
| 		entry.bounds.Max.X = entry.drawer.LayoutBounds().Dx() | 		entry.bounds.Max.X = entry.forcedMinimumWidth | ||||||
|  | 	} else { | ||||||
|  | 		entry.bounds.Max.X = | ||||||
|  | 			entry.drawer.LayoutBounds().Dx() + padding * 2 | ||||||
| 	} | 	} | ||||||
| 	 | 	 | ||||||
| 	entry.textPoint = image.Pt(0, 0).Sub(entry.drawer.LayoutBounds().Min) | 	entry.textPoint = | ||||||
|  | 		image.Pt(padding, padding / 2). | ||||||
|  | 		Sub(entry.drawer.LayoutBounds().Min) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (entry *ListEntry) Draw ( | func (entry *ListEntry) Draw ( | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ func (element *Artist) Resize (width, height int) { | |||||||
| 	element.core.AllocateCanvas(width, height) | 	element.core.AllocateCanvas(width, height) | ||||||
| 	bounds := element.Bounds() | 	bounds := element.Bounds() | ||||||
| 	element.cellBounds.Max.X = bounds.Dx() / 4 | 	element.cellBounds.Max.X = bounds.Dx() / 4 | ||||||
| 	element.cellBounds.Max.Y = (bounds.Dy() - 48) / 5 | 	element.cellBounds.Max.Y = (bounds.Dy() - 48) / 6 | ||||||
| 
 | 
 | ||||||
| 	drawStart := time.Now() | 	drawStart := time.Now() | ||||||
| 
 | 
 | ||||||
| @ -128,6 +128,17 @@ func (element *Artist) Resize (width, height int) { | |||||||
| 		drawTime.Milliseconds(), | 		drawTime.Milliseconds(), | ||||||
| 		drawTime.Microseconds()))) | 		drawTime.Microseconds()))) | ||||||
| 	textDrawer.Draw(element, uhex(0xFFFFFFFF), image.Pt(8, bounds.Max.Y - 24)) | 	textDrawer.Draw(element, uhex(0xFFFFFFFF), image.Pt(8, bounds.Max.Y - 24)) | ||||||
|  | 	 | ||||||
|  | 	// 0, 5 | ||||||
|  | 	artist.FillRectangle ( | ||||||
|  | 		element, | ||||||
|  | 		artist.QuadBeveled { | ||||||
|  | 			artist.NewUniform(hex(0x880000FF)), | ||||||
|  | 			artist.NewUniform(hex(0x00FF00FF)), | ||||||
|  | 			artist.NewUniform(hex(0x0000FFFF)), | ||||||
|  | 			artist.NewUniform(hex(0xFF00FFFF)), | ||||||
|  | 		}, | ||||||
|  | 		element.cellAt(0, 5)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (element *Artist) lines (weight int, bounds image.Rectangle) { | func (element *Artist) lines (weight int, bounds image.Rectangle) { | ||||||
|  | |||||||
| @ -14,9 +14,25 @@ var listPattern = artist.NewMultiBordered ( | |||||||
| 	artist.Stroke { Pattern: artist.NewUniform(hex(0x999C99FF)) }) | 	artist.Stroke { Pattern: artist.NewUniform(hex(0x999C99FF)) }) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| var listEntryPattern = artist.NewUniform(hex(0x999C99FF)) | var listEntryPattern = artist.NewMultiBordered ( | ||||||
|  | 	artist.Stroke { Weight: 1, Pattern: artist.QuadBeveled { | ||||||
|  | 		artist.NewUniform(hex(0x999C99FF)), | ||||||
|  | 		strokePattern, | ||||||
|  | 		artist.NewUniform(hex(0x999C99FF)), | ||||||
|  | 		strokePattern, | ||||||
|  | 	}}, | ||||||
|  | 	artist.Stroke { Pattern: artist.NewUniform(hex(0x999C99FF)) }) | ||||||
| 
 | 
 | ||||||
| var selectedListEntryPattern = accentPattern | var selectedListEntryPattern = artist.NewMultiBordered ( | ||||||
|  | 	artist.Stroke { Weight: 1, Pattern: strokePattern }, | ||||||
|  | 	artist.Stroke { | ||||||
|  | 		Weight: 1, | ||||||
|  | 		Pattern: artist.Beveled { | ||||||
|  | 			Highlight: artist.NewUniform(hex(0x3b534eFF)), | ||||||
|  | 			Shadow:    artist.NewUniform(hex(0x97a09cFF)), | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
|  | 	artist.Stroke { Pattern: artist.NewUniform(hex(0x97a09cFF)) }) | ||||||
| 
 | 
 | ||||||
| func ListPattern () (pattern artist.Pattern) { | func ListPattern () (pattern artist.Pattern) { | ||||||
| 	return listPattern | 	return listPattern | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user