115 lines
2.7 KiB
Go
115 lines
2.7 KiB
Go
package elements
|
|
|
|
import "image"
|
|
import "path/filepath"
|
|
import "git.tebibyte.media/sashakoshka/tomo"
|
|
|
|
// TODO: base on flow implementation of list. also be able to switch to a table
|
|
// variant for a more information dense view.
|
|
|
|
type historyEntry struct {
|
|
location string
|
|
filesystem ReadDirStatFS
|
|
}
|
|
|
|
// Directory displays a list of files within a particular directory and
|
|
// file system.
|
|
type Directory struct {
|
|
*List
|
|
history []historyEntry
|
|
historyIndex int
|
|
onChoose func (file string)
|
|
}
|
|
|
|
// NewDirectory creates a new directory view. If within is nil, it will use
|
|
// the OS file system.
|
|
func NewDirectory (
|
|
location string,
|
|
within ReadDirStatFS,
|
|
) (
|
|
element *Directory,
|
|
err error,
|
|
) {
|
|
element = &Directory {
|
|
List: NewList(8),
|
|
}
|
|
err = element.SetLocation(location, within)
|
|
return
|
|
}
|
|
|
|
// Location returns the directory's location and filesystem.
|
|
func (element *Directory) Location () (string, ReadDirStatFS) {
|
|
if len(element.history) < 1 { return "", nil }
|
|
current := element.history[element.historyIndex]
|
|
return current.location, current.filesystem
|
|
}
|
|
|
|
// SetLocation sets the directory's location and filesystem. If within is nil,
|
|
// it will use the OS file system.
|
|
func (element *Directory) SetLocation (
|
|
location string,
|
|
within ReadDirStatFS,
|
|
) error {
|
|
if within == nil {
|
|
within = defaultFS { }
|
|
}
|
|
element.scroll = image.Point { }
|
|
|
|
if element.history != nil {
|
|
element.historyIndex ++
|
|
}
|
|
element.history = append (
|
|
element.history[:element.historyIndex],
|
|
historyEntry { location, within })
|
|
return element.Update()
|
|
}
|
|
|
|
// Backward goes back a directory in history
|
|
func (element *Directory) Backward () (bool, error) {
|
|
if element.historyIndex > 1 {
|
|
element.historyIndex --
|
|
return true, element.Update()
|
|
} else {
|
|
return false, nil
|
|
}
|
|
}
|
|
|
|
// Forward goes forward a directory in history
|
|
func (element *Directory) Forward () (bool, error) {
|
|
if element.historyIndex < len(element.history) - 1 {
|
|
element.historyIndex ++
|
|
return true, element.Update()
|
|
} else {
|
|
return false, nil
|
|
}
|
|
}
|
|
|
|
// Update refreshes the directory's contents.
|
|
func (element *Directory) Update () error {
|
|
location, filesystem := element.Location()
|
|
entries, err := filesystem.ReadDir(location)
|
|
|
|
children := make([]tomo.Element, len(entries))
|
|
for index, entry := range entries {
|
|
filePath := filepath.Join(location, entry.Name())
|
|
file, _ := NewFile(filePath, filesystem)
|
|
file.OnChoose (func () {
|
|
if element.onChoose != nil {
|
|
element.onChoose(filePath)
|
|
}
|
|
})
|
|
|
|
children[index] = file
|
|
}
|
|
|
|
element.DisownAll()
|
|
element.Adopt(children...)
|
|
return err
|
|
}
|
|
|
|
// OnChoose sets a function to be called when the user double-clicks a file or
|
|
// sub-directory within the directory view.
|
|
func (element *Directory) OnChoose (callback func (file string)) {
|
|
element.onChoose = callback
|
|
}
|