basic directory walking
This commit is contained in:
2
go.mod
2
go.mod
@@ -2,7 +2,7 @@ module git.yetaga.in/alazyreader/why
|
||||
|
||||
go 1.24.0
|
||||
|
||||
require modernc.org/tk9.0 v0.62.0
|
||||
require modernc.org/tk9.0 v0.62.1-0.20250222163156-e78eb59c0674
|
||||
|
||||
require (
|
||||
github.com/adrg/xdg v0.5.3 // indirect
|
||||
|
2
go.sum
2
go.sum
@@ -111,5 +111,7 @@ modernc.org/tcl9.0 v0.15.25 h1:3xNx26D+vYmSY3K9FaNdPmlHd8Hcz39YGiqsBFCYx5c=
|
||||
modernc.org/tcl9.0 v0.15.25/go.mod h1:hCbqZz0GQRzN3Xnfn4dKpMCwvA9sfEb+Go++cw1cJ3A=
|
||||
modernc.org/tk9.0 v0.62.0 h1:V4lyYhCRSXZKn+txvjZCyUnWodAFVJRYFDpFuLldGlk=
|
||||
modernc.org/tk9.0 v0.62.0/go.mod h1:vzTmvDro5F7yCnusSheZrF8VXXOzmY9RxH2c5M3YFqc=
|
||||
modernc.org/tk9.0 v0.62.1-0.20250222163156-e78eb59c0674 h1:iIzjoNi8sZ4lw0zIjfNNX730AqytNGIRnE+bZgrWhTg=
|
||||
modernc.org/tk9.0 v0.62.1-0.20250222163156-e78eb59c0674/go.mod h1:vzTmvDro5F7yCnusSheZrF8VXXOzmY9RxH2c5M3YFqc=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
|
BIN
gopher.png
BIN
gopher.png
Binary file not shown.
Before Width: | Height: | Size: 18 KiB |
130
main.go
130
main.go
@@ -11,15 +11,17 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
tk "modernc.org/tk9.0"
|
||||
)
|
||||
|
||||
//go:embed gopher.png
|
||||
var gopher []byte
|
||||
// this is a default image
|
||||
//
|
||||
//go:embed noise.png
|
||||
var noise []byte
|
||||
|
||||
var validFileTypes = []tk.FileType{
|
||||
{
|
||||
@@ -40,14 +42,32 @@ var validFileTypes = []tk.FileType{
|
||||
},
|
||||
}
|
||||
|
||||
var metaPressed bool
|
||||
var metaActive bool
|
||||
|
||||
func isType(filename string, desired string) bool {
|
||||
splode := strings.Split(filename, ".")
|
||||
if len(splode) < 2 {
|
||||
var directoryState struct {
|
||||
currentDirectory string
|
||||
currentFile string
|
||||
images []string
|
||||
}
|
||||
|
||||
func isImage(entry os.DirEntry) bool {
|
||||
if entry.IsDir() {
|
||||
return false
|
||||
}
|
||||
ext := filepath.Ext(entry.Name())
|
||||
for _, ft := range validFileTypes {
|
||||
if slices.Contains(ft.Extensions, ext) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isType(filename string, desired string) bool {
|
||||
ext := filepath.Ext(filename)
|
||||
if ext == "" {
|
||||
return false
|
||||
}
|
||||
ext := fmt.Sprintf(".%s", splode[len(splode)-1])
|
||||
for _, ft := range validFileTypes {
|
||||
if slices.Contains(ft.Extensions, ext) && ft.TypeName == desired {
|
||||
return true
|
||||
@@ -79,59 +99,93 @@ func jpegToPng(in io.Reader) (*bytes.Buffer, error) {
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func loadImage(img *tk.LabelWidget) func() {
|
||||
func newDirectory(img *tk.LabelWidget) func() {
|
||||
return func() {
|
||||
files := tk.GetOpenFile(tk.Filetypes(validFileTypes))
|
||||
if len(files) > 0 {
|
||||
f, err := os.Open(files[0])
|
||||
directoryState.currentFile = filepath.Base(files[0])
|
||||
directoryState.currentDirectory = filepath.Dir(files[0])
|
||||
dirfiles, err := os.ReadDir(directoryState.currentDirectory)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
log.Println(err)
|
||||
}
|
||||
var r io.Reader
|
||||
if isType(files[0], "JPEG") {
|
||||
r, err = jpegToPng(f)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
directoryState.images = []string{}
|
||||
for _, v := range dirfiles {
|
||||
if isImage(v) {
|
||||
directoryState.images = append(directoryState.images, v.Name())
|
||||
}
|
||||
} else {
|
||||
r = f
|
||||
}
|
||||
i, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
img.Configure(tk.Image(tk.NewPhoto(tk.Data(i))))
|
||||
updateImage(files[0], img)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateImage(file string, img *tk.LabelWidget) {
|
||||
f, err := os.Open(file)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
var r io.Reader
|
||||
if isType(file, "JPEG") {
|
||||
r, err = jpegToPng(f)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
r = f
|
||||
}
|
||||
i, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
return
|
||||
}
|
||||
img.Configure(tk.Image(tk.NewPhoto(tk.Data(i))))
|
||||
directoryState.currentFile = filepath.Base(file)
|
||||
}
|
||||
|
||||
func main() {
|
||||
img := tk.Label(tk.Image(tk.NewPhoto(tk.Data(gopher))))
|
||||
img := tk.Label(tk.Image(tk.NewPhoto(tk.Data(noise))))
|
||||
|
||||
menubar := tk.Menu()
|
||||
fileMenu := menubar.Menu()
|
||||
fileMenu.AddCommand(tk.Lbl("Open"), tk.Underline(0), tk.Accelerator("Meta+O"), tk.Command(loadImage(img)))
|
||||
fileMenu.AddCommand(tk.Lbl("Open"), tk.Underline(0), tk.Accelerator("Meta+O"), tk.Command(newDirectory(img)))
|
||||
menubar.AddCascade(tk.Lbl("File"), tk.Underline(0), tk.Mnu(fileMenu))
|
||||
|
||||
// TODO: if someone presses the Meta key again after the openfile dialog box closes,
|
||||
// it triggers a _release_ event instead of a press event. The second time afterward, it works correctly.
|
||||
tk.Bind(tk.App, "<KeyPress>", tk.Command(func(e *tk.Event) {
|
||||
if e.Keysym == "Meta_L" || e.Keysym == "Meta_R" {
|
||||
metaPressed = true
|
||||
}
|
||||
if e.Keysym == "o" && metaPressed {
|
||||
loadImage(img)()
|
||||
curr := slices.Index(directoryState.images, directoryState.currentFile)
|
||||
switch e.Keysym {
|
||||
case ".":
|
||||
log.Printf("state: %+v", directoryState)
|
||||
case "Meta_L", "Meta_R":
|
||||
metaActive = true
|
||||
case "o":
|
||||
if metaActive {
|
||||
newDirectory(img)()
|
||||
}
|
||||
case "Up":
|
||||
if curr > 0 {
|
||||
updateImage(filepath.Join(directoryState.currentDirectory, directoryState.images[curr-1]), img)
|
||||
}
|
||||
case "Down":
|
||||
if curr < len(directoryState.images)-1 && curr != -1 {
|
||||
updateImage(filepath.Join(directoryState.currentDirectory, directoryState.images[curr+1]), img)
|
||||
}
|
||||
}
|
||||
}))
|
||||
tk.Bind(tk.App, "<KeyRelease>", tk.Command(func(e *tk.Event) {
|
||||
if e.Keysym == "Meta_L" || e.Keysym == "Meta_R" {
|
||||
metaPressed = false
|
||||
switch e.Keysym {
|
||||
case "Meta_L", "Meta_R":
|
||||
metaActive = false
|
||||
}
|
||||
}))
|
||||
tk.Bind(tk.App, "<TouchpadScroll>", tk.Command(func(e *tk.Event) {
|
||||
// TODO: this event doesn't contain deltas, which means I can't tell if I'm scrolling "in" or "out"
|
||||
}))
|
||||
// todo: resize image based on scroll events
|
||||
// tk.Bind(tk.App, "<TouchpadScroll>", tk.Command(func(e *tk.Event) {
|
||||
// log.Printf("%v, %v", int16(e.Delta>>16), int16(e.Delta&0xFFFF))
|
||||
// }))
|
||||
|
||||
tk.Pack(img)
|
||||
tk.App.Configure(tk.Mnu(menubar)).Center().Wait()
|
||||
|
Reference in New Issue
Block a user