Hello Daan, Hello List,
I just tried to create my own custom widget based on HtmlWindow. I
encountered a few problems which I want to share with you:
1) Surprisingly to me I had to realize that there is a separate
CWXCHtmlWindow hierarchy. As the corresponding creation function
wxcHtmlWindowCreate is not documented I first assumed that it is
used to implemented HtmlWindow, which on a closer look I had to
realize it is NOT. My current guess is that it is a left over
from the automatic wrapping process. Which normally wouldn't
bother me that much but unfortunately the function
htmlWindowOnHtmlEvent can ONLY be called on a CWXCHtmlWindow! Why
is that?
2) A bigger problem: while the attribute handling is really nice to
have and works well with the wrapped C++ widgets it can be quite
difficult to provide with new self written widgets. Let's for
the sake of argument assume that I want to write a wrapper for the
HtmlWindow which maps the HtmlLinkClicked event to the select
event of the class Selecting and provides a attribute
selectedLink :: Attr w (Maybe String).
Iff I got it right one cannnot "derive" from a builtin widget and
add new "state" to the created value. That is write something
like newtype MyWindow = MyWindow (MyState, HtmlWindow ())
and then just add some instance declarations to make it work with
the wxHaskell routines.
Therefore the only way I see to associate some state with a
window is to use the windowGetId function and a table of
Int -> MyState.
Add this point we hit a kind of open design problem in haskell!
It is not yet possible (as far as I know) to write a global value
which originally was part of the IO monad. Or at least it is not
possible to do so safely! Using unsafePerformIO one can do this:
{-# noinline states #-}
states :: Var (FiniteMap Int MyState)
states = unsafePerformIO $ varCreate state
So this is probably not a really satisfactory solution, but if it
happens to be the only way one can solve above problem it should
probably be part of the library.
So is there a better way / thoughts / suggestions? Note that at
the moment I can not even do this as windowGetId can not be
called on values of type CWXCHtmlWindow.
Cheers,
Bene
PS @Daan: Together with a colleaque of mine I recently found a small bug in
wxHaskell but not having had any response from you I assume that
mailing to you directly failed again and therefore I include it here
again:
In WX.Controls.MultiListBox:
Controls.hs 598:
-- | Abstract type of the 'MultiListBox' class.
data CMultiListBox a = CMultiListBox
instance Selections (MultiListBox a) where
selections
= newAttr "selections" listBoxGetSelectionList setter
where
setter w is
= mapM_ (\i -> listBoxSetSelection w i True) is
This code is obviously incorrect in that it only adds elements
to the selection but never removes elements of it.
this bugfix should do the trick:
-- | Abstract type of the 'MultiListBox' class.
data CMultiListBox a = CMultiListBox
instance Selections (MultiListBox a) where
selections
= newAttr "selections" listBoxGetSelectionList setter
where
setter w is
= do s <- listBoxGetSelectionList w
mapM_ (\i -> listBoxSetSelection w i False) s
mapM_ (\i -> listBoxSetSelection w i True) is
|