News : The level of daily SPAM has reached insane proportions, all registrations are now admin activated. I also ask you to send me an e-mail (john (at) murga (dot) org), to confirm that you want me to activate your account and that you are not a bot or a spammer.


Post Reply  Post Thread 
(very) basic slideshow
Author Message
mikshaw
Senior Member
****


Posts: 521
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #1
(very) basic slideshow

This is an extension of the animation test from earlier today, with inspiration from John's work with drawing objects.

I'm really looking forward to murgaLua 0.5, because this socket.sleep() function is giving me a headache =o)

Problems:
The timer affects the length of time it takes to close the application (click anywhere to close), or to display it at all if you happen to focus a different desktop and come back to it.
It's always fullscreen for now, and large images do not scale down. It's just a test right now, so there are no features other than displaying images.
Since there is no filename filtering, some images will stay onscreen longer than others if you have anything but images in the directory. I have a plan to fix this, but have not implemented it yet.

I couldn't figure out a clean, simple way to prevent socket.sleep() from causing a 15-second pause before first displaying the window, so I set up an initial 0-second pause which gets reset after the first image is displayed.

HINT: Skip to the end of the thread for the most recent version of the script.

Code:
dir=os.getenv("HOME").."/image/"
timer=15 --seconds

fltk.fl_register_images()
images = murgaLua.readDirectory(dir)
table.sort(images)
Fl:visible_focus(0)
imgnum=1
pause=0

function exit() print("goodbye"); os.exit(0) end

function next_image()
socket.sleep(pause)
if imgnum == table.getn(images) then imgnum=2 else imgnum = imgnum+1 end
display:image(Fl_Shared_Image.get(dir..images[imgnum]))
display:redraw()
pause=timer
end

ww=Fl:w();wh=Fl:h()
w=fltk:Fl_Double_Window(ww,wh,"MurgaLua Slideshow")
w:color(fltk.FL_BLACK)
w:fullscreen()
display=fltk:Fl_Button(0,0,ww,wh)
display:box(1);display:color(fltk.FL_BLACK);display:selection_color(fltk.FL_BLACK)
display:callback(exit)
w:callback(next_image)

w:show()
while 1 do
Fl:check()
w:do_callback()
end
Fl:run()

This post was last modified: 07-17-2007 03:35 AM by mikshaw.

06-24-2007 08:55 AM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 521
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #2
RE: (very) basic slideshow

ahhh...
I added "if Fl:event(fltk.FL_PUSH) then break end" to the while loop, and it closes immediately (usually). There seems to be some issue with pressing Esc and then clicking, but it usually works.

EDIT: I was mistaken. It did seem to break the loop when I pressed a mouse button, but I didn't notice that it was actually already broken as soon as the loop started. If I'd waited 15 seconds before pressing, I'd have noticed that =op
Back to the docs...

This post was last modified: 06-24-2007 03:17 PM by mikshaw.

06-24-2007 12:53 PM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 521
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #3
RE: (very) basic slideshow

Messed around with it some more. I still haven't gotten a good delay going on; in fact the current one seems to be more annoying than the previous, but I'm taking a break from it for a while.

It's now an image viewer with a slideshow feature. Slideshow is enabled with the -d option, or by setting ss=1. A directory can be specified with -d <directory>, or by setting the dir variable. Fullscreen can be toggled with the f key, or set to default by setting fs=1.

In non-slideshow mode, left mouse or page down moves to the next image, right mouse or page up moves backward. Up and Down arrows toggle a "resize image to screen size" feature, which currently stretches the image if it doesn't have the same aspect ratio as your screen.

There are a pile of commented lines that I haven't yet removed...they are my tests while trying to improve the script.

I have no idea if this will work as-is in Windows or Mac, and it can get kinda resource-hungry...it needs to be seriously tweaked.

Code:
dir=os.getenv("HOME").."/image/"
--dir="/home/dsl/image/"
timer=5 --seconds
ss=0 -- screensaver 1=on 0=off
fs=0 -- fullscreen

-- Check for commandline arguments
for i=1,table.getn(arg) do
if arg[i] == "-s" then ss=1 end --activate slideshow
if arg[i] == "-f" then fs=1 end --force fullscreen
if arg[i] == "-d" and murgaLua.isDirectory(arg[i+1]) then dir=arg[i+1] end --specify a directory
end

fltk.fl_register_images()
images = murgaLua.readDirectory(dir)
table.sort(images)
Fl:visible_focus(0)
ww=Fl:w();wh=Fl:h()
imgnum=1
pause=0
fwd=1

function exit() print("goodbye"); os.exit(0) end

function toggle_fullscreen()
if fs==1 then
w:fullscreen_off(ww/2-active_image:w()/2,wh/2-active_image:h()/2,active_image:w(),active_image:h())
fs=0
else w:fullscreen(); fs=1
end
button:size(w:w(),w:h())
display:size(w:w(),w:h())
end

function zoomin()
zoom_image=active_image:copy(ww,wh)
display:image(zoom_image)
w:resize(0,0,ww,wh)
display:size(ww,wh)
display:redraw()
end
function zoomout()
display:image(active_image)
if fs==0 then fs=1; toggle_fullscreen() end
display:redraw()
end

function wait() -- this needs serious work
        fin=os.time()
        socket.sleep(1)
        if Fl:event() == fltk.FL_PUSH then exit() end
        Fl:check()
        if os.difftime (fin, start) < pause then wait() end
end

function next_image()
if fwd == 0 then
if imgnum <= 1 then imgnum=table.getn(images) else imgnum = imgnum-1 end
else
if imgnum >= table.getn(images) then imgnum=1 else imgnum = imgnum+1 end
end
--if active_image then active_image:uncache() end
active_image=Fl_Shared_Image.get(dir.."/"..images[imgnum])
if active_image then
if fs==0 then fs=1; toggle_fullscreen() end
display:image(active_image)
--if ss==1 then socket.sleep(pause) end
else next_image()
end
display:redraw()
button:take_focus()
pause=timer
end

function button_cb()
if Fl:event_button() == fltk.FL_RIGHT_MOUSE or Fl:event_key() == fltk.FL_Page_Up then fwd=0 else fwd=1 end
if Fl:event_button() == fltk.FL_MIDDLE_MOUSE then
toggle_fullscreen()
else    next_image()
--else w:redraw()
end
end

w=fltk:Fl_Double_Window(ww,wh,"MurgaLua Slideshow")
buttons={}
for i=1,4 do
        buttons[i]=fltk:Fl_Button(0,0,0,0)
--      buttons[i]:callback(button_cb)
end
button=fltk:Fl_Button(0,0,ww,wh)
button:box(1);button:color(fltk.FL_BLACK);button:selection_color(fltk.FL_BLACK)
display=fltk:Fl_Box(0,0,ww,wh)
--w:resizable(display)
display:box(1);display:color(fltk.FL_BLACK)
if ss==1 then
button:callback(exit)
w:callback(next_image)
else button:callback(button_cb); buttons[1]:callback(button_cb)
--button:when(fltk.FL_WHEN_NOT_CHANGED)
button:shortcut(fltk.FL_Page_Down)
buttons[1]:shortcut(fltk.FL_Page_Up)
buttons[2]:shortcut(fltk.FL_Up); buttons[2]:callback(zoomin)
buttons[3]:shortcut(fltk.FL_Down); buttons[3]:callback(zoomout)
buttons[4]:label("&fullscreen"); buttons[4]:callback(toggle_fullscreen)
--buttons[4]:shortcut(fltk.FL_Tab)
end

w:show()
--w:fullscreen()

if ss==1 then
-- run slideshow
while 1 do
--Fl:check()
w:do_callback()
start=os.time(); wait()
end
else
next_image()
end
Fl:run()

06-25-2007 05:02 AM
Find all posts by this user Quote this message in a reply
iGame3D
Moderator
***


Posts: 231
Group: Moderators
Joined: Apr 2007
Status: Offline
Reputation: 0
Post: #4
RE: (very) basic slideshow

Thats pretty neat, a bit slow in action but cool.
I haven't looked at the script for the timing, but basically how are you doing the timing?

I spent a bunch of time messing with your fish animation last night, I'll have to see if it still works and post it. But I changed the timing from a button to automatic.

I don't use Fl:wait() with a value greater than 0 and I don't use socket:wait() etc.
What I do is increment a value using a float for instance

time=time+.02 then
frame=image[math.floor(time)] -- only an integer is provided by math.floor

this way each frame is held until time actually reaches the next integer,
which varies according to the value I increment time.
There is a way to get that value according to some return of time between cpu cycles, which is generally some value like .004 or so , and doing so keeps the motion smooth and consistant across machines.

Ok going to test that other script and post it to the right thread.

06-25-2007 08:13 AM
Visit this user's website Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 521
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #5
RE: (very) basic slideshow

The timing is a half-baked hack, which still needs work or replacement
Originally it used socket.sleep() only, but every event, including exit, had to wait the length of the sleep time before performing.

I suck at math, so most of the stuff I do is based on a more abstract, maybe visual, approach.
The math.* functions are jibberish to me.

Currently it uses os.difftime within a function to see if the pause duration has passed. If not, it simply repeats the function. The initial test was a miserable failure (crash), so i stuck in a 1-second sleep for each run of the function. This way, no matter what the pause time is, events have only to wait that one second.

This is a pretty crappy method, though. As soon as I did it I noticed a huge performance hit and some odd behavior, but it did reach my temporary goal of getting (mostly) rid of the delay in events. It will likely be totally rewritten the next time i play with it.

06-25-2007 11:17 AM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 521
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #6
RE: (very) basic slideshow

Update using the new murgaLua.createFltkTimer() in murgaLua 0.5. It's much nicer now =o)
Also added a file list, but it hasn't been thoroughly tested.

Code:
#!/usr/bin/murgaLua
-- simple image viewer
-- mikshaw 2007
-- inspired by the work of john murga
-- requires murgaLua version 0.5 or greater

--dir=os.getenv("HOME").."/image/"
dir="./"
pause=5 --seconds
ss=0 -- screensaver 1=on 0=off
fs=0 -- fullscreen

-- Check for commandline arguments
for i=1,table.getn(arg) do
if arg[i] == "-s" then ss=1 end --activate slideshow
if arg[i] == "-f" then fs=1 end --force fullscreen ("f" to toggle)
if arg[i] == "-l" then ls=1 end --show file list {"l" to toggle)
if arg[i] == "-d" and murgaLua.isDirectory(arg[i+1]) then dir=arg[i+1] end --specify a directory
end

fltk.fl_register_images()
allfiles = murgaLua.readDirectory(dir)
table.sort(allfiles)
images = {}
for i=1,table.getn(allfiles) do
if string.find(allfiles[i],"%.jpg$") or string.find(allfiles[i],"%.png$") or string.find(allfiles[i],"%.gif$") then table.insert(images,allfiles[i]) end
end
Fl:visible_focus(0)
ww=Fl:w();wh=Fl:h()
imgnum=0
fwd=1

timer=murgaLua.createFltkTimer()

function exit() print("goodbye"); os.exit(0) end

function toggle_fullscreen()
if fs==1 then
w:fullscreen_off(ww/2-active_image:w()/2,wh/2-active_image:h()/2,active_image:w(),active_image:h())
fs=0
else w:fullscreen(); fs=1
end
button:size(w:w(),w:h())
display:size(w:w(),w:h())
end

function zoomin()
zoom_image=active_image:copy(ww,wh)
display:image(zoom_image)
w:resize(0,0,ww,wh)
display:size(ww,wh)
display:redraw()
end
function zoomout()
display:image(active_image)
if fs==0 then fs=1; toggle_fullscreen() end
display:redraw()
end

function toggle_list()
if ls==1 then ls=0; fw:hide() else ls=1; fw:show() end
end

function show_image()
active_image=Fl_Shared_Image.get(dir.."/"..images[imgnum])
if active_image then
if fs==0 then fs=1; toggle_fullscreen() end --reusing toggle_fullscreen to resize window to image size
display:image(active_image)
else next_image()
end
list:value(imgnum)
display:redraw()
end

function next_image()
if fwd == 0 then
if imgnum <= 1 then imgnum=table.getn(images) else imgnum = imgnum-1 end
else
if imgnum >= table.getn(images) then imgnum=1 else imgnum = imgnum+1 end
end
show_image()
if ss==1 then timer:doWait(pause) end
button:take_focus()
end

function button_cb()
if Fl:event_button() == fltk.FL_RIGHT_MOUSE or Fl:event_key() == fltk.FL_Page_Up then fwd=0 else fwd=1 end
if Fl:event_button() == fltk.FL_MIDDLE_MOUSE then
toggle_fullscreen()
else    next_image()
end
end

w=fltk:Fl_Double_Window(ww,wh,"MurgaLua Image Viewer")
buttons={}
for i=1,5 do buttons[i]=fltk:Fl_Button(0,0,0,0) end
button=fltk:Fl_Button(0,0,ww,wh)
button:box(1);button:color(fltk.FL_BLACK);button:selection_color(fltk.FL_BLACK)
display=fltk:Fl_Box(0,0,ww,wh)
--w:resizable(display)
display:box(1);display:color(fltk.FL_BLACK)
if ss==1 then
button:callback(exit)
timer:callback(next_image)
else button:callback(button_cb); buttons[1]:callback(button_cb)
button:shortcut(fltk.FL_Page_Down)
buttons[1]:shortcut(fltk.FL_Page_Up)
buttons[2]:shortcut(fltk.FL_Up); buttons[2]:callback(zoomin)
buttons[3]:shortcut(fltk.FL_Down); buttons[3]:callback(zoomout)
buttons[4]:label("&fullscreen"); buttons[4]:callback(toggle_fullscreen)
buttons[5]:label("&list"); buttons[5]:callback(toggle_list)
end
fltk.Fl_End()


fw=fltk:Fl_Window(0,0,ww/3,wh/2)
list=fltk:Fl_Hold_Browser(2,2,ww/3-4,wh/2-4) -- file list
fltk.Fl_End()
function choose_image()
imgnum=list:value()
show_image()
end
list:callback(choose_image)
for i=1,table.getn(images) do list:add(images[i]) end

w:show()
if ls==1 then fw:show() end
next_image()

Fl:run()

07-03-2007 04:57 AM
Find all posts by this user Quote this message in a reply
iGame3D
Moderator
***


Posts: 231
Group: Moderators
Joined: Apr 2007
Status: Offline
Reputation: 0
Post: #7
RE: (very) basic slideshow

Lookin good.
I get a frame of black between images when I use mouse click to switch frames.

But great animation results when I play with the timing of the slideshow.

07-03-2007 09:28 AM
Visit this user's website Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 521
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #8
RE: (very) basic slideshow

I'm not sure right now what that black would be, but it will be in development for a while so I'll definitely look into it. I'm hoping eventually to replace my use of gqview with this, at least for the typical jpg/gif/png files that comprise 90% of my image collection, since it won't require the bulky Gtk2 tool set. When it gets to a stable point I'll probably also push it as a tiny alternative to other image viewers for people who want to set up a digital picture frame with Puppy, DSL, etc.

Thanks for your feedback. Anything else you or anyone else has to say, positive or negative or just suggestions, would be welcome.

I really hope murgaLua gets the attention it deserves from other developers. The typical graphical toolkits used today are, in my opinion, rapidly becoming morbidly obese. At this time there are very few that I know of in active development that are worthy of the description "light and fast"...FLTK, Tk, and MurgaLua. With the increased power of faster processors and more ram in today's personal computers, I believe many developers waste these improvements by cramming more (unnecessary) graphically demanding widgets into their programs using the latest Qt and Gtk behemoths. The processing improvements could be better served using interpreted languages such as Tcl, Lua, and Ruby, which are much easier to customize, debug and improve since they remain plain text.

EDIT: The black frame is caused by the button coming to the top when clicked. I don't remember why I decided to separate the button and the actual image into two widgets, but this should be fixed next time i work on the script.

This post was last modified: 07-04-2007 12:24 AM by mikshaw.

07-03-2007 12:56 PM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 521
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #9
RE: (very) basic slideshow

I removed the "button" widget and made "display" a button instead of a box, so the blackout no longer occurs. I have no idea why I decided to separate the display from the button in the first place, but it's now been repaired.
I've also added a few other image formats (I have no idea how many image types FLTK natively supports), and support for changing the background color from the commandline. When I finish with my current "what hapens if I do this" session I'll post the update.

07-06-2007 06:29 AM
Find all posts by this user Quote this message in a reply
mikshaw
Senior Member
****


Posts: 521
Group: Registered
Joined: Apr 2007
Status: Offline
Reputation: 5
Post: #10
RE: (very) basic slideshow

current state is still not ideal, but it handles one or two of the issues the previous it had.
I would still love to be able to test for various filename extensions using regualr expressions rather than a series of "string.find" functions, but at least it works for now.

Code:
#!/usr/bin/murgaLua
-- simple image viewer
-- mikshaw 2007
-- inspired by the work of john murga
-- requires murgaLua version 0.5 or greater

dir="./" -- default image directory
pause=5 -- seconds between slideshow images
ss=0 -- slideshow 1=on 0=off
fs=0 -- fullscreen
bg=0 -- background color

-- Check for commandline arguments
for i=1,table.getn(arg) do
if arg[i] == "-s" then ss=1 end --activate slideshow
if arg[i] == "-f" then fs=1 end --force fullscreen ("f" to toggle)
if arg[i] == "-l" then ls=1 end --show file list {"l" to toggle)
if arg[i] == "-d" and murgaLua.isDirectory(arg[i+1]) then dir=arg[i+1] end --specify a directory
if arg[i] == "-bg" then bg=arg[i+1] end --specify a background color
end

fltk.fl_register_images()
allfiles = murgaLua.readDirectory(dir)
table.sort(allfiles)
images = {}
-- use only image files
for i=1,table.getn(allfiles) do
-- hoping there's a simpler way to do this
tempstring=string.lower(allfiles[i])
if string.find(tempstring,"%.png$") or
string.find(tempstring,"%.jpe?g$") or
string.find(tempstring,"%.bmp$") or
string.find(tempstring,"%.p[bgnp]m$") or
string.find(tempstring,"%.x[bp]m$") or
string.find(tempstring,"%.gif$")
then table.insert(images,allfiles[i]) end
end
--os.exit()
Fl:visible_focus(0)
ww=Fl:w();wh=Fl:h()
imgnum=0
fwd=1

timer=murgaLua.createFltkTimer()
function exit()
--confirm=fltk.fl_choice("sure you want to quit?","no","yes",NULL)
--if confirm == 1 then
print("goodbye"); os.exit(0)
--end
end

function toggle_fullscreen()
if fs==1 then
w:fullscreen_off(ww/2-active_image:w()/2,wh/2-active_image:h()/2,active_image:w(),active_image:h())
fs=0
else w:fullscreen(); fs=1
end
display:size(w:w(),w:h())
end

function zoomin()
zoom_image=active_image:copy(ww,wh)
display:image(zoom_image)
w:resize(0,0,ww,wh)
display:size(ww,wh)
display:redraw()
end
function zoomout()
display:image(active_image)
if fs==0 then fs=1; toggle_fullscreen() end
display:redraw()
end

function toggle_list()
if ls==1 then ls=0; fw:hide() else ls=1; fw:show() end
end

function show_image()
active_image=Fl_Shared_Image.get(dir.."/"..images[imgnum])
if active_image then
if fs==0 then fs=1; toggle_fullscreen() end --reusing toggle_fullscreen to resize window to image size
display:image(active_image)
else next_image()
end
list:value(imgnum)
display:redraw()
end

function next_image()
if fwd == 0 then
if imgnum <= 1 then imgnum=table.getn(images) else imgnum = imgnum-1 end
else
if imgnum >= table.getn(images) then imgnum=1 else imgnum = imgnum+1 end
end
show_image()
if ss==1 then timer:doWait(pause) end
end

function button_cb()
if Fl:event_button() == fltk.FL_RIGHT_MOUSE or Fl:event_key() == fltk.FL_Page_Up then fwd=0 else fwd=1 end
if Fl:event_button() == fltk.FL_MIDDLE_MOUSE then
toggle_fullscreen()
else    next_image()
end
end


w=fltk:Fl_Double_Window(ww,wh,"MurgaLua Image Viewer")
buttons={}
for i=1,5 do buttons[i]=fltk:Fl_Button(0,0,0,0) end
display=fltk:Fl_Button(0,0,ww,wh)
display:box(1);display:color(bg)
if ss==1 then
display:callback(exit)
timer:callback(next_image)
else
display:shortcut(fltk.FL_Page_Down); display:callback(button_cb);
buttons[1]:shortcut(fltk.FL_Page_Up); buttons[1]:callback(button_cb)
buttons[2]:shortcut(fltk.FL_Up); buttons[2]:callback(zoomin)
buttons[3]:shortcut(fltk.FL_Down); buttons[3]:callback(zoomout)
buttons[4]:label("&fullscreen"); buttons[4]:callback(toggle_fullscreen)
buttons[5]:label("&list"); buttons[5]:callback(toggle_list)
end
fltk.Fl_End()


fw=fltk:Fl_Window(0,0,ww/4,wh/3)
list=fltk:Fl_Hold_Browser(2,2,ww/4-4,wh/3-4) -- file list
fltk.Fl_End()
function choose_image()
imgnum=list:value()
show_image()
end
list:callback(choose_image)
for i=1,table.getn(images) do list:add(images[i]) end

w:callback(exit)
w:show()
if ls==1 then fw:show() end
next_image()

Fl:run()

07-16-2007 12:06 PM
Find all posts by this user Quote this message in a reply
Post Reply  Post Thread 

View a Printable Version
Send this Thread to a Friend
Subscribe to this Thread | Add Thread to Favorites

Forum Jump: