diff options
author | Will Thompson <will@willthompson.co.uk> | 2019-01-11 09:08:43 +0000 |
---|---|---|
committer | Will Thompson <will@willthompson.co.uk> | 2019-03-07 09:57:40 +0000 |
commit | 8be3319692ca7aa540a0427aad9d51f6e7f47cde (patch) | |
tree | 1f48dffd9fc0c5ad5c6f5768c2c7ce10e5ee5bb7 | |
parent | 91d6bbd8a45726c775dc41f345ab57da6794f815 (diff) |
FilterDialog: update Reset button state more efficiently
A step towards updating the diagram immediately, too.
-rw-r--r-- | Bustle/Types.hs | 22 | ||||
-rw-r--r-- | Bustle/UI/FilterDialog.hs | 52 |
2 files changed, 50 insertions, 24 deletions
diff --git a/Bustle/Types.hs b/Bustle/Types.hs index 63d1b16..78306c4 100644 --- a/Bustle/Types.hs +++ b/Bustle/Types.hs @@ -40,6 +40,9 @@ module Bustle.Types , NameFilter(..) , emptyNameFilter + , nameFilterAddOnly + , nameFilterAddNever + , nameFilterRemove , dbusName , dbusInterface @@ -104,10 +107,29 @@ data NameFilter = NameFilter { nfOnly :: Set UniqueName , nfNever :: Set UniqueName } + deriving + (Show, Eq, Ord) emptyNameFilter :: NameFilter emptyNameFilter = NameFilter Set.empty Set.empty +nameFilterModify :: (Set UniqueName -> Set UniqueName) + -> (Set UniqueName -> Set UniqueName) + -> NameFilter + -> NameFilter +nameFilterModify updateOnly updateNever nf = + nf { nfOnly = updateOnly $ nfOnly nf + , nfNever = updateNever $ nfNever nf + } + +nameFilterAddOnly, nameFilterAddNever, nameFilterRemove + :: UniqueName + -> NameFilter + -> NameFilter +nameFilterAddOnly u = nameFilterModify (Set.insert u) (Set.delete u) +nameFilterAddNever u = nameFilterModify (Set.delete u) (Set.insert u) +nameFilterRemove u = nameFilterModify (Set.delete u) (Set.delete u) + -- These useful constants disappeared from dbus in the grand removing of the -- -core suffix. dbusName :: BusName diff --git a/Bustle/UI/FilterDialog.hs b/Bustle/UI/FilterDialog.hs index ac16be7..873448f 100644 --- a/Bustle/UI/FilterDialog.hs +++ b/Bustle/UI/FilterDialog.hs @@ -23,11 +23,12 @@ module Bustle.UI.FilterDialog ) where -import Control.Monad (forM, forM_) +import Control.Monad (forM_) import Data.List (intercalate, groupBy, elemIndices, elemIndex) import qualified Data.Set as Set import Data.Set (Set) import qualified Data.Function as F +import Data.IORef import Graphics.UI.Gtk import Graphics.UI.Gtk.ModelView.CellRendererCombo (cellComboTextModel) @@ -172,33 +173,36 @@ runFilterDialog parent names currentFilter = do resetButton <- builderGetObject builder castToButton ("resetButton" :: String) resetButton `on` buttonActivated $ do n <- listStoreGetSize nameStore - forM_ [0..n-1] $ \i -> - nameStoreUpdate nameStore i $ \ne -> ne { neVisibility = NameVisibilityDefault } - - -- TODO: live-update the filter, and hence the view...? This callback is - -- grossly inefficient because in the rowChanged case we know what changed; - -- and in the initial case we can just look at currentFilter + forM_ [0..n-1] $ \i -> do + ne <- listStoreGetValue nameStore i + case neVisibility ne of + NameVisibilityDefault -> return () + _ -> listStoreSetValue nameStore i $ + ne { neVisibility = NameVisibilityDefault } + + -- TODO: expose this ref to the caller, with change notification, so the + -- diagram can update instantly + filterRef <- newIORef currentFilter let updateResetSensitivity = do - n <- listStoreGetSize nameStore - nes <- forM [0..n-1] $ listStoreGetValue nameStore - let vs = map neVisibility nes - widgetSetSensitive resetButton $ any (/= NameVisibilityDefault) vs + nf <- readIORef filterRef + let isEmpty = Set.null (nfOnly nf) && Set.null (nfNever nf) + widgetSetSensitive resetButton $ not isEmpty + updateResetSensitivity - nameStore `on` rowChanged $ \_path _iter -> updateResetSensitivity + nameStore `on` rowChanged $ \[i] _iter -> do + ne <- listStoreGetValue nameStore i + let u = neUniqueName ne + -- Should we smush this into nameFilterModify, move the enum into + -- Bustle.Types? + let f = case neVisibility ne of + NameVisibilityDefault -> nameFilterRemove + NameVisibilityOnly -> nameFilterAddOnly + NameVisibilityNever -> nameFilterAddNever + modifyIORef' filterRef $ f u + updateResetSensitivity _ <- dialogRun d widgetDestroy d - results <- listStoreToList nameStore - let onlys = Set.fromList [ neUniqueName ne - | ne <- results - , neVisibility ne == NameVisibilityOnly - ] - nevers = Set.fromList [ neUniqueName ne - | ne <- results - , neVisibility ne == NameVisibilityNever - ] - return $ NameFilter { nfOnly = onlys - , nfNever = nevers - } + readIORef filterRef |