[GUI] Are windows just ordinary widgets?

Axel Simon A.Simon@ukc.ac.uk
Fri, 2 May 2003 18:40:06 +0100


On Fri, May 02, 2003 at 12:08:41AM +0200, Wolfgang Thaller wrote:
> >This was my proposal:
> >http://haskell.org/pipermail/gui/2003-April/000459.html
> 
> OK so you're talking about upcast & downcast functions (as class 
> members). At least that's how I would try to describe your approach. 
> The question where to put the actual functions remains open.

I vote for not having them in classes at all. Overlap of function names of
different types are minimal and lumping (some) functions together into
categories is ad-hoc, hard to get right and impossible to change
afterwards without breaking code.

> I think upcast and downcast functions become ugly as soon as the 
> hierarchy doesn't match the underlying backend.

That might be true. I don't see a good way to interface an agreed object 
hierarchy to the existing Gtk type classes in gtk2hs. Yet.

> What "upcasted" generic types do we need anyway?
> As I said, we need a
> data Pane = ....
> class PaneClass p where
>     toPane :: p -> Pane
>     fromPane :: Pane -> Maybe p
> 
> ... at least in order to be able to implement dynamic layout in Haskell 
> (for platforms that don't have it).
> I'm using the term Pane to mean any widget that can be placed inside a 
> window; that is widgets minus windows and menu items.

I don't mind the name, Pane or Widget is fine with me.

> Do we need any other upcast/downcast functionality?

Dunno. Do you have anything in mind?

> Does anyone want to have a list of _any kind_ of widget, mixing windows 
> and buttons and layout containers etc?

I am currently assuming that I am able to compose layout containers into
other layout containers. As such, I layout containers and widgets have to
be in one class.

But I think it's a good idea to separate top-level windows by giving them 
a different root class.

> Does anyone want to have a list of any kind of buttons, that may 
> contain both push buttons and toggle buttons, but no edit text fields 
> and labels?

I thought about it and couldn't find a compelling "yes".

> If the answer is no, then let's not include any more upcast/downcast 
> functions, at least not in CGA 1.0, because they will never be 
> conveniently implementable on all platforms at the same time.
> 
> We could then just have classes that contain some functionality, and 
> some plain functions where a certain functionality is only available at 
> one widget.

I don't understand what you mean with more upcast/downcast functions. 
Could you explain or give an example?

> The next question we need to ask is, which widget type supports what 
> functionality?

I guess we do that widget-by-widget. And don't make these functions part 
of the widget type class.

I'd like to have

setButtonLabel :: ButtonClass b => b -> String -> IO ()
setButtonLabel b name = ... (toButtonClass b) ...

> Below I've attached what I'm currently thinking of... could we have 
> another quick "yes"/"no, because" vote and/or some counter-proposals?
> 
> Cheers,
> 
> Wolfgang
> 
> ================== cut here ==================
> 
> import Attributes -- from the CGA example (indirectly from HToolkit)
> 
> data Pane = ....
> class PaneClass p where
>     toPane :: p -> Pane
>     fromPane :: Pane -> Maybe p
Yes.

>     -- plus any functions and attributes that are supported by all 
> kinds of panes
>     -- and not supported by any window or other object
No. Every function that is supported by all panes can be implemented like 
the setButtonLabel example. I don't see any advantage of making these 
functions memebers of the class. The disadvantage is large dictionaries 
which probably all contain the same virtual function for a specific entry.

> 
> instance PaneClass Pane where
>     toPane = id
>     fromPane = Just
>     -- ...
Yes.

> 
> class Container c where
>     -- ...
> 
> class HasOnActivate a where
> 	doOnActivate :: a -> IO () -> IO( IO() )

No. As above.

> 
> data Button = ...
> instance PaneClass Button where
>     -- ...

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.

> mkButton :: Container c => c -> [Prop Button] -> IO Button
newButton. Please!?

[..]
No unexpected change of opinion.

Axel.