Programming and Scripting :: XPM Icon Viewer



Quote
I wasn't talking about murgaLua drag-n-drop
Well, that's good, because cross-application drag and drop in murgaLua is apparently a pain in the butt. I am pleased that I was able to do something with it, though, so the beta of the murgaLua widgets demo app will probably have some basic DND included. Personally I'm not comfortable with the way it works for me at this time...it seems to be inconsistent, and seems to require a constant loop simply to check for FL_DND_RELEASE.

Quote
But dragging an .xpm onto the Lua logo icon of your apps works as expected.
That was the easy part alluded to in the previous post. It's just checking arg[1], as you said, and using that instead of a selected file. I could see it becoming more complicated if the application supported other parameters, but for what I do I've found that either manually editing the script or using environment variables is often a simpler approach.

I'll probably go with the previous script, adding the parameter parsing. With the help of lfs we can check for a directory or regular file and determine whether to display the first icon in the directory or a particular icon as a result.

Quote
Next you need to make or find a nifty icon for your app. We don't want to leave it a boring Lua logo.
I haven't even thought about that yet, since the window manager I use most often doesn't show icons in its bar.

Quote
Not sure how the Lua DND is supposed to work. It didn't for me.
Do you mean that this particular app didn't accept files dragged onto the interface, or that you haven't gotten app-to-app drag and drop working in a murgaLua script? If it's the former, I don't know what to say. I've tested only in one window manager so far. If it's the latter, I'm not surprised. The FLTK docs are terrible with this subject. I spent most of the afternoon poking and guessing before finally something just happened to spit out a useable string.

Quote
I'll probably go with the previous script, adding the parameter parsing. With the help of lfs we can check for a directory or regular file and determine whether to display the first icon in the directory or a particular icon as a result.

I agree a better fit.
Quote
Do you mean that this particular app didn't accept files dragged onto the interface, or that you haven't gotten app-to-app drag and drop working in a murgaLua script? If it's the former, I don't know what to say. I've tested only in one window manager so far. If it's the latter, I'm not surprised.

murgaLua DND seems to be very dependent on the window manager in use. I get some to work others do not. I would tend to stay away from using this feature until better supported. Really for this app I did like your prior version better. Just adding the process of the arg(s) which provides the dnd via dfm would make it great.

Don't forget to provide me a nice icon to showcase your efforts!

Quote
Just adding the process of the arg(s) which provides the dnd via dfm would make it great.
I started putting that in last night, but got too "drowsy" to finish it. So far it properly loads the XPMs in a directory when a directory iconis dragged onto the script icon, but I have more work to do on dragging a specific file icon. I want to have that paticular XPM displayed, but haven't done that yet.

Ideally I'd also like to have the displayed icon be visible in the scroll, but so far it seems that the only way to accomplish it is to traverse the whole icon table again, comparing each item to the displayed item. I'mnot sure how much that might slow things down when mixed with the "stupid_space" check.

Quote
Don't forget to provide me a nice icon
That's at the back of my mind, but of course I want to make sure the app is tight before working on an icon. I have several Icons I created back in my Windows days, so maybe one of those would be appropriate. I also need to make sure the broken_xpm image is ok to use, since it was taken from firefox, otherwise I'll either make my own or find one that is explicitly free to use.

I was looking through the AIcons package the other day, and discovered that there are other potential issues with a few XPMs that cause them not to display in murgaLua and are not "fixed" by sxpm. I didn't look too closely at those images, but I'm guessing they might contain blank lines that are kept by sxpm.

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()

post removed
Next Page...
original here.