From f74f6a43f86eec083fab1041dd740933ff5954dc Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Thu, 23 Mar 2023 14:11:42 -0400 Subject: [PATCH] DirectoryView selects and de-selects files --- elements/file/directory.go | 24 +++++++++++--- elements/file/file.go | 67 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/elements/file/directory.go b/elements/file/directory.go index cdf559a..723ebe4 100644 --- a/elements/file/directory.go +++ b/elements/file/directory.go @@ -4,6 +4,7 @@ import "io/fs" import "image" import "path/filepath" import "git.tebibyte.media/sashakoshka/tomo/theme" +import "git.tebibyte.media/sashakoshka/tomo/input" import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/canvas" import "git.tebibyte.media/sashakoshka/tomo/config" @@ -76,7 +77,6 @@ func (element *DirectoryView) SetLocation ( // Update refreshes the directory's contents. func (element *DirectoryView) Update () error { - defer element.redoAll() entries, err := element.filesystem.ReadDir(element.location) // disown all entries @@ -95,17 +95,18 @@ func (element *DirectoryView) Update () error { file, err := NewFile ( filePath, element.filesystem) - if err != nil { return err } + if err != nil { continue } file.SetParent(element) - element.children[index].File = file - element.children[index].DirEntry = entry - element.OnChoose (func (filepath string) { + file.OnChoose (func () { if element.onChoose != nil { element.onChoose(filePath) } }) + element.children[index].File = file + element.children[index].DirEntry = entry } + element.redoAll() return err } @@ -127,6 +128,19 @@ func (element *DirectoryView) Child (index int) (child elements.Element) { return element.children[index].File } +func (element *DirectoryView) HandleMouseDown (x, y int, button input.Button) { + var file *File + for _, entry := range element.children { + if image.Pt(x, y).In(entry.Bounds) { + file = entry.File + } + } + if file != nil { + file.SetSelected(!file.Selected()) + } + element.Propagator.HandleMouseDown(x, y, button) +} + func (element *DirectoryView) redoAll () { if !element.core.HasImage() { return } diff --git a/elements/file/file.go b/elements/file/file.go index 9db6731..ca53cd6 100644 --- a/elements/file/file.go +++ b/elements/file/file.go @@ -1,7 +1,9 @@ package fileElements +import "time" import "io/fs" import "image" +import "git.tebibyte.media/sashakoshka/tomo/input" import "git.tebibyte.media/sashakoshka/tomo/theme" import "git.tebibyte.media/sashakoshka/tomo/artist" import "git.tebibyte.media/sashakoshka/tomo/config" @@ -17,10 +19,14 @@ type File struct { config config.Wrapped theme theme.Wrapped - + + lastClick time.Time + pressed bool iconID theme.Icon filesystem fs.StatFS location string + selected bool + onChoose func () } @@ -79,15 +85,68 @@ func (element *File) Update () error { return err } +func (element *File) Selected () bool { + return element.selected +} + +func (element *File) SetSelected (selected bool) { + if element.selected == selected { return } + element.selected = selected + element.drawAndPush() +} + +func (element *File) HandleKeyDown (key input.Key, modifiers input.Modifiers) { + if !element.Enabled() { return } + if key == input.KeyEnter { + element.pressed = true + element.drawAndPush() + } +} + +func (element *File) HandleKeyUp(key input.Key, modifiers input.Modifiers) { + if key == input.KeyEnter && element.pressed { + element.pressed = false + element.drawAndPush() + if !element.Enabled() { return } + if element.onChoose != nil { + element.onChoose() + } + } +} + func (element *File) OnChoose (callback func ()) { element.onChoose = callback } +func (element *File) HandleMouseDown (x, y int, button input.Button) { + if !element.Enabled() { return } + if !element.Focused() { element.Focus() } + if button != input.ButtonLeft { return } + element.pressed = true + element.drawAndPush() +} + +func (element *File) HandleMouseUp (x, y int, button input.Button) { + if button != input.ButtonLeft { return } + element.pressed = false + within := image.Point { x, y }. + In(element.Bounds()) + if time.Since(element.lastClick) < time.Second / 2 { + if element.Enabled() && within && element.onChoose != nil { + element.onChoose() + } + } else { + element.lastClick = time.Now() + } + element.drawAndPush() +} + func (element *File) state () theme.State { return theme.State { Disabled: !element.Enabled(), Focused: element.Focused(), - // Pressed: element.pressed, + Pressed: element.pressed, + On: element.selected, } } @@ -119,6 +178,7 @@ func (element *File) drawAll () { // background state := element.state() bounds := element.Bounds() + sink := element.theme.Sink(theme.PatternButton) element.theme. Pattern(theme.PatternButton, state). Draw(element.core, bounds) @@ -130,6 +190,9 @@ func (element *File) drawAll () { offset := image.Pt ( (bounds.Dx() - iconBounds.Dx()) / 2, (bounds.Dy() - iconBounds.Dy()) / 2) + if element.pressed { + offset = offset.Add(sink) + } icon.Draw ( element.core, element.theme.Color (