Search Members Help

» Welcome Guest
[ Log In :: Register ]

Mini-ITX Boards Sale, Fanless BareBones Mini-ITX, Bootable 1G DSL USBs, 533MHz Fanless PC <-- SALE $200 each!
Get The Official Damn Small Linux Book. DSL Market , Great VPS hosting provided by Tektonic
Pages: (10) </ [1] 2 3 4 5 6 ... >/

[ Track this topic :: Email this topic :: Print this topic ]

reply to topic new topic new poll
Topic: XPM Icon Viewer, murgaLua script< Next Oldest | Next Newest >
mikshaw Offline





Group: Members
Posts: 4856
Joined: July 2004
Posted: Oct. 31 2007,17:49 QUOTE

Requires murgaLua 0.5.5

A rewrite of an icon viewer I made several months ago.
This version displays only 32x32 XPM images, like those used in dfm.
Added features are the ability to change/refresh the directory from within the gui and opening the selected file in the editor of your choice (default is Beaver).

Please note that occasionally you may run into an XPM file that will crash the application. What I have found so far is files that have leading spaces in the image data, such as the mozilla_composer3* icons in the iceicons-default-0.10.0.tar.gz package, will kill it.

Code Sample

-- XPM icon viewer
-- mikshaw 2007

--dir=os.getenv("HOME").."/.dfm/" -- ending slash is vital
dir="./"
--text_editor="aterm -title Floaty -e vim"
text_editor="beaver"
xpm_size=32

function get_image_data(self)
 local old_data=display:image()
 if old_data then old_data:uncache() end
 local image_data=self:image()
 display:image(image_data:copy(128,128)) --show it bigger!
 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()
 if i_menu:text()=="&Edit" and current_file then os.execute(text_editor.." "..current_file.." &")
 elseif i_menu:text()=="&Directory" then chdir()
 elseif i_menu:text()=="&Refresh" then refresh()
 elseif i_menu:text()=="&Quit" then os.exit(0)
 end
end

function build_list()
 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(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
     butt[xpm_count]:image(icon[i])
     butt[xpm_count]:tooltip(images[i])
     butt[xpm_count]:callback(get_image_data)
     pack:add(butt[xpm_count])
   else icon[i]:uncache()
   end
 end
 if butt[1] then display:show(); butt[1]:do_callback() end -- show first image
 display2:label(xpm_count.." files | "..math.ceil(filesize/1024).." kb")
end

function refresh()
 local old_image=display:image()
 old_image:uncache(); display:hide()
 -- 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
   if string.find(dirname,"/$") then dir=dirname
   else dir=dirname.."/" end
   refresh()
 end
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
w=fltk:Fl_Window(ww,wh,"XPM Icons")

menu_items={"&Edit","&Directory","&Refresh","&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

xpm_count=0 -- set global variables
filesize=0
images={}; icon={}; butt={}

build_list()
w:show()
Fl:run()


--------------
http://www.tldp.org/LDP/intro-linux/html/index.html
Back to top
Profile PM WEB 
mikshaw Offline





Group: Members
Posts: 4856
Joined: July 2004
Posted: Oct. 31 2007,19:49 QUOTE

Minor changes and bug fix:

Fixed refresh crash if initial directory is empty
Ending slash on dir variable is not required
Changed start dir to /usr/share/dfm/icons (note: it's read-only)
Changed default editor to xpaint
Variable name "editor" instead of "text_editor"
Environment variable "XPM_EDITOR" overrides script variable "editor"

Code Sample

-- XPM icon viewer
-- mikshaw 2007

dir="/usr/share/dfm/icons"
editor="xpaint"
xpm_size=32

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()
 display:image(image_data:copy(128,128)) --show it bigger!
 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()
 if i_menu:text()=="&Edit" and current_file then os.execute(editor.." "..current_file.." &")
 elseif
i_menu:text()=="&Directory" then chdir()
 elseif i_menu:text()=="&Refresh" then refresh()
 elseif i_menu:text()=="&Quit" then os.exit(0)
 end
end

function build_list()
 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(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
     butt[xpm_count]:image(icon[i])
     butt[xpm_count]:tooltip(images[i])
     butt[xpm_count]:callback(get_image_data)
     pack:add(butt[xpm_count])
   else icon[i]:uncache()
   end
 end
 if butt[1] then display:show(); butt[1]:do_callback() end -- show first image
 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

-- 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
w=fltk:Fl_Window(ww,wh,"XPM Icons")

menu_items={"&Edit","&Directory","&Refresh","&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

xpm_count=0 -- set global variables
filesize=0
images={}; icon={}; butt={}

build_list()
w:show()
Fl:run()


--------------
http://www.tldp.org/LDP/intro-linux/html/index.html
Back to top
Profile PM WEB 
^thehatsrule^ Offline





Group: Members
Posts: 3275
Joined: July 2006
Posted: Oct. 31 2007,20:54 QUOTE

I see you've already had some changes that I was attempting on your first revision.  In any case it looks like the xpm loader code is causing the segfaulting... wonder if that'll get a bugfix?

The following is part of a semi-workaround, although I know it's not ideal.
Code Sample
function checkxpm(fname)
 local file = io.open(fname, "r")
 local line = file:read("*l")
 while (line) do
   local start = string.find(line, "^ ")
   if start == 1 then
      file:close()
     return false
   end
   line = file:read("*l")
 end
 file:close()
 return true
end

function makenewxpm(fname)
 local fname2 = fname .. "-tmpiconviewer"
 local fin = io.open(fname, "r")
 local fout = io.open(fname2, "w")

 local line = fin:read("*l")
 while (line) do
   line = string.gsub(line, "^ +" , "")
   fout:write(line .. "\n")
   line = fin:read("*l")
 end
 fin:close()
 fout:close()
 return fname2
end


So basically you can use checkxpm first, and if it returns false, call makenewxpm.  Of course, to make this useable, you'd have to have it so that it shows the temp image, yet edits the original (and refresh the temp image based on the temp image).  I guess using another array would be the simplest to add...

Code Sample
<snip>
...
for i=1,table.getn(images) do
  -- new stuff
  if checkxpm(dir .. "/" .. images[i]) == false then
    images2[i] = makenewxpm(dir .. "/" .. images[i])
  else
    images2[i] = images[i]
  end
  --icon[i]=fltk:Fl_XPM_Image(dir..images[i])
  icon[i]=fltk:Fl_XPM_Image(dir..images2[i])
  -- end of new stuff
  if icon[i]:w()==xpm_size and icon[i]:h()==xpm_size then
...
<snip>


And then add "images2={};" and "for i=1,table.getn(images2) do table.remove(images2) end".
Probably would be a good idea to make a better temporary name, and delete them after.
Back to top
Profile PM 
roberts Offline





Group: Members
Posts: 4983
Joined: Oct. 2003
Posted: Oct. 31 2007,23:16 QUOTE

Looking good. Would like this script for v4.1.
Maybe we have some artistic types who can create some new icons or suggest some improved ones.
With this tool it will certainly be alot easier to edit/create xpm icons.
Back to top
Profile PM WEB 
mikshaw Offline





Group: Members
Posts: 4856
Joined: July 2004
Posted: Nov. 01 2007,02:51 QUOTE

Quote
it looks like the xpm loader code is causing the segfaulting... wonder if that'll get a bugfix?
I suppose we could ask Murga if it is a murgaLua issue or if it's an FLTK bug. It might be as simple as rebuilding FLTK using a different xpm version.

I had no idea how I would address the issue through script, and it looks like your solution is definitely useable in some situations. What happens, though, if the icon is not writeable by the user? I think I would prefer to check the file as you suggested, but then just not load it if it's going to cause a crash.

Also an issue with checking every file is that it will probably slow things down considerably on a large number of files. The current script already takes a second or two on a 1.8ghz machine to read a directory with a couple hundred files.


--------------
http://www.tldp.org/LDP/intro-linux/html/index.html
Back to top
Profile PM WEB 
49 replies since Oct. 31 2007,17:49 < Next Oldest | Next Newest >

[ Track this topic :: Email this topic :: Print this topic ]

Pages: (10) </ [1] 2 3 4 5 6 ... >/
reply to topic new topic new poll
Quick Reply: XPM Icon Viewer

Do you wish to enable your signature for this post?
Do you wish to enable emoticons for this post?
Track this topic
View All Emoticons
View iB Code