first commit
This commit is contained in:
commit
3553790475
27 files changed
+3839
No files matched your search
@@ -0,0 +1,127 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"fyne.io/fyne/v2"
|
||||
"fyne.io/fyne/v2/container"
|
||||
"fyne.io/fyne/v2/widget"
|
||||
|
||||
"viewsagent/internal/capture"
|
||||
"viewsagent/internal/win32"
|
||||
)
|
||||
|
||||
// cardTitle 是答案浮窗的标题,win32 靠它找 HWND。
|
||||
const cardTitle = "viewsagent-card"
|
||||
|
||||
// floatCard 是贴在选区旁边的置顶小窗,只显示最新答案。
|
||||
type floatCard struct {
|
||||
win fyne.Window
|
||||
body *widget.RichText
|
||||
region capture.Region
|
||||
visible bool
|
||||
}
|
||||
|
||||
func newFloatCard(a fyne.App) *floatCard {
|
||||
c := &floatCard{win: a.NewWindow(cardTitle)}
|
||||
rt := widget.NewRichText()
|
||||
rt.Wrapping = fyne.TextWrapWord
|
||||
c.body = rt
|
||||
|
||||
c.win.SetContent(container.NewBorder(
|
||||
nil, nil, nil, nil,
|
||||
container.NewPadded(rt),
|
||||
))
|
||||
c.win.Resize(fyne.NewSize(400, 240))
|
||||
return c
|
||||
}
|
||||
|
||||
// setRegion 记录当前监视区域,用于定位浮窗。
|
||||
func (c *floatCard) setRegion(r capture.Region) {
|
||||
c.region = r
|
||||
}
|
||||
|
||||
// update 刷新浮窗内容。
|
||||
func (c *floatCard) update(text string) {
|
||||
text = strings.TrimSpace(text)
|
||||
if text == "" {
|
||||
text = "(空)"
|
||||
}
|
||||
c.body.ParseMarkdown(text)
|
||||
if c.visible {
|
||||
c.place()
|
||||
}
|
||||
}
|
||||
|
||||
// show 显示浮窗。
|
||||
func (c *floatCard) show() {
|
||||
if c.visible {
|
||||
c.place()
|
||||
c.win.RequestFocus()
|
||||
return
|
||||
}
|
||||
c.visible = true
|
||||
c.win.Show()
|
||||
go func() {
|
||||
time.Sleep(120 * time.Millisecond)
|
||||
fyne.Do(c.place)
|
||||
}()
|
||||
}
|
||||
|
||||
// hide 隐藏浮窗。
|
||||
func (c *floatCard) hide() {
|
||||
c.visible = false
|
||||
c.win.Hide()
|
||||
}
|
||||
|
||||
// toggle 切换显示状态。
|
||||
func (c *floatCard) toggle() {
|
||||
if c.visible {
|
||||
c.hide()
|
||||
return
|
||||
}
|
||||
c.show()
|
||||
}
|
||||
|
||||
// visibleNow 返回是否正在显示。
|
||||
func (c *floatCard) visibleNow() bool { return c.visible }
|
||||
|
||||
// place 把浮窗贴到选区下方(放不下就贴上方),并置顶。
|
||||
func (c *floatCard) place() {
|
||||
hwnd, err := win32.FindWindowByTitle(cardTitle)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
_ = win32.SetTopMost(hwnd)
|
||||
|
||||
rect, err := win32.WindowRect(hwnd)
|
||||
if err != nil || rect.Width() <= 0 || rect.Height() <= 0 {
|
||||
return
|
||||
}
|
||||
if !c.region.Valid() {
|
||||
return
|
||||
}
|
||||
mon, _ := win32.MonitorAt(c.region.X+c.region.W/2, c.region.Y+c.region.H/2)
|
||||
work := mon.Work
|
||||
if work.Width() <= 0 {
|
||||
work = mon.Rect
|
||||
}
|
||||
gap := int(8 * max(mon.Scale, 1))
|
||||
|
||||
x := c.region.X
|
||||
y := c.region.Y + c.region.H + gap
|
||||
if y+rect.Height() > work.Bottom {
|
||||
y = c.region.Y - rect.Height() - gap
|
||||
}
|
||||
if y < work.Top {
|
||||
y = work.Bottom - rect.Height()
|
||||
}
|
||||
if x+rect.Width() > work.Right {
|
||||
x = work.Right - rect.Width()
|
||||
}
|
||||
if x < work.Left {
|
||||
x = work.Left
|
||||
}
|
||||
_ = win32.MoveTo(hwnd, win32.Rect{Left: x, Top: y, Right: x + rect.Width(), Bottom: y + rect.Height()})
|
||||
}
|
||||
Reference in new issue
Block a user