Commit 5562643d authored by Bas Lijnse's avatar Bas Lijnse

Implemented proper reversal of effects when a selection no longer holds

parent ddbff293
......@@ -203,3 +203,4 @@ hideAttribute_ :: LUINo (UIAttributeKey -> Bool) UIAttributeKey (Map UIAttribute
matchAttributeKey_ :: UIAttributeSelection UIAttributeKey -> Bool
extractUIWithEffects_ :: (LUI,LUIMoves) -> Maybe UI
fullyApplied_ :: (LUI,LUIMoves) -> Bool
isPartOf_ :: LUINo LUINo -> Bool
......@@ -10,6 +10,7 @@ import StdEnum
from Data.Map as DM import qualified newMap, put, get, del, toList, fromList, delList, alter, union, keys, unions, singleton, member, null
from Data.Set as DS import qualified newSet, insert, delete, toList, fromList, null
from Data.Tuple import appSnd
from Data.Map import instance Functor (Map k)
import Text.GenJSON
......@@ -39,6 +40,7 @@ instance toString LUINo
where
toString (LUINo steps) = join "." (map toString steps)
/*
* The first thing we need for rule-based layouts is a datastructure that can keep track
* of what changes have been made by layout rules and that can 'buffer' upstream changes
......@@ -444,7 +446,6 @@ where
currentMove (LUIMoveDestination moveId _) = isMember moveId moved
currentMove _ = False
import StdDebug
layoutSubUIs :: UISelection LayoutRule -> LayoutRule
layoutSubUIs selection sub = rule
......@@ -454,14 +455,16 @@ where
//Check if the layout matches (without any dereferencing or selecting wrapped nodes)
apply path (lui,moves)
| nodeSelected_ ruleNo selection path lui moves //If the layout matches, apply the rule
= sub ruleNo (lui,moves)
= (sub ruleNo (lui,moves))
| otherwise
//We first undo effects previously applied by
# (lui,moves) = undoEffects_ ruleNo (lui,moves)
//We want to check the set of children at the time of `ruleNo`
= updateNode_ ruleNo (applyc path) (lui,moves)
applyc path (lui=:(LUINode type attr items changes effects),moves)
# (items,moves) = updateChildNodes_ ruleNo (\i (item,moves) -> apply (path ++ [i]) (item,moves)) (items,moves)
= (LUINode type attr items changes (revertEffect_ ruleNo effects),moves)
= (LUINode type attr items changes effects,moves)
sequenceLayouts :: [LayoutRule] -> LayoutRule
sequenceLayouts subs = rule
......@@ -907,18 +910,50 @@ where
Just (ESToBeRemoved _) = True
_ = False
//TODO Effects on types and attributes are not yet reverted
revertEffect_ :: LUINo LUIEffects -> LUIEffects
revertEffect_ ruleId effects=:{LUIEffects|additional,hidden,wrapper,unwrapped}
| additional === (ESApplied ruleId) = {LUIEffects|effects & additional = ESToBeRemoved ruleId}
| additional === (ESToBeApplied ruleId) = {LUIEffects|effects & additional = ESNotApplied}
| hidden === (ESApplied ruleId) = {LUIEffects|effects & hidden = ESToBeRemoved ruleId}
| hidden === (ESToBeApplied ruleId) = {LUIEffects|effects & hidden = ESNotApplied}
| wrapper === (ESApplied ruleId) = {LUIEffects|effects & wrapper = ESToBeRemoved ruleId}
| wrapper === (ESToBeApplied ruleId) = {LUIEffects|effects & wrapper = ESNotApplied}
| unwrapped === (ESApplied ruleId) = {LUIEffects|effects & unwrapped = ESToBeRemoved ruleId}
| unwrapped === (ESToBeApplied ruleId) = {LUIEffects|effects & unwrapped = ESNotApplied}
= effects
//Undo the effects of a previously applied rule for a single node
undoEffects_ :: LUINo (LUI,LUIMoves) -> (LUI,LUIMoves)
undoEffects_ ruleNo (LUINode type attr items changes effects,moves)
= (LUINode type attr items changes (undo ruleNo effects), moves)
where
undo ruleNo {overwrittenType,overwrittenAttributes,hiddenAttributes,additional,hidden,wrapper,unwrapped}
= {overwrittenType = undoEffect_ ruleNo fst overwrittenType
,overwrittenAttributes = fmap (undoEffect_ ruleNo fst) overwrittenAttributes
,hiddenAttributes = fmap (undoEffect_ ruleNo id) hiddenAttributes
,additional = undoEffect_ ruleNo id additional
,hidden = undoEffect_ ruleNo id hidden
,wrapper = undoEffect_ ruleNo id wrapper
,unwrapped = undoEffect_ ruleNo id unwrapped
}
undoEffects_ ruleNo (ref=:(LUIMoveSource moveId),moves) = case 'DM'.get moveId moves of
Nothing = (ref,moves)
Just (moveStage,lui)
# moveStage = undoEffect_ ruleNo id moveStage
# (lui,moves) = undoEffects_ ruleNo (lui,moves)
= (ref,'DM'.put moveId (moveStage,lui) moves)
undoEffects_ ruleNo (ref=:LUIMoveDestination moveId moveRule,moves) = case 'DM'.get moveId moves of
Nothing = (ref,moves)
Just (moveStage,lui)
# moveStage = undoEffect_ ruleNo id moveStage
# (lui,moves) = undoEffects_ ruleNo (lui,moves)
= (ref,'DM'.put moveId (moveStage,lui) moves)
undoEffects_ ruleNo (LUIShiftDestination shiftId,moves) = (LUIShiftDestination shiftId,moves)
undoEffect_ :: LUINo (a -> LUINo) (LUIEffectStage a) -> LUIEffectStage a
undoEffect_ ruleNo f (ESToBeApplied x) | isPartOf_ (f x) ruleNo = ESNotApplied
undoEffect_ ruleNo f (ESApplied x) | isPartOf_ (f x) ruleNo = ESToBeRemoved x
undoEffect_ ruleNo f (ESToBeUpdated c x) | isPartOf_ (f c) ruleNo = ESToBeRemoved c
undoEffect_ ruleNo f (ESToBeUpdated c x) | isPartOf_ (f x) ruleNo = ESApplied c
undoEffect_ _ _ es = es
isPartOf_ :: LUINo LUINo -> Bool
isPartOf_ (LUINo x) (LUINo y) = check x y
where
check _ [] = True
check [] _ = False
check [x:xs] [y:ys] = if (x == y) (check xs ys) False
/*
* Once layout rules have annotated their effects, the change that has to be applied downstream
......@@ -1372,3 +1407,4 @@ fullyApplied_ (LUIMoveDestination moveId _, moves)
= maybe False (\l -> fullyApplied_ (l,moves)) ('DM'.get moveId moves)
fullyApplied_ (LUIShiftDestination _, moves) = False
*/
......@@ -1223,6 +1223,14 @@ nodeExists_Tests =
'DM'.newMap
)
]
isPartOf_Tests =
[assertEqual "Is part of ruleNumbers: 1.1.3 1" True (isPartOf_ (LUINo [1,1,3]) (LUINo [1]))
,assertEqual "Is part of ruleNumbers: 1 2" False (isPartOf_ (LUINo [1]) (LUINo [2]))
,assertEqual "Is part of ruleNumbers: 1 2.4" False (isPartOf_ (LUINo [1]) (LUINo [2,4]))
,assertEqual "Is part of ruleNumbers: 3 3" True (isPartOf_ (LUINo [3]) (LUINo [3]))
]
compareLUINoTests =
[assertEqual "Comparison of ruleNumbers: 1 < 1.2" True (LUINo [1] < LUINo [1,2])
,assertEqual "Comparison of ruleNumbers: 1.2 < 3" True (LUINo [1,2] < LUINo [3])
......@@ -1528,6 +1536,23 @@ layoutSubUIsTests =
] noChanges noEffects
,initLUIMoves)
)
,assertEqual "Layout sub-uis rule: resetting when a selection no-longer holds"
(LUINode UIPanel ('DM'.fromList [("title",JSONString "A")])
[LUINode UIInteract 'DM'.newMap [] noChanges noEffects
,LUINode UIContainer 'DM'.newMap []
noChanges {noEffects & overwrittenAttributes = 'DM'.fromList [("help", ESToBeRemoved (LUINo [2,0],JSONString "Title"))]}
,LUINode UIStep 'DM'.newMap [] noChanges noEffects
] {noChanges & delAttributes = 'DS'.fromList ["title"]} noEffects
,initLUIMoves)
(layoutSubUIs (SelectByHasAttribute "title") (layoutSubUIs (SelectByPath [1]) (setUIAttributes ('DM'.fromList [("help",JSONString "Title")]))) (LUINo [2])
(LUINode UIPanel ('DM'.fromList [("title",JSONString "A")])
[LUINode UIInteract 'DM'.newMap [] noChanges noEffects
,LUINode UIContainer 'DM'.newMap [] noChanges
{noEffects & overwrittenAttributes = 'DM'.fromList [("help",ESApplied (LUINo [2,0],JSONString "Title"))]}
,LUINode UIStep 'DM'.newMap [] noChanges noEffects
] {noChanges & delAttributes = 'DS'.fromList ["title"]} noEffects
,initLUIMoves)
)
]
combinationTests =
//Applying the first change
......@@ -1619,6 +1644,7 @@ tests = applyUpstreamChangeTests
++ updateSubNode_Tests
++ scanToPosition_Tests
++ nodeExists_Tests
++ isPartOf_Tests
++ compareLUINoTests
++ setUITypeTests
++ setUIAttributesTests
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment