https://github.com/akkartik/mu/blob/main/browse-slack/environment.mu
1 type environment {
2 item-index: int
3 }
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 fn initialize-environment _self: (addr environment), _items: (addr item-list) {
20 var self/esi: (addr environment) <- copy _self
21 var items/eax: (addr item-list) <- copy _items
22 var newest-item-a/eax: (addr int) <- get items, newest
23 var newest-item/eax: int <- copy *newest-item-a
24 var dest/edi: (addr int) <- get self, item-index
25 copy-to *dest, newest-item
26 }
27
28 fn render-environment screen: (addr screen), env: (addr environment), users: (addr array user), channels: (addr array channel), items: (addr item-list) {
29 clear-screen screen
30 render-search-input screen, env
31 render-channels screen, env, channels
32 render-item-list screen, env, items, users
33 render-menu screen
34 }
35
36 fn render-channels screen: (addr screen), env: (addr environment), _channels: (addr array channel) {
37 var channels/esi: (addr array channel) <- copy _channels
38 var y/ebx: int <- copy 2/search-space-ver
39 y <- add 1/item-padding-ver
40 var i/ecx: int <- copy 0
41 var max/edx: int <- length channels
42 {
43 compare i, max
44 break-if->=
45 var offset/eax: (offset channel) <- compute-offset channels, i
46 var curr/eax: (addr channel) <- index channels, offset
47 var name-ah/eax: (addr handle array byte) <- get curr, name
48 var name/eax: (addr array byte) <- lookup *name-ah
49 compare name, 0
50 break-if-=
51 set-cursor-position screen, 2/x y
52 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "#", 0xf/grey 0/black
53 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, name, 0xf/grey 0/black
54 y <- add 2/channel-padding
55 i <- increment
56 loop
57 }
58 }
59
60 fn render-item-list screen: (addr screen), _env: (addr environment), _items: (addr item-list), users: (addr array user) {
61 var env/esi: (addr environment) <- copy _env
62 var tmp-width/eax: int <- copy 0
63 var tmp-height/ecx: int <- copy 0
64 tmp-width, tmp-height <- screen-size screen
65 var screen-width: int
66 copy-to screen-width, tmp-width
67 var screen-height: int
68 copy-to screen-height, tmp-height
69
70 var y/ecx: int <- copy 2/search-space-ver
71 y <- add 1/item-padding-ver
72 var newest-item/eax: (addr int) <- get env, item-index
73 var i/ebx: int <- copy *newest-item
74 var items/esi: (addr item-list) <- copy _items
75 var items-data-ah/eax: (addr handle array item) <- get items, data
76 var _items-data/eax: (addr array item) <- lookup *items-data-ah
77 var items-data/edi: (addr array item) <- copy _items-data
78 {
79 compare i, 0
80 break-if-<
81 compare y, screen-height
82 break-if->=
83 var offset/eax: (offset item) <- compute-offset items-data, i
84 var curr-item/eax: (addr item) <- index items-data, offset
85 y <- render-item screen, curr-item, users, y, screen-height
86 i <- decrement
87 loop
88 }
89 var top/eax: int <- copy screen-height
90 top <- subtract 2/menu-space-ver
91 clear-rect screen, 0 top, screen-width screen-height, 0/bg
92 }
93
94 fn render-search-input screen: (addr screen), env: (addr environment) {
95 set-cursor-position 0/screen, 0x22/x=search-position-x 1/y
96 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "search ", 7/fg 0/bg
97 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "________________________________", 0xf/fg 0/bg
98 }
99
100 fn render-menu screen: (addr screen) {
101 var width/eax: int <- copy 0
102 var y/ecx: int <- copy 0
103 width, y <- screen-size screen
104 y <- decrement
105 set-cursor-position screen, 2/x, y
106 draw-text-rightward-from-cursor screen, " / ", width, 0/fg 0xf/bg
107 draw-text-rightward-from-cursor screen, " search ", width, 0xf/fg, 0/bg
108 draw-text-rightward-from-cursor screen, " ^f ", width, 0/fg 0xf/bg
109 draw-text-rightward-from-cursor screen, " next page ", width, 0xf/fg, 0/bg
110 draw-text-rightward-from-cursor screen, " ^b ", width, 0/fg 0xf/bg
111 draw-text-rightward-from-cursor screen, " previous page ", width, 0xf/fg, 0/bg
112 }
113
114 fn render-item screen: (addr screen), _item: (addr item), _users: (addr array user), y: int, screen-height: int -> _/ecx: int {
115 var item/esi: (addr item) <- copy _item
116 var users/edi: (addr array user) <- copy _users
117 var author-index-addr/ecx: (addr int) <- get item, by
118 var author-index/ecx: int <- copy *author-index-addr
119 var author-offset/ecx: (offset user) <- compute-offset users, author-index
120 var author/ecx: (addr user) <- index users, author-offset
121
122 var author-avatar-ah/eax: (addr handle image) <- get author, avatar
123 var _author-avatar/eax: (addr image) <- lookup *author-avatar-ah
124 var author-avatar/ebx: (addr image) <- copy _author-avatar
125 {
126 compare author-avatar, 0
127 break-if-=
128 var y/edx: int <- copy y
129 y <- shift-left 4/log2font-height
130 var x/eax: int <- copy 0x20/main-panel-hor
131 x <- shift-left 3/log2font-width
132 x <- add 0x18/item-padding-hor
133 render-image screen, author-avatar, x, y, 0x50/avatar-side, 0x50/avatar-side
134 }
135
136 var channel-name-ah/eax: (addr handle array byte) <- get item, channel
137 var channel-name/eax: (addr array byte) <- lookup *channel-name-ah
138 {
139 var x/eax: int <- copy 0x20/main-panel-hor
140 x <- add 0x40/channel-offset-x
141 set-cursor-position screen, x y
142 }
143 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, "#", 7/grey 0/black
144 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, channel-name, 7/grey 0/black
145
146 var author-real-name-ah/eax: (addr handle array byte) <- get author, real-name
147 var author-real-name/eax: (addr array byte) <- lookup *author-real-name-ah
148 {
149 var x/ecx: int <- copy 0x20/main-panel-hor
150 x <- add 0x10/avatar-space-hor
151 set-cursor-position screen, x y
152 draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen, author-real-name, 0xf/white 0/black
153 }
154 increment y
155
156 var text-ah/eax: (addr handle array byte) <- get item, text
157 var _text/eax: (addr array byte) <- lookup *text-ah
158 var text/edx: (addr array byte) <- copy _text
159 var x/eax: int <- copy 0x20/main-panel-hor
160 x <- add 0x10/avatar-space-hor
161 var text-y/ecx: int <- copy y
162 text-y <- add 1/author-name-padding-ver
163 x, text-y <- draw-text-wrapping-right-then-down screen, text, x text-y, 0x70/xmax=post-right-coord screen-height, x text-y, 7/fg 0/bg
164 text-y <- add 2/item-padding-ver
165
166 add-to y, 6/avatar-space-ver
167 compare y, text-y
168 {
169 break-if-<
170 return y
171 }
172 return text-y
173 }
174
175 fn update-environment env: (addr environment), key: byte, items: (addr item-list) {
176 {
177 compare key, 6/ctrl-f
178 break-if-!=
179 page-down env, items
180 return
181 }
182 {
183 compare key, 2/ctrl-b
184 break-if-!=
185 page-up env, items
186 return
187 }
188 }
189
190 fn page-down _env: (addr environment), _items: (addr item-list) {
191 var env/edi: (addr environment) <- copy _env
192 var items/esi: (addr item-list) <- copy _items
193 var items-data-ah/eax: (addr handle array item) <- get items, data
194 var _items-data/eax: (addr array item) <- lookup *items-data-ah
195 var items-data/ebx: (addr array item) <- copy _items-data
196 var src/eax: (addr int) <- get env, item-index
197 var new-item-index/ecx: int <- copy *src
198 var y/edx: int <- copy 2
199 {
200 compare new-item-index, 0
201 break-if-<
202 compare y, 0x28/screen-height-minus-menu
203 break-if->=
204 var offset/eax: (offset item) <- compute-offset items-data, new-item-index
205 var item/eax: (addr item) <- index items-data, offset
206 var item-text-ah/eax: (addr handle array byte) <- get item, text
207 var item-text/eax: (addr array byte) <- lookup *item-text-ah
208 var h/eax: int <- estimate-height item-text
209 set-cursor-position 0/screen, 0 0
210 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, h, 4/fg 0/bg
211 y <- add h
212 new-item-index <- decrement
213 loop
214 }
215 new-item-index <- increment
216 var dest/eax: (addr int) <- get env, item-index
217 copy-to *dest, new-item-index
218 }
219
220 fn page-up _env: (addr environment), _items: (addr item-list) {
221 var env/edi: (addr environment) <- copy _env
222 var items/esi: (addr item-list) <- copy _items
223 var items-data-ah/eax: (addr handle array item) <- get items, data
224 var _items-data/eax: (addr array item) <- lookup *items-data-ah
225 var items-data/ebx: (addr array item) <- copy _items-data
226 var newest-item-index-a/esi: (addr int) <- get items, newest
227 var src/eax: (addr int) <- get env, item-index
228 var new-item-index/ecx: int <- copy *src
229 var y/edx: int <- copy 2
230 {
231 compare new-item-index, *newest-item-index-a
232 break-if->
233 compare y, 0x28/screen-height-minus-menu
234 break-if->=
235 var offset/eax: (offset item) <- compute-offset items-data, new-item-index
236 var item/eax: (addr item) <- index items-data, offset
237 var item-text-ah/eax: (addr handle array byte) <- get item, text
238 var item-text/eax: (addr array byte) <- lookup *item-text-ah
239 var h/eax: int <- estimate-height item-text
240 set-cursor-position 0/screen, 0 0
241 draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, h, 4/fg 0/bg
242 y <- add h
243 new-item-index <- increment
244 loop
245 }
246 new-item-index <- decrement
247 var dest/eax: (addr int) <- get env, item-index
248 copy-to *dest, new-item-index
249 }
250
251
252 fn estimate-height _message-text: (addr array byte) -> _/eax: int {
253 var message-text/esi: (addr array byte) <- copy _message-text
254 var result/eax: int <- length message-text
255 var remainder/edx: int <- copy 0
256 result, remainder <- integer-divide result, 0x40/post-width
257 compare remainder, 0
258 {
259 break-if-=
260 result <- increment
261 }
262 result <- add 2/item-padding-ver
263 compare result, 6/avatar-space-ver
264 {
265 break-if->
266 return 6/avatar-space-ver
267 }
268 return result
269 }