[GUI] Are windows just ordinary widgets?
Wolfgang Thaller
wolfgang.thaller@gmx.net
Wed, 30 Apr 2003 23:42:55 +0200
Axel Simon wrote:
> IMHO the classes should just reflect the object hierarchy. If we have
> e.g.
>
> class Button b where...
> class ToggleButton b where...
> instance Button ToggleButton where...
>
> then we can have the simple function
>
> onActivate :: Button b => b -> IO () -> IO ()
>
> and use it with ToggleButton as well (but not with a plain Widget or
> anything on the other branches of the tree). Having onActivate as a
> class
> member doesn't give any improvement in type safety, is less efficient
> (bigger dictionaries) and doesn't lend itself to automatic creation of
> this type hierarchy.
>
> Axel.
I'm no longer entirely sure what we are talking about. What is "the
object hierarchy"?
Could somebody who has an opinion on these issues knock up a concrete
example; I'm not thinking of code, just some class declarations and
signatures...
Here's a summary of what's in the FLTK-based example that David Sankel
posted a while ago. I've added some comments.
class IsWidget a where
toWidget :: a -> IO Widget
data Widget
instance IsWidget Widget
class HasOnActivate a where
doOnActivate :: a -> IO () -> IO( IO() )
class HasTitle w where
title :: Attr w String
-- This should be left to layout management:
class HasPosition w where
position :: Attr w (Int,Int)
class HasSize w where
size :: Attr w (Int,Int)
-- The following two are not possible, because of some toolkits'
inability to reparent widgets after creation:
class HasAddChild a where
addChild :: IsWidget b => a -> b -> IO ()
class HasChildren w ehere
children :: Attr w [Widget]
-- ===
data Window
mkWindow :: [Prop Window] -> IO Window
instance IsWidget window
instance HasAddChild window
instance HasChildren window
visible :: Attr Window Bool
-- ===
data Button
mkButton :: [Prop Button] -> IO Button
instance IsWidget Button
instance HasTitle Button
instance HasOnActivate Button
instance HasPosition Button
instance HasSize Button
-- ===
-- The whole "Box" widget should probably be replaced by different
kinds of boxes
-- that do different kinds of layout.
data Box
mkBox :: [Prop Box] -> IO Box
instance IsWidget Box
instance HasTitle Box -- <= it seems that in fltk, a box is more than
just a simple container....
instance HasPosition Box
instance HasSize Box
-- ===
Some more notes:
If we want to implement a dynamic layout manager in Haskell for
platforms that don't support that natively,
we will need a way to query things like minimum size when we have just
values of some general type
(like Widget, though I already suggesting having a generic type that
only includes all widgets _except_ windows).
The current "CGA example" doesn't provide that.
Also, the CGA example currently has completely separate code for the
"HasSize" instances for Buttons and Boxes; but in the end, they both
call the same virtual member function on a C++ object. There should be
a way for backend implementors to avoid that needless duplication of
work.
Cheers,
Wolfgang