From: dreamer <Ben...@we...> - 2004-12-07 09:10:22
|
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 |