Hi!
Attached is the current version of my image organizing program.
If you dbl-click on a thumbnail, it will show the image (1:1 zoom) in a
dialog, and eat some memory....
Gergo
--
+-[ Kontra, Gergely<kgergely@mcl.hu> PhD student Room IB113 ]---------+
| http://www.mcl.hu/~kgergely "Olyan langesz vagyok, hogy |
| Mobil:(+36 20) 356 9656 ICQ: 175564914 poroltoval kellene jarnom" |
+-- Magyar php mirror es magyar php dokumentacio: http://hu.php.net --+
-------------- next part --------------
require ''wxruby''
require ''find''
include Wx
ID_SETROOT,ID_TOOLBAR,ID_SHOWCAT,ID_EDITLAB,=(1..40).to_a # nicer way???
# Tree = Tree(label, children) | Object (where Object is String...)
class Tree
attr_reader :label, :children
def initialize label, children=nil
@label, @children = label, children
end
end
THM_HEIGHT=THM_WIDTH=128
#=======================================================================
class MyImageFrame < Dialog # -- opens a dialog to show a picture
def initialize parent, title, filename
super(parent, -1, title)
@bitmap=Bitmap.new(filename,BITMAP_TYPE_ANY) # why should I say
BITMAP_TYPE_ANY?
set_client_size_wh(@bitmap.get_width,@bitmap.get_height)
evt_paint {on_paint()}
evt_left_down {on_click()}
end
def on_click
@bitmap.destroy()
self.destroy()
end
def on_paint
dc = PaintDC.new(self)
dc.draw_bitmap(@bitmap,0,0,true)
end
end
class Pictures < ListCtrl # -- show the pictures
def initialize parent
super parent,-1,DEFAULT_POSITION,DEFAULT_SIZE,LC_ICON|LC_AUTOARRANGE
assign_image_list(@imageList=ImageList.new(THM_WIDTH,THM_HEIGHT),IMAGE_LIST_NORMAL)
# evt_list_begin_drag(self.get_id) {|e| log_status "Oh, dragging";
dragsrc = DropSource.new(self); true }
evt_list_item_activated(self.get_id) {|e|
fn=e.get_item.get_text
MyImageFrame.new(self,fn,fn).show()
}
end
def thm_name filename
dir,fn=File.split filename
[dir+"/.thumb#{THM_WIDTH}x#{THM_HEIGHT}/",fn+''.jpg'']
end
def gen_thm filename
img = Image.new(filename)
w,h=img.get_width.to_f,img.get_height.to_f
return nil if w*h==0
xscale,yscale=w/THM_WIDTH,h/THM_HEIGHT
thm_w,thm_h=THM_WIDTH,THM_HEIGHT
if xscale>=yscale
thm_h=(h/xscale+0.5).to_i
else
thm_w=(w/yscale+0.5).to_i
end
img.rescale(thm_w,thm_h)
dir,fn=thm_name filename
Dir.mkdir(dir) unless FileTest.directory? dir
img.save_file dir+"/"+fn, BITMAP_TYPE_JPEG
end
def show_list list
num_images=list.length
log_status ''Removing images''
@imageList.remove_all
clear_all
list.each_with_index{|fn,i|
insert_item i,fn,i
}
Thread.new {
Thread.current.priority=-1
list.each_with_index{|fn,i|
log_status "Generating thumbnails #{i+1}/#{num_images}: #{fn}"
thm_file=thm_name(fn).join
gen_thm fn unless FileTest.file? thm_file
icon_data=Bitmap.new(thm_file, BITMAP_TYPE_JPEG)
w,h=icon_data.get_width,icon_data.get_height
icon=Bitmap.new(THM_WIDTH,THM_HEIGHT)
icon_dc=MemoryDC.new()
icon_dc.select_object(icon)
icon_dc.set_brush(TRANSPARENT_BRUSH)
icon_dc.clear()
icon_dc.draw_bitmap(icon_data,(THM_WIDTH-w)/2,(THM_HEIGHT-h)/2,false)
icon_dc.select_object(NULL_BITMAP)
@imageList.add icon
refresh_item i
Thread.pass
}
}
end
end
#=======================================================================
class Categories < TreeCtrl
attr :root
def initialize parent
#,id=-1,pos=DEFAULT_POSITION,size=DEFAULT_SIZE,style=TR_HAS_BUTTONS|TR_ROW_LINES|TR_EDIT_LABELS#|TR_HIDE_ROOT
super parent,-1,DEFAULT_POSITION,DEFAULT_SIZE,TR_EDIT_LABELS|TR_HAS_BUTTONS
@cats = Tree.new( ''All pictures (sok)'',[
Tree.new(''Location'',[''Budapest'',''Venice'']),
Tree.new(''Type'',[''Landscape'',''Portre'']),
])
build_from_tree nil,@cats
#set_drop_target(MyFileDropTarget.new())
#evt_tree_begin_drag(self.get_id) { |e|
# puts e.get_item
#}
evt_tree_item_right_click(self.get_id) {|e|
ShowMenu(e.get_item,e.get_point)
}
evt_menu(ID_EDITLAB) {
edit_label get_selection
}
evt_tree_key_down(self.get_id) {|e|
case e.get_key_code
when K_F2
edit_label get_selection
end
}
end
def build_from_tree parent,tree
m = parent.nil? ? Proc.new {|p,l| @root=add_root l} : Proc.new {|p,l|
append_item p,l}
unless tree.kind_of? Tree
m.call parent,tree
else # tree is real tree
node = m.call parent,tree.label
tree.children.each {|i|
build_from_tree node,i
}
end
end
def ShowMenu id, pt
@tree_item = id
menu=Menu.new "Menu for #{id}"
menu.append ID_SHOWCAT, "&Open category"
menu.append ID_EDITLAB, "&Change name"
popup_menu menu, pt
end
end
#=======================================================================
class MyFrame < Frame
def initialize title
super nil, -1, title
@title=title
set_icon Icon.new("bitmaps/pictorG.xpm")
@config = ConfigBase::get()
self.root_dir=@config.read("/rootdir")||ENV[''HOME'']||ENV[''USERPROFILE'']
@catalog_file=''''
# File menu
menuFile = Menu.new
menuFile.append ID_NEW,"&New catalog\tN","Creates a new
catalog"
menuFile.append ID_OPEN,"&Open catalog\tO","Opens an
existing catalog"
menuFile.append ID_SETROOT,"&Set root dir\tR","Sets the
root directory of the catalog"
menuFile.append_separator
menuFile.append ID_EXIT,"E&xit\tQ","Quits the
program"
# Help menu
menuHelp = Menu.new
menuHelp.append(ID_ABOUT,"&About\tCtrl-F1","Show program
information")
# the Menubar
menuBar = MenuBar.new
menuBar.append menuFile, "&File"
menuBar.append menuHelp, "&Help"
set_menu_bar menuBar
# Toolbar
toolBar = create_tool_bar TB_HORIZONTAL&TB_FLAT&TB_TEXT, ID_TOOLBAR
toolBar.add_tool ID_ABOUT, "Help",
Bitmap.new("bitmaps/help.xpm"), "Get help"
toolBar.realize()
ToolTip.enable true
# Frame (splitter inside)
splitter=SplitterWindow.new(self,-1)
# Categories
@cat=Categories.new(splitter)
@cat.evt_tree_item_activated(@cat.get_id) { |e|
self.show_pics() #if e.get_item == @cat.root
}
@pic=Pictures.new(splitter)
splitter.split_vertically @cat,@pic,150
#set_auto_layout(TRUE)
# Statusbar
create_status_bar()
# Events
evt_menu(ID_NEW) {message_box "New db"}
evt_menu(ID_OPEN) {
filedlg=FileDialog.new(self,''Open
catalog'','''','''',''Picture
organizer catalog *.poc|*.poc'',OPEN|CHANGE_DIR).show_modal}
evt_menu(ID_SETROOT) {
dirdlg=DirDialog.new(self,''Catalog base dir'',@root_dir)
self.root_dir=dirdlg.get_path if dirdlg.show_modal==ID_OK
}
evt_menu(ID_EXIT) {close TRUE }
evt_menu(ID_ABOUT) {message_box "pictorG - PICTure ORganizer by
Gregory\n?Gergely Kontra","About pictorG",OK|ICON_INFORMATION}
#show_pics
end
def root_dir= (dir)
@config.write("/rootdir",@root_dir=dir)
set_title @title +'' - Browsing in ''+@root_dir
end
def show_pics
return message_box("Set root directory first!") unless @root_dir
list=[]
log = Thread.new {
while 1
log_status "Collecting files (#{list.last})"
sleep 0.5
end
}
Find.find(@root_dir) {|fn|
Find.prune if fn=~/.thumb\d+x\d+/
error "Ouch! Processing #{fn}" if fn=~/.thumb\d+x\d+/
list << fn.gsub!(''\\'',''/'') if
fn=~/\.(jpe?g|gif|png|bmp|xpm)$/i
}
log.kill
@pic.show_list list
end
end
#=======================================================================
class MyApp < App
def OnInit
MyFrame.new("pictorG - PICTure ORganizer by Gregory").show
end
end
init_all_image_handlers
MyApp.new.main_loop()