summaryrefslogtreecommitdiff
path: root/html/examples/show_image_touch.wlua
blob: b919eafc3222b29042fbfcc6b47cad84a18a6ef6 (plain)
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