icecon/main_windows.go

164 lines
3.1 KiB
Go
Raw Permalink Normal View History

2016-05-05 20:39:46 +00:00
//+build windows
2016-05-06 18:39:44 +00:00
2016-05-05 20:39:46 +00:00
package main
2016-05-06 18:39:44 +00:00
//go:generate ui2walk
2016-05-05 20:39:46 +00:00
import (
"fmt"
"log"
"strings"
"syscall"
"github.com/lxn/walk"
"gopkg.in/alecthomas/kingpin.v2"
)
var (
hasGraphicalUI = true
flagGui = kingpin.
Flag("gui", "Run as GUI (runs automatically as GUI if no arguments given, ignored if command flag used)").
Short('g').Bool()
2016-05-06 18:40:12 +00:00
guiInitErr error
kernel32 *syscall.DLL
2016-05-05 20:39:46 +00:00
freeConsole *syscall.Proc
dlg *mainDialog
)
func init() {
kernel32, guiInitErr = syscall.LoadDLL("kernel32.dll")
freeConsole, guiInitErr = kernel32.FindProc("FreeConsole")
}
func uiLogError(text string) {
uiNormalize(&text)
dlg.Synchronize(func() {
dlg.ui.rconOutput.AppendText("ERROR: " + text + "\r\n")
walk.MsgBox(dlg, "Error",
text,
walk.MsgBoxIconError)
})
}
func uiLog(text string) {
uiNormalize(&text)
dlg.Synchronize(func() {
dlg.ui.rconOutput.AppendText(text + "\r\n")
})
}
func uiNormalize(textRef *string) {
text := *textRef
text = strings.Replace(text, "\r", "", -1)
text = strings.Replace(text, "\n", "\r\n", -1)
*textRef = text
}
func runGraphicalUi() (err error) {
dlg = new(mainDialog)
if err := dlg.init(); err != nil {
panic(err)
}
defer dlg.Dispose()
// Window icon
// TODO - Do this more intelligently
for i := uintptr(0); i < uintptr(128); i++ {
if icon, err := walk.NewIconFromResourceId(i); err == nil {
dlg.SetIcon(icon)
break
}
}
// Quit button
quitAction := walk.NewAction()
if err = quitAction.SetText("&Quit"); err != nil {
return
}
quitAction.Triggered().Attach(func() { dlg.Close() })
if err = dlg.Menu().Actions().Add(quitAction); err != nil {
return
}
// Connect button
connectAction := walk.NewAction()
if err = connectAction.SetText("&Connect"); err != nil {
return
}
connectAction.Triggered().Attach(func() {
addressStr := ""
if address != nil {
addressStr = address.String()
}
result, addr, pw, err := runConnectDialog(addressStr, password, dlg)
if err != nil {
uiLogError(fmt.Sprintf("Failed to run connect dialog: %s", err))
return
}
if result {
if err = initSocketAddr(addr); err != nil {
uiLogError(fmt.Sprintf("Couldn't use that address: %s", err))
return
}
password = pw
dlg.ui.rconOutput.SetText("")
}
})
if err = dlg.Menu().Actions().Add(connectAction); err != nil {
return
}
// Handle input
dlg.ui.rconInput.KeyPress().Attach(func(key walk.Key) {
if key != walk.KeyReturn {
return
}
if address == nil {
uiLogError("No server configured.")
return
}
cmd := dlg.ui.rconInput.Text()
dlg.ui.rconInput.SetText("")
uiLog(address.String() + "> " + cmd)
sendRcon(cmd)
})
// When window is initialized we can let a secondary routine print all
// output received
dlg.Synchronize(func() {
go func() {
for {
msg, err := receiveRcon()
if err != nil {
uiLogError(err.Error())
continue
}
switch strings.ToLower(msg.Name) {
case "print":
uiLog(string(msg.Data))
default:
log.Println(msg.Name)
}
}
}()
})
2016-05-06 18:40:12 +00:00
2016-05-05 20:39:46 +00:00
// Get rid of the console window
freeConsole.Call()
dlg.Show()
// Message loop starts here and will block the main goroutine!
dlg.Run()
return
}