From: Magicloud M. <mag...@gm...> - 2009-04-14 03:09:41
|
Hi, I just noticed a mail named "gtk2hs question - derive SettingsWindow from Window" in gtk2hs ML. As it said, I wonder, is it possible to subclass a widget? If I use newtype as the mail said, is the "newtype MyWindow" a widget, so I can use it like "containerAdd myWin"? -- 竹密岂妨流水过 山高哪阻野云飞 |
From: Axel S. <Axe...@en...> - 2009-04-14 19:30:21
|
On Apr 14, 2009, at 5:09, Magicloud Magiclouds wrote: > Hi, > I just noticed a mail named "gtk2hs question - derive SettingsWindow > from Window" in gtk2hs ML. As it said, I wonder, is it possible to > subclass a widget? If I use newtype as the mail said, is the "newtype > MyWindow" a widget, so I can use it like "containerAdd myWin"? > The use of the Haskell type class system to model the object sub- typing relationship is not really meant to be extended using Haskell values. In fact, the classes of most widgets contain no methods at all such that the compiler can optimize the class contexts away. Creating a new Haskell type that contains a pointer to a Widget w and making it appear as if it were a value of type w is not easily possible in this setting. We could add the appropriate methods to the type classes but this would incur the overhead to each method that is of no use except for this special case. The benefit of being able to create a Haskell value that looks like a Gtk object is not that clear to me. Furthermore, if it seems important to extend a given Gtk object, a lightweight alternative is to simply add new fields to the object using 'objectCreateAttribute' in Glib.System.GObject: type MyWidget = Label extraData :: Attr MyWidget (Maybe String) extraData = unsafePerformIO objectCreateAttribute myWidgetGetData :: MyWidget -> IO String myWidgetGetData w = do mData <- get w extraData case mData of Just v -> return v Nothing -> error "myWidgetGetData: extraData not present in Label" myWidgetSetData :: MyWidget -> String -> IO () myWidgetSetData w s = set w [extraData := s] This is obviously not quite what a true sub-type can give you since the type synonym MyWidget gives you no guarantee that the new field always exists (hence the need for the error message). But I think this is a good enough compromise between the full version that incurs a lot of overhead for all Gtk2Hs programs and the ability to extend an object. Cheers, Axel. |
From: Duncan C. <dun...@wo...> - 2009-04-16 09:43:59
|
On Tue, 2009-04-14 at 21:29 +0200, Axel Simon wrote: > The use of the Haskell type class system to model the object sub- > typing relationship is not really meant to be extended using Haskell > values. In fact, the classes of most widgets contain no methods at > all such that the compiler can optimize the class contexts away. If I recall correctly, that optimisation was my fault. Previously it did exactly do a class-based upcast. Now it does the pointer cast and just uses the classes to say when this is safe. At the time I thought the optimisation was important, now I'm not nearly so sure. In fact last time I thought about it I think I figured it'd be better on balance to do proper class upcasts. If we can go direct from each widget type to GObject in a single go (rather than a massive chain of cast functions) then it should get optimised away in the normal case where we know the exact widget type. The benefit of course is that it'd allow people to subclass much more easily. I think it's worth investigating at least. (I don't mean it's more important than other priorities, just that given enough dev time I think it's interesting to look at.) As you mention, it doesn't make it look like a different Haskell type and if you pass it to C code and back then you loose the extra info etc. But it's probably useful for people making new widgets just in Haskell, eg things based on custom drawn DrawWindows etc. Duncan |