Tables reacting to click events on a per cell basis

I have a graph to display in a table.

Here's an example of my current solution:

import Graphics.UI.Gtk
import Control.Monad.IO.Class

main = do
  initGUI
  window <- windowNew
  view <- treeViewNew
  store <- listStoreNew initialData
  treeViewSetModel view store
  containerAdd window view
  prepareCols view store
  window `on` deleteEvent $ liftIO mainQuit >> return False
  widgetShowAll window
  mainGUI

initialData :: [[String]]
initialData = [["foo", "bar"], ["baz", "42"]]

prepareCols :: TreeView -> ListStore [String] -> IO ()
prepareCols view store = do
  size <- listStoreGetSize store
  mapM_ (addColumn view store) [0..size-1]

addColumn :: TreeView -> ListStore [String] -> Int -> IO ()
addColumn view store i = addTextColumn view store (!! i) $ show i

addTextColumn :: (TreeViewClass view
                 , TreeModelClass (model row)
                 , TypedTreeModelClass model
                 )
                => view -> model row -> (row -> String) -> String -> IO ()
addTextColumn view model f name = do
  col <- treeViewColumnNew
  rend <- cellRendererTextNew
  treeViewColumnSetTitle col name
  treeViewColumnPackStart col rend True
  cellLayoutSetAttributes col rend model (\row -> [ cellText := f row ])
  treeViewColumnSetExpand col True
  treeViewAppendColumn view col
  return ()

      

Now I would like to make each cell with the right mouse button, but gtk2hs only suggests activating the row, no information that was activated, or making the column header available.

What would be the path in gtk2hs, for a table that responds to click events with information about which row and column were clicked (for a column, a numeric index would be ideal, so I can use that index to modify the list I started with) without resorting to nasty things like using Table

and removing / adding labels to it at runtime.

Im using gtk2hs (gtk3) version 0.12.5.6

+3


source to share


1 answer


You can take the solution described in this Python answer .

A buttonPressEvent

callback can be set in your function prepareCols

that checks that the event is a right click and then decodes the coordinates of the events into a path TreeStore

:



onPathRightClick :: (TreeViewClass view) 
                 => view
                 -> (TreePath -> Int -> IO ()) 
                 -> IO (ConnectId view)
onPathRightClick view callback =
    on view buttonReleaseEvent $ (return False <*) $ runMaybeT $ do
        RightButton <- lift eventButton
        (x, y) <- lift eventCoordinates
        let x' = round x
            y' = round y
        (path, col, _cellpoint) <- MaybeT . liftIO $ treeViewGetPathAtPos view (x', y')
        colIdx <- MaybeT . liftIO $ findIndex (== col) <$> treeViewGetColumns view
        liftIO $ callback path colIdx

prepareCols :: TreeView -> ListStore [String] -> IO ()
prepareCols view store = do
    size <- listStoreGetSize store
    mapM_ (addColumn view store) [0..size-1]
    void $ onPathRightClick view $ \path col -> do
        putStrLn . unwords $ [ "Column:" , show col]
        putStrLn . unwords $ [ "Path:" , show path]

      

+1


source







All Articles