GUI Tutorial

From Dyrdex.com
Revision as of 21:44, 28 December 2022 by Admin (talk | contribs) (→‎Add a Sidebar)
Jump to navigation Jump to search

People keep asking how to set up the gui, so, here's some information you can expand upon.

The GUI is set up using the #SPLIT and #DRAW commands, often using #FORMAT, and using your #VAR's.

Split Your Screen

First, establish your desired top/bottom screen #SPLIT with some room to print data into. I go 4 or 5 lines top and bottom.

  • Run your #SPLIT command manually or make an alias that might be handy later for resetting.
    • The #BUFFER command reprints the scrolling region after splitting:
#ALIAS {split} {
 #SPLIT 5 5;
 #BUFFER end;
 }

Draw Tiles

Second, you can draw tiles of all the vars you want to populate your split region however you want. Here I'm formatting an existing var, then drawing its tile:

#ALIAS {draw} {
 #FORMAT {room_string} {%c%.44s} {<ddd>}{$msdp_info[ROOM_NAME]};
 #DRAW tile 3 2 3 44 $room_string;
 #FORMAT {area_string} {%c%.40s} {<bbb>}{$msdp_info[AREA_NAME]};
 #DRAW tile 2 2 2 43 $area_string;
 }

Just add every var you want to draw to screen into that draw alias really. You'll have to read #Help draw to understand all your options, and how to use the coordinate system to place those into exact positions on screen. You'll also want to learn #FORMAT so you can align those and specify their lengths to avoid overrun.

This approach can become a problem when it comes to auto-updating the screen however. You'll want to read this entire page, especially the very bottom, before you go ahead setting up something like the above and wasting time adding more data to it.


Note that I'm calling MSDP vars here, you can establish those by reading in my MSDP script prior to mud connection:

https://dyrdex.com/tinscripts/MSDP.tin

Draw Lists

Instead of drawing individual tiles, you can also generate a list and draw that all at once.

Here, we will generate such a list, and then also create a sidebar box, and draw the whole list in there:

Format a List

First, format your vars into a list:

#alias get_affects {
        #list affects clear;
        #foreach {*msdp_info[AFFECTS][]} {affect}
        {
                #if {$msdp_info[AFFECTS][$affect] < 50} {#var Color {<dbb>}};
                #if {$msdp_info[AFFECTS][$affect] > 49 && $msdp_info[AFFECTS][$affect] < 99} {#var Color {<ffd>}};
                #if {$msdp_info[AFFECTS][$affect] > 99} {#var Color {<ddd>}};
                #format {affect_line} {%c%+15.15s %c%-4s%c} {<bbb>}{$affect}{$Color}{$msdp_info[AFFECTS][$affect]}{<ddd>};
                #LIST {affects} {add} {$affect_line};
        };
        #unvar Color;
        #unvar affect_line;
};

That will generate a var named $affects. Type "#VAR affects" to see what it looks like.


Now, you can draw that list anywhere. For example, here we can just print it into a box in the scrolling region (it'll move when the screen scrolls next):

#draw box 10 60 50 90 $affects[1..-1]

If you have short lists, those could probably fit in your top/bottom split. For long lists, you'll probably want a sidebar.

Add a Sidebar

So now let's do a sidebar, and draw a whole $affects list there.

First, use the #SCREEN command to get information about your existing #SPLIT. These commands create a $screen var that contains the top/bottom/left/right split sizes so we can call those as vars in case they change later. Then we set a new split to have the original top/bottom but also a right-sidebar (24 spaces in this example). We also need to do #BUFFER end to reprint the scrolling region, and our original 'draw' alias to draw the normal top/bottom split data into place. Finally we will set a #var sidebar 1 just to track that the sidebar is indeed turned on, so we can use that info later.

#ALIAS {side_split} {
       #SCREEN get split_top_bar screen[split_top];
       #SCREEN get split_bot_bar screen[split_bot];
       #SCREEN get split_left_bar screen[split_left];
       #SCREEN get split_right_bar screen[split_right];
       #SPLIT  $screen[split_top] $screen[split_bot] 0 24;
       #BUFFER end;
       draw;
       #VAR sidebar 1;
       }

Second, draw a box with your list data into the new side split region. I'm drawing the box 'blue' here so you can see it, can change that to 'blanked' to make the outline invisible if you desire. We set the box top/bottom values by modifying the existing top/bottom split data, so the box doesn't draw on top of the top/bottom split lines (it will cause them to blank out or flicker). We also set the box left/right values to correspond to our right-hand split value (24) and -1 (last column of the right side of the screen)

#alias draw_sidebar {
       #MATH {mod_top} {$screen[split_top] + 1};
       #MATH {mod_bottom} {$screen[split_bot] + 2};
       #draw blue box $mod_top -24 -$mod_bottom -1 $affects[1..-1];
       };

Sidebar Controls

Unless you want that sidebar to always be on, you'll probably want some controls for it.

First, make a single alias that does the entire sidebar operation:

#ALIAS {sidebar} {get_affects;side_split;draw_sidebar}

Finally, make an alias to toggle the sidebar on/off by checking the $sidebar var. This uses our original 'split' alias to reset the screen if the sidebar is off.

#ALIAS {affs} {
     #IF {"$sidebar" == "1"} {#VAR sidebar 0;split;draw};  
     #ELSE {get_affects;side_split;draw_sidebar};                            
     }

So, typing 'affs' will turn the side bar on if it was off, and then turn it off again if it was on. It's a toggle.

Auto-Updates

Now, let's say you want that to auto-update that sidebar every time your affects vars update.

Inside your MSDP script code, at the point where it is parsing the AFFECTS string, you can put this check:

#IF {"$sidebar" == "1"} {draw_sidebar};

Another approach to auto-update is to use an #EVENT.

For example, to have your gui redrawn every time you enter a new room, and print the new room name, you can use the 'variable updated' event.

#EVENT {VARIABLE UPDATED msdp_info[ROOM_NAME]} {RE DRAW RELEVENT TILE!}

So, this is why I prefer to draw each screen element as an individual tile, so you can set EACH tile to have its own #event and #alias to update each of them. For example, you might make a specific aliases for each tile:

#ALIAS {draw_room_tile} {
      #FORMAT {room_string} {%c%.44s} {<ddd>}{$msdp_info[ROOM_NAME]};
      #DRAW tile 3 2 3 44 $room_string;
      }
 #ALIAS {draw_area_tile} {
       #FORMAT {area_string} {%c%.40s} {<bbb>}{$msdp_info[AREA_NAME]};
       #DRAW tile 2 2 2 43 $area_string;
       }

Then have an event to update each one:

 #EVENT {VARIABLE UPDATED msdp_info[ROOM_NAME]} {draw_room_tile}
 #EVENT {VARIABLE UPDATED msdp_info[AREA_NAME]} {draw_area_tile}


How you manage your vars, and how/when to draw/update them is up to you. I've experimented with a few approachs, and have found that handling each screen element as its own small tile, with its own draw alias, with its own event, runs quite efficiently so I'm only ever drawing tiny tiles, and not redrawing the whole screen and doing unnecessary computation to generate parts of the screen that haven't changed.

Conclusion

The concepts here are just the tip of the iceberg. You'll run into a lot of headscratchers along the way as far as how to properly set up your gui so it doesn't have conflicts, or draw things redundantly, and auto-updates, and doesn't fight with other sessions. Also, you'll have to put a bit of effort into how to actually integrate it into the rest of your system.

For me, I load my gui script after mud connection (as a module in my tt5 suite). I have some additional triggers firing in my connection script that then push gui re-draws upon things like session activation (changing characters), msdp reception updates, other variable updates, and code to limit when/where I draw to only work upon the active character session. This is kinda where things really get into the weeds, and you'll have to spend some time and thought on how best you want to handle all that sort of stuff. Session management is a bitch.

General advice:

  • The simpler you can make each gui element, the better. You should be able to get very specific about what you want to draw, or redraw, so that the rest of your scripting can easily update your screen without too much work.
  • As a beginner at this, I would suggest just trying to get one split region working and printing some info, for example, just set a bottom prompt and try to start putting your character info there, see if you can get that working. Before you draw out your entire screen in some elaborate fashion like I have, start small, one bar, and get that all working before you expand.


Code

Here's all the code from this page in one block so you can copy/paste and then play with in your own system.

Use the 'affs' alias to toggle the sidebar on/off.

#ALIAS {split} {
     #SPLIT 5 5;
     #BUFFER end;
     }

#ALIAS {draw} {
     #FORMAT {room_string} {%c%.44s} {<ddd>}{$msdp_info[ROOM_NAME]};
     #DRAW tile 3 2 3 44 $room_string;
     #FORMAT {area_string} {%c%.40s} {<bbb>}{$msdp_info[AREA_NAME]};
     #DRAW tile 2 2 2 43 $area_string;
     }

#ALIAS {get_affects} {
     #LIST  affects clear;
     #FOREACH{*msdp_info[AFFECTS][]} {affect}
          {
          #IF {$msdp_info[AFFECTS][$affect] < 50} {#var Color {<dbb>}};
          #IF {$msdp_info[AFFECTS][$affect] > 49 && $msdp_info[AFFECTS][$affect] < 99} {#var Color {<ffd>}};
          #IF {$msdp_info[AFFECTS][$affect] > 99} {#var Color {<ddd>}};
          #FORMAT {affect_line} {%c%+15.15s %c%-4s%c} {<bbb>}{$affect}{$Color}{$msdp_info[AFFECTS][$affect]}{<ddd>};
          #LIST {affects} {add} {$affect_line};
          };
     #UNVAR Color;
     #UNVAR affect_line;
     };

#ALIAS {side_split} {
     #SCREEN get split_top_bar screen[split_top];
     #SCREEN get split_bot_bar screen[split_bot];
     #SCREEN get split_left_bar screen[split_left];
     #SCREEN get split_right_bar screen[split_right];
     #SPLIT  $screen[split_top] $screen[split_bot] 0 24;
     #BUFFER end;
     #VAR sidebar 1;
     draw;
     }

#ALIAS {draw_sidebar} {
     #MATH {mod_top} {$screen[split_top] + 1};
     #MATH {mod_bottom} {$screen[split_bot] + 2};
     #DRAW blue box $mod_top -24 -$mod_bottom -1 $affects[1..-1];
     };

#ALIAS {affs} {
   #IF {"$sidebar" == "1"} {#VAR sidebar 0;split;draw};  
   #ELSE {get_affects;side_split;draw_sidebar};                            
   }