-
Notifications
You must be signed in to change notification settings - Fork 1
/
luigi2_example.nim
236 lines (170 loc) · 8.24 KB
/
luigi2_example.nim
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
import std/strutils
import luigi/luigi2
# TODO find a way so i dont have to import this, i really dont like using this
proc snprintf*(s: cstring, maxlen: csize_t, format: cstring): cint {.importc,
header: "<stdio.h>", varargs.}
var
window: ptr Window
label: ptr Label
sliderHoriz: ptr Slider
gaugeHoriz1: ptr Gauge
gaugeHoriz2: ptr Gauge
sliderVert: ptr Slider
gaugeVert1: ptr Gauge
gaugeVert2: ptr Gauge
code: ptr Code
selected: int
proc btnMessage(element: ptr Element, message: Message, di: cint, dp: pointer): cint {.cdecl.} =
if message == msgClicked:
echo "Clicked!"
elementDestroy(element)
elementRefresh(element.parent)
proc menuCallback(cp: pointer) {.cdecl.} =
labelSetContent(label, cast[cstring](cp))
elementRefresh(addr label.e)
proc btn2Message(element: ptr Element, message: Message, di: cint, dp: pointer): cint {.cdecl.} =
if message == msgClicked:
let menu = menuCreate(element)
menuAddItem(menu, 0, "Item 1\tCtrl+F5", castInt, menuCallback, cast[pointer](cstring"Item 1 clicked!"))
menuAddItem(menu, 0, "Item 1\tF6", castInt, menuCallback, cast[pointer](cstring"Item 2 clicked!"))
menuShow(menu)
# NEW
proc codeMessage(element: ptr Element, message: Message, di: cint, dp: pointer): cint {.cdecl.} =
if message == msgMouseMove:
let lineno = codeHitTest(code, element.window.cursorX, element.window.cursorY)
codeFocusLine(code, lineno)
proc sliderHMessage(element: ptr Element, message: Message, di: cint, dp: pointer): cint {.cdecl.} =
if message == msgValueChanged:
gaugeHoriz2.position = sliderHoriz.position
gaugeVert1.position = sliderHoriz.position
elementRepaint(addr gaugeHoriz2.e)
elementRepaint(addr gaugeVert1.e)
proc sliderVMessage(element: ptr Element, message: Message, di: cint, dp: pointer): cint {.cdecl.} =
if message == msgValueChanged:
gaugeVert2.position = sliderVert.position
gaugeHoriz1.position = sliderVert.position
elementRepaint(addr gaugeVert2.e)
elementRepaint(addr gaugeHoriz1.e)
proc winMessage(element: ptr Element, message: Message, di: cint, dp: pointer): cint {.cdecl.} =
if message == msgWindowDropFiles:
var paths: seq[cstring]
# when message == msgWindowDropFiles, `dp` is an UncheckedArray of the file
# paths, and `di` is the number of files.
for path in cast[ptr UncheckedArray[cstring]](dp).toOpenArray(0, int di - 1):
paths.add path
codeInsertContent(code, cstring readFile($paths[^1]), castInt, true)
elementRefresh(addr code.e)
proc tblMessage(element: ptr Element, message: Message, di: cint, dp: pointer): cint {.cdecl.} =
if message == msgTableGetItem:
var m = cast[ptr TableGetItem](dp)
m.isSelected = selected == m.index
if m.column == 0:
return snprintf(m.buffer, m.bufferBytes, cstring "Item " & $m.index)
else:
return snprintf(m.buffer, m.bufferBytes, cstring "other column " & $m.index)
elif message == msgLeftDown:
let hit = tableHitTest(cast[ptr Table](element), element.window.cursorX, element.window.cursorY)
if selected != hit:
selected = hit
if not tableEnsureVisible(cast[ptr Table](element), cint selected):
elementRepaint(element)
initialise()
window = windowCreate(nil, 0, "luigi2 - Example Application")
window.e.messageUser = winMessage
let
# Split window (vertically) into top/bottom panes.
splitTopBottom = splitPaneCreate(addr window.e, SPLIT_PANE_VERTICAL, 0.75)
# Split top pane (horizontally) into left/right panes.
splitTopLeftright = splitPaneCreate(addr splitTopBottom.e, 0, 0.3)
block:
# In the top-left pane - create a single panel taking up the whole pane.
let panel = panelCreate(addr splitTopLeftright.e, PANEL_COLOR_1 or PANEL_MEDIUM_SPACING)
# Panels are by default vertical in layout, so items start at top and go down.
buttonCreate(addr panel.e, 0, "Hello World").e.messageUser = btnMessage
# Create a new horizontal-layout "sub-panel" and put left and right panels inside it.
let subpanel = panelCreate(addr panel.e, PANEL_COLOR_1 or PANEL_HORIZONTAL)
# The left side will layout elements horizontally, with custom borders and gap.
let subLeft = panelCreate(addr subpanel.e, PANEL_COLOR_1 or PANEL_HORIZONTAL)
subLeft.border.t = 10
subLeft.border.b = 10
subLeft.border.l = 10
subLeft.border.r = 10
subLeft.gap = 2
gaugeVert1 = gaugeCreate(addr subLeft.e, GAUGE_VERTICAL)
gaugeVert2 = gaugeCreate(addr subLeft.e, GAUGE_VERTICAL)
sliderVert = sliderCreate(addr subLeft.e, SLIDER_VERTICAL)
sliderVert.e.messageUser = sliderVMessage
# The right side will lay out elements vertically (the default), with default medium spacing.
let subRight = panelCreate(addr subpanel.e, PANEL_COLOR_1 or PANEL_MEDIUM_SPACING)
buttonCreate(addr subRight.e, 0, "1").e.messageUser = btnMessage
buttonCreate(addr subRight.e, 0, "2").e.messageUser = btnMessage
buttonCreate(addr subRight.e, 0, "3").e.messageUser = btnMessage
buttonCreate(addr subRight.e, 0, "4").e.messageUser = btnMessage
buttonCreate(addr subRight.e, 0, "5").e.messageUser = btnMessage
# Back outside of the "sub-panel", we continue layout downwards.
buttonCreate(addr panel.e, 0, "Goodbye World").e.messageUser = btnMessage
gaugeHoriz1 = gaugeCreate(addr panel.e)
gaugeHoriz2 = gaugeCreate(addr panel.e)
sliderHoriz = sliderCreate(addr panel.e)
sliderHoriz.e.messageUser = sliderHMessage
discard textboxCreate(addr panel.e)
discard textboxCreate(addr panel.e, TEXTBOX_HIDE_CHARACTERS)
# Set default slider positions.
sliderSetPosition(sliderVert, 0.1, true)
sliderSetPosition(sliderHoriz, 0.3, true)
block:
# Top-Right pane.
let buffer =
readFile(currentSourcePath() & "/../../src/luigi/luigi2.nim") # readFile("../src/luigi/source/luigi.c")
.replace("\r", "") # leaving '\r' in there makes files look weird
code = codeCreate(addr splitTopLeftright.e)
code.e.messageUser = codeMessage
codeInsertContent(code, cstring buffer, castInt, false)
codeFocusLine(code, 0)
# Split bottom pane (horizontally) into left/right panes.
let splitBottomLeftright = splitPaneCreate(addr splitTopBottom.e, 0, 0.3)
block:
# Bottom-Left pane.
let panel = panelCreate(addr splitBottomLeftright.e, PANEL_COLOR_2)
panel.border = Rectangle(l: 5, r: 5, t: 5, b: 5)
panel.gap = 5
buttonCreate(addr panel.e, 0, "It's a button??").e.messageUser = btn2Message
label = labelCreate(addr panel.e, ELEMENT_H_FILL, "Hello, I am a label!")
block:
# Bottom-Right pane
let tabPane = tabPaneCreate(addr splitBottomLeftright.e, 0, "Tab 1\tMiddle Tab\tTab 3")
let table = tableCreate(addr tabPane.e, 0, "Column 1\tColumn 2")
table.itemCount = 10000
table.e.messageUser = tblMessage
tableResizeColumns(table)
discard labelCreate(addr panelCreate(addr tabPane.e, PANEL_COLOR_1).e, 0, "you're in tab 2, bucko")
discard labelCreate(addr panelCreate(addr tabPane.e, PANEL_COLOR_1).e, 0, "haiii !!!")
# windowRegisterShortcut(window):
# Shortcut(
# code: KEYCODE_LETTER('T'),
# ctrl: true,
# shift: false,
# alt: false,
# invoke: menuCallback,
# cp: cast[pointer](cstring "Keyboard shortcut!")
# )
block:
# Create a separate window demonstrating the MDI element
window = windowCreate(nil, 0, "luigi 2 - MDI Example")
let client = mdiClientCreate(addr window.e, 0)
let child1 = mdiChildCreate(addr client.e, MDI_CHILD_CLOSE_BUTTON, Rectangle(l: 10, r: 600, t: 10, b: 400), "My Window")
let panel1 = panelCreate(addr child1.e, PANEL_COLOR_1 or PANEL_MEDIUM_SPACING)
discard labelCreate(addr panel1.e, 0, "It's a christmas miracle")
let child2 = mdiChildCreate(addr client.e, MDI_CHILD_CLOSE_BUTTON, Rectangle(l: 40, r: 630, t: 40, b: 430), "Second Window")
let panel2 = panelCreate(addr child2.e, PANEL_COLOR_1 or PANEL_MEDIUM_SPACING)
discard labelCreate(addr panel2.e, 0, "the system is down")
let child3 = mdiChildCreate(addr client.e, MDI_CHILD_CLOSE_BUTTON, Rectangle(l: 70, r: 670, t: 70, b: 470), "Third Window")
discard buttonCreate(addr child3.e, 0, "giant button!!")
echo "Tip: Try dragging a text file on the test window."
# wanna try out different fonts?
when defined(lFreetype):
let robotoMono = fontCreate("./RobotoMono-VariableFont_wght.ttf", 11)
let firaCode = fontCreate("./FiraCode-Retina.ttf", 10)
fontActivate(robotoMono)
code.font = firaCode
quit messageLoop()