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,
|
artist.FillRectangle (
|
||||||
entryPosition.Y - theme.Padding() / 2,
|
element,
|
||||||
bounds.Dx() - theme.Padding() / 2,
|
theme.ListEntryPattern(true),
|
||||||
entryPosition.Y + entry.Bounds().Dy() +
|
entry.Bounds().Add(entryPosition))
|
||||||
theme.Padding() / 2)
|
}
|
||||||
artist.FillRectangle (
|
|
||||||
element,
|
|
||||||
theme.ListEntryPattern(element.selectedEntry == index),
|
|
||||||
selectionMarkerBounds)
|
|
||||||
|
|
||||||
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