Difference between revisions of "User talk:Akaya"

From Mudlet
Jump to navigation Jump to search
 
(15 intermediate revisions by the same user not shown)
Line 1: Line 1:
=Introduction to Frameworks: Geyser and Vyzor=
+
=Create a Clickable Compass=
Frameworks can make GUI creation loads easier by providing support for common GUI-related goals. The two most commonly used in the Mudlet world are Geyser and Vyzor. Each have their own pros and cons and it is ultimately up to you as to which you choose. Vyzor is great for creating an entire GUI and sharing them with others as it handles window resizing for you. Meaning the GUI will appear the same regardless of the user's screen size. Geyser handles widgets much better than Vyzor but does not offer dynamic resizing or individual manipulation of stylesheet elements by default. In short, there is really nothing that one can do that the other cannot with a bit of work. Again, the decision is up to you.
+
[[File: compass.png]]
==Geyser==
+
The following will walk you through the process of creating your own clickable compass using the Geyser framework.
One of the major highlights of Geyser is that it is built into Mudlet. No installation is necessary to utilize its API. This makes sharing your work a breeze.
+
==Setup the image files==
===Create a label===
+
The compass requires a handful of images to work properly. You can find them here: https://www.dropbox.com/sh/53l7xrn4ds35wnq/WpWOziVKmH <br>
[[File:Screenshot.png|thumb|Click to enlarge]]
+
Download each image and place it in your profile folder. You can find your profile folder with getMudletHomeDir()<br>
<lua>myLabel = Geyser.Label:new({
+
If you're using Mudlet 2.1+ you can enter '''lua getMudletHomeDir()''' from the command line to return the profile folder path on your computer.
  name = "myLabel",
 
  x = 0,
 
  y = "50%",
 
  width = 100,
 
  height = "10%",
 
},main)</lua>
 
#'''Geyser.Label:new()''' To create a label via Geyser we must use the Geyser.Label:new() function. It has two parameters: a table of label information and the container.
 
#'''Setting a variable''' Though not necessary, it is normally a wise choice to assign our label to a variable. This will allow us to refer to it later on. In our example, the variable name is set to ''myLabel''.
 
#'''Name''' This is the name that Geyser will use internally to manipulate our label. It is not uncommon (and usually best) to have this match our variable name. We've done this in our example, naming it ''myLabel''
 
#'''Position''' This is where our label will reside on the screen in relavance to the main Mudlet window via x and y coordinates. 0,0 representing the top left. These coordinates can be a percentage of its container encased in quotations (a string) or a pixel value (a number). In our example, x is set to 0 (a pixel value) which will hug it to the left side of the screen. y is set to "50%" which will set it halfway down the screen. If we want to adjust the starting position of the label, we would adjust these values.
 
#'''Size''' This will determine the size of our label using width and height. Just like the position, this can be a percentage or pixel value. In our example, the width has been set to 100 which will make it 100px wide. The height is set to "10%" which will make it's height 10% of the main Mudlet window.
 
#'''Container''' The container is the last thing to be specified during label creation. It is the second parameter of Geyser.Label:new() so you'll want to separate it from the first with a comma as shown in the above example. Since we don't really have a container made yet, we're simply placing the label in the main Mudlet window or ''main''.
 
===Style a label===
 
[[File:Blue.png|thumb|Click to enlarge]]
 
<lua>myLabel:setStyleSheet([[
 
  background-color: blue;
 
]])</lua>
 
#'''setStyleSheet()''' Styling a label is done using the Qt Stylesheet. Using the setStyleSheet() function we specify the properties of our label's stylesheet in a single string. The variable ''myLabel'' is prefixed so that the function knows which stylesheet its changing. Each property of the stylesheet is separated with a semicolon. There are numerous things you can do with this and a full list of features can be found here: [http://harmattan-dev.nokia.com/docs/library/html/qt4/stylesheet-reference.html]
 
#'''Stylesheet contents''' setStyleSheet() has but a single parameter: a single string containing every property of the stylesheet. This single parameter is encased with double brackets as there may be a string within a string. In our example, we have only provided a single property: background-color. Each property is separated from it's value with a colon.
 
===Create a container===
 
==Vyzor==
 
Blah Vyzor Blah
 
  
=Creating a Clickable Compass=
+
==Create a new script==
The following will walk you through the process of creating your own clickable compass using the Geyser framework.
+
Script Name: '''''compass.resize'''''<br>
 +
Registered Event Handlers: '''''sysWindowResizeEvent'''''<p>
 +
Every snippet of code will be placed within this script.
 
==Store the screen size==
 
==Store the screen size==
 
We'll want to store the screen size in some local variables so they can be easily referenced to later on.
 
We'll want to store the screen size in some local variables so they can be easily referenced to later on.
Line 36: Line 16:
  
 
==Create a global table or namespace==
 
==Create a global table or namespace==
Creating one will make each of your variables unique. Our name space will be called '''''compass''''' and everything we make from here on out will be stored within the compass table. We'll also add a few values to it: dirs and ratio. '''''compass.dirs''''' will store each direction while '''''compass.ratio''''' will store the ratio of our screen size so you can 'square up' your compass.
+
Creating a global table will make each of your variables unique. Our namespace will be called '''''compass''''' and everything we make from here on out will be stored within the compass table. We'll also add a few values to it: dirs and ratio. '''''compass.dirs''''' will store each direction while '''''compass.ratio''''' will store the ratio of our screen size so you can 'square up' your compass.
 
<lua>compass = compass or {
 
<lua>compass = compass or {
 
   dirs = {"nw","n","ne","w","center","e","sw","s","se"},
 
   dirs = {"nw","n","ne","w","center","e","sw","s","se"},
Line 43: Line 23:
  
 
==Create the parent label==
 
==Create the parent label==
 +
[[File: grey.png|thumbnail]]
 +
The 'parent label' refers to the label on the bottom layer. The entire compass will be created within this label. It's container is '''main''' for it's parent is the main window.
 
<lua>compass.back = Geyser.Label:new({
 
<lua>compass.back = Geyser.Label:new({
 
   name = "compass.back",
 
   name = "compass.back",
Line 50: Line 32:
 
   height = "10%",
 
   height = "10%",
 
},main)</lua>
 
},main)</lua>
 +
 
==Set the parent label stylesheet==
 
==Set the parent label stylesheet==
 +
[[File: blue.png|thumbnail]]
 +
This will create the blue sphere that makes up most of the compass. The background color is a radial gradient that goes from a deep blue to a brighter shade. The border radius rounds the edges. When the radius is exactly half of the label width it forms a circle. The arrows of the compass actually protrude from the sphere so we give it a margin to suck it in a bit for this effect.
 
<lua>compass.back:setStyleSheet([[
 
<lua>compass.back:setStyleSheet([[
 
   background-color: QRadialGradient(cx:.3,cy:1,radius:1,stop:0 rgb(0,0,50),stop:.5 rgb(0,0,100),stop:1 rgb(0,0,255));
 
   background-color: QRadialGradient(cx:.3,cy:1,radius:1,stop:0 rgb(0,0,50),stop:.5 rgb(0,0,100),stop:1 rgb(0,0,255));
  border-style: solid;
 
 
   border-radius: ]]..tostring(compass.back:get_width()/2-14)..[[px;
 
   border-radius: ]]..tostring(compass.back:get_width()/2-14)..[[px;
 
   margin: 10px;
 
   margin: 10px;
 
]])</lua>
 
]])</lua>
 +
 
==Create a 3x3 grid==
 
==Create a 3x3 grid==
 +
The compass is split into 9 sections. One for each cardinal direction plus an extra space that sits in the center. This 3x3 grid is created by 3 VBoxes that sit within a single HBox (or vice versa but I flipped a coin and this is what it gave me).<br>
 +
So first off, we create the HBox. It will be the same size as its parent, ''compass.back''.
 
<lua>  compass.box = Geyser.HBox:new({
 
<lua>  compass.box = Geyser.HBox:new({
 
     name = "compass.box",
 
     name = "compass.box",
Line 65: Line 52:
 
     height = "100%",
 
     height = "100%",
 
   },compass.back)</lua>
 
   },compass.back)</lua>
 
+
Next, we create our 3 VBoxes. You don't need to specify position or size because these are placed within ''compass.box'', an HBox.
 
<lua>    compass.row1 = Geyser.VBox:new({
 
<lua>    compass.row1 = Geyser.VBox:new({
 
       name = "compass.row1",
 
       name = "compass.row1",
Line 75: Line 62:
 
       name = "compass.row3",
 
       name = "compass.row3",
 
     },compass.box)</lua>
 
     },compass.box)</lua>
 
+
Finally, we add our 9 labels. Take note that they are split up into even groups of 3. Each group is placed into a different ''compass.row#''
 
<lua>      compass.nw = Geyser.Label:new({
 
<lua>      compass.nw = Geyser.Label:new({
 
         name = "compass.nw",
 
         name = "compass.nw",
Line 112: Line 99:
 
       },compass.row3)</lua>
 
       },compass.row3)</lua>
 
==Create a callback function==
 
==Create a callback function==
 +
We'll want our compass to head in the direction of the arrow we're clicking. This is where we specify so. When the arrow is clicked, this function will be ran with the arrow direction as the argument.
 
<lua>function compass.click(name)
 
<lua>function compass.click(name)
 
   send(name)
 
   send(name)
 
end</lua>
 
end</lua>
 
==Create the hover functions==
 
==Create the hover functions==
 +
We want our arrows to turn yellow when we hover over them. We do so by simply resetting the label's stylesheet and changing the border image. Don't forget to include the margin as we still want that.
 
<lua>function compass.onEnter(name)
 
<lua>function compass.onEnter(name)
 
   compass[name]:setStyleSheet([[
 
   compass[name]:setStyleSheet([[
Line 130: Line 119:
 
end</lua>
 
end</lua>
 
==Set the stylesheets in the grid==
 
==Set the stylesheets in the grid==
 +
[[File: Sample.png|thumb]]
 +
Each of the 9 labels need an image of an arrow. Rather than setting each individually, we'll iterate over the ''compass.dirs'' table we made awhile back and add the respective image to each. The names of images are a reflection of the ''compass.dirs'' table. This keeps it consistent and easy to refer to. During the iteration, the callback, setLabelOnEnter and setLabelOnLeave are also set for each label.
 
<lua>for k,v in pairs(compass.dirs) do
 
<lua>for k,v in pairs(compass.dirs) do
 
   compass[v]:setStyleSheet([[
 
   compass[v]:setStyleSheet([[
Line 141: Line 132:
  
 
==Resize the compass into a square==
 
==Resize the compass into a square==
 +
[[File: final.png|thumb]]
 +
Most screen size ratios aren't a perfect 1:1. This will cause a 10% x 10% label to be far from square. By multiplying our height (the smaller of the two numbers) by our ''compass.ratio'' we set earlier, we can resize our compass to a near perfect square. This function is also the name of our script because we want it to run each time sysWindowResizeEvent is raised.
 
<lua>function compass.resize()
 
<lua>function compass.resize()
 
   compass.back:resize(compass.back:get_width(),math.floor(compass.back:get_height()*compass.ratio))
 
   compass.back:resize(compass.back:get_width(),math.floor(compass.back:get_height()*compass.ratio))
Line 146: Line 139:
  
 
compass.resize()</lua>
 
compass.resize()</lua>
 +
 +
=Create a Tabbed Window=
 +
[[File: tabwindow.png]]
 +
The following will walk you through the process of creating your own tabbed window using the Geyser framework.
 +
 +
==Create a new script==
 +
Script Name: '''''Tabbed Window'''''<br>
 +
Every snippet of code will be placed within this script.
 +
==Create a global table==
 +
Creating a global table will make each of your variables unique. Our namespace will be called '''''menu''''' and everything we make from here on out will be stored within the menu table. We'll also add a few values to it: tabs, color1, color2, width, height and current. <br>
 +
''''tabs'''' will be a table that stores all our tab names. If we want our tabs to have different names, we alter this table.<br>
 +
''''color1'''' and ''''color2'''' will store the colors of our tabbed window. If we want to change the color of our tabbed window, we alter these values.<br>
 +
''''width'''' and ''''height'''' will store the size of our tabbed window. If we want to change the size of the tabbed window, we alter these values.<br>
 +
''''current'''' keeps track of which tab is selected. Since no tab is selected at startup, we'll make this an empty string.<br>
 +
<lua>menu = menu or {
 +
  tabs = {"Tab1","Tab2","Tab3","Tab4"},
 +
  color1 = "rgb(0,0,70)",
 +
  color2 = "rgb(0,0,50)",
 +
  width = "20%",
 +
  height = "40%",
 +
  current = "",
 +
}</lua>
 +
==Create the main container==
 +
Our tabbed window will need a container. This will be the bottom layer. Containers are invisible so no need to set a stylesheet.
 +
<lua>menu.container = Geyser.Container:new({
 +
  name = "menu.back",
 +
  x = "50%", y = "25%",
 +
  width = menu.width,
 +
  height = menu.height,
 +
},main)</lua>
 +
==Create an HBox==
 +
All of our tabs will be evenly spaced. So we'll create an HBox to sit at the top of our container.
 +
<lua>menu.header = Geyser.HBox:new({
 +
  name = "menu.header",
 +
  x = 0, y = 0,
 +
  width = "100%",
 +
  height = "10%",
 +
},menu.container)</lua>
 +
==Create a label==
 +
This label will serve as a container for each window. It sits right underneath the HBox we just created for the tabs.
 +
<lua>menu.footer = Geyser.Label:new({
 +
  name = "menu.footer",
 +
  x = 0, y = "10%",
 +
  width = "100%",
 +
  height = "90%",
 +
},menu.container)</lua>
 +
We don't want this to be a big grey box at startup, so we'll set the stylesheet to appear like the rest of the windows.
 +
<lua>
 +
menu.footer:setStyleSheet([[
 +
  background-color: ]]..menu.color1..[[;
 +
  border-bottom-left-radius: 10px;
 +
  border-bottom-right-radius: 10px;
 +
]])</lua>
 +
Each window actually has two labels. One for the light blue background, and another for the dark blue center. This will create that dark blue center.
 +
<lua>menu.center = Geyser.Label:new({
 +
  name = "menu.center",
 +
  x = 0, y = 0,
 +
  width = "100%",
 +
  height = "100%",
 +
},menu.footer)
 +
menu.center:setStyleSheet([[
 +
  background-color: ]]..menu.color2..[[;
 +
  border-radius: 10px;
 +
  margin: 5px;
 +
]])</lua>
 +
==Add your tabs and their windows==
 +
Now we'll want to add our tabs and windows. We do this in a single for loop of the ''''menu.tabs'''' table since it holds all our tab names.
 +
<lua>for k,v in pairs(menu.tabs) do
 +
</lua>
 +
This will create the tabs. Each tab will be named: menu.<tabname>tab
 +
<lua>
 +
  menu[v.."tab"] = Geyser.Label:new({
 +
    name = "menu."..v.."tab",
 +
  },menu.header)
 +
</lua>
 +
Here is where we set the tab stylesheet. Each tab has a rounded top, so we set the border-radius of the top-left and top-right to 10px. Each tab has a small space for separation so we give the right and left sides a tiny margin of 1px.
 +
<lua>
 +
  menu[v.."tab"]:setStyleSheet([[
 +
    background-color: ]]..menu.color1..[[;
 +
    border-top-left-radius: 10px;
 +
    border-top-right-radius: 10px;
 +
    margin-right: 1px;
 +
    margin-left: 1px;
 +
  ]])
 +
</lua>
 +
This will display the name of each tab on the tab.
 +
<lua>
 +
  menu[v.."tab"]:echo("<center>"..v)
 +
</lua>
 +
We need our tabs to do stuff when clicked, so we'll assign it a callback function, '''''menu.click''''', which we'll create later on. Our tab name is the argument.
 +
<lua>
 +
  menu[v.."tab"]:setClickCallback("menu.click",v)
 +
</lua>
 +
Now we create the windows that appear when each tab is clicked. Each window has two labels, one atop the other. The first, which we'll create here, has rounded edges on its bottom.
 +
<lua>
 +
  menu[v] = Geyser.Label:new({
 +
    name = "menu."..v,
 +
    x = 0, y = 0,
 +
    width = "100%",
 +
    height = "100%",
 +
  },menu.footer)
 +
 +
  menu[v]:setStyleSheet([[
 +
    background-color: ]]..menu.color1..[[;
 +
    border-bottom-left-radius: 10px;
 +
    border-bottom-right-radius: 10px;
 +
  ]])
 +
</lua>
 +
The second label serves as the window's center and has rounded edges on all sides. And a margin of 5px from it's parent, the label we just created. When adding stuff to your windows, this is the label you'll want to use. '''''menu.<tabname>center'''''
 +
<lua>
 +
  menu[v.."center"] = Geyser.Label:new({
 +
    name = "menu."..v.."center",
 +
    x = 0, y = 0,
 +
    width = "100%",
 +
    height = "100%",
 +
  },menu[v])
 +
</lua><lua>
 +
  menu[v.."center"]:setStyleSheet([[
 +
    background-color: ]]..menu.color2..[[;
 +
    border-radius: 10px;
 +
    margin: 5px;
 +
  ]])
 +
</lua>
 +
Finally, we hide all the windows and end the for loop.
 +
<lua>
 +
  menu[v]:hide()
 +
end</lua>
 +
==Create a callback function==
 +
The last step is to create our callback function for when a tab is clicked. This will hide that tab that is stored in '''''menu.current''''', set menu.current to the clicked tab, and then show the menu.current tab.
 +
<lua>function menu.click(tab)
 +
  menu[menu.current]:hide()
 +
  menu.current = tab
 +
  menu[menu.current]:show()
 +
end</lua>
 +
==Adding content to your windows==
 +
Add content to '''menu.<tab name>center'''
 +
So if we wanted to display our gold in a window we could:<lua>menu.Tab1center:echo(myGold)</lua>
 +
If we wanted to add a map to a window we could:
 +
<lua>myMap = Geyser.Mapper:new({
 +
  name = "myMap",
 +
  x = 0, y = 0,
 +
  width = "100%",
 +
  height = "100%",
 +
},menu.Tab2center)</lua>

Latest revision as of 20:09, 7 September 2013

Create a Clickable Compass

Compass.png The following will walk you through the process of creating your own clickable compass using the Geyser framework.

Setup the image files

The compass requires a handful of images to work properly. You can find them here: https://www.dropbox.com/sh/53l7xrn4ds35wnq/WpWOziVKmH
Download each image and place it in your profile folder. You can find your profile folder with getMudletHomeDir()
If you're using Mudlet 2.1+ you can enter lua getMudletHomeDir() from the command line to return the profile folder path on your computer.

Create a new script

Script Name: compass.resize

Registered Event Handlers: sysWindowResizeEvent

Every snippet of code will be placed within this script.

Store the screen size

We'll want to store the screen size in some local variables so they can be easily referenced to later on. <lua>local mw, mh = getMainWindowSize()</lua>

Create a global table or namespace

Creating a global table will make each of your variables unique. Our namespace will be called compass and everything we make from here on out will be stored within the compass table. We'll also add a few values to it: dirs and ratio. compass.dirs will store each direction while compass.ratio will store the ratio of our screen size so you can 'square up' your compass. <lua>compass = compass or {

 dirs = {"nw","n","ne","w","center","e","sw","s","se"},
 ratio = mw / mh

}</lua>

Create the parent label

Grey.png

The 'parent label' refers to the label on the bottom layer. The entire compass will be created within this label. It's container is main for it's parent is the main window. <lua>compass.back = Geyser.Label:new({

 name = "compass.back",
 x = "25%",
 y = "25%",
 width = "10%",
 height = "10%",

},main)</lua>

Set the parent label stylesheet

Blue.png

This will create the blue sphere that makes up most of the compass. The background color is a radial gradient that goes from a deep blue to a brighter shade. The border radius rounds the edges. When the radius is exactly half of the label width it forms a circle. The arrows of the compass actually protrude from the sphere so we give it a margin to suck it in a bit for this effect. <lua>compass.back:setStyleSheet([[

 background-color: QRadialGradient(cx:.3,cy:1,radius:1,stop:0 rgb(0,0,50),stop:.5 rgb(0,0,100),stop:1 rgb(0,0,255));
 border-radius: ]]..tostring(compass.back:get_width()/2-14)..[[px;
 margin: 10px;

]])</lua>

Create a 3x3 grid

The compass is split into 9 sections. One for each cardinal direction plus an extra space that sits in the center. This 3x3 grid is created by 3 VBoxes that sit within a single HBox (or vice versa but I flipped a coin and this is what it gave me).
So first off, we create the HBox. It will be the same size as its parent, compass.back. <lua> compass.box = Geyser.HBox:new({

   name = "compass.box",
   x = 0,
   y = 0,
   width = "100%",
   height = "100%",
 },compass.back)</lua>

Next, we create our 3 VBoxes. You don't need to specify position or size because these are placed within compass.box, an HBox. <lua> compass.row1 = Geyser.VBox:new({

     name = "compass.row1",
   },compass.box)
   compass.row2 = Geyser.VBox:new({
     name = "compass.row2",
   },compass.box)
   compass.row3 = Geyser.VBox:new({
     name = "compass.row3",
   },compass.box)</lua>

Finally, we add our 9 labels. Take note that they are split up into even groups of 3. Each group is placed into a different compass.row# <lua> compass.nw = Geyser.Label:new({

       name = "compass.nw",
     },compass.row1)
     compass.w = Geyser.Label:new({
       name = "compass.w",
     },compass.row1)
   
     compass.sw = Geyser.Label:new({
       name = "compass.sw",
     },compass.row1)
 
     compass.n = Geyser.Label:new({
       name = "compass.n",
     },compass.row2)
       
     compass.center = Geyser.Label:new({
       name = "compass.center",
     },compass.row2)
     compass.s = Geyser.Label:new({
       name = "compass.s",
     },compass.row2)
     compass.ne = Geyser.Label:new({
       name = "compass.ne",
     },compass.row3)
   
     compass.e = Geyser.Label:new({
       name = "compass.e",
     },compass.row3)
 
     compass.se = Geyser.Label:new({
       name = "compass.se",
     },compass.row3)</lua>

Create a callback function

We'll want our compass to head in the direction of the arrow we're clicking. This is where we specify so. When the arrow is clicked, this function will be ran with the arrow direction as the argument. <lua>function compass.click(name)

 send(name)

end</lua>

Create the hover functions

We want our arrows to turn yellow when we hover over them. We do so by simply resetting the label's stylesheet and changing the border image. Don't forget to include the margin as we still want that. <lua>function compass.onEnter(name)

 compass[name]:setStyleSheet([[
   border-image: url("]]..getMudletHomeDir()..User talk:Akaya/..name..[[hover.png");
   margin: 5px;
 ]])

end

function compass.onLeave(name)

 compass[name]:setStyleSheet([[
   border-image: url("]]..getMudletHomeDir()..User talk:Akaya/..name..[[.png");
   margin: 5px;
 ]])

end</lua>

Set the stylesheets in the grid

Sample.png

Each of the 9 labels need an image of an arrow. Rather than setting each individually, we'll iterate over the compass.dirs table we made awhile back and add the respective image to each. The names of images are a reflection of the compass.dirs table. This keeps it consistent and easy to refer to. During the iteration, the callback, setLabelOnEnter and setLabelOnLeave are also set for each label. <lua>for k,v in pairs(compass.dirs) do

 compass[v]:setStyleSheet([[
   border-image: url("]]..getMudletHomeDir()..User talk:Akaya/..v..[[.png");
   margin: 5px;
 ]])
 compass[v]:setClickCallback("compass.click",v)
 setLabelOnEnter("compass."..v,"compass.onEnter",v)
 setLabelOnLeave("compass."..v,"compass.onLeave",v)

end</lua>

Resize the compass into a square

Final.png

Most screen size ratios aren't a perfect 1:1. This will cause a 10% x 10% label to be far from square. By multiplying our height (the smaller of the two numbers) by our compass.ratio we set earlier, we can resize our compass to a near perfect square. This function is also the name of our script because we want it to run each time sysWindowResizeEvent is raised. <lua>function compass.resize()

 compass.back:resize(compass.back:get_width(),math.floor(compass.back:get_height()*compass.ratio))

end

compass.resize()</lua>

Create a Tabbed Window

Tabwindow.png The following will walk you through the process of creating your own tabbed window using the Geyser framework.

Create a new script

Script Name: Tabbed Window
Every snippet of code will be placed within this script.

Create a global table

Creating a global table will make each of your variables unique. Our namespace will be called menu and everything we make from here on out will be stored within the menu table. We'll also add a few values to it: tabs, color1, color2, width, height and current.
'tabs' will be a table that stores all our tab names. If we want our tabs to have different names, we alter this table.
'color1' and 'color2' will store the colors of our tabbed window. If we want to change the color of our tabbed window, we alter these values.
'width' and 'height' will store the size of our tabbed window. If we want to change the size of the tabbed window, we alter these values.
'current' keeps track of which tab is selected. Since no tab is selected at startup, we'll make this an empty string.
<lua>menu = menu or {

 tabs = {"Tab1","Tab2","Tab3","Tab4"},
 color1 = "rgb(0,0,70)",
 color2 = "rgb(0,0,50)",
 width = "20%",
 height = "40%",
 current = "",

}</lua>

Create the main container

Our tabbed window will need a container. This will be the bottom layer. Containers are invisible so no need to set a stylesheet. <lua>menu.container = Geyser.Container:new({

 name = "menu.back",
 x = "50%", y = "25%",
 width = menu.width,
 height = menu.height,

},main)</lua>

Create an HBox

All of our tabs will be evenly spaced. So we'll create an HBox to sit at the top of our container. <lua>menu.header = Geyser.HBox:new({

 name = "menu.header",
 x = 0, y = 0,
 width = "100%",
 height = "10%",

},menu.container)</lua>

Create a label

This label will serve as a container for each window. It sits right underneath the HBox we just created for the tabs. <lua>menu.footer = Geyser.Label:new({

 name = "menu.footer",
 x = 0, y = "10%",
 width = "100%",
 height = "90%",

},menu.container)</lua> We don't want this to be a big grey box at startup, so we'll set the stylesheet to appear like the rest of the windows. <lua> menu.footer:setStyleSheet([[

 background-color: ]]..menu.color1..[[;
 border-bottom-left-radius: 10px;
 border-bottom-right-radius: 10px;

]])</lua> Each window actually has two labels. One for the light blue background, and another for the dark blue center. This will create that dark blue center. <lua>menu.center = Geyser.Label:new({

 name = "menu.center",
 x = 0, y = 0,
 width = "100%",
 height = "100%",

},menu.footer) menu.center:setStyleSheet([[

 background-color: ]]..menu.color2..[[;
 border-radius: 10px;
 margin: 5px;

]])</lua>

Add your tabs and their windows

Now we'll want to add our tabs and windows. We do this in a single for loop of the 'menu.tabs' table since it holds all our tab names. <lua>for k,v in pairs(menu.tabs) do </lua> This will create the tabs. Each tab will be named: menu.<tabname>tab <lua>

 menu[v.."tab"] = Geyser.Label:new({
   name = "menu."..v.."tab",
 },menu.header)

</lua> Here is where we set the tab stylesheet. Each tab has a rounded top, so we set the border-radius of the top-left and top-right to 10px. Each tab has a small space for separation so we give the right and left sides a tiny margin of 1px. <lua>

 menu[v.."tab"]:setStyleSheet([[
   background-color: ]]..menu.color1..[[;
   border-top-left-radius: 10px;
   border-top-right-radius: 10px;
   margin-right: 1px;
   margin-left: 1px;
 ]])

</lua> This will display the name of each tab on the tab. <lua>

menu[v.."tab"]:echo("

"..v)

</lua> We need our tabs to do stuff when clicked, so we'll assign it a callback function, menu.click, which we'll create later on. Our tab name is the argument. <lua>

 menu[v.."tab"]:setClickCallback("menu.click",v)

</lua> Now we create the windows that appear when each tab is clicked. Each window has two labels, one atop the other. The first, which we'll create here, has rounded edges on its bottom. <lua>

 menu[v] = Geyser.Label:new({
   name = "menu."..v,
   x = 0, y = 0,
   width = "100%",
   height = "100%",
 },menu.footer)
 menu[v]:setStyleSheet([[
   background-color: ]]..menu.color1..[[;
   border-bottom-left-radius: 10px;
   border-bottom-right-radius: 10px;
 ]])

</lua> The second label serves as the window's center and has rounded edges on all sides. And a margin of 5px from it's parent, the label we just created. When adding stuff to your windows, this is the label you'll want to use. menu.<tabname>center <lua>

 menu[v.."center"] = Geyser.Label:new({
   name = "menu."..v.."center",
   x = 0, y = 0,
   width = "100%",
   height = "100%",
 },menu[v])

</lua><lua>

 menu[v.."center"]:setStyleSheet([[
   background-color: ]]..menu.color2..[[;
   border-radius: 10px;
   margin: 5px;
 ]])

</lua> Finally, we hide all the windows and end the for loop. <lua>

 menu[v]:hide()

end</lua>

Create a callback function

The last step is to create our callback function for when a tab is clicked. This will hide that tab that is stored in menu.current, set menu.current to the clicked tab, and then show the menu.current tab. <lua>function menu.click(tab)

 menu[menu.current]:hide()
 menu.current = tab
 menu[menu.current]:show()

end</lua>

Adding content to your windows

Add content to menu.<tab name>center So if we wanted to display our gold in a window we could:<lua>menu.Tab1center:echo(myGold)</lua> If we wanted to add a map to a window we could: <lua>myMap = Geyser.Mapper:new({

 name = "myMap",
 x = 0, y = 0,
 width = "100%",
 height = "100%",

},menu.Tab2center)</lua>