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 {
|
||||
*core.Core
|
||||
core core.CoreControl
|
||||
|
||||
enabled bool
|
||||
selected bool
|
||||
pressed bool
|
||||
|
||||
contentHeight int
|
||||
forcedMinimumWidth int
|
||||
forcedMinimumHeight int
|
||||
|
||||
selectedEntry int
|
||||
scroll int
|
||||
entries []ListEntry
|
||||
@ -28,7 +32,7 @@ type List struct {
|
||||
|
||||
// NewList creates a new list element with the specified entries.
|
||||
func NewList (entries ...ListEntry) (element *List) {
|
||||
element = &List { }
|
||||
element = &List { enabled: true, selectedEntry: -1 }
|
||||
element.Core, element.core = core.NewCore(element)
|
||||
|
||||
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.selected { element.Select() }
|
||||
if button != tomo.ButtonLeft { return }
|
||||
|
||||
// if element.core.HasImage() {
|
||||
// element.draw()
|
||||
// element.core.DamageAll()
|
||||
// }
|
||||
element.pressed = true
|
||||
if element.selectUnderMouse(x, y) && element.core.HasImage() {
|
||||
element.draw()
|
||||
element.core.DamageAll()
|
||||
}
|
||||
}
|
||||
|
||||
func (element *List) HandleMouseUp (x, y int, button tomo.Button) {
|
||||
if button != tomo.ButtonLeft { return }
|
||||
// element.pressed = false
|
||||
element.pressed = false
|
||||
// if element.core.HasImage() {
|
||||
// element.draw()
|
||||
// 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) 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) {
|
||||
entry.Collapse(element.forcedMinimumWidth)
|
||||
return entry
|
||||
@ -332,7 +370,6 @@ func (element *List) resizeEntryToFit (entry ListEntry) (resized ListEntry) {
|
||||
func (element *List) updateMinimumSize () {
|
||||
element.contentHeight = 0
|
||||
for _, entry := range element.entries {
|
||||
element.contentHeight += theme.Padding()
|
||||
element.contentHeight += entry.Bounds().Dy()
|
||||
}
|
||||
|
||||
@ -340,11 +377,18 @@ func (element *List) updateMinimumSize () {
|
||||
minimumHeight := element.forcedMinimumHeight
|
||||
|
||||
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 {
|
||||
minimumHeight = element.contentHeight
|
||||
minimumHeight = element.contentHeight + theme.Padding() * 2
|
||||
}
|
||||
|
||||
element.core.SetMinimumSize(minimumWidth, minimumHeight)
|
||||
@ -359,27 +403,21 @@ func (element *List) draw () {
|
||||
bounds)
|
||||
|
||||
dot := image.Point {
|
||||
bounds.Min.X + theme.Padding(),
|
||||
bounds.Min.Y - element.scroll,
|
||||
bounds.Min.X,
|
||||
bounds.Min.Y - element.scroll + theme.Padding() / 2,
|
||||
}
|
||||
for index, entry := range element.entries {
|
||||
dot.Y += theme.Padding()
|
||||
entryPosition := dot
|
||||
dot.Y += entry.Bounds().Dy()
|
||||
if dot.Y < bounds.Min.Y { continue }
|
||||
if entryPosition.Y > bounds.Max.Y { break }
|
||||
|
||||
selectionMarkerBounds := image.Rect (
|
||||
theme.Padding() / 2,
|
||||
entryPosition.Y - theme.Padding() / 2,
|
||||
bounds.Dx() - theme.Padding() / 2,
|
||||
entryPosition.Y + entry.Bounds().Dy() +
|
||||
theme.Padding() / 2)
|
||||
artist.FillRectangle (
|
||||
element,
|
||||
theme.ListEntryPattern(element.selectedEntry == index),
|
||||
selectionMarkerBounds)
|
||||
|
||||
if element.selectedEntry == index {
|
||||
artist.FillRectangle (
|
||||
element,
|
||||
theme.ListEntryPattern(true),
|
||||
entry.Bounds().Add(entryPosition))
|
||||
}
|
||||
entry.Draw (
|
||||
element, entryPosition,
|
||||
element.selectedEntry == index && element.selected)
|
||||
|
@ -33,13 +33,20 @@ func (entry *ListEntry) Collapse (width int) {
|
||||
}
|
||||
|
||||
func (entry *ListEntry) updateBounds () {
|
||||
padding := theme.Padding()
|
||||
|
||||
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 {
|
||||
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 (
|
||||
|
@ -28,7 +28,7 @@ func (element *Artist) Resize (width, height int) {
|
||||
element.core.AllocateCanvas(width, height)
|
||||
bounds := element.Bounds()
|
||||
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()
|
||||
|
||||
@ -128,6 +128,17 @@ func (element *Artist) Resize (width, height int) {
|
||||
drawTime.Milliseconds(),
|
||||
drawTime.Microseconds())))
|
||||
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) {
|
||||
|
@ -14,9 +14,25 @@ var listPattern = artist.NewMultiBordered (
|
||||
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) {
|
||||
return listPattern
|
||||
|
Reference in New Issue
Block a user