Sunday, February 7, 2010

Here is my line lua script again, but I'll tell you what everything means this time (at least as best as I understand it).

require 'cairo'
This calls in the cairo library. Cairo is the vector graphics application that will be used to display anything you want displayed.

function conky_draw_lines()
This is the name of my function. In conky I call "draw_line". This function contains everything that is going to be displayed in conky

local updates=conky_parse('${updates}')
Conky_parse is what makes the whole thing work. Here we tell Lua to perform the conky ${updates} object. The first " updates" is a string (or maybe it's technically a variable, which holds a string, but for simplicity I'm going to call it a string). You may wonder what the "local" means, and I have to say I'm a bit hazy on the use of local as opposed to global strings (global string would be just updates=conky_parse('${updates}') ) . From the Lua documents it's to do with visibility.
Lua uses strings to hold information and in this case updates holds the output of conky_parse('${updates}')

The (updates) is the same as the updates string from the line above. The "tonumber" part tells Lua to read the information stored in the string "updates" and turn it into a "readable" output. This output is stored in the update_num string.

if update_num > 5 then
This part looks at the information stored in the "update_num" string and asks if the number is greater than 5. If it is then the lines below are performed.
The reason for this is:
"if you are using the 'cpu' function, it will cause a segmentation fault if it tries to draw a ring straight away. Generally, a value of 5s is long enough, so if you update Conky every 1s, use update_num > 5 in that if statement (the default). If you only update Conky every 2s, you should change it to update_num > 3; conversely if you update Conky every 0.5s, you should use update_num > 10". From londonali1010's rings Lua.

if conky_window==nil then return end
Not to sure why this one is needed... I would assume that if your trying to run a Lua script in conky then there will always be a conky window. Most likely this prevents something from going wrong.

local w=conky_window.width
local h=conky_window.height
local cs=cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, w, h)
This section sets up the surface onto which cairo will draw. It sets the "canvas" to the height and width of the conky window. I just put this into my functions at the beginning. I can't say that I fully understand all the terms :) .

cairo_select_font_face (cr, "White Rabbit", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
Here we are getting into the cairo drawing part of the script. A cairo function in Lua will always start with "cairo". Following the cairo function are the variables for that function in brackets. The first variable is always cr. In this line I am setting the font with which I shall be displaying text later. The cairo documentation about the options for fonts here.

cairo_set_font_size (cr, 12.0);
This sets the font size to 12.

--Line 1 settings
A double hyphyn -- denotes a comment in Lua. This lets you write things into the script to designate sections and help to remind you of things.

local a_arg=conky_parse('${cpu}')
local a_thick=10
local a_red=1
local a_green=0
local a_blue=0
local a_alpha=1
local a_start=10
--line 1 settings end
Here I am setting up strings that will be used below. They will all be used to set the parameters of the lines that will be drawn. The reason to do this is so that the settings for a function can be defined in one area instead of looking through the cairo code and trying to change parameters. a_arg stores the information from the conky abject I'm parsing. This info will be later read by tonumber as above. a_thick sets line thickness, a_red, a_green and a_blue sets the color parameters. a_alpha sets the transparency and a_start sets where I want my line to start.
NOTE about color - cairo uses a system of red, green, blue to set color. Each color is a number from 0 to 1. Many other applications that define colors, GIMP, for example uses an RGB system that sets each color a number from 0 to 255. I typically used GIMP to find out the numbers for my colors. So when I take my RGB numbers I have to divide them by 255. You can do this calculation directly in the Lua script itself if you like... e.g. a_red=100/255.

local a_num=tonumber(a_arg)
tonumber reads a_arg and stores the output in a_num.

--line 1 background
another comment, telling me that the next section will set the background lines

cairo_set_source_rgba (cr, a_red, a_green, a_blue, 0.5);
here you can see the strings that we defined above being placed into a cairo function, in this case we are setting the color for the background line. the 0.5 is the alpha value I shall use for this line. This 0.5 gives the background line a 50% transparency.

cairo_set_line_width (cr, a_thick);
here line width is being set via the string a_thick.

cairo_move_to (cr, a_start, a_start);
the cairo_move_to sets the starting position for any drawing function of cairo. In this case my start position is set by the a_start string. The variables for the cairo_move_to are (cr, x-position, y-position). x and y position are in pixels (x is horizontal and y is vertical). In conky 0,0 is the top left corner of the window. 100, 100 moves 100 pixels across and 100 pixels down.

cairo_rel_line_to (cr, 100, 100);
cairo_rel_line tells cairo to draw a line to the coordinates given. The "rel" part stands for relative and means that the coordinates are plotted relative to the start position set by cairo_move_to. cairo_line_to would draw a line starting from cairo_move_to but the end coordinates are relative to 0,0 instead.

cairo_stroke (cr);
cairo_stroke tells cairo to actually display the line that we have defined above.

--line 1 indicator
cairo_set_source_rgba (cr, a_red, a_green, a_blue, a_alpha);
cairo_set_line_width (cr, a_thick);
cairo_move_to (cr, a_start, a_thick);
cairo_rel_line_to (cr, a_num, a_num);
cairo_stroke (cr);
This sets up the "indicator" line. Unlike the background line, which always has a set length, the length of the "indicator" line is set by the string a_num (which holds the output of the conky object ${cpu}). Therefore this line is directly proportional to current cpu usage and as max cpu usage is 100%, at 100% the indicator line will completely cover the background line. The string a_alpha is also used to define the transparecy of the indicator line.

--line 1 title
cairo_set_source_rgba (cr, a_red, a_green, a_blue, a_alpha);
cairo_move_to (cr, a_start+a_thick, a_thick);
Above we set the color and start position for the title text for the line. To get the position right there is a calculation to set the x coordinate "a_start+a_thick".

cairo_rotate (cr, 45*math.pi/180)
This is one of the avaialble transformations in cairo. The rotate function in cairo works on radians (who knows why degrees aren't the unit of choice, but I guess there is a reason.) Anyway the calculation "45*math.pi/180" converts 45 degrees to radians. The "math." part tells Lua to read pi as the number pi.

cairo_show_text (cr, "CPU");
This part tells cairo to display the text "CPU" and due to the above rotation function, the text is rotated 45 degrees clockwise, to sit along side the indicator bar.

cairo_rotate (cr, -45*math.pi/180)
this part is important if anything else is coming in the function (such as subsequent bars). Transformation functions in cairo are relative, in that everything below the above "rotate" command will be rotated. So in this line we rotate cairo's "reference" back to normal.

This first end closes the if update_num > 5 then from the beginning of the function
This second end closes the function. I am always getting tripped up by having either too few or too many ends.

And that's it! You have yourself a function. Here are a few basic tips that help me work with Lua and conky. And you can go here and take a look at a more complicated script that I have annotated.

1 comment:

  1. huge thanks for your write MrPeachy,
    my question is how to make the bottom curved,
    something like this image,