To: wakita at is.titech.ac.jp Cc: lablgtk at kaba.or.jp Subject: Re: reusing button class In-Reply-To: <20010104162842A.wakita at is.titech.ac.jp> References: <20010104162842A.wakita at is.titech.ac.jp> Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-Id: <20010105115319P.garrigue at kurims.kyoto-u.ac.jp> Date: Fri, 05 Jan 2001 11:53:19 +0900 From: Jacques Garrigue Lines: 89 From: Ken Wakita > I tried to define [image_button] class that contain an icon and an > optional label. It was easy to implement a function that make a > button with an icon. > > Then I tried to make a lablgtk style object-oriented class definition > and I was in a trouble. Lablgtk style seems to require defining both > the class and constructor function. However, initialization code by > using low-level interface makes this difficult to do in a handy > manner. So I pushed the iniitalization code in the initializer of the > class definition and obtained attached below. > class button ?label ?border_width ?width ?height ?packing ?show () = > let obj = GtkButton.Button.create ?label () in > object (self) > inherit GButton.button_skel (GtkButton.Button.coerce obj) > method connect = new GButton.button_signals obj > method event = new GObj.event_ops obj > initializer > GtkBase.Container.set obj ?border_width ?width ?height; > ignore (GObj.pack_return self ?packing ?show) > end Class and constructors are not distinguished so much for good style, but rather for technical reasons. LablGTK classes are just wrappers to raw GTK widgets, and they must have a constructor taking the raw widget as argument, since you do not only wrap newly created widgets, but also those returned by methods, or manually casted ones. Then the problem is that ocaml objects have only one constructor. So in the old beta1 version of lablGTK, there were actually two classes for each widget: one acting just as a wrapper, called [button_wrapper], and another one defined very much like you are doing here, called [button]. However this meant a bit of gymnastic to hide the [button_wrapper] type, and have [new button_wrapper w] return an object of type [button]. Also this appeared to be a cause of code bloat, which is not so nice when what you are doing is just interfacing to the real library. Still there was something nice about it: according to olabl optional semantics, [new button] would return a button, without need to write [new button ()] like with a function. But optional semantics changed with ocaml 3, and I went back to a simpler approach, using a normal function as constructor. Another point was of course that you could inherit from the [button] class more naturally, as you state here. However I have grown more and more convinced than inheritance is generally not what you want. That is, inheritance is not a way to organize a library (that should be subtyping, at best), but just to throw around your code. So here is how I would write you image_button example in the new lablgtk style. class image_button ~file ?(label = "") ?border_width ?width ?height ?packing ?show () = let button = GButton.button ?border_width ?width ?height ?packing ?show () in let box = GPack.vbox ~packing:button#add () in let pm = GMisc.pixmap (GDraw.pixmap_from_xpm ~window: box ~file ()) ~packing:box#add in let label = GMisc.label ~text: label ~packing () in object inherit GButton.button (GtkButton.Button.cast button#as_widget) method label = label method pixmap = pm end In this specific case, it is natural to inherit from button, but in most cases I would even avoid it, and write class image_button ... = ... object inherit GObj.widget button#coerce method connect = new GButton.button_signals obj method event = new GObj.event_ops obj method button = button method pixmap = pm method label = label end I don't try to separate class and constructor here, since this is not really relevant. If you want to add it, you still don't need to beta-expand let image_button = new image_button Cheers, and Happy New Year, Jacques --------------------------------------------------------------------------- Jacques Garrigue Kyoto University garrigue at kurims.kyoto-u.ac.jp JG