packages feed

xtc (empty) → 1.0

raw patch · 5 files changed

+565/−0 lines, 5 filesdep +basedep +wxdep +wxcoresetup-changed

Dependencies added: base, wx, wxcore

Files

+ Graphics/UI/XTC.hs view
@@ -0,0 +1,438 @@+--------------------------------------------------------------------------------+{-| +    Module      :  XTC+    Copyright   :  (c) Martijn Schrage 2005++    Maintainer  :  martijn@cs.uu.nl+    Stability   :  experimental+    Portability :  portable+++    XTC: eXtended & Typed Controls for wxHaskell+    +    The XTC library provides a typed interface to several wxHaskell controls.++      - radio view (typed radio box)++      - single-selection list view (typed single-selection list box)++      - muliple-selection list view (typed multiple-selection list box)++      - choice view (typed choice box)++      - value entry (typed text entry)++    XTC controls keep track of typed values and items, rather than+    being string based. Selections in XTC controls consist of actual values+    instead of indices.+-}+--------------------------------------------------------------------------------+module Graphics.UI.XTC (+              -- * Classes+             Labeled( toLabel )+           , TypedValued( typedValue )+           , TypedItems( typedItems )+           , TypedSelection( typedSelection )+           , TypedMaybeSelection( typedMaybeSelection )+           , TypedSelections( typedSelections )+           , Observable( change )+             -- * Controls+             -- ** Radio view+           , RadioView, mkRadioView, mkRadioViewEx+             -- ** Single-selection list view+           , ListView, mkListView, mkListViewEx+             -- ** Multiple-selection list view+           , MultiListView, mkMultiListView, mkMultiListViewEx+             -- ** Choice view+           , ChoiceView, mkChoiceView, mkChoiceViewEx+             -- ** Value entry+           , ValueEntry, mkValueEntry, mkValueEntryEx+           ) where++import Graphics.UI.WX hiding (window, label)+import Graphics.UI.WXCore hiding (label, Event)+import Data.List+import Data.Maybe++-- | The labeled class is used by 'mkRadioView', 'mkListView', 'mkMultiListView', and+--   'mkChoiceView' for conveniently passing the function that maps an item onto its label.+class Labeled x where+  toLabel :: x -> String++instance Labeled String where+  toLabel str = str++-- | Widgets that have a typed selection. The selection can be accessed via the attribute 'typedSelection', and has type @x@.+class Selection w => TypedSelection x w | w -> x where+  typedSelection :: Attr w x++-- | Widgets that have a typed selection that may be empty. The selection can be accessed via the attribute 'typedMaybeSelection', and has type @Maybe x@.+class Selection w => TypedMaybeSelection x w | w -> x where+  typedMaybeSelection :: Attr w (Maybe x)++-- | Widgets that have a typed list of selections. The selection list can be accessed via the attribute 'typedSelections', and has type @[x]@.+class Selections w => TypedSelections x w | w -> x where+  typedSelections :: Attr w [x]++-- | Widgets that have a typed list of items. The item list can be accessed via the attribute 'typedItems', and has type @[x]@.+class Items w String => TypedItems x w | w -> x where+  typedItems :: Attr w [x]++-- | Widgets that have a typed value. The value can be accessed via the attribute 'typedValue', and has type @x@.+class TypedValued  x w | w -> x where+  typedValue :: Attr w (Maybe x)+++{--------------------------------------------------------------------------------+  Radio view+--------------------------------------------------------------------------------}++data CRadioView x b++-- | Pointer to a radio view, deriving from 'RadioBox'.+type RadioView x b = RadioBox (CRadioView x b)++instance TypedSelection x (RadioView x ()) where+  typedSelection+    = newAttr "typedSelection" radioViewGetTypedSelection radioViewSetTypedSelection++instance TypedItems x (RadioView x ()) where+  typedItems = newAttr "typedItems" viewGetTypedItems viewSetTypedItems++-- | Create a new radio view with an initial orientation and a list of+-- typed items. The item type (@x@) must be an instance of 'Labeled' to show each item's+-- label. Use attribute 'typedSelection' to access the currently selected item, and 'typedItems' to access the list of items. Note:+-- for a radio view (or radio box) the items may not be modified dynamically.+--+-- * Instances: 'TypedSelection', 'TypedItems', 'Selecting','Selection','Items' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkRadioView :: Labeled x => Window a -> Orientation -> [x] -> [Prop (RadioView x ())] -> IO (RadioView x ())+mkRadioView window orientation viewItems props =+  mkRadioViewEx window toLabel orientation viewItems props++-- | Create a new radio view with an initial orientation and a list of+-- typed items. A function of type @(x -> String)@ maps items onto labels. +-- Use attribute 'typedSelection' to access the currently selected item, and 'typedItems' to access the list of items. Note:+-- for a radio view (or radio box) the items may not be modified dynamically.+--+-- * Instances: 'TypedSelection', 'Selecting','Selection','Items' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkRadioViewEx :: Window a -> (x -> String) -> Orientation -> [x] -> [Prop (RadioView x ())] -> IO (RadioView x ())+mkRadioViewEx window present orientation viewItems props =+ do { model <- varCreate viewItems+    ; radioView <- fmap objectCast $ radioBox window orientation (map present viewItems) []+    ; objectSetClientData radioView (return ()) (model, present)+    ; set radioView props+    ; return radioView+    } -- cannot use mkViewEx because items must be set at creation (items is not writeable)+++radioViewSetTypedSelection :: RadioView x () -> x -> IO ()+radioViewSetTypedSelection radioView x = viewSetTypedMaybeSelection radioView (Just x)++radioViewGetTypedSelection :: RadioView x () -> IO x+radioViewGetTypedSelection radioView = + do { mSel <- viewGetTypedMaybeSelection radioView+    ; case mSel of+        Just item -> return item+        Nothing   -> internalError "XTC" "radioViewGetTypedSelection" "Radio view has empty selection"+    }+     +{--------------------------------------------------------------------------------+  Single-selection list view+--------------------------------------------------------------------------------}++data CListView a b++-- | Pointer to a single-selection list view, deriving from 'SingleListBox'.+type ListView a b = SingleListBox (CListView a b)++instance TypedMaybeSelection x (ListView x ()) where+  typedMaybeSelection = newAttr "typedMaybeSelection" viewGetTypedMaybeSelection viewSetTypedMaybeSelection++instance TypedItems x (ListView x ()) where+  typedItems = newAttr "typedItems" viewGetTypedItems viewSetTypedItems++-- | Create a single-selection list view. The item type (@x@) must be an instance of 'Labeled' to show each item's+-- label. Use attribute 'typedMaybeSelection' to access the currently selected item, and 'typedItems' to access the list of items.+--+-- * Instances: 'TypedMaybeSelection', 'TypedItems', 'Sorted','Selecting','Selection','Items' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkListView :: Labeled x => Window a -> [Prop (ListView x ())] -> IO (ListView x ())+mkListView window props = mkListViewEx window toLabel props++-- | Create a single-selection list view. A function of type @(x -> String)@ maps items onto labels. +-- Use attribute 'typedMaybeSelection' to access the currently selected item, and 'typedItems' to access the list of items.+--+-- * Instances: 'TypedMaybeSelection', 'TypedItems', 'Sorted','Selecting','Selection','Items' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkListViewEx :: Window a -> (x -> String) -> [Prop (ListView x ())] -> IO (ListView x ())+mkListViewEx window present props = mkViewEx singleListBox window present props+++{--------------------------------------------------------------------------------+  Multiple-selection list view+--------------------------------------------------------------------------------}++data CMultiListView a b++-- | Pointer to a multiple-selection list view, deriving from 'MultiListBox'.+type MultiListView a b = MultiListBox (CMultiListView a b)++instance TypedSelections x (MultiListView x ()) where+  typedSelections = newAttr "typedSelections" multiListViewGetTypedSelections multiListViewSetTypedSelections++instance TypedItems x (MultiListView x ()) where+  typedItems = newAttr "typedItems" viewGetTypedItems viewSetTypedItems++-- | Create a multiple-selection list view. The item type (@x@) must be an instance of 'Labeled' to show each item's+-- label.+-- Use attribute 'typedSelections' to access the currently selected items, and 'typedItems' to access the list of items.+--+-- * Instances: 'TypedSelections', 'TypedItems', 'Sorted', 'Selecting','Selections','Items' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkMultiListView :: Labeled x => Window a -> [Prop (MultiListView x ())] -> IO (MultiListView x ())+mkMultiListView window props = mkMultiListViewEx window toLabel props++-- | Create a multiple-selection list view. A function of type @(x -> String)@ maps items onto labels. +-- Use attribute 'typedSelections' to access the currently selected items, and 'typedItems' to access the list of items.+--+-- * Instances: 'TypedSelections', 'TypedItems', 'Sorted', 'Selecting','Selections','Items' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkMultiListViewEx :: Window a -> (x -> String) -> [Prop (MultiListView x ())] -> IO (MultiListView x ())+mkMultiListViewEx window present props = mkViewEx multiListBox window present props++multiListViewSetTypedSelections :: MultiListView x () -> [x] -> IO ()+multiListViewSetTypedSelections (multiListView :: MultiListView x ()) selectionItems =+ do { Just ((model, present) :: (Var [x], x -> String)) <-+        unsafeObjectGetClientData multiListView+    ; viewItems <- get model value+    ; let labels = map present selectionItems+    ; let indices = catMaybes [ findIndex (\it -> present it == label) viewItems+                              | label <- labels ]+    ; set multiListView [ selections := indices ]+    }++multiListViewGetTypedSelections :: forall x . MultiListView x () -> IO [x]+multiListViewGetTypedSelections multiListView =+ do { Just ((model, _) :: (Var [x], x -> String)) <-+        unsafeObjectGetClientData multiListView+    ; selectedIndices <- get multiListView selections+    ; viewItems <- get model value+    ; return (map (safeIndex "XTC.multiListViewGetTypedSelections" viewItems)+                    selectedIndices)+    }+++{--------------------------------------------------------------------------------+  Choice view+--------------------------------------------------------------------------------}++data CChoiceView a b++-- | Pointer to a choice view, deriving from 'Choice'.+type ChoiceView a b = Choice (CChoiceView a b)++instance TypedMaybeSelection x (ChoiceView x ()) where+  typedMaybeSelection = newAttr "typedMaybeSelection" viewGetTypedMaybeSelection viewSetTypedMaybeSelection++instance TypedItems x (ChoiceView x ()) where+  typedItems = newAttr "typedItems" viewGetTypedItems viewSetTypedItems++-- | Create a choice view to select one item from a list of typed items. The item type (@x@) must be an instance of 'Labeled' to show each item's+-- label.+-- Use attribute 'typedMaybeSelection' to access the currently selected item, and 'typedItems' to access the list of items.+--+-- * Instances: 'TypedMaybeSelection', 'TypedItems', 'Sorted', 'Selecting','Selection','Items' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkChoiceView :: Labeled x => Window a -> [Prop (ChoiceView x ())] -> IO (ChoiceView x ())+mkChoiceView window (props :: [Prop (ChoiceView x ())]) =+  mkViewEx choice window (toLabel :: x -> String) props++-- | Create a choice view to select one item from a list of typed items. A function of type @(x -> String)@ maps items onto labels. +-- Use attribute 'typedMaybeSelection' to access the currently selected item, and 'typedItems' to access the list of items.+--+-- * Instances: 'TypedMaybeSelection', 'TypedItems', 'Sorted', 'Selecting','Selection','Items' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkChoiceViewEx :: Window a -> (x -> String) -> Style -> [Prop (ChoiceView x ())] -> IO (ChoiceView x ())+mkChoiceViewEx window present stl props =+  mkViewEx (\win -> choiceEx win stl) window present props+++-- Generic constructors, getters, and setters++-- Generic mk function that puts a model and a present function in the client data.+-- Used for ListView, MultiListView, and ChoiceView.+mkViewEx :: (parent -> [p] -> IO (Object a)) -> parent -> (x -> String) -> [Prop (WxObject b)] ->+            IO (WxObject b)+mkViewEx mkView window present props =+ do { model <- varCreate []+    ; view <- fmap objectCast $ mkView window []+    ; objectSetClientData view (return ()) (model, present)+    ; set view props+    ; return view+    }++-- Generic getTypedMaybeSelection for RadioView, ListView, and ChoiceView.+viewGetTypedMaybeSelection :: forall x a . Selection (WxObject a) => WxObject a -> IO (Maybe x)+viewGetTypedMaybeSelection view =+ do { Just ((model, _) :: (Var [x], x -> String)) <-+        unsafeObjectGetClientData view+    ; selectedIndex <- get view selection+    ; if selectedIndex == -1+      then return Nothing+      else do { viewItems <- get model value+              ; return $ Just (safeIndex "XTC.viewGetTypedMaybeSelection" viewItems selectedIndex)+              }+    }++-- Generic setTypedMaybeSelection for RadioView, ListView, and ChoiceView.+viewSetTypedMaybeSelection :: forall x a . Selection (WxObject a) => WxObject a -> Maybe x -> IO ()+viewSetTypedMaybeSelection view mSelectionItem =+ do { Just ((model, present) :: (Var [x], x -> String)) <-+        unsafeObjectGetClientData view+    ; viewItems <- get model value+    ; let index = case mSelectionItem of+                    Nothing            -> -1+                    Just selectionItem -> let label = present selectionItem+                                          in  findLabelIndex present label viewItems+    ; set view [ selection := index ]+    }+ where findLabelIndex :: (x -> String) -> String -> [x] -> Int+       findLabelIndex present label theItems =+         case findIndex (\it -> present it == label) theItems of+           Just ix -> ix+           Nothing -> -1+           +-- Generic getTypedItems for ListView, MultiListView, and ChoiceView.+viewGetTypedItems :: forall x a . TypedItems x (WxObject a) => WxObject a -> IO [x]+viewGetTypedItems view =+ do { Just ((model, _) :: (Var [x], x -> String)) <-+        unsafeObjectGetClientData view+    ; viewItems <- get model value+    ; return viewItems+    }++-- Generic setTypedItems for ListView, MultiListView, and ChoiceView.+viewSetTypedItems :: forall x a . TypedItems x (WxObject a) => WxObject a -> [x] -> IO ()+viewSetTypedItems view viewItems =+ do { Just ((model, present) :: (Var [x], x -> String)) <-+        unsafeObjectGetClientData view+    ; set model [ value := viewItems ]+    ; set view [ items := map present viewItems ]+    }+++{--------------------------------------------------------------------------------+  Value entry+--------------------------------------------------------------------------------}++data CValueEntry x b++-- | Pointer to a choice view, deriving from 'TextCtrl'.+type ValueEntry x b = TextCtrl (CValueEntry x b)++instance TypedValued x (ValueEntry x ()) where+  typedValue+    = newAttr "typedValue" valueEntryGetTypedValue valueEntrySetTypedValue++-- | Create a single-line value entry control. The value type (@x@) must be an instance of 'Show' and 'Read'+-- to present a value as a string in the entry and parse the string from the entry back to (maybe) a value.+-- Use 'typedValue' to access the value.+-- Note: 'alignment' has to+-- be set at creation time (or the entry has default alignment (=left) ).+--+-- * Instances: 'TypedValued', 'Wrap', 'Aligned', 'Commanding' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkValueEntry :: (Show x, Read x) => Window b -> [ Prop (ValueEntry x ()) ] -> IO (ValueEntry x ())+mkValueEntry window props = mkValueEntryEx window show readParse props++-- | Create a single-line value entry control. The two functions of type @(x -> String)@ and @(String -> Maybe x)@ are used+-- to present a value as a string in the entry and parse the string from the entry back to (maybe) a value.+-- Use 'typedValue' to access the value.+-- Note: 'alignment' has to+-- be set at creation time (or the entry has default alignment (=left) ).+--+-- * Instances: 'TypedValued', 'Wrap', 'Aligned', 'Commanding' -- 'Textual', 'Literate', 'Dimensions', 'Colored', 'Visible', 'Child',+--             'Able', 'Tipped', 'Identity', 'Styled', 'Reactive', 'Paint'.+--+mkValueEntryEx :: Window b -> (x -> String) -> (String -> Maybe x) -> [ Prop (ValueEntry x ()) ] -> IO (ValueEntry x ())+mkValueEntryEx window present parse props =+ do { valueEntry <- fmap objectCast $ textEntry window []+    ; objectSetClientData valueEntry (return ()) (present, parse)+    ; set valueEntry $ props ++ [ on change :~ \handler -> do {validate valueEntry; handler} ]+    ; validate valueEntry+    ; return valueEntry+    }+ where validate :: ValueEntry x () -> IO ()+       validate valueEntry =+        do { mVal <- get valueEntry typedValue+           ; set valueEntry [ bgcolor := case mVal of+                                           Nothing -> rgb 255 100 100+                                           _       -> white+                            ]+           ; repaint valueEntry+           } -- drawing a squiggly is not possible because font metrics are not available++valueEntryGetTypedValue :: forall x . ValueEntry x () -> IO (Maybe x)+valueEntryGetTypedValue valueEntry =+ do { Just ((_, parse) :: (x -> String, String -> Maybe x)) <- unsafeObjectGetClientData valueEntry+    ; valueStr <- get valueEntry text+    ; return $ parse valueStr+    }++valueEntrySetTypedValue :: forall x . ValueEntry x () -> Maybe x -> IO ()+valueEntrySetTypedValue valueEntry mValue =+ do { Just ((present, _) :: (x -> String, String -> Maybe x)) <- unsafeObjectGetClientData valueEntry+    ; case mValue of+        Nothing    -> return ()+        Just theValue -> set valueEntry [ text := present theValue ]+    }+++-- Utility functions++-- A variation of 'read' that returns Nothing if the string cannot be parsed.+readParse :: Read x => String -> Maybe x+readParse str = case reads str of+                  [(x, "")] -> Just x+                  _         -> Nothing++safeIndex :: String -> [a] -> Int -> a+safeIndex msg xs i+    | i >= 0 && i < length xs = xs !! i+    | otherwise = internalError "XTC" "safeIndex" msg++internalError :: String -> String -> String -> a+internalError moduleName functionName errorString =+    error (moduleName ++ "." ++ functionName ++ ": " ++ errorString)+++-- Some bits that should be part of wxHaskell++instance Selecting (ChoiceView x ()) where+  select = newEvent "select" choiceGetOnCommand choiceOnCommand+-- Necessary because wxHaskell declares "instance Selecting (Choice ())" instead of+-- "Selecting (Choice a)".++instance Selection (ChoiceView x ()) where+  selection = newAttr "selection" choiceGetSelection choiceSetSelection+-- Necessary because wxHaskell declares "instance Selection (Choice ())" instead of+-- "Selection (Choice a)".+++-- The Observable class is missing from wxHaskell, even though the components are there.+class Observable w where+  change :: Event w (IO ())++instance Observable (TextCtrl a) where+  change = newEvent "change" (controlGetOnText) (controlOnText)
+ LICENSE view
@@ -0,0 +1,27 @@+Copyright (c) 2008, Martijn Shrage ++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright notice,+      this list of conditions and the following disclaimer.+    * Redistributions in binary form must reproduce the above copyright notice,+      this list of conditions and the following disclaimer in the documentation+      and/or other materials provided with the distribution.+    * Neither the name of the Maybench developers nor the names of its+      contributors may be used to endorse or promote products derived from this+      software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.lhs view
@@ -0,0 +1,3 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> main = defaultMain
+ xtc-example.hs view
@@ -0,0 +1,63 @@+import Graphics.UI.WX+import Graphics.UI.XTC++main :: IO ()+main = start $+ do {+    ; f <- frame []+    ; counterV <- mkValueEntry f [ typedValue := Just 1 ]++    ; listV <- mkListView f [ typedItems := ["abc", "def"]+                            , enabled := True+                            ]++    ; radioV <- mkRadioView f Vertical [ "Een", "Twee" ] []+    ; choiceV <- mkChoiceView f [ typedItems := ["un", "deux"]+                               , enabled := True+                               ]+--    ; comboV <- mkComboView f [ typedItems := ["sdfsdf", "fdssd"]+--                              , enabled := True+--                              ]+    ; t  <- textCtrl f []+    ; ve <- mkValueEntry f [ typedValue := Just True ]+--    ; set t [ on (change counterV) := \i -> set t [ text := show i ] ]++    ; bUp   <- button f [ text := "increase"+                        , on command := set counterV [ typedValue :~ fmap (+1) ] ]+    ; bDown <- button f [ text := "decrease"+                        , on command := set counterV [ typedValue :~ fmap (+ (-1::Int)) ]]++    ; let refreshT =+           do { -- s1 <- get comboV typedSelection+              ; s1 <- get radioV typedSelection+              ; s2 <- get listV typedMaybeSelection+              ; s3 <- get counterV typedValue+              ; s4 <- get choiceV typedMaybeSelection+              ; set t [ text := unlines [ "radio: " ++ s1+                      , "list:  " ++ show s2+                      , "counter: " ++ show s3+                      , "choice: " ++ show s4 ] ]+              }++    ; set bUp     [ on command :~ (>> refreshT) ]+    ; set bDown   [ on command :~ (>> refreshT) ]+    ; set listV   [ on select  :~ (>> refreshT) ]+    ; set radioV  [ on select  :~ (>> refreshT) ]+    ; set choiceV [ on select  :~ (>> refreshT) ]++--    ; bChangeHandler <- button f [ text := "change handler"+--                                 , on command := set t [ on (change counterV) := \i -> set t [text := "<<"++show i++">>"] ]]+    ; set f [ layout := column 5 [ row 5 [ Graphics.UI.WX.label "Counter value:", widget counterV ]+                                 , hfloatCenter $ row 5 [ widget bUp, widget bDown ]+                                 --, hfloatCenter $ widget bChangeHandler+                                 , widget listV+                                 , widget radioV+                                 , widget choiceV+--                                 , widget comboV+                                 , widget ve+                                 , glue+                                 , hfill $ widget t+                                 ]+                                 ]++    }
+ xtc.cabal view
@@ -0,0 +1,34 @@+name:                xtc+version:             1.0+synopsis:            eXtended & Typed Controls for wxHaskell.+description:         The XTC library provides a typed interface to several wxHaskell controls.+                     .+                     * radio view (typed radio box)+                     .+                     * single-selection list view (typed single-selection list box)+                     .+                     * muliple-selection list view (typed multiple-selection list box)+                     .+                     * choice view (typed choice box)+                     .+                     * value entry (typed text entry)+                     .+                     XTC controls keep track of typed values and items, rather than being string based. Selections in XTC controls consist of actual values instead of indices.  +category:            GUI, User Interfaces+license:             BSD3+license-file:        LICENSE+author:              Martijn Schrage+maintainer:          martijn@cs.uu.nl+build-Depends:       base, wx, wxcore+build-type:          Simple+exposed-modules:     Graphics.UI.XTC+extensions:          EmptyDataDecls+                     FunctionalDependencies+                     FlexibleContexts+                     FlexibleInstances+                     MultiParamTypeClasses+                     PatternSignatures+                     ScopedTypeVariables+                     TypeSynonymInstances+ghc-options:+data-files:          xtc-example.hs