[GUI] Are windows just ordinary widgets?

Axel Simon A.Simon@ukc.ac.uk
Sat, 3 May 2003 16:44:16 +0100


On Fri, May 02, 2003 at 09:15:48PM +0200, Wolfgang Thaller wrote:
> >I'd like to have
> >
> >setButtonLabel :: ButtonClass b => b -> String -> IO ()
> >setButtonLabel b name = ... (toButtonClass b) ...
> 
> I'm a afraid of that toButtonClass function... toButtonClass is what I 
> call an upcast function,
> and upcast functions can only be implemented conveniently if they 
> mirror what the backend does.

Ok, possible.

> See also the discussion of HasOnActivate below.
[..]
> Ah yes. You're probably right.
> But I'd like to add the remark that this _would_ have been a problem if 
> we wanted to
> do it for the "Widget" class which includes Windows and Panes, because 
> not all backends have a common base type for windows and panes.
> To avoid similar problems, I'd like to avoid having more "upcasted" 
> types like Pane, and use type classes for everything else.
> 
> >>class Container c where
> >>    -- ...
> >>
> >>class HasOnActivate a where
> >>	doOnActivate :: a -> IO () -> IO( IO() )
> >
> >No. As above.
> 
> Does that No refer to both Container and HasOnActivate?
> 
> For Container, I think we do need them, because there are at least two 
> independent types which would implement the Container class, Window and 
> GridBox.
Oh, sorry. No, the container class is fine with me.

> As far as HasOnActivate is concerned...
> We could have separate doOnButtonActivate and doOnToggleButtonToggle 
> functions without any classes, but I don't think that has any 
> advantages.
My observation is that common functionality is rare between widgets. Using 
classes for every signal and function is overkill (and causes name space 
pollution and perhaps even slow turn-around times). And grouping them into 
related classes seems hard to get right. But we can try. (I am getting 
more aquainted to that thought.)

> Are you perhaps thinking of
> 
> class ButtonClass b where
> 	toButton :: b -> Button
> instance ButtonClass Button
> instance ButtonClass ToggleButton
> doOnActivate :: ButtonClass b => b -> IO () -> IO ( IO () )
> doOnActivate b io = ... (toButton b) ...
> 
> I'm sceptical of that - is ToggleButton derived from Button in all 
> backends?
> Button and ToggleButton are actually siblings in Carbon (but there are 
> still some common functions to work with them, so it's not a real 
> problem; it might be in other cases, or for other backends).
> That's why I'm in favour of relying on type classes that contain the 
> actual functions rather than "toButton"-like functions for widgets;
> ... but as long as we're inside the "Pane" subtree, i.e. no Windows, I 
> think that most problems can be worked around relatively easily. So my 
> opinion isn't a very strong one in this case.
> 
> >I admit that I find it weird that the Button doesn't have a class. But 
> >if
> >it is a leave then it's probably not necessary.
> 
> My idea was to make all types inside the "Pane" hierarchy "leaves"; I 
> wanted to represent all other relationships using different type 
> classes.
> That way, we can't accidentally make assumptions about relationships 
> between widget types that just don't hold true on all backends.
> On the other hand, a hierarchy with toFoo (upcast) functions could be 
> perfectly viable _as long as_ we avoid the mistake of defining a 
> hierarchy that "doesn't fit" with all backends.

Ok, I think this is a good approach. Just a flat hierarchy to facilitate 
having a list of widgets.


Axel.