2 Nov 2010 12:10
Re: ListCtrl - Setting/Getting Associated Info?
Hi James,
On 29 October 2010 05:06, James d'Arcy <james.darcy-3zDfYNSkqkjz1n+OaKNE4w@public.gmane.org> wrote:
showStudy wgDbTable (idx,dcmStudy) = do
listCtrlInsertItemWithData wgDbTable idx $ studyUid dcmStudy
set wgDbTable [item idx := [(patientName . studyPatient) dcmStudy,
studyDescription dcmStudy,
studyDate dcmStudy]]
I suspect that the problem comes from mixing WXCore and WX functionality (highlighted in red above if you are using an HTML mailer - otherwise look at the . I doubt that it is safe to do this.
Below is an example I have tested. I've tried to make it as simple as possible, so it has a fixed list of (displayed) items, each of which has an Integer key (which is not displayed - it is stored as a data item). I'll write it up more fully in my blog (http://wewantarock.wordpress.com) shortly, but for the moment, just note that I am using the WXCore functions to insert the item data and the displayed contents.
module Main () where
import Graphics.UI.WXCore
import Graphics.UI.WX
-- Int data and strings for each column
entries
= [ (100, ["BouncingBalls.hs" ,"2402" ,"Jul 19 16:50"])
, (101, ["ByeDemo.hs" ,"1414" ,"Jul 13 23:18"])
, (102, ["Camels.hs" ,"7633" ,"Aug 20 11:57"])
, (103, ["Controls.hs" ,"3862" ,"Aug 20 11:57"])
, (104, ["HelloWorld.hs" ,"1028" ,"Aug 15 10:09"])
, (105, ["ImageViewer.hs" ,"3756" ,"Aug 20 11:57"])
, (106, ["Layout.hs" ,"1075" ,"Jul 13 23:18"])
, (107, ["ListCtrl.hs" ,"750" ,"Sep 8 16:22"])
, (108, ["Minimal.hs" ,"147" ,"Jul 13 23:18"])
, (109, ["Paint.hs" ,"1024" ,"Aug 20 11:57"])
, (110, ["Process.hs" ,"2261" ,"Aug 20 11:57"])
, (111, ["TimeFlows.hs" ,"4929" ,"Aug 20 11:57"])
, (112, ["TimeFlowsEx.hs" ,"8648" ,"Aug 20 11:57"])
, (113, ["desert.bmp" ,"61302" ,"Jul 13 23:31"])
]
main :: IO ()
main
= start gui
gui :: IO ()
gui
= do -- main gui elements: frame, panel, text control, and the notebook
f <- frame [text := "List Sample"]
-- panel: just for the nice grey color
p <- panel f []
textlog <- textCtrl p [enabled := False, wrap := WrapLine]
-- use text control as logger
textCtrlMakeLogActiveTarget textlog
logMessage "logging enabled"
-- list control
l <- listCtrl p [columns := [("Name", AlignLeft, 120)
,("Size", AlignRight, -1)
,("Date", AlignRight, -1)]]
set l [on listEvent := onListEvent l]
mapM_ (setItem l) entries
-- specify layout
set f [layout := container p $ margin 10 $
column 5 [ fill $ widget l
, hfill $ widget textlog
]
,clientSize := sz 400 300
]
return ()
where
onListEvent lc eventList
= case eventList of
ListItemSelected idx -> do
dat <-listCtrlGetItemData lc idx
logMessage ("item selected: " ++ show idx ++ " Data: " ++ show dat)
ListItemDeselected idx -> logMessage ("item de-selected: " ++ show idx)
other -> logMessage ("list control event.")
setItem lc (key_val, col_txts) =
do
count <- listCtrlGetItemCount lc
idx <- listCtrlInsertItemWithLabel lc count (show count) (-1)
mapM_ (\(column, col_txt) -> listCtrlSetItem lc idx column col_txt (-1)) (zip [0..] col_txts)
listCtrlSetItemData lc idx key_val
Hopefully the example shows how to do what you want...
Conceptually what I want to do is create items in the ListCtrl and associate a
unique identifier with each item. This identifier would not be displayed in the
UI. An Int64 would be ideal but a String would be fine. When a user clicks on
the item, I want to be able to retrieve this identifier and use it to find the
associated data, in this case a database record.
The items are inserted into the ListCtrl ok with the following code:
showStudy :: ListCtrl l -> (Int,DicomStudy) -> IO ()
showStudy wgDbTable (idx,dcmStudy) = do
listCtrlInsertItemWithData wgDbTable idx $ studyUid dcmStudy
set wgDbTable [item idx := [(patientName . studyPatient) dcmStudy,
studyDescription dcmStudy,
studyDate dcmStudy]]
and the event handler looks like this:
onDbTableEvent :: HasturContext -> EventList -> IO ()
onDbTableEvent HasturCtx {guiDbTable=wgDbTable, guiSeriesList=wgSeriesList} event =
case event of
ListItemSelected idx -> do
studyUid <- listCtrlGetItemData wgSeriesList idx
infoM "Hastur" $ "DB Table event: " ++ show studyUid
propagateEvent
otherwise ->
propagateEvent
When the user clicks on the ListCtrl item I get an error dialog pop up saying:
"Couldn't retrieve information about list control item X"
where X is idx. The infoM call produces:
"DB Table event: 0"
What am I missing? I've tried listCtrl{Get/Set}Data, listCtrl{Get/Set}Text all
with the same result. listCtrlDeleteItem in the event handler doesn't delete the
item but produces the result: False.
showStudy wgDbTable (idx,dcmStudy) = do
listCtrlInsertItemWithData wgDbTable idx $ studyUid dcmStudy
set wgDbTable [item idx := [(patientName . studyPatient) dcmStudy,
studyDescription dcmStudy,
studyDate dcmStudy]]
I suspect that the problem comes from mixing WXCore and WX functionality (highlighted in red above if you are using an HTML mailer - otherwise look at the . I doubt that it is safe to do this.
Below is an example I have tested. I've tried to make it as simple as possible, so it has a fixed list of (displayed) items, each of which has an Integer key (which is not displayed - it is stored as a data item). I'll write it up more fully in my blog (http://wewantarock.wordpress.com) shortly, but for the moment, just note that I am using the WXCore functions to insert the item data and the displayed contents.
module Main () where
import Graphics.UI.WXCore
import Graphics.UI.WX
-- Int data and strings for each column
entries
= [ (100, ["BouncingBalls.hs" ,"2402" ,"Jul 19 16:50"])
, (101, ["ByeDemo.hs" ,"1414" ,"Jul 13 23:18"])
, (102, ["Camels.hs" ,"7633" ,"Aug 20 11:57"])
, (103, ["Controls.hs" ,"3862" ,"Aug 20 11:57"])
, (104, ["HelloWorld.hs" ,"1028" ,"Aug 15 10:09"])
, (105, ["ImageViewer.hs" ,"3756" ,"Aug 20 11:57"])
, (106, ["Layout.hs" ,"1075" ,"Jul 13 23:18"])
, (107, ["ListCtrl.hs" ,"750" ,"Sep 8 16:22"])
, (108, ["Minimal.hs" ,"147" ,"Jul 13 23:18"])
, (109, ["Paint.hs" ,"1024" ,"Aug 20 11:57"])
, (110, ["Process.hs" ,"2261" ,"Aug 20 11:57"])
, (111, ["TimeFlows.hs" ,"4929" ,"Aug 20 11:57"])
, (112, ["TimeFlowsEx.hs" ,"8648" ,"Aug 20 11:57"])
, (113, ["desert.bmp" ,"61302" ,"Jul 13 23:31"])
]
main :: IO ()
main
= start gui
gui :: IO ()
gui
= do -- main gui elements: frame, panel, text control, and the notebook
f <- frame [text := "List Sample"]
-- panel: just for the nice grey color
p <- panel f []
textlog <- textCtrl p [enabled := False, wrap := WrapLine]
-- use text control as logger
textCtrlMakeLogActiveTarget textlog
logMessage "logging enabled"
-- list control
l <- listCtrl p [columns := [("Name", AlignLeft, 120)
,("Size", AlignRight, -1)
,("Date", AlignRight, -1)]]
set l [on listEvent := onListEvent l]
mapM_ (setItem l) entries
-- specify layout
set f [layout := container p $ margin 10 $
column 5 [ fill $ widget l
, hfill $ widget textlog
]
,clientSize := sz 400 300
]
return ()
where
onListEvent lc eventList
= case eventList of
ListItemSelected idx -> do
dat <-listCtrlGetItemData lc idx
logMessage ("item selected: " ++ show idx ++ " Data: " ++ show dat)
ListItemDeselected idx -> logMessage ("item de-selected: " ++ show idx)
other -> logMessage ("list control event.")
setItem lc (key_val, col_txts) =
do
count <- listCtrlGetItemCount lc
idx <- listCtrlInsertItemWithLabel lc count (show count) (-1)
mapM_ (\(column, col_txt) -> listCtrlSetItem lc idx column col_txt (-1)) (zip [0..] col_txts)
listCtrlSetItemData lc idx key_val
Is what I am trying to achieve possible or would I be better maintaining a
Data.Map with a mapping between idx and the relevant data? If so, how would that
affect things if the ListCtrl contents are re-ordered (e.g. sort by date)?
Hopefully the example shows how to do what you want...
Sorry if this seems a stupid query, I'm new to Haskell and trying to learn after
years of using imperative languages.
It's an entirely sensible question if you ask me, but then I'm also a recovering imperative programmer

Regards
Jeremy
------------------------------------------------------------------------------ Nokia and AT&T present the 2010 Calling All Innovators-North America contest Create new apps & games for the Nokia N8 for consumers in U.S. and Canada $10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store http://p.sf.net/sfu/nokia-dev2dev
------------------------------------------------------------------------------ Nokia and AT&T present the 2010 Calling All Innovators-North America contest Create new apps & games for the Nokia N8 for consumers in U.S. and Canada $10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store http://p.sf.net/sfu/nokia-dev2dev
RSS Feed