mirror of
https://github.com/bloeys/gopad.git
synced 2025-12-29 15:08:21 +00:00
Native windows open file dialog
This commit is contained in:
@ -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
71
file_dialogs_windows.go
Executable 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
36
main.go
@ -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) {
|
||||||
}
|
|
||||||
|
|
||||||
if !input.KeyDownCaptured(sdl.K_LCTRL) || !input.KeyClickedCaptured(sdl.K_s) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
g.saveEditor(e)
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user