Native windows open file dialog

This commit is contained in:
bloeys
2024-04-20 14:50:17 +04:00
parent 5b15017fc6
commit 1f62c3ae60
3 changed files with 99 additions and 13 deletions

View File

@ -109,7 +109,10 @@ func (e *Editor) UpdateAndDraw(drawStartPos, winSize *imgui.Vec2, newRunes []run
imgui.PushStyleColorVec4(imgui.ColTextSelectedBg, settings.TextSelectionColor) imgui.PushStyleColorVec4(imgui.ColTextSelectedBg, settings.TextSelectionColor)
imgui.SetNextItemWidth(winSize.X) imgui.SetNextItemWidth(winSize.X)
if imgui.InputTextMultiline("", &e.FileContents, imgui.Vec2{X: winSize.X - winSize.X*0.02, Y: winSize.Y - winSize.Y*0.02}, imgui.InputTextFlagsNone, nil) {
// We want different lables so multiple editors don't mess eaach other, but we don't want the label to show
// so we prefix the whole thing with ##
if imgui.InputTextMultiline("##"+e.FilePath, &e.FileContents, imgui.Vec2{X: winSize.X - winSize.X*0.02, Y: winSize.Y - winSize.Y*0.02}, imgui.InputTextFlagsNone|imgui.InputTextFlagsAllowTabInput, nil) {
e.IsModified = true e.IsModified = true
} }

71
file_dialogs_windows.go Executable file
View File

@ -0,0 +1,71 @@
package main
import (
"fmt"
"syscall"
"unicode/utf16"
"unsafe"
)
var (
comdlg32 = syscall.NewLazyDLL("Comdlg32.dll")
procGetOpenFileName = comdlg32.NewProc("GetOpenFileNameW")
)
var (
Err_No_File_Chosen = fmt.Errorf("no file was chosen")
)
func OpenFileDialog(title string) (filepath string, err error) {
type OPENFILENAMEW struct {
LStructSize uint32
HwndOwner syscall.Handle
HInstance syscall.Handle
Filter *uint16
CustomFilter *uint16
MaxCustFilter uint32
FilterIndex uint32
File *uint16
MaxFile uint32
FileTitle *uint16
MaxFileTitle uint32
InitialDir *uint16
Title *uint16
Flags uint32
FileOffset uint16
FileExtension uint16
DefExt *uint16
CustData uintptr
FnHook syscall.Handle
TemplateName *uint16
PvReserved uintptr
DwReserved uint32
FlagsEx uint32
}
titleByteArr := utf16.Encode([]rune(title + "\x00"))
filterByteArr := utf16.Encode([]rune("All Files (*.*)\x00*.*\x00Text Files (*.txt)\x00*.txt\x00\x00"))
filenameByteArr := make([]uint16, syscall.MAX_LONG_PATH)
ofn := &OPENFILENAMEW{
HwndOwner: 0,
HInstance: 0,
LStructSize: uint32(unsafe.Sizeof(OPENFILENAMEW{})),
Title: &titleByteArr[0],
Filter: &filterByteArr[0],
File: &filenameByteArr[0],
MaxFile: syscall.MAX_LONG_PATH,
// OFN_FILEMUSTEXIST
Flags: 0x00001000,
}
ret, _, _ := procGetOpenFileName.Call(uintptr(unsafe.Pointer(ofn)))
if ret == 0 {
return "", Err_No_File_Chosen
}
filepath = syscall.UTF16ToString(filenameByteArr)
return filepath, nil
}

36
main.go
View File

@ -16,7 +16,9 @@ import (
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
) )
//TODO: Cache os.ReadDir so we don't have to use lots of disk // @TODO:
// - Cache os.ReadDir so we don't have to use lots of disk
// - Seems undo is broken
type Gopad struct { type Gopad struct {
Win *engine.Window Win *engine.Window
@ -85,7 +87,7 @@ func main() {
// so we do it here // so we do it here
g.LoadFonts() g.LoadFonts()
// engine.SetVSync(true) engine.SetVSync(true)
engine.Run(&g, g.Win, g.ImGUIInfo) engine.Run(&g, g.Win, g.ImGUIInfo)
} }
@ -171,6 +173,18 @@ func (g *Gopad) Update() {
g.showErrorPopup() g.showErrorPopup()
} }
if input.KeyDownCaptured(sdl.K_LCTRL) && input.KeyClickedCaptured(sdl.K_o) {
filepath, err := OpenFileDialog("Open")
if err != nil && err != Err_No_File_Chosen {
g.triggerError(err.Error())
}
if err == nil {
g.loadFileFromPath(filepath)
}
}
if input.MouseClickedCaptued(sdl.BUTTON_LEFT) { if input.MouseClickedCaptued(sdl.BUTTON_LEFT) {
x, y := input.GetMousePos() x, y := input.GetMousePos()
g.getActiveEditor().SetCursorPos(int(x), int(y)) g.getActiveEditor().SetCursorPos(int(x), int(y))
@ -189,15 +203,11 @@ func (g *Gopad) Update() {
e := g.getActiveEditor() e := g.getActiveEditor()
//Save if needed //Save if needed
if !e.IsModified { if e.IsModified {
return if input.KeyDownCaptured(sdl.K_LCTRL) && input.KeyClickedCaptured(sdl.K_s) {
g.saveEditor(e)
}
} }
if !input.KeyDownCaptured(sdl.K_LCTRL) || !input.KeyClickedCaptured(sdl.K_s) {
return
}
g.saveEditor(e)
} }
func (g *Gopad) saveEditor(e *Editor) { func (g *Gopad) saveEditor(e *Editor) {
@ -406,11 +416,11 @@ func (g *Gopad) drawDir(dir fs.DirEntry, path string) {
func (g *Gopad) drawFile(f fs.DirEntry, path string) { func (g *Gopad) drawFile(f fs.DirEntry, path string) {
if imgui.Button(f.Name()) { if imgui.Button(f.Name()) {
g.handleFileClick(path) g.loadFileFromPath(path)
} }
} }
func (g *Gopad) handleFileClick(fPath string) { func (g *Gopad) loadFileFromPath(fPath string) {
//Check if we already have the file open //Check if we already have the file open
editorIndex := -1 editorIndex := -1
@ -432,11 +442,13 @@ func (g *Gopad) handleFileClick(fPath string) {
//Read new file and switch to it //Read new file and switch to it
e := NewEditor(fPath) e := NewEditor(fPath)
e.RefreshFontSettings() e.RefreshFontSettings()
g.editors = append(g.editors, e) g.editors = append(g.editors, e)
g.activeEditor = len(g.editors) - 1 g.activeEditor = len(g.editors) - 1
} }
func (g *Gopad) FrameEnd() { func (g *Gopad) FrameEnd() {
g.newRunes = []rune{} g.newRunes = []rune{}
// Close editors if needed // Close editors if needed