client/client_webview.go

154 lines
2.7 KiB
Go

//go:build cgo
// +build cgo
package client
import (
_ "embed"
"os"
"path/filepath"
"strings"
"github.com/ssgo/tool/watcher"
webview "github.com/webview/webview_go"
)
type Webview struct {
id uint64
w webview.WebView
isRunning bool
// isAsync bool
isDebug bool
webRoot string
watcher *watcher.Watcher
html string
url string
closeChan chan bool
}
func (w *Webview) New(isDebug bool) {
w.w = webview.New(isDebug)
}
func (w *Webview) close() {
// fmt.Println("====== w.Close()")
if w.isRunning {
w.isRunning = false
// w.closeChan = make(chan bool, 1)
// fmt.Println("====== w.w.Terminate()")
w.w.Terminate()
// fmt.Println("====== w.w.Terminate() ok")
// <-w.closeChan
// w.closeChan = nil
}
}
func (w *Webview) doClose() {
// fmt.Println("====== w.doClose()")
if w.watcher != nil {
w.watcher.Stop()
w.watcher = nil
}
windowsLock.Lock()
delete(windows, w.id)
n := len(windows)
windowsLock.Unlock()
// fmt.Println("====== w.w.Destroy()")
w.w.Destroy()
// fmt.Println("====== w.w.Destroy() ok")
// 解除 w.Close 的等待
if w.closeChan != nil {
w.closeChan <- true
}
// 解除 gojs.WaitAll 的等待
if waitChan != nil && n == 0 {
waitChan <- true
}
}
func (w *Webview) loadHtml(html string) {
w.w.SetHtml(html)
}
func (w *Webview) loadURL(url string) {
if url != "" {
if strings.Contains(url, "://") {
w.w.Navigate(url)
} else {
if !filepath.IsAbs(url) {
curPath, _ := os.Getwd()
url = filepath.Join(curPath, url)
}
w.webRoot = filepath.Dir(url)
url = "file://" + url
w.w.Navigate(url)
}
} else {
w.w.Navigate("about:blank")
}
}
func (w *Webview) reload() {
if w.html != "" {
w.loadHtml(w.html)
} else {
w.loadURL(w.url)
}
}
func (w *Webview) setTitle(title string) {
w.w.SetTitle(title)
}
func (w *Webview) setSize(width int, height int, sizeMode string) {
w.w.SetSize(width, height, getSizeMode(sizeMode))
}
func (w *Webview) eval(code string) any {
w.w.Eval(code)
return nil
}
func (w *Webview) Dispatch(f func()) {
w.w.Dispatch(f)
}
func (w *Webview) Run() {
w.w.Run()
}
func (w *Webview) binds() {
tmpBinds := map[string]any{}
bindsLock.RLock()
for k, v := range binds {
tmpBinds[k] = v
}
bindsLock.RUnlock()
for k, v := range tmpBinds {
_ = w.w.Bind(k, v)
}
_ = w.w.Bind("__closeWindow", w.close)
_ = w.w.Bind("__setTitle", w.setTitle)
_ = w.w.Bind("__setSize", w.setSize)
_ = w.w.Bind("__eval", w.eval)
w.w.Init(appCode)
}
func getSizeMode(sizeMode string) webview.Hint {
switch sizeMode {
case "none":
return webview.HintNone
case "fixed":
return webview.HintFixed
case "min":
return webview.HintMin
case "max":
return webview.HintMax
default:
return webview.HintNone
}
}