-
-
Notifications
You must be signed in to change notification settings - Fork 620
Using Lua scripts (Part 08): Functions
take the example of the bar indicator with all the features we added and the entire lua script might look something like this
--[[this lua script draws vertical bar indicators]]
require 'cairo'
function conky_main()
if conky_window == nil then return end
local cs = cairo_xlib_surface_create(conky_window.display, conky_window.drawable, conky_window.visual, conky_window.width, conky_window.height)
cr = cairo_create(cs)
local updates=tonumber(conky_parse('${updates}'))
if updates>5 then
--#########################################################################################################
--SETTINGS FOR INDICATOR BAR
bar_bottom_left_x= 100
bar_bottom_left_y= 100
bar_width= 30
bar_height= 100
bar_value=tonumber(conky_parse("${cpu}"))
bar_max_value=100
--set bar background colors, 0.5,0.5,0.5,1 = fully opaque grey
bar_bg_red=0.5
bar_bg_green=0.5
bar_bg_blue=0.5
bar_bg_alpha=1
--bar border settings
bar_border=1 --set 1 for border or 0 for no border
--set border color rgba
border_red=0
border_green=1
border_blue=1
border_alpha=1
--set border thickness
border_width=10
--color change
--set value for first color change, low cpu usage to mid cpu usage
mid_value=50
--set "low" cpu usage color and alpha, ie bar color below 50% - 0,1,0,1=fully opaque green
lr,lg,lb,la=0,1,0,1
--set "mid" cpu usage color, between 50 and 79 - 1,1,0,1=fully opaque yellow
mr,mg,mb,ma=1,1,0,1
--set alarm value, this is the value at which bar color will change
alarm_value=80
--set alarm bar color, 1,0,0,1 = red fully opaque
ar,ag,ab,aa=1,0,0,1
--end of settings
--draw bar
--draw background
cairo_set_source_rgba (cr,bar_bg_red,bar_bg_green,bar_bg_blue,bar_bg_alpha)
cairo_rectangle (cr,bar_bottom_left_x,bar_bottom_left_y,bar_width,-bar_height)
cairo_fill (cr)
--draw indicator
if bar_value>=alarm_value then --ie if value is greater or equal to 50
cairo_set_source_rgba (cr,ar,ag,ab,aa)--yellow
elseif bar_value>=mid_value then --ie if bar_value is greater or equal to 80
cairo_set_source_rgba (cr,mr,mg,mb,ma)--red
else
cairo_set_source_rgba (cr,lr,lg,lb,la)--green
end
scale=bar_height/bar_max_value
indicator_height=scale*bar_value
cairo_rectangle (cr,bar_bottom_left_x,bar_bottom_left_y,bar_width,-indicator_height)
cairo_fill (cr)
--draw border
cairo_set_source_rgba (cr,border_red,border_green,border_blue,border_alpha)
cairo_set_line_width (cr,border_width)
border_bottom_left_x=bar_bottom_left_x-(border_width/2)
border_bottom_left_y=bar_bottom_left_y+(border_width/2)
brec_width=bar_width+border_width
brec_height=bar_height+border_width--remember that we need to make this value negative at some point because we are drawing up
cairo_rectangle (cr,border_bottom_left_x,border_bottom_left_y,brec_width,-brec_height)
cairo_stroke (cr)
--#########################################################################################################
end-- if updates>5
cairo_destroy(cr)
cairo_surface_destroy(cs)
cr=nil
end-- end main function
we can run the script from conky by adding these lines to the conkyrc
conky.config = {
lua_load = '/path-to-file/filename.lua',
lua_draw_hook_post = 'main',
};
conky.text = [[ ]];
but as it currently stands we only get one indicator bar out of it, currently set to display cpu%
there are plenty of other conky objects that we might want use our indicator bar with.
one thing we could do is copy all the code required to draw the bar, all the settings and all the drawing code, and paste it over and over, duplicating the code within the main lua function for as many bars as you want.
then you would go to each repetition of code, edit the settings (a minimum of setting a different conky object and new coordinates)
there is nothing wrong with this approach, plenty of my script have code repetitions in them and our code isnt all that long (we would have about 60 code lines per bar)...
BUT if our code was longer, and even for code this length, if we wanted lots of bars we would end up with a pretty large main function with settings and drawing code all mixed together. This can make harder work of editing when you want to make a change.
FUNCTIONS are a simple way to execute the same piece of code over and over again without increasing your line count and so keeping your main function free from clutter which makes it easier to navigate and edit.
before we go about editing our lua script to turn the bar code into a function, i'll do my best to explain what functions are all about!
if you look at other pre made lua scripts out there you will see that there are almost always other functions in the script in addition to the main function that is called in the conkyrc.
Functions can be as simple or as complex as you need the function to be. for use in conky, other functions are written outside of the main function either above or below.
due to the way lua scripts work, writing other functions below the main function isnt a problem.
From a programming point of view it would be more "proper" to have your other functions above the main. BUT many times you want to enter settings into the lua script, and more often than not these settings will go into the main function which is one reason why you may not want to bury your main function below the other functions.
all your other functions do not need the conky setup lines that the main function needs, you will be calling these other function from within the main function, so image that whenever you call a function, the script is simple substituting the function call with the code it contains, so that in essence the code exists within the main function
so all you need for other functions is to
- start the function
- give it a name
- set out what the function is going to do
- end the function
here is an example of a simple function
function multiply(number)
return number*2
end
this function accepts a number and returns the result of that number multiplied by 2
(for the sake of brevity i wont write out all the setup code for the main function just remember you need all the elements i described in part 1 of this how to for the main function if you want lua to display stuff in conky)
so how do we use the function i just wrote? lets say that we put it under the main function we would have a script like so
function conky_main()
*setup lines*
--#######################
result=multiply(16)
print (result)
--#######################
*close out lines
end-- main function
function multiply(number)
return number*2
end
the round brackets are very important here this is how we send information to our other functions
i am using the function inside main like this result=multiply(16)
So I am sending the multiply function the number 16 inside the curved brackets
The multiply function takes the number 16 and sets a string called "number" to that value function multiply(number)
so hopefully you can see the relationship between what is written between curved brackets when sending information to functions
This string could be called anything i wanted (as long as it didn't start with a number or have spaces) there is nothing special about calling it "number" it could just as easily be "baboons" but as ive said elsewhere i think its a good idea for the string name to reflect the contents of that string :)
the function takes the value held in "number", multiplies it by 2 and returns the result
in this case result=multiply(16)
the result returned by the multiply function is assigned to a string called "result" print(result) --> 32
A function doesn't have to return a value, they can be used for as many different purposes as you can think of
-think of what we are going to call the function, lets call it indicator_bar
so we can start our new function, and we will go and start the function below our main function we might as well put our "end" in there too, and comment it so we dont forget what its for :)
function indicator_bar()
--############################
--insert function code
--############################
end--of bar_indicator function
now we need to think about what code are going to put into our function?
this is one reason why i wrote my initial code so that there was a separate settings part where we assigned all the input values to strings and a separate drawing part where we manipulated our strings and plugged them into the commands that are responsible for getting the actual bar graphics onto the screen.
the point of making the function is that we want to be able to send our function different sets of settings and have the function output the graphics for each set
SO we will retain the setup portion for each bar within the main conky function and put the bar drawing code into the indicator_bar
.
we can just go ahead and cut the code out of the main conky function and paste it into the indicator_bar
function
once separated, the code would look something like this:
function conky_main()
*setup lines*
--#######################
--SETTINGS FOR INDICATOR BAR
bar_bottom_left_x= 100
bar_bottom_left_y= 100
bar_width= 30
bar_height= 100
bar_value=tonumber(conky_parse("${cpu}"))
bar_max_value=100
--set bar background colors, 0.5,0.5,0.5,1 = fully opaque grey
bar_bg_red=0.5
bar_bg_green=0.5
bar_bg_blue=0.5
bar_bg_alpha=1
--bar border settings
bar_border=1 --set 1 for border or 0 for no border
--set border color rgba
border_red=0
border_green=1
border_blue=1
border_alpha=1
--set border thickness
border_width=10
--color change
--set value for first color change, low cpu usage to mid cpu usage
mid_value=50
--set "low" cpu usage color and alpha, ie bar color below 50% - 0,1,0,1=fully opaque green
lr,lg,lb,la=0,1,0,1
--set "mid" cpu usage color, between 50 and 79 - 1,1,0,1=fully opaque yellow
mr,mg,mb,ma=1,1,0,1
--set alarm value, this is the value at which bar color will change
alarm_value=80
--set alarm bar color, 1,0,0,1 = red fully opaque
ar,ag,ab,aa=1,0,0,1
--end of settings
--#######################
*close out lines
end-- main function
function indicator_bar()
--############################
--draw bar
--draw background
cairo_set_source_rgba(cr,bar_bg_red,bar_bg_green,bar_bg_blue,bar_bg_alpha)
cairo_rectangle (cr,bar_bottom_left_x,bar_bottom_left_y,bar_width,-bar_height)
cairo_fill (cr)
--draw indicator
if bar_value>=alarm_value then --ie if value is greater or equal to 50
cairo_set_source_rgba (cr,ar,ag,ab,aa)--yellow
elseif bar_value>=mid_value then --ie if bar_value is greater or equal to 80
cairo_set_source_rgba (cr,mr,mg,mb,ma)--red
else
cairo_set_source_rgba (cr,lr,lg,lb,la)--green
end
scale=bar_height/bar_max_value
indicator_height=scale*bar_value
cairo_rectangle (cr,bar_bottom_left_x,bar_bottom_left_y,bar_width,-indicator_height)
cairo_fill (cr)
--draw border
cairo_set_source_rgba (cr,border_red,border_green,border_blue,border_alpha)
cairo_set_line_width (cr,border_width)
border_bottom_left_x=bar_bottom_left_x-(border_width/2)
border_bottom_left_y=bar_bottom_left_y+(border_width/2)
brec_width=bar_width+border_width
brec_height=bar_height+border_width--remember that we need to make this value negative at some point because we are drawing up
cairo_rectangle (cr,border_bottom_left_x,border_bottom_left_y,brec_width,-brec_height)
cairo_stroke (cr)
--############################
end--of bar_indicator function
the next thing is to think about how we get the settings information inside the conky_main
function to the bar drawing code inside the indicator_bar
function
we do this using curly brackets
--we call the function in the main function like so
indicator_bar(information to send to the function)
--and we need to set up the function to accept the information
function indicator_bar(information that was sent to the function)
there are a couple of ways to ago about this (as always) but for this example we will be sending and receiving strings
so what strings does the drawing code in indicator_bar need? the same strings that we set in the settings part,
we can write them in one line between our curved brackets separating each string from the next by a comma
these are the strings that indicator_bar
needs to receive to work properly so we can write the following:
function indicator_bar(bar_bottom_left_x,bar_bottom_left_y,bar_width,bar_height,bar_value,bar_max_value,bar_bg_red,bar_bg_green,bar_bg_blue,bar_bg_alpha,bar_border,border_red,border_green,border_blue,border_alpha,border_width,mid_value,lr,lg,lb,la,mr,mg,mb,ma,alarm_value,ar,ag,ab,aa)
that is our indicator_bar function finished.
NOTE the first code line in this function is a color setup line cairo_set_source_rgba(cr,bar_bg_red,bar_bg_green,bar_bg_blue,bar_bg_alpha)
and the first string this line needs is bar_bg_red
in our function the code takes the value for bar_bg_red
directly from the string of the same name found in the curved brackets following the function name
the same goes for all the other string values that the code needs
so when we call the function inside conky_main
, these are the things that we need to send
indicator_bar(bar_bottom_left_x,bar_bottom_left_y,bar_width,bar_height,bar_value,bar_max_value,bar_bg_red,bar_bg_green,bar_bg_blue,bar_bg_alpha,bar_border,border_red,border_green,border_blue,border_alpha,border_width,mid_value,lr,lg,lb,la,mr,mg,mb,ma,alarm_value,ar,ag,ab,aa)
NOTE when sending the information in the function call above there are several ways we can go about it
- we can input our values directly into the function call like so
indicator_bar(100,100,30,100,tonumber(conky_parse("${cpu}")),100,0.5,0.5,0.5,1,1,0,1,1,1,10,50,0,1,0,1,1,1,0,1,80,1,0,0,1)
we send this toindicator_bar
it takes the first string in its "string list" (the list inside the curly brackets following the functions name)
and sets that string to the value of the first thing in the "received list" which is the list of values received from the function call
bar_bottom_left_x=100
then it sets each subsequent string in its "string list" to each subsequent value the "received list"
next, 2nd entry in "string list" = 2nd entry in "received list"
bar_bottom_left_y=100
next, 3rd entry in "string list" = 3rd entry in "received list"
bar_width=30
SO every string in the functions "string list" requires a matching value in the list of things the function received from the function call
if we miss out a value (or put in an extra value) between () in the function call, the function just keeps on assigning vales in the order they are received leading to strings being assigned the wrong values
if we send 9 values in the function call but there are 10 strings to be set in the functions "string list" then the 10th string will have no value and be set to nil
trying to perform operations on strings that have a value of nil is a sure way to an error
i'll continue with function in a next part, i think i have already over-explained everything :D
- Home
- Installation
- Configurations
- Window Configuration
- Configs
- FAQ
- Lua
- Variables
- Compatibility
- Using Lua scripts
- How does a Lua script work
- Displaying stuff in conky
- Drawing lines
- Drawing rectangles, circles and arcs
- Making a bar meter and a circle meter
- Borders and if statements
- Alarm colors and complex if statements
- Functions
- Function parameters
- Table parameters
- For loops and cpu chart
- Clock and circular things
- Useful functions and code
- CLI commands timers and line editing
- Mouse events
- Contributing
- Issue Reporting