When I was trying to learn how to use cairo to create custom widgets in the GTK with ruby, I ran into a real lack of documentation online. There were lists of functions and all, but lists of functions just don't compare to samples, as far as I'm concerned. So I've decided to put together a little bit of code that can be used as a how-to or as a starting point for someone else's projects
The following Ruby code is an example of a custom GTK control created using the RCairo SVG library (cairo is built into GTK 2.8+) by extending the Gtk::DrawingArea class.
#we need to include these for obvious reasons
require 'gtk2'
require 'cairo'
#This class extends Gtk::DrawingArea
class CustomWidget < Gtk::DrawingArea
def initialize#call Gtk::DrawingArea's constructor first
super()
#connect the expose event
#(means drawing is needed)
#to the fRedraw function
self.signal_connect("expose_event") doend
fRedraw
end
#called when we get an expose event
def fRedraw#create our drawing context.#whatever we draw on this ends up on the screen #self.window is a Gdk::Windowend
context = self.window.create_cairo_context
#get the actual height/width of this control
height = self.allocation.height.to_f
width = self.allocation.width.to_f
#make drawing occur offscreen (double-buffering)
rect = Gdk::Rectangle.new(0, 0, self.allocation.width, self.allocation.height)
self.window.begin_paint(rect)
#set the colour and flood the region
c.set_source_rgba(0.5, 0.4, 0.6, 0.9)
c.paint
#set the colour and draw a line
c.set_source_rgba(0, 0, 0, 0.9)
c.move_to(height / 2.0, width / 2.0)
c.rel_line_to(height, width)
c.stroke
self.window.end_paint
end
That is a very basic example. From what I understand, it would be a good idea to try and buffer it by using an ImageSurface and creating a graphics context for it, then drawing to the ImageSurface's context. Once you're done, you can set the window context's source to the ImageSurface, and .fill the area.
for example, to create the image
@image = Cairo::ImageSurface.new(Cairo::FORMAT_ARGB32, height, width) @imageContext = Cairo::Context.new(@image)
Then in the fRedraw function where context is the window's context
context.set_source(@image, 0, 0)
context.paint
You'll still need to add this control to a parent control such as a window or a layout container. You'll also need to .show it for it to be visible.
For drawing things with a fixed scale, you can use the .scale command to scale a context down to a specific size. There's a really good tutorial for using cairo for drawing here. It's in Python, but it's still very helpful.
No comments:
Post a Comment