aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTerry Truong <terry06890@gmail.com>2022-03-28 01:15:53 +1100
committerTerry Truong <terry06890@gmail.com>2022-03-28 01:22:25 +1100
commitb82d3a24b2487454397535c6fefda250d4ff6114 (patch)
tree87d2f0e4aa7984fc57eff66fb98f4a2d6738ea05
parent567b5b605bf57f305197621d0ddc5f2b8c23ed64 (diff)
Enable auto-mode to trigger expand/collapse-fail animations
Done by sending a signal to a failed-operation's LayoutNode's Tile component via a watched property on LayoutNode. Also added code to prevent auto-mode from retrying a failed expand/collapse. Not an ideal solution, but signalling via LayoutNode is more general, and arguably cleaner, than the previous method of triggering fail animations by getting Tile to pass a callback upward as event data.
-rw-r--r--src/App.vue29
-rw-r--r--src/components/Tile.vue28
-rw-r--r--src/lib.ts4
3 files changed, 39 insertions, 22 deletions
diff --git a/src/App.vue b/src/App.vue
index 295bceb..45f7a03 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -120,6 +120,7 @@ export default defineComponent({
animationActive: false,
autoWaitTime: 500, //ms (in auto mode, time to wait after an action ends)
autoPrevAction: null as Action | null, // Used in auto-mode for reducing action cycles
+ autoPrevActionFail: false, // Used in auto-mode to avoid re-trying a failed expand/collapse
helpOpen: false,
// Options
layoutOptions: {...defaultLayoutOptions},
@@ -205,20 +206,20 @@ export default defineComponent({
}
},
// For tile expand/collapse events
- onInnerLeafClicked({layoutNode, failCallback}: {layoutNode: LayoutNode, failCallback?: () => void}){
+ onInnerLeafClicked(layoutNode: LayoutNode){
let success = tryLayout(this.activeRoot, this.layoutMap,
this.tileAreaPos, this.tileAreaDims, this.layoutOptions, false, {type: 'expand', node: layoutNode});
- if (!success && failCallback != null){
- failCallback();
+ if (!success){
+ layoutNode.expandFailFlag = !layoutNode.expandFailFlag; // Triggers failure animation
}
return success;
},
- onInnerHeaderClicked({layoutNode, failCallback}: {layoutNode: LayoutNode, failCallback?: () => void}){
+ onInnerHeaderClicked(layoutNode: LayoutNode){
let oldChildren = layoutNode.children;
let success = tryLayout(this.activeRoot, this.layoutMap,
this.tileAreaPos, this.tileAreaDims, this.layoutOptions, false, {type: 'collapse', node: layoutNode});
- if (!success && failCallback != null){
- failCallback();
+ if (!success){
+ layoutNode.collapseFailFlag = !layoutNode.collapseFailFlag; // Triggers failure animation
}
return success;
},
@@ -328,7 +329,7 @@ export default defineComponent({
return;
}
// Attempt tile-expand
- let success = this.onInnerLeafClicked({layoutNode});
+ let success = this.onInnerLeafClicked(layoutNode);
if (success){
setTimeout(() => this.expandToTolNode(tolNode), this.componentOptions.transitionDuration);
return;
@@ -393,7 +394,7 @@ export default defineComponent({
} else {
actionWeights = {
'move across': 1, 'move down': 2, 'move up': 1,
- 'collapse': 1, 'expand to view': 1, 'expand parent bar': 1
+ 'collapse': 1, 'expand to view': 0.5, 'expand parent bar': 0.5
};
// Zero weights for disallowed actions
if (node == this.activeRoot || node.parent!.children.length == 1){
@@ -417,6 +418,9 @@ export default defineComponent({
if (revAction != null && revAction in actionWeights){
actionWeights[revAction as keyof typeof actionWeights] = 0;
}
+ if (this.autoPrevActionFail){
+ actionWeights[this.autoPrevAction as keyof typeof actionWeights] = 0;
+ }
}
// Choose action
let actionList = Object.getOwnPropertyNames(actionWeights);
@@ -427,24 +431,25 @@ export default defineComponent({
action = actionList[randWeightedChoice(weightList)!] as Action;
}
// Perform action
+ this.autoPrevActionFail = false;
switch (action){
case 'move across':
let siblings = node.parent!.children.filter(n => n != node);
let siblingWeights = siblings.map(n => n.dCount + 1);
- this.setLastFocused(siblings[randWeightedChoice(siblingWeights)]);
+ this.setLastFocused(siblings[randWeightedChoice(siblingWeights)!]);
break;
case 'move down':
let childWeights = node.children.map(n => n.dCount + 1);
- this.setLastFocused(node.children[randWeightedChoice(childWeights)]);
+ this.setLastFocused(node.children[randWeightedChoice(childWeights)!]);
break;
case 'move up':
this.setLastFocused(node.parent!);
break;
case 'expand':
- this.onInnerLeafClicked({layoutNode: node});
+ this.autoPrevActionFail = !this.onInnerLeafClicked(node);
break;
case 'collapse':
- this.onInnerHeaderClicked({layoutNode: node});
+ this.autoPrevActionFail = !this.onInnerHeaderClicked(node);
break;
case 'expand to view':
this.onInnerHeaderClickHeld(node);
diff --git a/src/components/Tile.vue b/src/components/Tile.vue
index 99994d1..df124e9 100644
--- a/src/components/Tile.vue
+++ b/src/components/Tile.vue
@@ -120,6 +120,20 @@ export default defineComponent({
};
}
},
+ collapseFailFlag(){
+ return this.layoutNode.collapseFailFlag;
+ },
+ expandFailFlag(){
+ return this.layoutNode.expandFailFlag;
+ },
+ },
+ watch: {
+ expandFailFlag(newVal){
+ this.triggerAnimation('animate-expand-shrink');
+ },
+ collapseFailFlag(newVal){
+ this.triggerAnimation('animate-shrink-expand');
+ },
},
methods: {
// Leaf click handling
@@ -143,10 +157,7 @@ export default defineComponent({
return;
}
this.prepForTransition();
- this.$emit('leaf-clicked', {
- layoutNode: this.layoutNode,
- failCallback: () => {this.triggerAnimation('animate-expand-shrink')}
- });
+ this.$emit('leaf-clicked', this.layoutNode);
},
onLeafClickHold(){
if (!this.isExpandable){
@@ -174,10 +185,7 @@ export default defineComponent({
},
onHeaderClick(){
this.prepForTransition();
- this.$emit('header-clicked', {
- layoutNode: this.layoutNode,
- failCallback: () => {this.triggerAnimation('animate-shrink-expand')}
- });
+ this.$emit('header-clicked', this.layoutNode);
},
onHeaderClickHold(){
this.prepForTransition();
@@ -195,10 +203,10 @@ export default defineComponent({
this.nonLeafHighlight = false;
},
// Child event propagation
- onInnerLeafClicked(data: {layoutNode: LayoutNode, failCallback: () => void}){
+ onInnerLeafClicked(data: LayoutNode){
this.$emit('leaf-clicked', data);
},
- onInnerHeaderClicked(data: {layoutNode: LayoutNode, failCallback: () => void}){
+ onInnerHeaderClicked(data: LayoutNode){
this.$emit('header-clicked', data);
},
onInnerLeafClickHeld(data: LayoutNode){
diff --git a/src/lib.ts b/src/lib.ts
index 450eb90..a82bbd9 100644
--- a/src/lib.ts
+++ b/src/lib.ts
@@ -30,6 +30,8 @@ export class LayoutNode {
sepSweptArea: SepSweptArea | null;
hidden: boolean;
hasFocus: boolean;
+ collapseFailFlag: boolean; // Used to trigger failure animations
+ expandFailFlag: boolean; // Used to trigger failure animations
// Used for layout heuristics and info display
dCount: number; // Number of descendant leaf nodes
depth: number; // Number of ancestor nodes
@@ -45,6 +47,8 @@ export class LayoutNode {
this.sepSweptArea = null;
this.hidden = false;
this.hasFocus = false;
+ this.collapseFailFlag = false;
+ this.expandFailFlag = false;
this.dCount = children.length == 0 ? 1 : arraySum(children.map(n => n.dCount));
this.depth = 0;
this.empSpc = 0;