# Mu - browse-slack/environment.mu

https://github.com/akkartik/mu/blob/main/browse-slack/environment.mu

      1 type environment {
      2   item-index: int
      3 }
      4
      5 # static buffer sizes in this file:
      6 #   main-panel-hor            # in characters
      7 #   item-padding-hor          # in pixels
      8 #   item-padding-ver          # in characters
      9 #   avatar-side               # in pixels
     10 #   avatar-space-hor          # in characters
     11 #   avatar-space-ver          # in characters
     12 #   search-position-x         # in characters
     13 #   search-space-ver          # in characters
     14 #   author-name-padding-ver   # in characters
     15 #   post-right-coord          # in characters
     16 #   channel-offset-x          # in characters
     17 #   menu-space-ver            # in characters
     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   # author avatar
    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   # channel
    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   # author name
    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   # text
    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   # flush
    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 # keep sync'd with render-item
    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 }