1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
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
|