Forgive me for a very long post, but here is all I've don to make drawing usefull.
I made a simple lua module (to be stored as CHDK/LUALIB/drawings.lua):
SCREEN_DRAWINGS={}
draw={}
draw.add = function( d_type, p1, p2, p3, p4, p5, p6, p7 )
local n=table.getn(SCREEN_DRAWINGS)+1
if d_type=="pixel" then
SCREEN_DRAWINGS[n]={"p",p1,p2,p3}--x,y,cl
return n;
end
if d_type=="line" then
SCREEN_DRAWINGS[n]={"l",p1,p2,p3,p4,p5}--x1,y1,x2,y2,cl
return n;
end
if d_type=="rect" then
SCREEN_DRAWINGS[n]={"r",p1,p2,p3,p4,p5,p6}--x1,y1,x2,y2,cl,th
return n;
end
if d_type=="ellipse" then
SCREEN_DRAWINGS[n]={"e",p1,p2,p3,p4,p5}--x,y,a,b,cl
return n;
end
return false
end
draw.replace = function( n, d_type, p1, p2, p3, p4, p5, p6, p7 )
draw.remove(n)
if d_type=="pixel" then
SCREEN_DRAWINGS[n]={"p",p1,p2,p3}--x,y,cl
return n;
end
if d_type=="line" then
SCREEN_DRAWINGS[n]={"l",p1,p2,p3,p4,p5}--x1,y1,x2,y2,cl
return n;
end
if d_type=="rect" then
SCREEN_DRAWINGS[n]={"r",p1,p2,p3,p4,p5,p6}--x1,y1,x2,y2,cl,th
return n;
end
if d_type=="ellipse" then
SCREEN_DRAWINGS[n]={"e",p1,p2,p3,p4,p5}--x,y,a,b,cl
return n;
end
return false
end
draw.get_params = function(n)
local out={nil}
if SCREEN_DRAWINGS[n][1] == "p" then out[1]="pixel" end
if SCREEN_DRAWINGS[n][1] == "l" then out[1]="line" end
if SCREEN_DRAWINGS[n][1] == "r" then out[1]"rect" end
if SCREEN_DRAWINGS[n][1] == "e" then out[1]="ellipse" end
if (out[1]~=nil) then
for i=2, table.getn(SCREEN_DRAWINGS[n]) do
out[i]=SCREEN_DRAWINGS[n][i]
end
end
return out
end
draw.redraw = function()
draw_clear()
for i=1,table.getn(SCREEN_DRAWINGS) do
local d_type=SCREEN_DRAWINGS[i][1]
if d_type=="p" then
local x=SCREEN_DRAWINGS[i][2]
local y=SCREEN_DRAWINGS[i][3]
local c=SCREEN_DRAWINGS[i][4]
draw_pixel(x,y,c)
end
if d_type=="l" then
local x1=SCREEN_DRAWINGS[i][2]
local y1=SCREEN_DRAWINGS[i][3]
local x2=SCREEN_DRAWINGS[i][4]
local y2=SCREEN_DRAWINGS[i][5]
local c=SCREEN_DRAWINGS[i][6]
draw_line(x1,y1,x2,y2,c)
end
if d_type=="r" then
local x1=SCREEN_DRAWINGS[i][2]
local y1=SCREEN_DRAWINGS[i][3]
local x2=SCREEN_DRAWINGS[i][4]
local y2=SCREEN_DRAWINGS[i][5]
local c=SCREEN_DRAWINGS[i][6]
local t=SCREEN_DRAWINGS[i][7]
draw_rect(x1,y1,x2,y2,c,t)
end
if d_type=="e" then
local x=SCREEN_DRAWINGS[i][2]
local y=SCREEN_DRAWINGS[i][3]
local a=SCREEN_DRAWINGS[i][4]
local b=SCREEN_DRAWINGS[i][5]
local c=SCREEN_DRAWINGS[i][6]
draw_rect(x,y,a,b,c)
end
end
end
draw.remove = function(n)
if (n<=table.getn(SCREEN_DRAWINGS)) then
for i=1,table.getn(SCREEN_DRAWINGS[n]) do
SCREEN_DRAWINGS[n][i]=nil
end
end
end
This module provides a really simple way to use the draw functions which are described before. With this module you have a few nice functions.
Usage:
- first you have to load the module:
require "drawings"
this will also create special array - SCREEN_DRAWINGS which contains all the data
- now you are able to use functions:
draw.add(type,p1,p2,...,color)
this function adds the drawing object of type type to the SCREEN_DRAWINGS. The types are strings and p1,p2..., color are numbers. Type names and corresponding parameters are as follows:
"pixel" - x, y, color
"line" - x1, y1, x2, y2, color
"rect" - x1, y1, x2, y2, color (, thickness )
"ellipse" - x, y, a, b, color
The function draw.add() returns a integer which is the identifier for the created object. It can be asigned to a variable to controll this object in the script (removing, changing coordinates or color)
When you use draw.add() function the drawing does not appear on the screen! It's only added to the array. To make all these changes visible you have to redraw screen using:
draw.redraw()
When you have to remove an object from the SCREEN_DRAWINGS table you can simply use:
draw.remove(id)
where id is an integer - the object identifier that was returned by draw.add() function when this object was created. Of course draw.remove() does not change the screen display - have to redraw to make changes visible!
Next function is:
draw.replace(id, type, p1,p2...color)
This function in fact removes object which identifier is id and creates new one with specified parameters insted. It might be used either for changing parameters of the object or even replacing one type object with the other. Example:
require "drawings"
--create a rect
my_rect = draw.add("rect",20,20,50,50,30)
--make it visible
draw.redraw()
--do some waste of time
sleep(3000)
--move this rect 10 pixels rigth
draw.replace(my_rect, "rect", 30,20,50,50,30)
--make the change visible
draw.redraw()
--do some waste of time
sleep(3000)
--replace this rect with a circle with the centre on 100x100
draw.replace(my_rect, "ellipse", 100, 100, 50, 50, 30)
--do dome waste of time
sleep(3000)
print(done!)
Note: in this example variable my_rect holds the id of the rect and after replacing it with ellipse (circle) it still holds the id of the same object, which now is not a rect but a ellipse.
If you need to get the parameters of the object with known id you can use function:
parameters = draw.get_params(id)
It returns an array. Note: this can be also done by directly reading SCREEN_DRAWINGS table. In this case the parameters and SCREEN_DRAWINGS[id] holds the same table.
At the end of this post I can sumarize this as potentially very usefull tool. Using a few new lua functions with the new module we can add a very powerfull method to draw almost anything on the screen. There's no reason we could not add to this module functions like:
draw.popup_window(title, text, buttons_array,selected_button_number)
which gives lua-writers possibility to write simple GUI applications. Lua scripts with GUI? Great!
PS. I've tested these new functions + module by drawing 5000 lines using script:
--[[
@title module draw test
@param l lin
@default l 5000
--]]
require "drawings"
for i=1, l do
x1=math.random(1,300)
x2=math.random(1,300)
y1=math.random(1,300)
y2=math.random(1,300)
cl=math.random(1,30)
draw.add("line",x1,y1,x2,y2,cl)
end
draw.redraw()
sleep(3000)
print("done!")
This script drawed 5000 lines which took 5 secounds on my sx130is without any crash or 'not enough memory'. I guess that 5000 lines is much more than anybody need...