File and directory view elements wip
This commit is contained in:
parent
60aac053fb
commit
d9bddce20b
73
elements/file/directory.go
Normal file
73
elements/file/directory.go
Normal file
@ -0,0 +1,73 @@
|
||||
package fileElements
|
||||
|
||||
import "io/fs"
|
||||
import "path/filepath"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
|
||||
type ReadDirStatFS interface {
|
||||
fs.ReadDirFS
|
||||
fs.StatFS
|
||||
}
|
||||
|
||||
type DirectoryView struct {
|
||||
*basicElements.List
|
||||
|
||||
filesystem ReadDirStatFS
|
||||
location string
|
||||
onChoose func (file string)
|
||||
}
|
||||
|
||||
func NewDirectoryView (
|
||||
location string,
|
||||
within ReadDirStatFS,
|
||||
) (
|
||||
element *DirectoryView,
|
||||
err error,
|
||||
) {
|
||||
element = &DirectoryView {
|
||||
List: basicElements.NewList(),
|
||||
}
|
||||
err = element.SetLocation(location, within)
|
||||
return
|
||||
}
|
||||
|
||||
func (element *DirectoryView) Location () (string, fs.ReadDirFS) {
|
||||
return element.location, element.filesystem
|
||||
}
|
||||
|
||||
func (element *DirectoryView) SetLocation (
|
||||
location string,
|
||||
within ReadDirStatFS,
|
||||
) error {
|
||||
if within == nil {
|
||||
within = defaultFS { }
|
||||
}
|
||||
element.location = location
|
||||
element.filesystem = within
|
||||
return element.Update()
|
||||
}
|
||||
|
||||
func (element *DirectoryView) Update () error {
|
||||
entries, err := element.filesystem.ReadDir(element.location)
|
||||
|
||||
listEntries := make([]basicElements.ListEntry, len(entries))
|
||||
for index, entry := range entries {
|
||||
filePath := filepath.Join(element.location, entry.Name())
|
||||
listEntries[index] = basicElements.NewListEntry (
|
||||
entry.Name(),
|
||||
func () {
|
||||
filePath := filePath
|
||||
if element.onChoose != nil {
|
||||
element.onChoose(filePath)
|
||||
}
|
||||
})
|
||||
}
|
||||
element.Clear()
|
||||
element.Append(listEntries...)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (element *DirectoryView) OnChoose (callback func (file string)) {
|
||||
element.onChoose = callback
|
||||
}
|
67
elements/file/file.go
Normal file
67
elements/file/file.go
Normal file
@ -0,0 +1,67 @@
|
||||
package fileElements
|
||||
|
||||
import "io/fs"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
|
||||
// File is a
|
||||
type File struct {
|
||||
*basicElements.Icon
|
||||
|
||||
// we inherit from Icon directly because it is not our responsibility
|
||||
// to draw text. this will be the responsibility of the directory that
|
||||
// contains the file. we don't handle mouse events on the file label
|
||||
// text either because when the user clicks on that we want to rename
|
||||
// the file.
|
||||
|
||||
filesystem fs.StatFS
|
||||
location string
|
||||
onChoose func ()
|
||||
}
|
||||
|
||||
func NewFile (
|
||||
location string,
|
||||
within fs.StatFS,
|
||||
) (
|
||||
element *File,
|
||||
err error,
|
||||
) {
|
||||
element = &File {
|
||||
Icon: basicElements.NewIcon(theme.IconFile, theme.IconSizeLarge),
|
||||
}
|
||||
err = element.SetLocation(location, within)
|
||||
return
|
||||
}
|
||||
|
||||
func (element *File) Location () (string, fs.StatFS) {
|
||||
return element.location, element.filesystem
|
||||
}
|
||||
|
||||
func (element *File) SetLocation (
|
||||
location string,
|
||||
within fs.StatFS,
|
||||
) error {
|
||||
if within == nil {
|
||||
within = defaultFS { }
|
||||
}
|
||||
element.location = location
|
||||
element.filesystem = within
|
||||
return element.Update()
|
||||
}
|
||||
|
||||
func (element *File) Update () error {
|
||||
info, err := element.filesystem.Stat(element.location)
|
||||
if err != nil { return err }
|
||||
|
||||
if info.IsDir() {
|
||||
element.SetIcon(theme.IconDirectory, theme.IconSizeLarge)
|
||||
} else {
|
||||
element.SetIcon(theme.IconFile, theme.IconSizeLarge)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (element *File) OnChoose (callback func ()) {
|
||||
element.onChoose = callback
|
||||
}
|
18
elements/file/fs.go
Normal file
18
elements/file/fs.go
Normal file
@ -0,0 +1,18 @@
|
||||
package fileElements
|
||||
|
||||
import "os"
|
||||
import "io/fs"
|
||||
|
||||
type defaultFS struct { }
|
||||
|
||||
func (defaultFS) Open (name string) (fs.File, error) {
|
||||
return os.Open(name)
|
||||
}
|
||||
|
||||
func (defaultFS) ReadDir (name string) ([]DirEntry, error) {
|
||||
return os.ReadDir(name)
|
||||
}
|
||||
|
||||
func (defaultFS) Stat (name string) (FileInfo, error) {
|
||||
return os.Stat(name)
|
||||
}
|
62
examples/fileBrowser/main.go
Normal file
62
examples/fileBrowser/main.go
Normal file
@ -0,0 +1,62 @@
|
||||
package main
|
||||
|
||||
import "os"
|
||||
import "git.tebibyte.media/sashakoshka/tomo"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/theme"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/layouts/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/file"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/basic"
|
||||
import "git.tebibyte.media/sashakoshka/tomo/elements/containers"
|
||||
import _ "git.tebibyte.media/sashakoshka/tomo/backends/all"
|
||||
|
||||
func main () {
|
||||
tomo.Run(run)
|
||||
}
|
||||
|
||||
func run () {
|
||||
window, _ := tomo.NewWindow(384, 384)
|
||||
window.SetTitle("File browser")
|
||||
container := containers.NewContainer(basicLayouts.Vertical { true, true })
|
||||
window.Adopt(container)
|
||||
|
||||
controlBar := containers.NewContainer(basicLayouts.Horizontal { })
|
||||
backButton := basicElements.NewButton("Back")
|
||||
backButton.SetIcon(theme.IconBackward)
|
||||
backButton.ShowText(false)
|
||||
forwardButton := basicElements.NewButton("Forward")
|
||||
forwardButton.SetIcon(theme.IconForward)
|
||||
forwardButton.ShowText(false)
|
||||
refreshButton := basicElements.NewButton("Refresh")
|
||||
refreshButton.SetIcon(theme.IconRefresh)
|
||||
refreshButton.ShowText(false)
|
||||
upwardButton := basicElements.NewButton("Go Up")
|
||||
upwardButton.SetIcon(theme.IconUpward)
|
||||
upwardButton.ShowText(false)
|
||||
locationInput := basicElements.NewTextBox("Location", "")
|
||||
|
||||
scrollContainer := containers.NewScrollContainer(false, true)
|
||||
homeDir,_ := os.UserHomeDir()
|
||||
directoryView, _ := fileElements.NewDirectoryView(homeDir)
|
||||
directoryView.Collapse(0, 8)
|
||||
choose := func (filePath string) {
|
||||
directoryView.SetLocation(filePath)
|
||||
locationInput.SetValue(directoryView.Location())
|
||||
}
|
||||
directoryView.OnChoose(choose)
|
||||
locationInput.OnEnter (func () {
|
||||
choose(locationInput.Value())
|
||||
})
|
||||
choose(homeDir)
|
||||
|
||||
scrollContainer.Adopt(directoryView)
|
||||
controlBar.Adopt(backButton, false)
|
||||
controlBar.Adopt(forwardButton, false)
|
||||
controlBar.Adopt(refreshButton, false)
|
||||
controlBar.Adopt(upwardButton, false)
|
||||
controlBar.Adopt(locationInput, true)
|
||||
container.Adopt(controlBar, false)
|
||||
container.Adopt(scrollContainer, true)
|
||||
|
||||
window.OnClose(tomo.Stop)
|
||||
window.Show()
|
||||
}
|
Reference in New Issue
Block a user