wails/exp/pkg/application/window.go
Lea Anthony 2b91ced1b7
Support SetPosition
Optimise event listener callbacks
2022-12-24 13:38:48 +11:00

398 lines
6.8 KiB
Go

package application
import (
"fmt"
"sync"
"github.com/wailsapp/wails/exp/pkg/events"
"github.com/wailsapp/wails/exp/pkg/options"
)
type (
windowImpl interface {
setTitle(title string)
setSize(width, height int)
setAlwaysOnTop(alwaysOnTop bool)
setURL(url string)
setResizable(resizable bool)
setMinSize(width, height int)
setMaxSize(width, height int)
execJS(js string)
setMaximised()
setMinimised()
setFullscreen()
isMinimised() bool
isMaximised() bool
isFullscreen() bool
restore()
setBackgroundColour(color *options.RGBA)
run()
center()
size() (int, int)
width() int
height() int
position() (int, int)
destroy()
reload()
forceReload()
toggleFullscreen()
toggleDevTools()
resetZoom()
zoomIn()
zoomOut()
close()
zoom()
minimize()
setHTML(html string)
setPosition(x int, y int)
on(eventID uint)
}
)
type Window struct {
options *options.Window
impl windowImpl
implLock sync.RWMutex
id uint
eventListeners map[uint][]func()
eventListenersLock sync.RWMutex
}
var windowID uint
var windowIDLock sync.RWMutex
func getWindowID() uint {
windowIDLock.Lock()
defer windowIDLock.Unlock()
windowID++
return windowID
}
func NewWindow(options *options.Window) *Window {
if options.Width == 0 {
options.Width = 800
}
if options.Height == 0 {
options.Height = 600
}
return &Window{
id: getWindowID(),
options: options,
eventListeners: make(map[uint][]func()),
}
}
func (w *Window) SetTitle(title string) *Window {
w.implLock.RLock()
defer w.implLock.RUnlock()
w.options.Title = title
if w.impl != nil {
w.impl.setTitle(title)
}
return w
}
func (w *Window) SetSize(width, height int) *Window {
w.options.Width = width
w.options.Height = height
if w.impl != nil {
w.impl.setSize(width, height)
}
return w
}
func (w *Window) Run() {
if w.impl != nil {
return
}
w.implLock.Lock()
w.impl = newWindowImpl(w)
w.implLock.Unlock()
w.impl.run()
}
func (w *Window) SetAlwaysOnTop(b bool) *Window {
w.options.AlwaysOnTop = b
if w.impl == nil {
w.impl.setAlwaysOnTop(b)
}
return w
}
func (w *Window) SetURL(s string) *Window {
w.options.URL = s
if w.impl != nil {
w.impl.setURL(s)
}
return w
}
func (w *Window) SetResizable(b bool) *Window {
w.options.DisableResize = !b
if w.impl != nil {
w.impl.setResizable(b)
}
return w
}
func (w *Window) Resizable() bool {
return !w.options.DisableResize
}
func (w *Window) SetMinSize(minWidth, minHeight int) *Window {
w.options.MinWidth = minWidth
if w.options.Width < minWidth {
w.options.Width = minWidth
}
w.options.MinHeight = minHeight
if w.options.Height < minHeight {
w.options.Height = minHeight
}
if w.impl != nil {
w.impl.setSize(w.options.Width, w.options.Height)
w.impl.setMinSize(minWidth, minHeight)
}
return w
}
func (w *Window) SetMaxSize(maxWidth, maxHeight int) *Window {
w.options.MinWidth = maxWidth
if w.options.Width > maxWidth {
w.options.Width = maxWidth
}
w.options.MinHeight = maxHeight
if w.options.Height > maxHeight {
w.options.Height = maxHeight
}
if w.impl != nil {
w.impl.setSize(w.options.Width, w.options.Height)
w.impl.setMaxSize(maxWidth, maxHeight)
}
return w
}
func (w *Window) ExecJS(js string) {
if w.impl == nil {
return
}
w.impl.execJS(js)
}
func (w *Window) SetMaximized() *Window {
w.options.StartState = options.WindowStateMaximised
if w.impl != nil {
w.impl.setMaximised()
}
return w
}
// Set Minimized
func (w *Window) SetMinimized() *Window {
w.options.StartState = options.WindowStateMinimised
if w.impl == nil {
w.impl.setMinimised()
}
return w
}
func (w *Window) SetFullscreen() *Window {
w.options.StartState = options.WindowStateFullscreen
if w.impl == nil {
w.impl.setFullscreen()
}
return w
}
// IsMinimised returns true if the window is minimised
func (w *Window) IsMinimised() bool {
if w.impl == nil {
return false
}
return w.impl.isMinimised()
}
// IsMaximised returns true if the window is maximised
func (w *Window) IsMaximised() bool {
if w.impl == nil {
return false
}
return w.impl.isMaximised()
}
// Size returns the current size of the window
func (w *Window) Size() (int, int) {
if w.impl == nil {
return 0, 0
}
return w.impl.size()
}
// IsFullscreen returns true if the window is fullscreen
func (w *Window) IsFullscreen() bool {
w.implLock.RLock()
defer w.implLock.RUnlock()
if w.impl == nil {
return false
}
return w.impl.isFullscreen()
}
func (w *Window) SetBackgroundColour(colour *options.RGBA) *Window {
w.options.BackgroundColour = colour
if w.impl != nil {
w.impl.setBackgroundColour(colour)
}
return w
}
func (w *Window) handleMessage(message string) {
fmt.Printf("[window %d] %s", w.id, message)
// Check for special messages
if message == "test" {
w.SetTitle("Hello World")
}
}
func (w *Window) Center() {
if w.impl == nil {
return
}
w.impl.center()
}
func (w *Window) On(eventType events.WindowEventType, callback func()) {
eventID := uint(eventType)
w.eventListenersLock.Lock()
defer w.eventListenersLock.Unlock()
w.eventListeners[eventID] = append(w.eventListeners[eventID], callback)
if w.impl != nil {
w.impl.on(eventID)
}
}
func (w *Window) handleWindowEvent(id uint) {
w.eventListenersLock.RLock()
for _, callback := range w.eventListeners[id] {
go callback()
}
w.eventListenersLock.RUnlock()
}
func (w *Window) Width() int {
if w.impl == nil {
return 0
}
return w.impl.width()
}
func (w *Window) Height() int {
if w.impl == nil {
return 0
}
return w.impl.height()
}
func (w *Window) Position() (int, int) {
w.implLock.RLock()
defer w.implLock.RUnlock()
if w.impl == nil {
return 0, 0
}
return w.impl.position()
}
func (w *Window) Destroy() {
if w.impl == nil {
return
}
w.impl.destroy()
}
func (w *Window) Reload() {
if w.impl == nil {
return
}
w.impl.reload()
}
func (w *Window) ForceReload() {
if w.impl == nil {
return
}
w.impl.forceReload()
}
func (w *Window) ToggleFullscreen() {
if w.impl == nil {
return
}
w.impl.toggleFullscreen()
}
func (w *Window) ToggleDevTools() {
if w.impl == nil {
return
}
w.impl.toggleDevTools()
}
func (w *Window) ResetZoom() *Window {
if w.impl != nil {
w.impl.resetZoom()
}
return w
}
func (w *Window) ZoomIn() {
if w.impl == nil {
return
}
w.impl.zoomIn()
}
func (w *Window) ZoomOut() {
if w.impl == nil {
return
}
w.impl.zoomOut()
}
func (w *Window) Close() {
if w.impl == nil {
return
}
w.impl.close()
}
func (w *Window) Minimize() {
if w.impl == nil {
return
}
w.impl.minimize()
}
func (w *Window) Zoom() {
if w.impl == nil {
return
}
w.impl.zoom()
}
func (w *Window) SetHTML(html string) *Window {
w.options.HTML = html
if w.impl != nil {
w.impl.setHTML(html)
}
return w
}
func (w *Window) SetPosition(x, y int) *Window {
w.options.X = x
w.options.Y = y
if w.impl != nil {
w.impl.setPosition(x, y)
}
return w
}