-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdropdown.go
216 lines (197 loc) · 10 KB
/
dropdown.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package consolizer
import (
"github.com/supercom32/consolizer/constants"
"github.com/supercom32/consolizer/internal/memory"
"github.com/supercom32/consolizer/internal/stringformat"
"github.com/supercom32/consolizer/types"
)
type DropdownInstanceType struct {
layerAlias string
dropdownAlias string
}
type dropdownType struct{}
var Dropdown dropdownType
func (shared *DropdownInstanceType) Delete() *DropdownInstanceType {
if memory.IsDropdownExists(shared.layerAlias, shared.dropdownAlias) {
memory.DeleteDropdown(shared.layerAlias, shared.dropdownAlias)
}
return nil
}
func (shared *DropdownInstanceType) GetValue() string {
dropdownEntry := memory.GetDropdown(shared.layerAlias, shared.dropdownAlias)
return dropdownEntry.SelectionEntry.SelectionValue[dropdownEntry.ItemSelected]
}
func (shared *DropdownInstanceType) GetAlias() string {
dropdownEntry := memory.GetDropdown(shared.layerAlias, shared.dropdownAlias)
return dropdownEntry.SelectionEntry.SelectionAlias[dropdownEntry.ItemSelected]
}
/*
Add allows you to add a Dropdown to a given text layer. Once called, an instance of
your control is returned which will allow you to read or manipulate the properties for it.
The Style of the Dropdown will be determined by the style entry passed in. If you wish to
remove a Dropdown from a text layer, simply call 'DeleteDropdown'. In addition, the
following information should be noted:
- Dropdowns are not drawn physically to the text layer provided. Instead,
they are rendered to the terminal at the same time when the text layer is
rendered. This allows you to create dropdowns without actually overwriting
the text layer data under it.
- If the Dropdown to be drawn falls outside the range of the provided layer,
then only the visible portion of the Checkbox will be drawn.
- If the number of selections available is smaller or equal to the Selector height,
then no scrollbars will be drawn.
*/
func (shared *dropdownType) Add(layerAlias string, dropdownAlias string, styleEntry types.TuiStyleEntryType, selectionEntry types.SelectionEntryType, xLocation int, yLocation int, selectorHeight int, itemWidth int, defaultItemSelected int) DropdownInstanceType {
// TODO: Add validation to the default item selected.
memory.AddDropdown(layerAlias, dropdownAlias, styleEntry, selectionEntry, xLocation, yLocation, itemWidth, defaultItemSelected)
dropdownEntry := memory.GetDropdown(layerAlias, dropdownAlias)
dropdownEntry.ScrollBarAlias = stringformat.GetLastSortedUUID()
// Here we add +2 to x to account for the scroll bar being outside the Selector border on ether side. Also, we
// minus the scroll bar max selection size by the height of the Selector, so we don't scroll over values
// which do not change viewport.
selectorWidth := itemWidth
if len(selectionEntry.SelectionValue) <= selectorHeight {
selectorWidth = selectorWidth + 1
}
dropdownEntry.SelectorAlias = stringformat.GetLastSortedUUID()
// Here we add +1 to x and y to account for borders around the selection.
Selector.Add(layerAlias, dropdownEntry.SelectorAlias, styleEntry, selectionEntry, xLocation+1, yLocation+1, selectorHeight, selectorWidth, 1, 0, 0, true)
selectorEntry := memory.GetSelector(layerAlias, dropdownEntry.SelectorAlias)
selectorEntry.IsVisible = false
dropdownEntry.ScrollBarAlias = selectorEntry.ScrollBarAlias
scrollBarEntry := memory.GetScrollbar(layerAlias, dropdownEntry.ScrollBarAlias)
scrollBarEntry.IsVisible = false
if len(selectionEntry.SelectionValue) <= selectorHeight {
scrollBarEntry.IsEnabled = false
}
var dropdownInstance DropdownInstanceType
dropdownInstance.layerAlias = layerAlias
dropdownInstance.dropdownAlias = dropdownAlias
return dropdownInstance
}
func (shared *dropdownType) DeleteDropdown(layerAlias string, dropdownAlias string) {
memory.DeleteDropdown(layerAlias, dropdownAlias)
}
func (shared *dropdownType) DeleteAllDropdowns(layerAlias string) {
memory.DeleteAllDropdownsFromLayer(layerAlias)
}
/*
drawDropdownsOnLayer allows you to draw all dropdowns on a given text layer.
*/
func (shared *dropdownType) drawDropdownsOnLayer(layerEntry types.LayerEntryType) {
layerAlias := layerEntry.LayerAlias
for currentKey := range memory.Dropdown.Entries[layerAlias] {
shared.drawDropdown(&layerEntry, currentKey)
}
}
/*
drawDropdown allows you to draw A Dropdown on a given text layer. The
Style of the Dropdown will be determined by the style entry passed in. In
addition, the following information should be noted:
- dropdowns are not drawn physically to the text layer provided. Instead,
they are rendered to the terminal at the same time when the text layer is
rendered. This allows you to create dropdowns without actually overwriting
the text layer data under it.
- If the Dropdown to be drawn falls outside the range of the provided layer,
then only the visible portion of the Dropdown will be drawn.
*/
func (shared *dropdownType) drawDropdown(layerEntry *types.LayerEntryType, dropdownAlias string) {
layerAlias := layerEntry.LayerAlias
dropdownEntry := memory.GetDropdown(layerAlias, dropdownAlias)
localStyleEntry := types.NewTuiStyleEntry(&dropdownEntry.StyleEntry)
attributeEntry := types.NewAttributeEntry()
attributeEntry.ForegroundColor = localStyleEntry.SelectorForegroundColor
attributeEntry.BackgroundColor = localStyleEntry.SelectorBackgroundColor
attributeEntry.CellType = constants.CellTypeDropdown
attributeEntry.CellControlAlias = dropdownAlias
itemSelected := dropdownEntry.SelectionEntry.SelectionValue[dropdownEntry.ItemSelected]
// We add +2 to account for the Dropdown border window which will appear. Otherwise, the item name
// will appear 2 characters smaller than the popup Dropdown window.
formattedItemName := stringformat.GetFormattedString(itemSelected, dropdownEntry.ItemWidth+2, localStyleEntry.SelectorTextAlignment)
arrayOfRunes := stringformat.GetRunesFromString(formattedItemName)
printLayer(layerEntry, attributeEntry, dropdownEntry.XLocation, dropdownEntry.YLocation, arrayOfRunes)
attributeEntry.ForegroundColor = localStyleEntry.SelectorBackgroundColor
attributeEntry.BackgroundColor = localStyleEntry.SelectorForegroundColor
printLayer(layerEntry, attributeEntry, dropdownEntry.XLocation+len(arrayOfRunes), dropdownEntry.YLocation, []rune{constants.CharTriangleDown})
}
/*
updateDropdownStateMouse allows you to update the state of all dropdowns according to the current mouse event state.
In the event that a screen update is required this method returns true.
*/
func (shared *dropdownType) updateDropdownStateMouse() bool {
isUpdateRequired := false
mouseXLocation, mouseYLocation, buttonPressed, _ := memory.GetMouseStatus()
characterEntry := getCellInformationUnderMouseCursor(mouseXLocation, mouseYLocation)
layerAlias := characterEntry.LayerAlias
cellControlAlias := characterEntry.AttributeEntry.CellControlAlias
// If a buttonType is pressed AND (you are in a drag and drop event OR the cell type is scroll bar), then
// sync all Dropdown selectors with their appropriate scroll bars. If the control under focus
// matches a control that belongs to a Dropdown list, then stop processing (Do not attempt to close Dropdown).
if buttonPressed != 0 && (eventStateMemory.stateId == constants.EventStateDragAndDropScrollbar ||
characterEntry.AttributeEntry.CellType == constants.CellTypeScrollbar) {
isMatchFound := false
for currentKey := range memory.Dropdown.Entries[layerAlias] {
if !memory.IsDropdownExists(layerAlias, currentKey) {
continue
}
dropdownEntry := memory.GetDropdown(layerAlias, currentKey)
selectorEntry := memory.GetSelector(layerAlias, dropdownEntry.SelectorAlias)
scrollBarEntry := memory.GetScrollbar(layerAlias, dropdownEntry.ScrollBarAlias)
if selectorEntry.ViewportPosition != scrollBarEntry.ScrollValue {
selectorEntry.ViewportPosition = scrollBarEntry.ScrollValue
isUpdateRequired = true
}
if isControlCurrentlyFocused(layerAlias, dropdownEntry.ScrollBarAlias, constants.CellTypeScrollbar) {
isMatchFound = true
break // If the current scrollbar being dragged and dropped matches, don't process more dropdowns.
}
}
if isMatchFound {
return isUpdateRequired
}
}
// If our Dropdown alias is not empty, then open our Dropdown.
if buttonPressed != 0 && cellControlAlias != "" && characterEntry.AttributeEntry.CellType == constants.CellTypeDropdown &&
memory.IsDropdownExists(layerAlias, cellControlAlias) {
shared.closeAllOpenDropdowns(layerAlias)
dropdownEntry := memory.GetDropdown(layerAlias, cellControlAlias)
dropdownEntry.IsTrayOpen = true
selectorEntry := memory.GetSelector(layerAlias, dropdownEntry.SelectorAlias)
selectorEntry.IsVisible = true
scrollBarEntry := memory.GetScrollbar(layerAlias, dropdownEntry.ScrollBarAlias)
if scrollBarEntry.IsEnabled {
scrollBarEntry.IsVisible = true
setFocusedControl(layerAlias, selectorEntry.ScrollBarAlias, constants.CellTypeScrollbar)
}
isUpdateRequired = true
return isUpdateRequired
}
_, _, previousButtonPress, _ := memory.GetPreviousMouseStatus()
if buttonPressed != 0 && previousButtonPress == 0 && characterEntry.AttributeEntry.CellType != constants.CellTypeDropdown {
shared.closeAllOpenDropdowns(layerAlias)
}
return isUpdateRequired
}
/*
closeAllOpenDropdowns allows you to close all dropdowns for a given layer alias.
*/
func (shared *dropdownType) closeAllOpenDropdowns(layerAlias string) {
for currentKey := range memory.Dropdown.Entries[layerAlias] {
if !memory.IsDropdownExists(layerAlias, currentKey) {
continue
}
dropdownEntry := memory.GetDropdown(layerAlias, currentKey)
if dropdownEntry.IsTrayOpen == true {
selectorEntry := memory.GetSelector(layerAlias, dropdownEntry.SelectorAlias)
selectorEntry.IsVisible = false
scrollBarEntry := memory.GetScrollbar(layerAlias, dropdownEntry.ScrollBarAlias)
scrollBarEntry.IsVisible = false
dropdownEntry.IsTrayOpen = false
if dropdownEntry.ItemSelected != selectorEntry.ItemSelected {
dropdownEntry.ItemSelected = selectorEntry.ItemSelected
}
setFocusedControl("", "", constants.NullCellType)
// Reset the event state only if a tray is closed.
eventStateMemory.stateId = constants.EventStateNone
}
}
}