Files
voidraft/internal/services/window_service.go
2025-11-05 22:07:43 +08:00

142 lines
4.1 KiB
Go

package services
import (
"context"
"fmt"
"strconv"
"voidraft/internal/common/constant"
"github.com/wailsapp/wails/v3/pkg/application"
"github.com/wailsapp/wails/v3/pkg/events"
"github.com/wailsapp/wails/v3/pkg/services/log"
)
// WindowService 窗口管理服务
type WindowService struct {
logger *log.LogService
documentService *DocumentService
// 吸附服务引用
windowSnapService *WindowSnapService
}
// NewWindowService 创建新的窗口服务实例
func NewWindowService(logger *log.LogService, documentService *DocumentService, windowSnapService *WindowSnapService) *WindowService {
if logger == nil {
logger = log.New()
}
return &WindowService{
logger: logger,
documentService: documentService,
windowSnapService: windowSnapService,
}
}
// ServiceStartup 服务启动时初始化
func (ws *WindowService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
ws.windowSnapService.UpdateMainWindowCache()
return nil
}
// OpenDocumentWindow 为指定文档ID打开新窗口
func (ws *WindowService) OpenDocumentWindow(documentID int64) error {
app := application.Get()
windowName := strconv.FormatInt(documentID, 10)
if existingWindow, exists := app.Window.GetByName(windowName); exists {
// 窗口已存在,显示并聚焦
existingWindow.Show()
existingWindow.Restore()
existingWindow.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 := app.Window.NewWithOptions(application.WebviewWindowOptions{
Name: windowName,
Title: fmt.Sprintf("voidraft - %s", doc.Title),
Width: constant.VOIDRAFT_WINDOW_WIDTH,
Height: constant.VOIDRAFT_WINDOW_HEIGHT,
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),
})
// 注册窗口事件
ws.registerWindowEvents(newWindow, documentID)
// 向吸附服务注册新窗口
if ws.windowSnapService != nil {
ws.windowSnapService.RegisterWindow(documentID, newWindow)
}
// 最后才移动窗口到中心
newWindow.Center()
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) {
// 从吸附服务中取消注册
if ws.windowSnapService != nil {
ws.windowSnapService.UnregisterWindow(documentID)
}
}
// GetOpenWindows 获取所有打开的文档窗口
func (ws *WindowService) GetOpenWindows() []application.Window {
app := application.Get()
return app.Window.GetAll()
}
// IsDocumentWindowOpen 检查指定文档的窗口是否已打开
func (ws *WindowService) IsDocumentWindowOpen(documentID int64) bool {
app := application.Get()
windowName := strconv.FormatInt(documentID, 10)
_, exists := app.Window.GetByName(windowName)
return exists
}
// ServiceShutdown 实现服务关闭接口
func (ws *WindowService) ServiceShutdown() error {
// 从吸附服务中取消注册所有窗口
if ws.windowSnapService != nil {
windows := ws.GetOpenWindows()
for _, window := range windows {
if documentID, err := strconv.ParseInt(window.Name(), 10, 64); err == nil {
ws.windowSnapService.UnregisterWindow(documentID)
}
}
}
return nil
}