-
Notifications
You must be signed in to change notification settings - Fork 1
/
bring_display.go
115 lines (95 loc) · 2.41 KB
/
bring_display.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package main
import (
"image"
"image/color"
"fyne.io/fyne"
"fyne.io/fyne/canvas"
"fyne.io/fyne/widget"
"github.com/deluan/bring"
)
type bringDisplayRenderer struct {
objects []fyne.CanvasObject
remote *BringDisplay
}
func (r *bringDisplayRenderer) MinSize() fyne.Size {
return r.remote.MinSize()
}
func (r *bringDisplayRenderer) Layout(size fyne.Size) {
if len(r.objects) == 0 {
return
}
r.objects[0].Resize(size)
}
func (r *bringDisplayRenderer) Objects() []fyne.CanvasObject {
return r.objects
}
func (r *bringDisplayRenderer) BackgroundColor() color.Color {
return color.Transparent
}
func (r *bringDisplayRenderer) Refresh() {
if len(r.objects) == 0 {
raster := canvas.NewImageFromImage(r.remote.Display)
raster.FillMode = canvas.ImageFillContain
r.objects = append(r.objects, raster)
} else {
r.objects[0].(*canvas.Image).Image = r.remote.Display
}
r.Layout(r.remote.Size())
canvas.Refresh(r.remote)
}
func (r *bringDisplayRenderer) Destroy() {
}
// Custom Widget that represents the remote computer being controlled
type BringDisplay struct {
widget.BaseWidget
keyboardHandler
mouseHandler
lastUpdate int64
Display image.Image
Client *bring.Client
}
// Creates a new BringDisplay and does all the heavy lifting, setting up all event handlers
func NewBringDisplay(client *bring.Client, width, height int) *BringDisplay {
empty := image.NewNRGBA(image.Rect(0, 0, width-1, height-1))
b := &BringDisplay{
Client: client,
}
b.keyboardHandler.display = b
b.mouseHandler.display = b
b.SetDisplay(empty)
b.Client.OnSync(func(img image.Image, ts int64) {
if ts == b.lastUpdate {
return
}
b.lastUpdate = ts
b.SetDisplay(img)
})
go b.Client.Start()
return b
}
func (b *BringDisplay) MinSize() fyne.Size {
b.ExtendBaseWidget(b)
return fyne.Size{
Width: b.Display.Bounds().Dx(),
Height: b.Display.Bounds().Dy(),
}
}
func (b *BringDisplay) CreateRenderer() fyne.WidgetRenderer {
return &bringDisplayRenderer{
objects: []fyne.CanvasObject{},
remote: b,
}
}
// This forces a display refresh if there are any pending updates, instead of waiting for the next
// OnSync event. Ex: when moving the mouse we want instant feedback of the new cursor position
func (b *BringDisplay) updateDisplay() {
img, ts := b.Client.Screen()
if ts != b.lastUpdate {
b.SetDisplay(img)
b.lastUpdate = ts
}
}
func (b *BringDisplay) SetDisplay(img image.Image) {
b.Display = img
b.Refresh()
}