luaforwindows/files/examples/im/show_image_touch.wlua

230 lines
5.6 KiB
Lua

require"imlua"
require"cdlua"
require"cdluaim"
require"iuplua"
require"iupluacd"
require"iupluatuio"
cnv = iup.canvas{rastersize = "1024x768", border = "NO", touch="Yes"}
img_x = 0
img_y = 0
-- comment this line to NOT use the TUIO client, only Windows 7 supports multi-touch
tuio = iup.tuioclient{}
function load_image(filename)
local new_image = im.FileImageLoadBitmap(filename)
if (not new_image) then
iup.Message("Error", "LoadBitmap failed.")
else
if (image) then image:Destroy() end
loaded = true
image = new_image
iup.Update(cnv)
end
end
function cnv:map_cb() -- the CD canvas can only be created when the IUP canvas is mapped
canvas = cd.CreateCanvas(cd.IUP, self)
end
function cnv:action() -- called everytime the IUP canvas needs to be repainted
canvas:Activate()
canvas:Clear()
if (image) then
if (loaded) then
local cnv_w, cnv_h = canvas:GetSize()
-- inicial zoom and position
img_w = image:Width()
img_h = image:Height()
img_x = (cnv_w-img_w)/2
img_y = (cnv_h-img_h)/2
loaded = false
end
image:cdCanvasPutImageRect(canvas, img_x, img_y, img_w, img_h, 0, 0, 0, 0) -- use default values
end
end
function cnv:multitouch_cb(count, pid, px, py, pstatus)
if (count == 1) then
if (pstatus[1] == string.byte('D')) then -- DOWN
old_x = px[1]
old_y = canvas:UpdateYAxis(py[1])
translate = 1
elseif (pstatus[1] == string.byte('U')) then -- UP
if (translate == 1) then
translate = 0
end
elseif (pstatus[1] == string.byte('M')) then -- MOVE
if (translate == 1) then
-- translate only
local y = canvas:UpdateYAxis(py[1])
local x = px[1]
img_x = img_x + (x - old_x)
img_y = img_y + (y - old_y)
old_x = x
old_y = y
iup.Update(cnv)
end
end
elseif (count == 2) then
if (pstatus[1] == string.byte('D') or pstatus[2] == string.byte('D')) then -- DOWN
diff_x = math.abs(px[2]-px[1])
diff_y = math.abs(py[2]-py[1])
ref_x = img_x+img_w/2 -- center of the image as reference
ref_y = img_y+img_h/2
old_angle = math.atan2(py[2]-py[1], px[2]-px[1])
zoom = 1
elseif (pstatus[1] == string.byte('U') or pstatus[2] == string.byte('U')) then -- UP
if (zoom == 1) then
zoom = 0
end
elseif (pstatus[1] == string.byte('M') or pstatus[2] == string.byte('M')) then -- MOVE
if (zoom == 1) then
-- zoom
local new_diff_x = math.abs(px[2]-px[1])
local new_diff_y = math.abs(py[2]-py[1])
local angle = math.atan2(py[2]-py[1], px[2]-px[1])
local abs_diff_x = new_diff_x-diff_x
local abs_diff_y = new_diff_y-diff_y
local diff = 0
if (math.abs(abs_diff_y) > math.abs(abs_diff_x)) then
diff = abs_diff_y
else
diff = abs_diff_x
end
local prev_w = img_w
local prev_h = img_h
img_w = img_w + diff
img_h = img_h + diff
local str = string.format("%g %d %d", -(angle-old_angle)*cd.RAD2DEG, ref_x, ref_y)
print("ROTATE=", str)
canvas:SetAttribute("ROTATE", str)
-- translate to maintain fixed the reference point
local orig_x = ref_x - img_x
local orig_y = ref_y - img_y
orig_x = (img_w/prev_w)*orig_x
orig_y = (img_h/prev_h)*orig_y
img_x = ref_x - orig_x
img_y = ref_y - orig_y
diff_x = new_diff_x
diff_y = new_diff_y
iup.Update(cnv)
end
end
end
end
function cnv:button_cb(button,pressed,x,y,status)
-- start drag if button1 is pressed
if button ==iup.BUTTON1 and pressed == 1 then
y = canvas:UpdateYAxis(y)
old_x = x
old_y = y
start_x = x
start_y = y
drag = 1
else
if (drag == 1) then
drag = 0
end
end
end
function cnv:motion_cb(x,y,status)
if (drag == 1) then
y = canvas:UpdateYAxis(y)
if (iup.iscontrol(status)) then
-- zoom
local diff_x = (x - old_x)
local diff_y = (y - old_y)
local diff = 0
if (math.abs(diff_y) > math.abs(diff_x)) then
diff = diff_y
else
diff = diff_x
end
local prev_w = img_w
local prev_h = img_h
img_w = img_w + diff
img_h = img_h + diff
-- translate to maintain fixed the reference point
local orig_x = start_x - img_x
local orig_y = start_y - img_y
orig_x = (img_w/prev_w)*orig_x
orig_y = (img_h/prev_h)*orig_y
img_x = start_x - orig_x
img_y = start_y - orig_y
else
-- translate only
img_x = img_x + (x - old_x)
img_y = img_y + (y - old_y)
end
old_x = x
old_y = y
iup.Update(cnv)
end
end
function cnv:k_any(c)
if c == iup.K_q or c == iup.K_ESC then
return iup.CLOSE
end
if c == iup.K_F1 then
if fullscreen then
fullscreen = false
dlg.fullscreen = "No"
else
fullscreen = true
dlg.fullscreen = "Yes"
end
end
if c == iup.K_F2 then
filename = iup.GetFile("*.*")
if (filename) then
load_image(filename)
end
end
end
dlg = iup.dialog{cnv}
function dlg:close_cb()
if (image) then
image:Destroy()
end
canvas:Kill()
self:destroy()
return iup.IGNORE -- because we destroy the dialog
end
if (tuio) then
tuio.connect = "YES"
tuio.targetcanvas = cnv
end
dlg:show()
cnv.rastersize = nil -- remove minimum size
if arg and arg[1] ~= nil then
filename = arg[1]
else
filename = iup.GetFile("*.*")
end
if (filename) then
load_image(filename)
end
if (iup.MainLoopLevel()==0) then
iup.MainLoop()
end