167 lines
4.4 KiB
Go
167 lines
4.4 KiB
Go
// pkg/window/window.go
|
|
package window
|
|
|
|
import (
|
|
"sort"
|
|
"sync"
|
|
)
|
|
|
|
// Window is CoreGUI's own window descriptor, not a Wails type alias.
|
|
type Window struct {
|
|
Name string `json:"name,omitempty"`
|
|
Title string `json:"title,omitempty"`
|
|
URL string `json:"url,omitempty"`
|
|
Width int `json:"width,omitempty"`
|
|
Height int `json:"height,omitempty"`
|
|
X int `json:"x,omitempty"`
|
|
Y int `json:"y,omitempty"`
|
|
MinWidth int `json:"minWidth,omitempty"`
|
|
MinHeight int `json:"minHeight,omitempty"`
|
|
MaxWidth int `json:"maxWidth,omitempty"`
|
|
MaxHeight int `json:"maxHeight,omitempty"`
|
|
Frameless bool `json:"frameless,omitempty"`
|
|
Hidden bool `json:"hidden,omitempty"`
|
|
AlwaysOnTop bool `json:"alwaysOnTop,omitempty"`
|
|
BackgroundColour [4]uint8 `json:"backgroundColour,omitempty"`
|
|
DisableResize bool `json:"disableResize,omitempty"`
|
|
EnableFileDrop bool `json:"enableFileDrop,omitempty"`
|
|
}
|
|
|
|
// ToPlatformOptions converts a Window to PlatformWindowOptions for the backend.
|
|
func (w *Window) ToPlatformOptions() PlatformWindowOptions {
|
|
return PlatformWindowOptions{
|
|
Name: w.Name, Title: w.Title, URL: w.URL,
|
|
Width: w.Width, Height: w.Height, X: w.X, Y: w.Y,
|
|
MinWidth: w.MinWidth, MinHeight: w.MinHeight,
|
|
MaxWidth: w.MaxWidth, MaxHeight: w.MaxHeight,
|
|
Frameless: w.Frameless, Hidden: w.Hidden,
|
|
AlwaysOnTop: w.AlwaysOnTop, BackgroundColour: w.BackgroundColour,
|
|
DisableResize: w.DisableResize, EnableFileDrop: w.EnableFileDrop,
|
|
}
|
|
}
|
|
|
|
// Manager manages window lifecycle through a Platform backend.
|
|
type Manager struct {
|
|
platform Platform
|
|
state *StateManager
|
|
layout *LayoutManager
|
|
windows map[string]PlatformWindow
|
|
defaultWidth int
|
|
defaultHeight int
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
// NewManager creates a window Manager with the given platform backend.
|
|
func NewManager(platform Platform) *Manager {
|
|
return &Manager{
|
|
platform: platform,
|
|
state: NewStateManager(),
|
|
layout: NewLayoutManager(),
|
|
windows: make(map[string]PlatformWindow),
|
|
}
|
|
}
|
|
|
|
// NewManagerWithDir creates a window Manager with a custom config directory for state/layout persistence.
|
|
// Useful for testing or when the default config directory is not appropriate.
|
|
func NewManagerWithDir(platform Platform, configDir string) *Manager {
|
|
return &Manager{
|
|
platform: platform,
|
|
state: NewStateManagerWithDir(configDir),
|
|
layout: NewLayoutManagerWithDir(configDir),
|
|
windows: make(map[string]PlatformWindow),
|
|
}
|
|
}
|
|
|
|
func (m *Manager) SetDefaultWidth(width int) {
|
|
if width > 0 {
|
|
m.defaultWidth = width
|
|
}
|
|
}
|
|
|
|
func (m *Manager) SetDefaultHeight(height int) {
|
|
if height > 0 {
|
|
m.defaultHeight = height
|
|
}
|
|
}
|
|
|
|
// Create opens a window from a declarative spec.
|
|
// Example: m.Create(Window{Name: "editor", Title: "Editor", URL: "/"})
|
|
func (m *Manager) Create(spec Window) (PlatformWindow, error) {
|
|
w := spec
|
|
if w.Name == "" {
|
|
w.Name = "main"
|
|
}
|
|
if w.Title == "" {
|
|
w.Title = "Core"
|
|
}
|
|
if w.Width == 0 {
|
|
if m.defaultWidth > 0 {
|
|
w.Width = m.defaultWidth
|
|
} else {
|
|
w.Width = 1280
|
|
}
|
|
}
|
|
if w.Height == 0 {
|
|
if m.defaultHeight > 0 {
|
|
w.Height = m.defaultHeight
|
|
} else {
|
|
w.Height = 800
|
|
}
|
|
}
|
|
if w.URL == "" {
|
|
w.URL = "/"
|
|
}
|
|
|
|
// Apply saved state if available
|
|
m.state.ApplyState(&w)
|
|
|
|
pw := m.platform.CreateWindow(w.ToPlatformOptions())
|
|
|
|
m.mu.Lock()
|
|
m.windows[w.Name] = pw
|
|
m.mu.Unlock()
|
|
|
|
return pw, nil
|
|
}
|
|
|
|
// Get returns a tracked window by name.
|
|
func (m *Manager) Get(name string) (PlatformWindow, bool) {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
pw, ok := m.windows[name]
|
|
return pw, ok
|
|
}
|
|
|
|
// List returns all tracked window names.
|
|
func (m *Manager) List() []string {
|
|
m.mu.RLock()
|
|
defer m.mu.RUnlock()
|
|
names := make([]string, 0, len(m.windows))
|
|
for name := range m.windows {
|
|
names = append(names, name)
|
|
}
|
|
sort.Strings(names)
|
|
return names
|
|
}
|
|
|
|
// Remove stops tracking a window by name.
|
|
func (m *Manager) Remove(name string) {
|
|
m.mu.Lock()
|
|
delete(m.windows, name)
|
|
m.mu.Unlock()
|
|
}
|
|
|
|
// Platform returns the underlying platform for direct access.
|
|
func (m *Manager) Platform() Platform {
|
|
return m.platform
|
|
}
|
|
|
|
// State returns the state manager for window persistence.
|
|
func (m *Manager) State() *StateManager {
|
|
return m.state
|
|
}
|
|
|
|
// Layout returns the layout manager.
|
|
func (m *Manager) Layout() *LayoutManager {
|
|
return m.layout
|
|
}
|