 So today I'll be sharing building terminal apps with cursors. So for me I've always seen those old school looking interfaces on terminals and then I have always wondered like how did they build it. And then I don't know somehow when reading somewhere and I chance upon this thing called end cursors and which suddenly answered my question on how they built these interfaces. So today I'm just going to go a very basic introduction and then how can we build cursors with Ruby and then also a walkthrough of a demo app that I built which is actually like the app to navigate file systems like my own computer's file system. So let me, I'm going to change my slides. Give me a moment to write my slides. Okay, and then share. Okay, I'm going to share my screen because later I got a demo. So, okay, I think I'll just go with this if you can see it properly. So my talk today again will be talking mainly about these cursors library. So the outline is for this talk will be what is cursors firstly and then the Ruby binding for cursors because cursors is a library written in C. So if I'm using Ruby we need some sort of connection and then also a demo and a code walkthrough. So first of all what is cursors? Cursors is actually a library created a while back to allow programmers to build text user interfaces. So now it's like graphical user interfaces GUI but back in the days is TUI. So it's text user interfaces. And then the good thing about cursors is that you write it you write the text user interface and then it can run on most terminal types. So back in the days like from my research digging through a bit of history back in the days where people are still using terminals a lot and then in a market there are a lot of types of terminals and then there's competition basically there's competition unlike today actually today there's only a few main winners right on shell or terminal types. So today so then this is like a big thing where you write a interface you write a text user interface and then it can be like used in most terminal types. And then it was put together actually it was first I would okay this one I think I right wrong the first so there are many types of cursors but this one specifically that was created in 1980 by University of California Berkeley was built was really like pushed out to support this game called screen oriented dungeon game. So on the right you can see it's really like made of text although there are some lines but mainly SD characters so also considered text. So historically there are actually many versions of cursors because like people built and built and built and then like try to come out with better and better ones and then where you have big companies trying to create their own cursors and stuff. So only until recently that okay maybe not recently like maybe a few years back or 10 years back or something that anchorses became the official standard cursors for Linux. So this is from what I can remember is pretty recent. So basically it's a very small library that lets you build text user interfaces in terminals. So in Ruby actually cursors was shipped as part of Ruby in the past up to Ruby 2.1. So this is beyond me so because when I started it's really way past 2.1 Ruby 2.1 but for what I can understand is that it was shipped then together and that time was about the time that Ruby gems came out. So instead of shipping cursors as part of Ruby itself I forgot the person's name but basically one of the Ruby devs it moves cursors out into a separate gem and then from then on cursors it goes a separate way from the major Ruby releases. So which means that today if you're using Ruby 2.1 you probably still have cursors inside your Ruby but then if after that you have to install the gem to use cursors so it kind of moves out but it's still inside the Ruby standard library. So now I'm going to go through some basics of how cursors work, the top flow and how can you build one of the most basic commands that you can find in the Ruby standard library. Cursors gem, okay. So for cursors the first thing is actually the init screen and the closing of a screen. So the idea of cursors is that there's always one screen that is called the standard screen. So when you init the screen right it actually initializes that standard screen which actually takes up your whole terminal length and width and height. So that is the init screen. So whenever you want to, because it's inside the terminal so you have to call close screen to reset the terminal back to the normal state which is actually like having the cursor in the left bottom part of the terminal that is like the original state. So if you don't do that then your terminal is still inside your cursors like the screen kind of state. So you should always call close when you want to stop the app and return the terminal back to normal state and then call init to initialize the screen. So of course there I said I mentioned the standard screen object right. So in Ruby it's OOP so definitely it's an object. So the screen is definitely an object. So to get the object reference to the object you can call cursors.stdsrc which is just a short form for standard screen. And then when you want to build your app I'm sure you will need to know how white is the app or how tall is the screen right. So you can call cursors.columns to get the number of columns in the terminal screen that actually started this app which is the grid and then the lines will be the height. So the next thing is talking about colors. So the colors is not supported in all terminal types but I believe all the more modern ones will all have supported colors. So in order to have colors actually you must initialize this colors thing which then you call cursors.startcolor at some point after you need your screen. So when you call startcolor then you can start initializing some pairs some color pairs which then you can reference it after that. So in here I have actually initialized two pairs of colors for just demo sake. So there's one primary set of color and one secondary set of color. So because it's a text-based right so it's only foreground and background. Foreground is like where the text when you have text then it will be highlighted in that color. Then background is just like if there's no text it will not be highlighted in that color. So here I initialize like pair one and pair two and then the color is just opposite cyan, black, black, cyan. And then now that we have initialized some pairs then we have to set the color pairs to the screen itself. So here I set standard screen and then there's this attribute set method and then you reference the color pair there. So cursors.color pair one will be what we initialize under cursors.init pair one. So then now my standard screen the color scheme so color scheme is actually foreground and cyan where the text is and then background is black color. So this is colors using colors in cursors. And then the next part is then now that we initialize the screen and then we also set up the colors attributes then now is the part where actually the UI comes out which is actually drawing of the drawing something on the screen for the user to see. So drawing on the screen because it's text based right so there's only two main things first is to set the position of your cursor so then another thing is to add the string like from the point of the cursor onwards. So in this example I write set post S-E-T-P-O-S is actually set position I set it right in the middle of the screen and then I type hollow world from the middle of the screen onwards. So of course it's a bit off center right because if I really want to be centered then my column needs to be like minus half of hollow world that string length but this is just an example that kind of bring it from the center of the screen onwards. So in this example if you're going to see the terminal you will see the hollow world in the middle of the screen where everything else is black and then the hollow world is in cyan background highlighted in cyan. So this is drawing on the screen but then the next most important part is understanding the life cycle of how cursor draw. So when you do set position then change position and add things then you start draw everything out but it will not appear on the terminal screen. After you draw everything it's only when you call refresh then you will draw everything out and you will display everything out. So the general cycle that I think what I can gather is the best way to do is actually you always clear the screen and then you draw everything and then you call refresh and then you will appear. So from what I read is that in the past doing this is more efficient because if you keep drawing then you will like real time update the screen right and then it's not so efficient for the computers in the past now. So then they have this idea of only when you call refresh then everything will be drawn out. So the last part is so now we know how to draw we know how to set colors we know how to initialize screen then what about like whether you can support multiple sort of smaller screens so in cursor they also have this idea of windows or this concept of windows where you can have a screen and you have multiple windows and then you can choose to display one window or change one window basically it's more OOP window style it's like our OS they have a lot of a lot of like apps where you have each one windows that can be more dynamic so basically it's the same thing in cursors and the idea of windows works actually almost similar it's exactly the same as a standard screen just that you have instead of calling in its screen on top of that you still need to do cursors window.new so when you initialize a window you can set how white you want the window to be or how tall you want the window to be what is the X and Y coordinates where you want the window to initialize app with reference to your standard screen and then you can also set a color scheme and then the drawing part is still also the same you call clear on it then you do all your drawing then you call refresh to display it so this is up to here is just some basics of cursors and how to actually how to display something on the app so so now I'm going to show you guys a demo of what I built so it will be oh sorry so this is the app so this is an example of the app that I built so like I said it's a file directory system so I just have a title here and then I have Ruby, this tells me which directory I'm in and then I can kind of traverse up so basically this is the oh no I have so many files so this is what I have okay I think I've lost so from here you can see that okay you probably cannot tell but then I can share with you and later I will have the code for you then you will make it more you will make it clearer as to what I'm saying now so this is actually one window and then this is another window and then this is another window and then this last one is another window so I have four windows here and yeah so this is the basic sections of the app so when I change or when I change directory using this window so when I change directory then I will update this window so generally I never update this one and never update the last one because they will not change so this is an example of a terminal app built with cursors yeah cursors so I'm going to go through the code quickly here okay so it's actually just one file yeah if you I just put it all into one file because it's a very small app so if you can see that the app is actually here let me put it bigger so this is the main application class for my app and then it's just like this I will start a new app and this is my own Ruby object and then I will just call start and then I call stop and then that's how the entire app runs so so when I start a new app application then I call new is initialized right so I will start the screen I will start the screen the standard screen then I will initialize all the colors I have three color paths here one for packs, one for header bar and then I also do some basic config so this is just make the cursor disappear invisible and then I just initialize the screen oh I just initialize the instance variable to the standard screen and then I just set the color scheme for the standard screen which is then foreground and color background okay after I initialize the screen actually the next thing is to start the app so when I start the app the first thing I do actually is to initialize all the four windows that I have so here is initializing the function to initialize windows and actually just now I said that I have four windows header, pwd the directory structure and the navigation so you can see that actually there is a x, y coordinate and the height and width and then the color color path color scheme for that window so then I have a set of 5 for every window I have here and then I create a new window so this window is actually my my own window class this is actually my own window class which is a wrapper over the cursor's window class it's just for me to add some methods for me to make it easier to manage for example when I want to close it definitely had to run all this in sequence so actually I'm just wrapping the cursor's window and to create one windows so here after I initialize all the windows then the next part is I have a loop here which this loop will keep drawing the window over and over again so so let's look at the draw windows part just now I initialize all the windows but I didn't draw anything at all so now the thing about windows is that inside the windows itself the x and y coordinate goes back to zero with reference to the just from the inside the window so it's easy for you to know where to draw the thing draw your stuff so this is the header just now I mention so this is the header I just draw this and then and then I draw the PWD window and then I draw the navigation is the last one so this one is a bit like flip over but then this is the main part where the directory window is so basically I just go through the whole directory and bring line by line out so now I draw the window already and then here this line actually puts a block at the navigation window so basically the navigation window is listening for key press and then this is where I detect what are the different key presses to do what I want to do so when you press Q it will quit the app and then actually take care of the resizing of the screen and then you need to draw everything based on the size of your screen again and then if you press up and down actually it just moves the highlighted part up and down and then and then new line is actually press enter so actually my app also supports like you can enter the folder by pressing enter yeah okay so basically you can go to the dot dot and press enter it will go to the next so go to the previous directory so then right and left is also let me go in or go up the directory yep so so this is where it detects all the inputs so once input comes in it will do whatever it needs to do and then it comes back into the loop and then basically do what it needs to do means it sets all the states and then you draw the window again and then it blocks on the waiting for keyboard input again so when this loop is broken so here Q when you press the users press Q and it breaks and it causes a break and breaks the loop and actually this method ends and the app just stops after that and then when it stops I'll just close all the window and then I just close the screen basically that's it so like a proper teardown proper teardown of the application so yep this is the demo plus the code walkthrough so I believe that actually I only watched the tip of the iceberg because when I was reading I could get something working but when I was reading the documentation there was still some stuff that I didn't really understand so but I think that this is enough for anybody to build a basic user interface using CSS yep and yeah that's all for my sharing today oh right there's something that I'm supposed to show I wanted to show what are the softwares that builds using CSS it's not here basically if you just wikipedia you'll find there's this email client called Alpine client it's a terminal base terminal base email client which is pretty cool and then I saw another one is actually a mixer or music mixer I think which is also built with CSS so actually there's a lot of very interesting things but it's probably very old school that is built because so I thought that was really really interesting yeah okay now this marks the real end of my top okay oh I shouldn't have stopped sharing anybody have any questions let me share back no but that was a good presentation thanks gang welcome yeah alright anybody Al have any questions no questions but it was nice one I was already thinking about a chat application using the terminal while we are writing this one yeah it will be fun you can just add and press enter selecting to some API so if you are some application configuration everything can be done instead of UI so whoever working with Linux machine which I do will be easier to configure your app for example now we do for many applications so we can create products which can configure other applications through text based usually usually anything now we have UI to check about configures so yeah it's very nice to know that we can create applications on text based UI application so it's I was thinking in the past chat apps or like chatting systems that is probably before my time by the time I learned programming that era is already over but I can imagine like in the past probably people chat you can easily build an app on terminal like that for people to chat with each other yeah I think that will be a lot of very interesting use cases ok and then if nobody have any questions let me just wait can you see the ruby slides yeah ok so that's all I have today it was a very interesting exercise for me too so yeah this is the part about jobs if anybody have any looking for jobs or have any jobs that you know are available