[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.