Files
voidraft/internal/services/window_service.go

150 lines
3.9 KiB
Go

package services
import (
"fmt"
"sync"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
"github.com/wailsapp/wails/v3/pkg/services/log"
)
// WindowInfo 窗口信息
type WindowInfo struct {
Window *application.WebviewWindow
DocumentID int64
Title string
}
// WindowService 窗口管理服务
type WindowService struct {
logger *log.Service
documentService *DocumentService
app *application.App
mainWindow *application.WebviewWindow
windows map[int64]*WindowInfo // documentID -> WindowInfo
mu sync.RWMutex
}
// NewWindowService 创建新的窗口服务实例
func NewWindowService(logger *log.Service, documentService *DocumentService) *WindowService {
if logger == nil {
logger = log.New()
}
return &WindowService{
logger: logger,
documentService: documentService,
windows: make(map[int64]*WindowInfo),
}
}
// SetAppReferences 设置应用和主窗口引用
func (ws *WindowService) SetAppReferences(app *application.App, mainWindow *application.WebviewWindow) {
ws.app = app
ws.mainWindow = mainWindow
}
// OpenDocumentWindow 为指定文档ID打开新窗口
func (ws *WindowService) OpenDocumentWindow(documentID int64) error {
ws.mu.Lock()
defer ws.mu.Unlock()
// 检查窗口是否已经存在
if windowInfo, exists := ws.windows[documentID]; exists {
// 窗口已存在,显示并聚焦
windowInfo.Window.Show()
windowInfo.Window.Restore()
windowInfo.Window.Focus()
return nil
}
// 获取文档信息
doc, err := ws.documentService.GetDocumentByID(documentID)
if err != nil {
return fmt.Errorf("failed to get document: %w", err)
}
if doc == nil {
return fmt.Errorf("document not found: %d", documentID)
}
// 创建新窗口
newWindow := ws.app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: fmt.Sprintf("voidraft - %s", doc.Title),
Width: 700,
Height: 800,
Hidden: false,
Frameless: true,
DevToolsEnabled: false,
DefaultContextMenuDisabled: false,
Mac: application.MacWindow{
InvisibleTitleBarHeight: 50,
Backdrop: application.MacBackdropTranslucent,
TitleBar: application.MacTitleBarHiddenInset,
},
Windows: application.WindowsWindow{
Theme: application.SystemDefault,
},
BackgroundColour: application.NewRGB(27, 38, 54),
URL: fmt.Sprintf("/?documentId=%d", documentID),
})
newWindow.Center()
ws.app.Window.Add(newWindow)
// 保存窗口信息
windowInfo := &WindowInfo{
Window: newWindow,
DocumentID: documentID,
Title: doc.Title,
}
ws.windows[documentID] = windowInfo
// 注册窗口关闭事件
ws.registerWindowEvents(newWindow, documentID)
return nil
}
// registerWindowEvents 注册窗口事件
func (ws *WindowService) registerWindowEvents(window *application.WebviewWindow, documentID int64) {
// 注册窗口关闭事件
window.RegisterHook(events.Common.WindowClosing, func(event *application.WindowEvent) {
ws.onWindowClosing(documentID)
})
}
// onWindowClosing 处理窗口关闭事件
func (ws *WindowService) onWindowClosing(documentID int64) {
ws.mu.Lock()
defer ws.mu.Unlock()
windowInfo, exists := ws.windows[documentID]
if exists {
windowInfo.Window.Close()
delete(ws.windows, documentID)
}
}
// GetOpenWindows 获取所有打开的窗口信息
func (ws *WindowService) GetOpenWindows() []WindowInfo {
ws.mu.RLock()
defer ws.mu.RUnlock()
var windows []WindowInfo
for _, windowInfo := range ws.windows {
windows = append(windows, *windowInfo)
}
return windows
}
// IsDocumentWindowOpen 检查指定文档的窗口是否已打开
func (ws *WindowService) IsDocumentWindowOpen(documentID int64) bool {
ws.mu.RLock()
defer ws.mu.RUnlock()
_, exists := ws.windows[documentID]
return exists
}