-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
border.go
92 lines (84 loc) · 3.3 KB
/
border.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
// Copyright (c) 2021-2024 by Richard A. Wilkes. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, version 2.0. If a copy of the MPL was not distributed with
// this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// This Source Code Form is "Incompatible With Secondary Licenses", as
// defined by the Mozilla Public License, version 2.0.
package unison
const previousFocusCallbacksKey = "internal.previous.focus.callbacks"
type previousFocusCallbacks struct {
GainedFocusCallback func()
LostFocusCallback func()
}
// Border defines methods required of all border providers.
type Border interface {
// Insets returns the insets describing the space the border occupies on each side.
Insets() Insets
// Draw the border into rect.
Draw(canvas *Canvas, rect Rect)
}
// NewDefaultFieldBorder creates the default border for a field.
func NewDefaultFieldBorder(focused bool) Border {
var adj float32
var ink Ink
if focused {
adj = 0
ink = ThemeFocus
} else {
adj = 1
ink = ThemeSurfaceEdge
}
return NewCompoundBorder(
NewLineBorder(ink, 0, NewUniformInsets(2-adj), false),
NewEmptyBorder(Insets{Top: 2 + adj, Left: 2 + adj, Bottom: 1 + adj, Right: 2 + adj}),
)
}
// InstallFocusBorders installs the provided borders on the borderTarget and chains into the focus handling of the
// focusTarget to adjust the border as focus changes. To prevent the display from shifting around, the borders should
// have the same insets.
func InstallFocusBorders(focusTarget, borderTarget Paneler, focusedBorder, unfocusedBorder Border) {
focusPanel := focusTarget.AsPanel()
borderPanel := borderTarget.AsPanel()
clientData := focusPanel.ClientData()
previous, ok := clientData[previousFocusCallbacksKey].(previousFocusCallbacks)
if !ok {
previous = previousFocusCallbacks{
GainedFocusCallback: focusPanel.GainedFocusCallback,
LostFocusCallback: focusPanel.LostFocusCallback,
}
}
clientData[previousFocusCallbacksKey] = previous
focusPanel.GainedFocusCallback = func() {
borderPanel.SetBorder(focusedBorder)
if previous.GainedFocusCallback != nil {
previous.GainedFocusCallback()
}
}
focusPanel.LostFocusCallback = func() {
borderPanel.SetBorder(unfocusedBorder)
if previous.LostFocusCallback != nil {
previous.LostFocusCallback()
}
}
borderPanel.SetBorder(unfocusedBorder)
}
// UninstallFocusBorders removes the focus handling and border from the borderTarget that was installed by a previous
// call to InstallFocusBorders.
func UninstallFocusBorders(focusTarget, borderTarget Paneler) {
focusPanel := focusTarget.AsPanel()
borderPanel := borderTarget.AsPanel()
clientData := focusPanel.ClientData()
if previous, ok := clientData[previousFocusCallbacksKey].(previousFocusCallbacks); ok {
focusPanel.GainedFocusCallback = previous.GainedFocusCallback
focusPanel.LostFocusCallback = previous.LostFocusCallback
}
borderPanel.SetBorder(nil)
delete(clientData, previousFocusCallbacksKey)
}
// InstallDefaultFieldBorder installs the default field border on the borderTarget and chains into the focus handling of
// the focusTarget to adjust the border as focus changes.
func InstallDefaultFieldBorder(focusTarget, borderTarget Paneler) {
InstallFocusBorders(focusTarget, borderTarget, NewDefaultFieldBorder(true), NewDefaultFieldBorder(false))
}