summaryrefslogtreecommitdiff
path: root/html/examples/animate_gif.wlua
blob: 4334f37c76af140a0a439e4e1eb82035219512f9 (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
-- Based on a code from Stuart P. Bentley

require"imlua"
require"cdlua"
require"cdluaim"
require"iuplua"
require"iupluacd"
require"iupluaimglib"

images={}
frame=1

function print_error(err)
  local msg = {}
  msg[im.ERR_OPEN] = "Error Opening File."
  msg[im.ERR_MEM] = "Insuficient memory."
  msg[im.ERR_ACCESS] = "Error Accessing File."
  msg[im.ERR_DATA] = "Image type not Suported."
  msg[im.ERR_FORMAT] = "Invalid Format."
  msg[im.ERR_COMPRESS] = "Invalid or unsupported compression."
  
  if msg[err] then
    print(msg[err])
  else
    print("Unknown Error.")
  end
end

function load_frames(file_name)

  ifile, err=im.FileOpen(file_name)
  if not ifile then
      print_error(err)
      return
  end

  images={}
  images.delays={}
  images.disposal={}
  frame=1

  for i=1, select(3,ifile:GetInfo()) do
    images[i]=ifile:LoadBitmap(i-1)
    err, images[i] = im.ConvertColorSpaceNew(images[i], im.RGB, true)
    local delay=images[i]:GetAttribute("Delay") -- time to wait betweed frames in 1/100 of a second]
    if delay then
      images.delays[i]=delay[1]*10 -- timer in miliseconds
    else
      if (i == 1) then 
        images.delays[i]=100 
      else
        images.delays[i]=images.delays[i-1]
      end
    end
    images.disposal[i]=images[i]:GetAttribute("Disposal", true) --  [UNDEF, LEAVE, RBACK, RPREV]
  end

  ifile:Close()
  
  cnv.rastersize = images[1]:Width().."x"..images[1]:Height()
  dlg.size=nil
  iup.Refresh(cnv)
end

t = iup.timer{}

function start_timer()
  dlg.title = "Animated Gif"
  dlg.play_bt.image="IUP_MediaPause" dlg.play_bt.title="Pause"
  t.run = "NO"
  t.time = images.delays[frame]
  t.run = "YES"
  iup.Update(cnv)
end

function stop_timer()
  dlg.title = "Animated Gif "..frame.."/"..#images
  dlg.play_bt.image="IUP_MediaPlay" dlg.play_bt.title="Play" 
  t.run="NO"
  iup.Update(cnv)
end

function set_frame(f)
  frame = f
  if frame > #images then
    frame = #images
  end
  if frame < 1 then
    frame = 1
  end
  stop_timer()
end

function t:action_cb()
  frame = frame + 1
  if frame == #images+1 then
    frame = 1
  end
  
  start_timer()
end
    
cnv = iup.canvas{border = "NO"}

function cnv:map_cb()-- the CD canvas can only be created when the IUP canvas is mapped
  canvas = cd.CreateCanvas(cd.IUP, self)
  canvas:Activate()
  
  start_timer()
end

function cnv:action()-- called everytime the IUP canvas needs to be repainted
  canvas:Activate()
  if (images.disposal[frame] == "RBACK") then
    canvas:Clear()
  end
  images[frame]:cdCanvasPutImageRect(canvas, 0, 0, 0, 0, 0, 0, 0, 0) -- use default values
end

function cnv:resize_cb()
  canvas:Activate()
  canvas:Clear()
end

function cnv:button_cb(but, pressed)
  if (but == iup.BUTTON1 and pressed==1) then
    local file_name, error = iup.GetFile("*.*")
    if error ~= 0 then
      return
    end
    
    load_frames(file_name)  
    canvas:Activate()
    canvas:Clear()
    start_timer()
  end
end

buts = iup.hbox{
  iup.button{title="First", image="IUP_MediaGotoBegin", action=function(self) set_frame(1) end}, 
  iup.button{title="Previous", image="IUP_MediaRewind", action=function(self) set_frame(frame-1) end}, 
  iup.button{title="Pause", image="IUP_MediaPause", action=function(self) if (t.run=="YES") then stop_timer() else start_timer() end end}, 
  iup.button{title="Next", image="IUP_MediaForward", action=function(self) set_frame(frame+1) end}, 
  iup.button{title="Last", image="IUP_MediaGoToEnd", action=function(self) set_frame(#images) end}, 
  }
dlg = iup.dialog{iup.vbox{cnv, buts},title="Animated Gif", margin="5x5", gap=10}
dlg.play_bt = dlg[1][2][3]

function dlg:close_cb()
  iup.Destroy(t)
  images=nil --Destroys will be called by the garbage collector
  canvas:Kill()
  self:destroy()
  return iup.IGNORE -- because we destroy the dialog
end

load_frames(iup.GetFile("*.*"))

dlg:show()
iup.MainLoop()