...
1 package cview
2
3 import (
4 "sync"
5
6 "github.com/gdamore/tcell/v2"
7 )
8
9
10
11 type Window struct {
12 *Box
13
14 primitive Primitive
15
16 fullscreen bool
17
18 normalX, normalY int
19 normalW, normalH int
20
21 dragX, dragY int
22 dragWX, dragWY int
23
24 sync.RWMutex
25 }
26
27
28 func NewWindow(primitive Primitive) *Window {
29 w := &Window{
30 Box: NewBox(),
31 primitive: primitive,
32 dragWX: -1,
33 dragWY: -1,
34 }
35 w.Box.focus = w
36 return w
37 }
38
39
40
41 func (w *Window) SetFullscreen(fullscreen bool) {
42 w.Lock()
43 defer w.Unlock()
44
45 if w.fullscreen == fullscreen {
46 return
47 }
48
49 w.fullscreen = fullscreen
50 if w.fullscreen {
51 w.normalX, w.normalY, w.normalW, w.normalH = w.GetRect()
52 } else {
53 w.SetRect(w.normalX, w.normalY, w.normalW, w.normalH)
54 }
55 }
56
57
58 func (w *Window) Focus(delegate func(p Primitive)) {
59 w.Lock()
60 defer w.Unlock()
61
62 w.Box.Focus(delegate)
63
64 w.primitive.Focus(delegate)
65 }
66
67
68 func (w *Window) Blur() {
69 w.Lock()
70 defer w.Unlock()
71
72 w.Box.Blur()
73
74 w.primitive.Blur()
75 }
76
77
78 func (w *Window) HasFocus() bool {
79 w.RLock()
80 defer w.RUnlock()
81
82 focusable := w.primitive.GetFocusable()
83 if focusable != nil {
84 return focusable.HasFocus()
85 }
86
87 return w.Box.HasFocus()
88 }
89
90
91 func (w *Window) Draw(screen tcell.Screen) {
92 if !w.GetVisible() {
93 return
94 }
95
96 w.RLock()
97 defer w.RUnlock()
98
99 w.Box.Draw(screen)
100
101 x, y, width, height := w.GetInnerRect()
102 w.primitive.SetRect(x, y, width, height)
103 w.primitive.Draw(screen)
104 }
105
106
107 func (w *Window) InputHandler() func(event *tcell.EventKey, setFocus func(p Primitive)) {
108 return w.primitive.InputHandler()
109 }
110
111
112 func (w *Window) MouseHandler() func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) {
113 return w.WrapMouseHandler(func(action MouseAction, event *tcell.EventMouse, setFocus func(p Primitive)) (consumed bool, capture Primitive) {
114 if !w.InRect(event.Position()) {
115 return false, nil
116 }
117
118 if action == MouseLeftDown || action == MouseMiddleDown || action == MouseRightDown {
119 setFocus(w)
120 }
121
122 if action == MouseLeftDown {
123 x, y, width, height := w.GetRect()
124 mouseX, mouseY := event.Position()
125
126 leftEdge := mouseX == x
127 rightEdge := mouseX == x+width-1
128 bottomEdge := mouseY == y+height-1
129 topEdge := mouseY == y
130
131 if mouseY >= y && mouseY <= y+height-1 {
132 if leftEdge {
133 w.dragX = -1
134 } else if rightEdge {
135 w.dragX = 1
136 }
137 }
138
139 if mouseX >= x && mouseX <= x+width-1 {
140 if bottomEdge {
141 w.dragY = -1
142 } else if topEdge {
143 if leftEdge || rightEdge {
144 w.dragY = 1
145 } else {
146 w.dragWX = mouseX - x
147 w.dragWY = mouseY - y
148 }
149 }
150 }
151 }
152
153 _, capture = w.primitive.MouseHandler()(action, event, setFocus)
154 return true, capture
155 })
156 }
157
View as plain text