5
0
mirror of https://github.com/wailsapp/wails.git synced 2025-05-03 20:22:08 +08:00
wails/v2/internal/app/desktop.go
Lea Anthony a081c1e498
Support for dynamic menus.
Fixed bug in accelerator handling
2020-12-04 15:04:51 +11:00

188 lines
4.2 KiB
Go

// +build desktop,!server
package app
import (
"fmt"
goruntime "runtime"
"github.com/wailsapp/wails/v2/internal/binding"
"github.com/wailsapp/wails/v2/internal/ffenestri"
"github.com/wailsapp/wails/v2/internal/logger"
"github.com/wailsapp/wails/v2/internal/messagedispatcher"
"github.com/wailsapp/wails/v2/internal/runtime"
"github.com/wailsapp/wails/v2/internal/servicebus"
"github.com/wailsapp/wails/v2/internal/signal"
"github.com/wailsapp/wails/v2/internal/subsystem"
"github.com/wailsapp/wails/v2/pkg/menu"
"github.com/wailsapp/wails/v2/pkg/options"
)
// App defines a Wails application structure
type App struct {
window *ffenestri.Application
servicebus *servicebus.ServiceBus
logger *logger.Logger
signal *signal.Manager
options *options.App
// Subsystems
log *subsystem.Log
runtime *subsystem.Runtime
event *subsystem.Event
binding *subsystem.Binding
call *subsystem.Call
menu *subsystem.Menu
dispatcher *messagedispatcher.Dispatcher
// Indicates if the app is in debug mode
debug bool
// This is our binding DB
bindings *binding.Bindings
// Application Stores
loglevelStore *runtime.Store
appconfigStore *runtime.Store
}
// Create App
func CreateApp(options *options.App) *App {
// Merge default options
options.MergeDefaults()
// Set up logger
myLogger := logger.New(options.Logger)
myLogger.SetLogLevel(options.LogLevel)
window := ffenestri.NewApplicationWithConfig(options, myLogger)
result := &App{
window: window,
servicebus: servicebus.New(myLogger),
logger: myLogger,
bindings: binding.NewBindings(myLogger),
}
result.options = options
// Initialise the app
result.Init()
return result
}
// Run the application
func (a *App) Run() error {
// Setup signal handler
signalsubsystem, err := signal.NewManager(a.servicebus, a.logger)
if err != nil {
return err
}
a.signal = signalsubsystem
a.signal.Start()
// Start the service bus
a.servicebus.Debug()
a.servicebus.Start()
// Start the runtime
runtimesubsystem, err := subsystem.NewRuntime(a.servicebus, a.logger,
a.options.Mac.Menu)
if err != nil {
return err
}
a.runtime = runtimesubsystem
a.runtime.Start()
// Application Stores
a.loglevelStore = a.runtime.GoRuntime().Store.New("wails:loglevel", a.options.LogLevel)
a.appconfigStore = a.runtime.GoRuntime().Store.New("wails:appconfig", a.options)
// Start the binding subsystem
bindingsubsystem, err := subsystem.NewBinding(a.servicebus, a.logger,
a.bindings, a.runtime.GoRuntime())
if err != nil {
return err
}
a.binding = bindingsubsystem
a.binding.Start()
// Start the logging subsystem
log, err := subsystem.NewLog(a.servicebus, a.logger, a.loglevelStore)
if err != nil {
return err
}
a.log = log
a.log.Start()
// create the dispatcher
dispatcher, err := messagedispatcher.New(a.servicebus, a.logger)
if err != nil {
return err
}
a.dispatcher = dispatcher
dispatcher.Start()
// Start the eventing subsystem
event, err := subsystem.NewEvent(a.servicebus, a.logger)
if err != nil {
return err
}
a.event = event
a.event.Start()
// Start the menu subsystem
var platformMenu *menu.Menu
switch goruntime.GOOS {
case "darwin":
platformMenu = a.options.Mac.Menu
// case "linux":
// platformMenu = a.options.Linux.Menu
// case "windows":
// platformMenu = a.options.Windows.Menu
default:
return fmt.Errorf("unsupported OS: %s", goruntime.GOOS)
}
menusubsystem, err := subsystem.NewMenu(platformMenu, a.servicebus, a.logger)
if err != nil {
return err
}
a.menu = menusubsystem
a.menu.Start()
// Start the call subsystem
call, err := subsystem.NewCall(a.servicebus, a.logger, a.bindings.DB(), a.runtime.GoRuntime())
if err != nil {
return err
}
a.call = call
a.call.Start()
// Dump bindings as a debug
bindingDump, err := a.bindings.ToJSON()
if err != nil {
return err
}
result := a.window.Run(dispatcher, bindingDump, a.debug)
a.logger.Trace("Ffenestri.Run() exited")
a.servicebus.Stop()
return result
}
// Bind a struct to the application by passing in
// a pointer to it
func (a *App) Bind(structPtr interface{}) {
// Add the struct to the bindings
err := a.bindings.Add(structPtr)
if err != nil {
a.logger.Fatal("Error during binding: " + err.Error())
}
}