Search code examples
haskellgtkgtk2hs

Custom implementation for Widget class in gtkhs


Gtk2hs has various widget datatypes that implements Widget class. Is it possible to write custom datatype which does the same?

Say I want to have widget for displaying and running Lua code like this.

data LuaWidget = LuaWidget { text :: TextView, package :: HBox } deriving Eq
instance Widget LuaWidget where
    ....

Is it possible on Haskell level?


Solution

  • It is not possible to create new widget 'classes' with Haskell in gtk.

    What you can do is give custom attributes to an existing widget type. For example, in the package plot-gtk a custom data field (System.Glib.GObject) is added to a drawingArea widget:

    import System.Glib.GObject
    import Graphics.UI.Gtk
    
    -- | create a new 'Figure' plot
    plotNew :: FigureHandle -> IO DrawingArea
    plotNew f = do
       canvas <- drawingAreaNew
    
       set canvas [maybeFigure := (Just f)]
    
       _ <- on canvas exposeEvent $ tryEvent $ liftIO $ do 
               s <- widgetGetSize canvas
               drw <- widgetGetDrawWindow canvas
               fig <- get canvas figure 
               renderWithDrawable drw (renderFigureState fig s)
    
       return canvas
    
    -- | the figure attribute
    figure :: Attr DrawingArea FigureState
    figure = newAttr getFigure setFigure
       where getFigure o = do
                  Just f <- get o maybeFigure 
                  readMVar f 
             setFigure o f = set o [maybeFigure :~> (\(Just h) -> do
                  modifyMVar_ h (\_ -> return f)
                  return $ Just h)]
    
    maybeFigure :: Attr DrawingArea (Maybe FigureHandle)
    maybeFigure = unsafePerformIO $ objectCreateAttribute
    {-# NOINLINE maybeFigure #-}