| mikshaw  
 
  
 
 
 Group: Members
 Posts: 4856
 Joined: July 2004
 | 
|  | Posted: Nov. 03 2007,23:28 |  |  You can probably consider this a beta. I'm going to try to work out some kinks, but basically I think it does what you're hoping.
 
 I started to work out a way to check if a file is truly an xpm file in the same loop that checks for spaces, but I haven't gotten far with that yet. As it stands at this time, a non-xpm file with an xpm filename extension will crash the program.
 
 I tested it out on a directory of over 600 images, and like the original script it chokes on such a large number of files. I'm guessing it's a limitation of FLTK.
 
 
 | Code Sample |  | #!/bin/murgaLua 
 -- XPM icon viewer
 -- mikshaw 2007
 -- thanks to ^thehatsrule^ for help and suggestions
 
 dir="/usr/share/dfm/icons"
 editor="xpaint"
 xpm_size=32
 
 broken_xpm_data=[[
 /* XPM */
 static char *broken_image[] = {
 /* columns rows colors chars-per-pixel */
 "16 16 4 1",
 "  c red",
 ". c #C4BF91",
 "X c #FFF8D6",
 "o c None",
 /* pixels */
 "ooo..........ooo",
 "ooo. XXXXX X.ooo",
 "ooo.  XXX  X.ooo",
 "ooo.X  X  XX.ooo",
 "ooo.XX   XXX.ooo",
 "ooo.X  X  XX.ooo",
 "ooo.  XXX  Xoooo",
 "ooo. XXXXo ooooo",
 "ooo.XXXXoooooooo",
 "ooo.XoXooooooooo",
 "ooo.oooooooo.ooo",
 "oooooooooXoX.ooo",
 "ooooooooXXXX.ooo",
 "oooooXoXXXXX.ooo",
 "ooooXXXXXXXX.ooo",
 "ooo..........ooo"
 };
 ]]
 xpm_tempfile=os.tmpname()
 xpm_write=io.open(xpm_tempfile,"w")
 if xpm_write then
 xpm_write:write(broken_xpm_data)
 xpm_write:close()
 broken_xpm=fltk:Fl_XPM_Image(xpm_tempfile)
 os.remove(xpm_tempfile)
 end
 
 edvar=os.getenv("XPM_EDITOR")
 if edvar then editor=edvar end
 
 function get_image_data(self)
 local old_data=display:image()
 if old_data then old_data:uncache() end
 local image_data=self:image()
 if image_data then
 display:image(image_data:copy(128,128)) --show it bigger!
 broken=nil
 i_menu:mode(3,1) -- disable "fix" item
 else
 display:image(broken_xpm)
 broken=self:tooltip()
 i_menu:mode(3,0)
 end
 current_file=dir..self:tooltip() -- for editor
 display:label("\n"..self:tooltip().."\n"..lfs.attributes(current_file).size.." bytes")
 display:redraw()
 end
 
 function menu_cb()
 local v=i_menu:value()
 if v==0 and current_file then os.execute(editor.." "..current_file.." &")
 elseif v==1 then chdir()
 elseif v==2 then refresh()
 elseif v==3 then fix_xpm()
 elseif v==4 then os.exit(0)
 end
 end
 
 function find_stupid_space(infile)
 local data=io.open(infile)
 if data then
 local is_xpm,found=0,0
 for line in data:lines() do
 --if string.find(line,"^%s") then is_xpm=1 end
 if string.find(line,"^%s") then found=1; break end
 end
 data:close()
 --if is_xpm~=1 or found==1 then return found end
 return found
 end
 end
 
 function build_list(dfile)
 print(dfile)
 local active=1
 if not string.find(dir,"/$") then dir=dir.."/" end
 scroll=fltk:Fl_Scroll(5,bh,sw,sh)
 w:add(scroll)
 pack=fltk:Fl_Pack(5,bh,bw,sh)
 pack:spacing(2)
 scroll:add(pack)
 -- get all xpm files
 for file in lfs.dir(dir) do
 if string.find(string.lower(file),"%.xpm$") then
 table.insert(images,file)
 end
 end
 table.sort(images)
 -- make buttons for "xpm_size" images only
 xpm_count=0
 filesize=0
 for i=1,table.getn(images) do
 icon[i]=fltk:Fl_XPM_Image(dir..images[i])
 if icon[i]:w()==xpm_size and icon[i]:h()==xpm_size then
 xpm_count=1+xpm_count
 filesize=filesize+lfs.attributes(dir..images[i]).size
 butt[xpm_count]=fltk:Fl_Button(0,0,bw,bw)
 butt[xpm_count]:box(15) --shadow
 if find_stupid_space(dir..images[i])==0 then
 butt[xpm_count]:image(icon[i])
 else butt[xpm_count]:label("bad\nimage")
 end
 butt[xpm_count]:callback(get_image_data)
 butt[xpm_count]:tooltip(images[i])
 if broken==images[i] or dfile==images[i] then active=xpm_count end -- for refreshing display
 pack:add(butt[xpm_count])
 else icon[i]:uncache()
 end
 end
 if butt[active] then
 -- show first image
 display:show()
 butt[active]:do_callback()
 end
 display2:label(xpm_count.." files | "..math.ceil(filesize/1024).." kb")
 end
 
 function refresh()
 local old_image=display:image()
 if old_image then old_image:uncache(); display:hide() end
 -- clear all tables and remove buttons
 for i=1,table.getn(images) do table.remove(images) end
 for i=1,table.getn(icon) do icon[i]:uncache() end
 for i=1,table.getn(icon) do table.remove(icon) end
 for i=1,table.getn(butt) do table.remove(butt) end
 w:remove(scroll)
 Fl:delete_widget(scroll)
 scroll=nil
 build_list()
 end
 
 function chdir()
 local dirname=fltk.fl_dir_chooser("pick a dir...",dir)
 if dirname then
 dir=dirname
 refresh()
 end
 end
 
 function fix_xpm()
 if broken then
 os.execute("cd "..dir.." && sxpm -nod "..broken.." -o "..broken)
 refresh()
 end
 end
 
 function open_file(what)
 if lfs.attributes(what).mode=="directory" then
 dir=what
 else
 dragfile=fltk.fl_filename_name(what)
 print(dragfile)
 dir=string.gsub(what,"(.*/).*$","%1")
 end
 build_list(dragfile)
 end
 
 -- candy
 Fl:set_boxtype(fltk.FL_UP_BOX,fltk.FL_THIN_UP_BOX)
 Fl:set_boxtype(fltk.FL_DOWN_BOX,fltk.FL_THIN_DOWN_BOX)
 fltk.fl_define_FL_SHADOW_BOX()
 Fl:set_color(fltk.FL_DARK3,150,150,150) -- shadow
 Fl:set_color(fltk.FL_GRAY0,128,128,128) -- frame
 --Fl_Tooltip:disable()
 
 -- some sizes and positions are determined by xpm_size
 bw=xpm_size+20 -- button width
 bh=30; sw=bw+20; sh=250 -- menu, scroll size
 ww=sw+sh+10
 wh=bh+sh+10
 images={}; icon={}; butt={}
 w=fltk:Fl_Window(ww,wh,"XPM Icons")
 
 menu_items={"&Edit","&Directory","&Refresh","&Fix","&Quit"}
 i_menu=fltk:Fl_Menu_Button(0,0,sw+5,bh,"&Menu")
 i_menu:align(20)
 i_menu:callback(menu_cb)
 i_menu:selection_color(fltk.FL_WHITE)
 for i,v in ipairs(menu_items) do i_menu:add(v) end
 
 display=fltk:Fl_Box(sw+5,0,sh,sh) -- big image
 display2=fltk:Fl_Box(sw+5,sh,sh,bh) -- dir info
 
 if arg[1] then open_file(arg[1]) else build_list() end -- drag and drop
 w:show()
 Fl:run()
 
 | 
 
 --------------
 http://www.tldp.org/LDP/intro-linux/html/index.html
 |