Murga-Projects Forums

Full Version: ascii art viewer
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
While working on another project I got an idea for this, so figured I'd try it out. My regular text editor (vim) isn't suited for viewing high-res ascii art as it is presently configured...I use a light foreground on a dark background, and changing font and font sizes on-the-fly isn't something I know how to do (or want to bother with). So this script loads all *.txt file names from a directory and allows you to navigate through them like a simple image browser. Fullscreen can be toggled with "f" key, forward and back are done with period and comma, and scaling the text is done with less-than and greater-than.

Due to limitations of my window manager, the fullscreen function doesn't use Fl_Window:fullscreen(), but resizes and repositions the window according to screen size. I also disable win:resizable(art) on my machine because my tiling window manager doesn't allow a non-fixed-width window to scale itself.

Other notes:
*Change asciidir to point to a directory of text files (trailing slash required).
*Set your Fl_SCREEN font to your favorite monospace font if desired (or delete that line if your system already uses an appropriate monospaced font for FL_SCREEN).
*Set mts to the font size you want for the file list (or delete that line if you like the 14px default font).
*Up and Down arrows don't work for the file list as they would normally do with Fl_Browser. This is because the behavior changed when the text display received focus. I ended up giving the display focus after every action and setting hotkeys for navigation, so the behavior should be consistent. It's another kludge, but i didn't want to spend too much time tweaking this.

I appreciate any bug testing, as well as criticism and suggestions.

The license for this script is do-whatever-you-want-with-it-just-don't-blame-me-if-it-breaks-something.

Code:
buggy code removed

Really nice!
After F'ing to fullscreen the files disappear and <> stops working however.
JP
Well, its keyboard control is definitely patched together in an unusual way, so I'm not too surprised that it failed.

The file list is supposed to disappear in fullscreen, but I guess it's pointless if you lose the ability to navigate through them with the keyboard. I hope it reappears when you get out of fullscreen mode? One of the problems I had with using Fl_Window:fullscreen() was that the file list would reappear sometimes for some reason...it was being moved off the window (invisible but still accessible with the keyboard), but i think my window manager doesn't like that.

So I'm guessing both of those bugs may be related to shortcut keys. I seem to remember seeing someone create global hotkeys once, but I couldn't find anything about that in the docs. I think using global hotkeys should prevent any unexpected problems with focus.

EDIT: Oh...it was John Murga did it in one of his examples. I guess the global hotkeys are specific to Fl_Menu*. So I'm looking into that now.
Does this one work better? I switched the individual hotkey buttons to a single menu_bar, which seems to be a little cleaner.

EDIT: When trying to add a "change directory" function (not included here), it somehow killed the prev/next and font scaling, but kept the fullscreen and cd. I dunno what's going on...maybe I'll look at it again tonight, maybe not. Maybe i'll try splitting up the functions and have one menu item for each callback.

Code:
removed

I think I might have fixed it. Having two menu items using the same callback was somehow causing trouble....most likely me not handling the concept properly.

Added change directory ("c" key), and as a result had to include a directory separator (sep) because depending on how you select with the fl_dir_chooser you may or may not end up with a trailing slash. I have no idea if this willwork as-is in windows. Is now also case-insensitive so it won't ignore *.TXT or *.Txt

Code:
#!/usr/bin/env murgaLua

--[[

simple text display directed primarily toward high-res ASCII art
mikshaw 2010

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

--]]


asciidir="/home/shared/image/ascii"
sep="/" -- "\" for Windows
Fl:set_font(fltk.FL_SCREEN,"mono")
Fl:set_boxtype(fltk.FL_UP_BOX,fltk.FL_THIN_UP_BOX)
Fl:set_boxtype(fltk.FL_DOWN_BOX,fltk.FL_THIN_DOWN_BOX)
ts=11 -- list txt size

ww,wh,mw,index,fullscr=720,486,140,0,0
win=fltk:Fl_Double_Window(ww,wh,"ASCII Images")

function load_txt()
list:value(index)
artbuff:loadfile(asciidir..filetab[index])
win:redraw()
end

-- file navigation
function list_cb()
if list:value()>0 then
  index=list:value()
  load_txt()
end
end
function nav_dn()
if index<list:size() then
  index=index+1
  load_txt()
end
end
function nav_up()
if index>1 then
  index=index-1
  load_txt()
end
end

-- font size
function refresh_buff()
tmp=artbuff:text()
artbuff:text(tmp)
win:redraw()
end
function fnt_sm()
if art:textsize()>1 then
  art:textsize(art:textsize()-1)
  refresh_buff()
end
end
function fnt_lg()
if art:textsize()<16 then
  art:textsize(art:textsize()+1)
  refresh_buff()
end
end

-- fullscreen, kludged for dwm which doesn't like Fl_Window:fullscreen()
function tog_fs()
if fullscr==0 then
  list:hide()
  wx,wy,ww,wh=win:x(),win:y(),win:w(),win:h()
  win:resize(0,0,Fl:w(),Fl:h())
  art:resize(0,0,Fl:w(),Fl:h())
  fullscr=1
else
  list:show()
  win:resize(wx,wy,ww,wh)
  art:resize(mw,0,ww-mw,wh)
  fullscr=0
end
win:redraw()
end

-- change directory
function cd()
local newdir=fltk.fl_dir_chooser("pick a new directory",asciidir,0)
if newdir then
  asciidir=newdir
  get_files()
end
end

-- add files to list
function get_files()
list:clear_output()
filetab={}
list:clear()
if not string.find(asciidir,sep.."$") then asciidir=asciidir..sep end
for i in lfs.dir(asciidir) do
  if string.find(string.lower(i),"%.txt$") then table.insert(filetab,i) end
end
table.sort(filetab)
for i,v in pairs(filetab) do
  list:add(string.sub(v,1,-5))
end
if list:size()==0 then
  list:add("no text files found")
  list:set_output()
else
  list:value(1); list:do_callback()
end
end

-- files
list=fltk:Fl_Hold_Browser(0,0,mw,wh)
list:callback(list_cb)
if ts then list:textsize(ts) end

-- display area
art=fltk:Fl_Text_Display(mw,0,ww-mw,wh)
artbuff=fltk:Fl_Text_Buffer()
art:buffer(artbuff)
art:textfont(fltk.FL_SCREEN)
art:textsize(5)

-- hotkeys
hk=fltk:Fl_Menu_Bar(0,0,0,0)
hk:add("fullscreen",string.byte("f"),tog_fs)
hk:add("big",string.byte(">"),fnt_lg)
hk:add("little",string.byte("<"),fnt_sm)
hk:add("next",string.byte("."),nav_dn)
hk:add("prev",string.byte(","),nav_up)
hk:add("change directory",string.byte("c"),cd)
hk:global()

get_files()
win:resizable(art)
win:show()
Fl:run()

It still borks in Fullscreen though. It seems the textbox freezes, even scrolling up and down (it's a big file I'm viewing) stops working. The fullscreen events do get registered however. A bit weird I think ...
Hmm...maybe I should try putting in the original (pre-release) fullscreen function as an option, to see if that influences it.

When you say "big file", how big are you talking? My largest files are just over 300k, and while they slow things down slightly they don't seem to break it (3ghz/512mb machine, single core).

I never learned exactly what was breaking in the previous version, just discovered it stopped breaking for me when I broke up the nav/scale functions. That not knowing thing means there's a good chance that I've only fixed a symptom and not the problem itself...kinda like taking pain killers.

The only difference here is that I disable the win:resize() for my window manager. I can't see why that might break it, but maybe it does.

Also saw a noticeable slowdown when the font is set at its smallest size.

For now I guess I'll just add the secondary fullscreen function and then let it be for a while. Unless I can reproduce the bug, or someone smarter can figure it out, I don't know what else to do.
No idea if this will work better. It's worse for me, but only because of my aforementioned wm limitations.

It's funny it doesn't work if I resize art to the window's position and size before going fullscreen, so I still have to use screen dimensions.

Code:
function tog_fs()
if fullscr==0 then
  list:hide()
  wx,wy,ww,wh=win:x(),win:y(),win:w(),win:h()
  win:fullscreen()
  art:resize(0,0,Fl:w(),Fl:h())
  fullscr=1
else
  list:show()
  win:fullscreen_off(wx,wy,ww,wh)
  art:resize(mw,0,ww-mw,wh)
  fullscr=0
end
win:redraw()
end

Some additions and some reorganization/cleanup.

You can now swap foreground and background colors (key "x").
User-set variables are all in one place, including hotkeys.
Changed default cd key to "o" because I kept pressing it instead of "c".
Scrollbars now hide (resize to zero, actually) in fullscreen.
Text display font is now set to courier (I forgot screen is not the default monospace font in Fltk).
Fl_Window:fullscreen() is the default method of going fullscreen now, although I left the kludge version in comments.

I'm considering an attempt at disabling direct keyboard interaction with the file list. I find myself initially using up and down arrows, and then when I go fullscreen I have to switch to the hotkeys.

Code:
#!/usr/bin/env murgaLua

--[[

simple text display directed primarily toward high-res ASCII art
mikshaw 2010

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

--]]

-- preferences
asciidir="." -- start directory
--asciidir="/home/shared/image/ascii"
sep="/" -- directory name separator, "\" for Windows
ww,wh=720,486 -- main window width & height
lw=140 -- file list width
as=5 -- initial art text size
fs_key="f" -- fullscreen hotkey
big_key=">" -- art font bigger
lil_key="<" -- font smaller
next_key="." -- show next file
prev_key="," -- show previous file
cd_key="o" -- change directory
swap_key="x" -- swap fg and bg colors
-- OPTIONAL preferences, can be deleted or commented out
ts=11 -- list text size
Fl:set_boxtype(fltk.FL_UP_BOX,fltk.FL_THIN_UP_BOX)
Fl:set_boxtype(fltk.FL_DOWN_BOX,fltk.FL_THIN_DOWN_BOX)
Fl:scrollbar_size(10) -- scrollbar width
--Fl:set_font(fltk.FL_COURIER,"some font") -- ascii text font


function load_txt()
list:value(index)
artbuff:loadfile(asciidir..filetab[index])
win:redraw()
end

-- file navigation
function list_cb()
if list:value()>0 then
  index=list:value()
  load_txt()
end
end
function nav_dn()
if index<list:size() then
  index=index+1
  load_txt()
end
end
function nav_up()
if index>1 then
  index=index-1
  load_txt()
end
end

-- font size
function refresh_buff()
art:textsize(as)
tmp=artbuff:text()
artbuff:text(tmp)
win:redraw()
end
function fnt_sm()
if as>1 then
  as=as-1
  refresh_buff()
end
end
function fnt_lg()
if as<24 then
  as=as+1
  refresh_buff()
end
end

-- swap colors
function invert()
fg,bg=art:color(),art:textcolor()
art:textcolor(fg)
art:color(bg)
art:redraw()
end

--[[
-- fullscreen, kludged for dwm which doesn't like Fl_Window:fullscreen()
function tog_fs()
if fullscr==0 then
  list:hide()
  art:scrollbar_width(0)
  wx,wy,ww,wh=win:x(),win:y(),win:w(),win:h()
  win:resize(0,0,Fl:w(),Fl:h())
  art:resize(0,0,Fl:w(),Fl:h())
  fullscr=1
else
  list:show()
  art:scrollbar_width(Fl:scrollbar_size())
  win:resize(wx,wy,ww,wh)
  art:resize(lw,0,ww-lw,wh)
  fullscr=0
end
win:redraw()
end
--]]

-- normal fullscreen
function tog_fs()
if fullscr==0 then
  list:hide()
  wx,wy,ww,wh=win:x(),win:y(),win:w(),win:h()
  win:fullscreen()
  art:resize(0,0,Fl:w(),Fl:h())
  fullscr=1
else
  list:show()
  win:fullscreen_off(wx,wy,ww,wh)
  art:resize(mw,0,ww-mw,wh)
  fullscr=0
end
win:redraw()
end

-- change directory
function cd()
local newdir=fltk.fl_dir_chooser("pick a new directory",asciidir,0)
if newdir then
  asciidir=newdir
  get_files()
end
end

-- add files to list
function get_files()
list:clear_output()
filetab={}
list:clear()
if not string.find(asciidir,sep.."$") then asciidir=asciidir..sep end
for i in lfs.dir(asciidir) do
  if string.find(string.lower(i),"%.txt$") then table.insert(filetab,i) end
end
table.sort(filetab)
for i,v in pairs(filetab) do
  list:add(string.sub(v,1,-5))
end
if list:size()==0 then
  list:add("no text files found")
  list:set_output()
else
  list:value(1); list:do_callback()
end
end

-- interface
Fl:get_system_colors()
win=fltk:Fl_Double_Window(ww,wh,"ASCII Images")

-- files
list=fltk:Fl_Hold_Browser(0,0,lw,wh)
list:callback(list_cb)
if ts then list:textsize(ts) end

-- display area
art=fltk:Fl_Text_Display(lw,0,ww-lw,wh)
artbuff=fltk:Fl_Text_Buffer()
art:buffer(artbuff)
art:textfont(fltk.FL_COURIER)
art:textsize(as)

-- hotkeys
hk=fltk:Fl_Menu_Bar(0,0,0,0)
hk:add("fullscreen",string.byte(fs_key),tog_fs)
hk:add("big",string.byte(big_key),fnt_lg)
hk:add("little",string.byte(lil_key),fnt_sm)
hk:add("next",string.byte(next_key),nav_dn)
hk:add("prev",string.byte(prev_key),nav_up)
hk:add("change directory",string.byte(cd_key),cd)
hk:add("swap colors",string.byte(swap_key),invert)
hk:global()

index,fullscr=0,0
get_files()
win:resizable(art)
win:show()
Fl:run()

Reference URL's