187 lines
4.7 KiB
Lua
187 lines
4.7 KiB
Lua
-- Based on a code from Stuart P. Bentley
|
|
|
|
require"imlua"
|
|
require"cdlua"
|
|
require"cdluaim"
|
|
require"iuplua"
|
|
require"iupluacd"
|
|
require"iupluaimglib"
|
|
|
|
anim={}
|
|
|
|
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
|
|
|
|
anim.images={}
|
|
anim.delays={}
|
|
anim.disposal={}
|
|
anim.pos={}
|
|
anim.frame=1
|
|
|
|
local ScreenWidth = 0
|
|
local ScreenHeight = 0
|
|
|
|
for i=1, select(3,ifile:GetInfo()) do
|
|
|
|
anim.images[i]=ifile:LoadBitmap(i-1)
|
|
err, anim.images[i] = im.ConvertColorSpaceNew(anim.images[i], im.RGB, true)
|
|
|
|
local delay=anim.images[i]:GetAttribute("Delay") -- time to wait betweed frames in 1/100 of a second]
|
|
if delay then
|
|
anim.delays[i]=delay[1]*10 -- timer in miliseconds
|
|
else
|
|
if (i == 1) then
|
|
anim.delays[i]=100
|
|
else
|
|
anim.delays[i]=anim.delays[i-1]
|
|
end
|
|
end
|
|
|
|
anim.disposal[i]=anim.images[i]:GetAttribute("Disposal", true) -- [UNDEF, LEAVE, RBACK, RPREV]
|
|
|
|
local w = anim.images[i]:Width()
|
|
local h = anim.images[i]:Height()
|
|
if (w > ScreenWidth) then ScreenWidth = w end
|
|
if (h > ScreenHeight) then ScreenHeight = h end
|
|
w = anim.images[i]:GetAttribute("ScreenWidth")
|
|
h = anim.images[i]:GetAttribute("ScreenHeight")
|
|
if (w and w[1] > ScreenWidth) then ScreenWidth = w[1] end
|
|
if (h and h[1] > ScreenHeight) then ScreenHeight = h[1] end
|
|
|
|
local X = anim.images[i]:GetAttribute("XScreen")
|
|
local Y = anim.images[i]:GetAttribute("YScreen")
|
|
anim.pos[i] = {x=0, y=0}
|
|
if (X) then anim.pos[i].x = X[1] end
|
|
if (Y) then anim.pos[i].y = Y[1] end
|
|
end
|
|
|
|
ifile:Close()
|
|
|
|
anim.ScreenHeight = ScreenHeight
|
|
anim.ScreenWidth = ScreenWidth
|
|
|
|
cnv.rastersize = ScreenWidth.."x"..ScreenHeight
|
|
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 = anim.delays[anim.frame]
|
|
t.run = "YES"
|
|
iup.Update(cnv)
|
|
end
|
|
|
|
function stop_timer()
|
|
dlg.title = "Animated Gif "..anim.frame.."/"..#anim
|
|
dlg.play_bt.image="IUP_MediaPlay" dlg.play_bt.title="Play"
|
|
t.run="NO"
|
|
iup.Update(cnv)
|
|
end
|
|
|
|
function set_frame(f)
|
|
anim.frame = f
|
|
if anim.frame > #anim.images then
|
|
anim.frame = #anim.images
|
|
end
|
|
if anim.frame < 1 then
|
|
anim.frame = 1
|
|
end
|
|
stop_timer()
|
|
end
|
|
|
|
function t:action_cb()
|
|
anim.frame = anim.frame + 1
|
|
if anim.frame == #anim.images+1 then
|
|
anim.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 (anim.disposal[anim.frame] == "RBACK") then
|
|
canvas:Clear()
|
|
end
|
|
local x = anim.pos[anim.frame].x
|
|
local y = anim.ScreenHeight - anim.pos[anim.frame].y - anim.images[anim.frame]:Height()
|
|
anim.images[anim.frame]:cdCanvasPutImageRect(canvas, x, y, 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(anim.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(anim.frame+1) end},
|
|
iup.button{title="Last", image="IUP_MediaGoToEnd", action=function(self) set_frame(#anim) 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)
|
|
anim=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()
|