Message-ID: <433A46AE.8000004 at irisa.fr> Date: Wed, 28 Sep 2005 09:30:54 +0200 From: Sebastien Ferre Organization: IRISA MIME-Version: 1.0 To: lablgtk at math.nagoya-u.ac.jp Subject: GTree: delaying the computation of a pixbuf upon visibility References: <43355ED4.5000004 at inria.fr> In-Reply-To: <43355ED4.5000004 at inria.fr> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Hi, I'm working on a GUI in which there is a 'GTree.list_store' of thumbnails (look at http://www.irisa.fr/lande/ferre/camelis for screen captions). I use the library CamlImages for computing these thumbnails from JPEG pictures. The problem is that computing these thumbnails is really slow. For example it takes about 20s for 100 thumbnails, whereas only a few are visible at one time. So I wonder if it is possible to delay these computations upon the visibility of a row of the list inside the scrolling window ? What I want is also to keep control on the scrolling and selecting while thumbnails are being computed and displayed. Here is the code I use to build a pixbuf from a JPEG file. Can it be made more efficient ? let pixbuf_of_jpeg = let ht = Hashtbl.create 100 in fun ~maxside filename -> try Hashtbl.find ht filename with Not_found -> let spec = { spec_width = Scale 0.2; spec_height = Scale 0.2; spec_aspect = Keep_at_most; spec_switch = Smaller_only; spec_x = 0; spec_y = 0} in let _, _, img = OJpeg.load_thumbnail filename [] spec in let img = OImages.rgb24 img in let w = img#width in let h = img#height in let scale = max maxside (max w h) / maxside in let width = w / scale in let height = h / scale in let newimage = img#resize None width height in let pixmap = OXimage2.pixmap_of_image (Gdk.Window.root_parent ()) None newimage#coerce in let pixbuf = GdkPixbuf.create ~width ~height () in GdkPixbuf.get_from_drawable ~dest:pixbuf pixmap#pixmap; Hashtbl.add ht filename pixbuf; pixbuf And now, here is the code I use for building the list. In the model I put the filename of the source picture, and in the view I use a 'cell_renderer_pixbuf' and redefine the cell_data_func. let cell_thumb = GTree.cell_renderer_pixbuf[] let col_thumb = GTree.view_column ~title:"Thumbnail" () ~renderer:(cell_thumb, []) let _ = col_thumb#set_sizing `AUTOSIZE let _ = col_thumb#set_cell_data_func cell_thumb (fun model iter -> let colormap = Gdk.Color.get_system_colormap () in let black = Gdk.Color.alloc ~colormap `BLACK in let thumbname = model#get ~row:iter ~column:thumb in try if thumbname = "" then raise Not_found; let pixbuf = pixbuf_of_jpeg ~maxside:150 thumbname in let height = GdkPixbuf.get_height pixbuf in let width = GdkPixbuf.get_width pixbuf in cell_thumb#set_properties [`HEIGHT (height+20); `PIXBUF pixbuf; `VISIBLE true] with _ -> cell_thumb#set_properties [`VISIBLE false]) [...] let make_list nbobj = model_extent#clear; for oid=1 to nbobj do let item = model_extent#append () in model_extent#set ~row:item ~column:id oid; model_extent#set ~row:item ~column:thumb (file_of_oid oid); done Thanks for your help, Sebastien