From ccda8c57600382db7edc4e8b79a6f1df4e1e852e Mon Sep 17 00:00:00 2001 From: Lea Anthony Date: Thu, 22 Jul 2021 19:49:54 +1000 Subject: [PATCH] [window] frontend experiment --- v2/go.mod | 4 + v2/go.sum | 5 + v2/internal/appng/app.go | 121 +++++++++++++++++++++++ v2/internal/frontend/frontend.go | 43 ++++++++ v2/internal/frontend/frontend_windows.go | 11 +++ v2/internal/frontend/windows/frontend.go | 95 ++++++++++++++++++ v2/wails.go | 2 + v2/wails_windows.go | 27 +++++ 8 files changed, 308 insertions(+) create mode 100644 v2/internal/appng/app.go create mode 100644 v2/internal/frontend/frontend.go create mode 100644 v2/internal/frontend/frontend_windows.go create mode 100644 v2/internal/frontend/windows/frontend.go create mode 100644 v2/wails_windows.go diff --git a/v2/go.mod b/v2/go.mod index 094362c41..2ff619553 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -28,6 +28,7 @@ require ( github.com/olekukonko/tablewriter v0.0.4 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.7.0 // indirect + github.com/tadvi/winc v0.0.0-20190405175627-5454f291903d github.com/tdewolff/minify v2.3.6+incompatible github.com/tdewolff/parse v2.3.4+incompatible // indirect github.com/tdewolff/test v1.0.6 // indirect @@ -43,3 +44,6 @@ require ( golang.org/x/tools v0.1.0 nhooyr.io/websocket v1.8.6 ) + +replace github.com/tadvi/winc v0.0.0-20190405175627-5454f291903d => C:\Users\leaan\GolandProjects\winc + diff --git a/v2/go.sum b/v2/go.sum index 6ab26f0d8..245ae15c1 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -111,6 +111,8 @@ github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e h1:9MlwzLdW7QSDrhDjFlsEYmxpFyIoXmYRon3dt0io31k= github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lxn/win v0.0.0-20210218163916-a377121e959e h1:H+t6A/QJMbhCSEH5rAuRxh+CtW96g0Or0Fxa9IKr4uc= +github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= @@ -143,6 +145,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tadvi/winc v0.0.0-20190405175627-5454f291903d h1:IMe61i0F1F/AugXLCNYqi8NSqRm6ybWloiU/lQRnk+I= +github.com/tadvi/winc v0.0.0-20190405175627-5454f291903d/go.mod h1:tNBZi4sduF/C3bQE2wGTIccmErQ4A9M9QkPsICVg+oE= github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo= github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs= github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38= @@ -202,6 +206,7 @@ golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/v2/internal/appng/app.go b/v2/internal/appng/app.go new file mode 100644 index 000000000..8283eda24 --- /dev/null +++ b/v2/internal/appng/app.go @@ -0,0 +1,121 @@ +package appng + +import ( + "context" + "github.com/wailsapp/wails/v2/internal/binding" + "github.com/wailsapp/wails/v2/internal/frontend" + "github.com/wailsapp/wails/v2/internal/logger" + "github.com/wailsapp/wails/v2/internal/menumanager" + "github.com/wailsapp/wails/v2/internal/signal" + "github.com/wailsapp/wails/v2/pkg/options" + "time" +) + +// App defines a Wails application structure +type App struct { + frontend frontend.Frontend + logger *logger.Logger + signal *signal.Manager + options *options.App + + menuManager *menumanager.Manager + + // Indicates if the app is in debug mode + debug bool + + // This is our binding DB + bindings *binding.Bindings + + // Startup/Shutdown + startupCallback func(ctx context.Context) + shutdownCallback func() +} + +func (a *App) Run() error { + + go func() { + time.Sleep(1 * time.Second) + println("fullscreen") + a.frontend.WindowFullscreen() + time.Sleep(1 * time.Second) + println("unfullscreen") + a.frontend.WindowUnFullscreen() + time.Sleep(1 * time.Second) + println("hide") + a.frontend.WindowHide() + time.Sleep(1 * time.Second) + println("show") + a.frontend.WindowShow() + time.Sleep(1 * time.Second) + }() + + return a.frontend.Run() +} + +// CreateApp +func CreateApp(appoptions *options.App) (*App, error) { + + // Merge default options + options.MergeDefaults(appoptions) + + // Set up logger + myLogger := logger.New(appoptions.Logger) + myLogger.SetLogLevel(appoptions.LogLevel) + + // Create the menu manager + menuManager := menumanager.NewManager() + + // Process the application menu + appMenu := options.GetApplicationMenu(appoptions) + err := menuManager.SetApplicationMenu(appMenu) + if err != nil { + return nil, err + } + + // Process context menus + contextMenus := options.GetContextMenus(appoptions) + for _, contextMenu := range contextMenus { + menuManager.AddContextMenu(contextMenu) + } + + // Process tray menus + trayMenus := options.GetTrayMenus(appoptions) + for _, trayMenu := range trayMenus { + _, err := menuManager.AddTrayMenu(trayMenu) + if err != nil { + return nil, err + } + } + + //window := ffenestri.NewApplicationWithConfig(appoptions, myLogger, menuManager) + appFrontend := frontend.NewFrontend(appoptions, myLogger) + + // Create binding exemptions - Ugly hack. There must be a better way + bindingExemptions := []interface{}{appoptions.Startup, appoptions.Shutdown} + + result := &App{ + frontend: appFrontend, + logger: myLogger, + bindings: binding.NewBindings(myLogger, appoptions.Bind, bindingExemptions), + menuManager: menuManager, + startupCallback: appoptions.Startup, + shutdownCallback: appoptions.Shutdown, + } + + result.options = appoptions + + //// Initialise the app + //err := result.Init() + //if err != nil { + // return nil, err + //} + // + //// Preflight Checks + //err = result.PreflightChecks(appoptions) + //if err != nil { + // return nil, err + //} + + return result, nil + +} diff --git a/v2/internal/frontend/frontend.go b/v2/internal/frontend/frontend.go new file mode 100644 index 000000000..55eeede18 --- /dev/null +++ b/v2/internal/frontend/frontend.go @@ -0,0 +1,43 @@ +package frontend + +type Frontend interface { + + // Main methods + Run() error + Quit() + + //// Events + //NotifyEvent(message string) + //CallResult(message string) + // + //// Dialog + //OpenFileDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) + //OpenMultipleFilesDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) + //OpenDirectoryDialog(dialogOptions dialog.OpenDialogOptions, callbackID string) + //SaveDialog(dialogOptions dialog.SaveDialogOptions, callbackID string) + //MessageDialog(dialogOptions dialog.MessageDialogOptions, callbackID string) + + // Window + //WindowSetTitle(title string) + WindowShow() + WindowHide() + //WindowCenter() + //WindowMaximise() + //WindowUnmaximise() + //WindowMinimise() + //WindowUnminimise() + //WindowPosition(x int, y int) + //WindowSize(width int, height int) + //WindowSetMinSize(width int, height int) + //WindowSetMaxSize(width int, height int) + WindowFullscreen() + WindowUnFullscreen() + //WindowSetColour(colour int) + // + //// Menus + //SetApplicationMenu(menu *menu.Menu) + //SetTrayMenu(menu *menu.TrayMenu) + //UpdateTrayMenuLabel(menu *menu.TrayMenu) + //UpdateContextMenu(contextMenu *menu.ContextMenu) + //DeleteTrayMenuByID(id string) +} diff --git a/v2/internal/frontend/frontend_windows.go b/v2/internal/frontend/frontend_windows.go new file mode 100644 index 000000000..b70238c15 --- /dev/null +++ b/v2/internal/frontend/frontend_windows.go @@ -0,0 +1,11 @@ +package frontend + +import ( + "github.com/wailsapp/wails/v2/internal/frontend/windows" + "github.com/wailsapp/wails/v2/internal/logger" + "github.com/wailsapp/wails/v2/pkg/options" +) + +func NewFrontend(appoptions *options.App, myLogger *logger.Logger) *windows.Frontend { + return windows.NewFrontend(appoptions, myLogger) +} diff --git a/v2/internal/frontend/windows/frontend.go b/v2/internal/frontend/windows/frontend.go new file mode 100644 index 000000000..79977d51f --- /dev/null +++ b/v2/internal/frontend/windows/frontend.go @@ -0,0 +1,95 @@ +package windows + +import ( + "github.com/tadvi/winc" + "github.com/tadvi/winc/w32" + "github.com/wailsapp/wails/v2/internal/logger" + "github.com/wailsapp/wails/v2/pkg/options" + "runtime" + "time" +) + +type Frontend struct { + options *options.App + logger *logger.Logger + + // main window handle + mainWindow *winc.Form +} + +func (f *Frontend) Run() error { + + exStyle := w32.WS_EX_CONTROLPARENT | w32.WS_EX_APPWINDOW + if f.options.Windows.WindowBackgroundIsTranslucent { + exStyle |= w32.WS_EX_NOREDIRECTIONBITMAP + } + + var dwStyle uint + if f.options.Frameless { + dwStyle = w32.WS_POPUP + } + + mainWindow := winc.NewCustomForm(nil, exStyle, dwStyle) + f.mainWindow = mainWindow + mainWindow.SetSize(f.options.Width, f.options.Height) + mainWindow.SetText(f.options.Title) + mainWindow.EnableSizable(!f.options.DisableResize) + mainWindow.EnableMaxButton(!f.options.DisableResize) + + if f.options.Windows.WindowBackgroundIsTranslucent { + mainWindow.SetTranslucentBackground() + } + + if f.options.Fullscreen { + mainWindow.Fullscreen() + } + + mainWindow.Center() + mainWindow.Show() + mainWindow.OnClose().Bind(func(arg *winc.Event) { + if f.options.HideWindowOnClose { + + go func() { + time.Sleep(1 * time.Second) + f.WindowShow() + }() + } else { + f.Quit() + } + }) + + winc.RunMainLoop() + return nil +} + +func (f *Frontend) WindowFullscreen() { + runtime.LockOSThread() + f.mainWindow.Fullscreen() +} + +func (f *Frontend) WindowUnFullscreen() { + runtime.LockOSThread() + f.mainWindow.UnFullscreen() +} + +func (f *Frontend) WindowShow() { + runtime.LockOSThread() + f.mainWindow.Show() +} + +func (f *Frontend) WindowHide() { + runtime.LockOSThread() + f.mainWindow.Hide() +} + +func (f *Frontend) Quit() { + winc.Exit() +} + +func NewFrontend(appoptions *options.App, myLogger *logger.Logger) *Frontend { + + return &Frontend{ + options: appoptions, + logger: myLogger, + } +} diff --git a/v2/wails.go b/v2/wails.go index f2177fe3b..00b61d7dd 100644 --- a/v2/wails.go +++ b/v2/wails.go @@ -1,3 +1,5 @@ +// +build !windows + // Package wails is the main package of the Wails project. // It is used by client applications. package wails diff --git a/v2/wails_windows.go b/v2/wails_windows.go new file mode 100644 index 000000000..a5575d740 --- /dev/null +++ b/v2/wails_windows.go @@ -0,0 +1,27 @@ +// +build windows + +// Package wails is the main package of the Wails project. +// It is used by client applications. +package wails + +import ( + app "github.com/wailsapp/wails/v2/internal/appng" + "github.com/wailsapp/wails/v2/pkg/options" +) + +// Run creates an application based on the given config and executes it +func Run(options *options.App) error { + + // Call an Init method manually + err := Init() + if err != nil { + return err + } + + mainapp, err := app.CreateApp(options) + if err != nil { + return err + } + + return mainapp.Run() +}