Examples 2
Weather
Select a location from the dropdown to display the current weather forecast. The program is available in the CVS repository.
The required libraries in this case are:
require "gtk"
require "gtk.http_co"
require "lxp"
require "gtk.strict"
"lxp" is LuaExpat, the binding to the expat xml parser. The following function is the handler for changes in the dropdown and starts an asynchronous HTTP request to fetch the weather info. The "_co" suffix indicates that a coroutine is used.
function on_location_changed(box)
local store = box:get_model()
local iter = gtk.new "GtkTreeIter"
box:get_active_iter(iter)
local code = store:get_value(iter, 1, nil)
gtk.http_co.request_co{
host = "xoap.weather.com",
uri = "/weather/local/" .. tostring(code)
.. "?cc=*&unit=m&dayf="..forecast_days,
callback = weather_info_callback,
}
end
The total code size of this example is about 270 lines, most of it concerned with parsing the response and building the GUI elements to show it.
Pixmap
This demo creates a GdkPixmap and draws on it using functions like draw_rectangle, draw_layout (for Pango layouts).
The code is interesting as it uses quite a few low level functions, accesses to structure elements and so forth. The following function is called to create the pixmap at a given size after size change of the window:
function on_configure(da, ev, ifo)
local window = ifo.win.window
local width, height = window:get_size(0, 0)
-- allocates memory in X server... default drawable, width, height, depth
-- loses the reference to the previous pixmap, if any.
ifo.pixmap = gtk.gdk_pixmap_new(window, width, height, -1)
local style = ifo.win:get_style()
local white_gc = style.white_gc
local black_gc = style.black_gc
-- clear the whole pixmap
ifo.pixmap:draw_rectangle(white_gc, true, 0, 0, width, height)
-- draw a rectangle
if width > 20 and height > 20 then
ifo.pixmap:draw_rectangle(black_gc, false, 10, 10, width - 20,
height - 20)
end
-- draw a text message
local message = "Hello, World! " .. ifo.msg
local layout = ifo.win:create_pango_layout(message)
ifo.pixmap:draw_layout(black_gc, 15, 15, layout)
-- get size of message
local region = layout:get_clip_region(0, 0, {0, string.len(message)}, 1)
local rect = gtk.new("GdkRectangle")
region:get_clipbox(rect)
if rect.width > 0 then
ifo.pixmap:draw_layout(black_gc, width - 15 - rect.width,
height - 15 - rect.height, layout)
end
-- Make sure that the unreferenced pixmap is freed NOW and not eventually,
-- because this can eat up loads of memory of the X server.
collectgarbage()
collectgarbage()
return true
end