-
-
Notifications
You must be signed in to change notification settings - Fork 620
Using Lua scripts (Part 03): Drawing lines
One of the basic things to be able to do is to draw a line. There are several commands we need to consider for lines.
line thickness
cairo_set_line_width (cr, 1)
NOTE, you can see here and in other examples the general form that
the Cairo commands take is cairo_something (cr, settings)
. We set
the value of cr in our main function's setup lines. Every time you
use a Cairo command, the first thing within the curved brackets will
be cr
.
Line end cap:
cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT)
or
cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND)
or
cairo_set_line_cap (cr, CAIRO_LINE_CAP_SQUARE)
See here for more info: Cairo Manual. The default is BUTT, so that is what you get if you don't set up the cap type.
And then a command we have seen before, cairo_set_source_rgba (cr, 1, 1, 1, 1)
.
And we need to specify where the line is going to start: cairo_move_to (cr, 100, 100)
.
We could do our setup like we did for our text.
line_width = 1
line_cap = CAIRO_LINE_CAP_BUTT
red, green, blue, alpha = 1, 1, 1, 1
startx = 100
starty = 100
---------------------------
cairo_set_line_width (cr, line_width)
cairo_set_line_cap (cr, line_cap)
cairo_set_source_rgba (cr, red, green, blue, alpha)
cairo_move_to (cr, startx, starty)
Now we need to draw the line and there are two ways to do it: you can
specify the ending coordinates directly -- cairo_line_to (cr, 200, 100)
-- or you can specify where the line should go relative
to the start -- cairo_rel_line_to (cr, 100, 0)
.
In this case we get the same result ... In the first example we start at 100, 100 and tell Cairo to draw a line to 200, 100.
In the second example we start at 100, 100 and tell Cairo to draw a line to a point 100 pixels to the right and 0 pixels down from where we started.
So both examples will produce a horizontal line 100 pixels long.
Once we have finished specifying the coordinates we then tell Cairo to
actually draw the line (cairo_stroke (cr)
).
I tend to use the absolute method -- "line_to" -- rather than the relative method.
So altogether, we have:
line_width = 1
line_cap = CAIRO_LINE_CAP_BUTT
red, green, blue, alpha = 1, 1, 1, 1
startx = 100
starty = 100
endx = 200
endy = 100
----------------------------
cairo_set_line_width (cr, line_width)
cairo_set_line_cap (cr, line_cap)
cairo_set_source_rgba (cr, red, green, blue, alpha)
cairo_move_to (cr, startx, starty)
cairo_line_to (cr, endx, endy)
cairo_stroke (cr)
About line thickness. We set a line from 100, 100
to
200, 100
but setting a line thickness greater than 1 will affect not
only what the line looks like but where it appears to have been drawn.
If we set, for example, a line width of 10, then the line will be 5
pixels wide to one side of the base line, and 5 pixels wide to the
other side.
That is, the top left corner of the line will actually be at 100, 95
and the bottom left corner at 100, 105
(remember that the larger the
x and y numbers, the more right and down they are) -- the line will be
more of a rectangle.
But with some math and tweaking we can easily make this line change in length relative to a Conky object.
Once you get the idea of using variables and strings to affect the coordinates and other values of drawn objects then you are a good way there and everything else is just the complexity of the interactions and what is being drawn.
For example, we want to make a cpu usage indicator line cpu_perc = tonumber (conky_parse ("${cpu}"))
. I will use tonumber just to make
sure ... it can be easy to get lost in curved brackets when using
compound commands like this :).
This will output a number between 0 and 100. The line we have already drawn is 100 pixels long so its easy enough to do the following:
cpu_perc = tonumber (conky_parse ("${cpu}"))
line_width = 1
line_cap = CAIRO_LINE_CAP_BUTT
red, green, blue, alpha = 1, 1, 1, 1
startx = 100
starty = 100
endx = startx + cpu_perc
endy = starty
----------------------------
cairo_set_line_width (cr, line_width)
cairo_set_line_cap (cr, line_cap)
cairo_set_source_rgba (cr, red, green, blue, alpha)
cairo_move_to (cr, startx, starty)
cairo_line_to (cr, endx, endy)
cairo_stroke (cr)
This is what is going to make the line move: endx = startx + cpu_perc
. The horizontal end point of my line will change in relation
to the value of cpu_perc
as measured through the Conky variable
${cpu}
.
I have made a couple of other changes ... instead of saying endx = 100 + cpu_perc
I have put endx = startx + cpu_perc
and instead of
endy = 100
I have endy = starty
.
Using this method, all I have to do is edit startx and starty and those changes will follow on to the other strings.
When I am writing scripts I find it timesaving to set as few "absolute" vales as possible. this gives you less things to find later on when you want to make changes.
You can do more with lines than just draw lines.
You can use lines to draw shapes. You can then have these shapes as outlines or fill them in.
A triangle, for example. There are some other things to consider when using multiple lines. One is how to join the lines together, which is set by the following:
cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER)
or
cairo_set_line_join (cr, CAIRO_LINE_JOIN_BEVEL)
or
cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND)
See here for more details Cairo manual (line join).
MITER is the default, so that is what you get when you don't set line join type
We can also use this command: cairo_close_path (cr)
. Close path tells
Cairo that the lines should be joined together at the ends to make one
continuous line.
This is what you get without close_path on the left and with close_path on the right, and using the default MITER line join.
NOTE, as soon as you set cairo_close_path
, the setting for line
cap type becomes redundant, as there are no longer any line ends.
Here is the code for the figure on the right above.
line_width = 20
line_cap = CAIRO_LINE_CAP_BUTT -- We don't need this any more after closing
-- the path.
line_join = CAIRO_LINE_JOIN_MITER -- but this will still affect how the lines
-- look
red, green, blue, alpha = 1, 1, 1, 1
startx = 100
starty = 100
pointx = startx + 100
pointy = starty + 100
endx = pointx - 100
endy = pointy
----------------------------
cairo_set_line_width (cr, line_width)
cairo_set_line_cap (cr, line_cap)
cairo_set_source_rgba (cr, red, green, blue, alpha)
cairo_move_to (cr, startx, starty)
cairo_line_to (cr, pointx, pointy)
cairo_line_to (cr, endx, endy)
cairo_line_to (cr, startx, starty)
cairo_set_line_join (cr, line_join)
cairo_close_path (cr)
cairo_stroke (cr)
NOTE, as you can see, you don't have to draw each individual line, as you are instead drawing a "path". Imagine a pen being drawn on paper in one continuous line from point to point.
You only need to use cairo_stroke
at the end to draw along the path
you set to see the lines.
It is also good to know that by using the close_path command we don't
actually need to draw the third side of the triangle. When you use
close_path
Cairo will draw a line from wherever you stop back to the
start.
If we want to fill in the triangle we use cairo_fill (cr)
instead of
cairo_stroke (cr)
.
But with cairo_fill
the setting for line width no longer applies.
Also with fill the line join type no longer applies.
The fill fills in only the triangle bound by the coordinates we set.
ALSO, with cairo_fill
, we need not use the close_path command, as
the fill command will automatically close the path in order to
generate a boundary area to fill in ... but it never hurts to use the
close_path command and nothing bad will happen if you set redundant
commands :D.
For example I could specify all 3 sides of the triangle, close_path
and then cairo_fill
and I will still get a filled-in triangle! Lua
code can be quite forgiving.
Here is stroke vs fill:
And if you want the shape outlined and filled (for example in
different colors) you would first use cairo_fill_preserve
(instead
of just cairo_fill
), then set our second color and use
cairo_stroke
to draw the outline.
cairo_set_line_width (cr, 20)
cairo_move_to (cr, 100, 100) -- Start point.
cairo_line_to (cr, 200, 200) -- Diagonal line down.
cairo_line_to (cr, 100, 200) -- Horizontal line.
cairo_close_path (cr) -- Draws vertical line back to start.
cairo_set_source_rgba (cr, 1, 1, 1, 1) -- White.
cairo_fill_preserve (cr) -- Fills in the triangle in white.
cairo_set_source_rgba (cr, 1, 0, 0, 1) -- Red.
cairo_stroke (cr) -- Draws the triangle outline in red.
- 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