From c761287a8a3b46ea5c066bb7f9ea3c50b4dc2595 Mon Sep 17 00:00:00 2001 From: str4d <str4d@mail.i2p> Date: Mon, 26 Aug 2013 01:23:00 +0000 Subject: [PATCH] Added support for complex branching with Conditionals --- .../i2p/android/wizard/model/Conditional.java | 54 +++++++++++++++ src/net/i2p/android/wizard/model/Page.java | 65 ++++++++++++++++++- 2 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 src/net/i2p/android/wizard/model/Conditional.java diff --git a/src/net/i2p/android/wizard/model/Conditional.java b/src/net/i2p/android/wizard/model/Conditional.java new file mode 100644 index 000000000..0458c2b83 --- /dev/null +++ b/src/net/i2p/android/wizard/model/Conditional.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013 str4d + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.i2p.android.wizard.model; + +import java.util.ArrayList; +import java.util.List; + +public class Conditional implements ModelCallbacks { + private Object mData = null; + private List<Page> mConditionalPages = new ArrayList<Page>(); + + public void onPageDataChanged(Page page) { + mData = page.getData().get(Page.SIMPLE_DATA_KEY); + for (Page p : mConditionalPages) + p.isSatisfied(); + } + + public void onPageTreeChanged() { + } + + public interface Condition { + public boolean isSatisfied(); + } + + public class EqualCondition<T> implements Condition { + private T mCompValue; + + public EqualCondition(Page page, T compValue) { + mCompValue = compValue; + mConditionalPages.add(page); + } + + public boolean isSatisfied() { + // If we have no data from the conditional, + // assume that the page will be shown. + if (mData == null) return true; + return mCompValue.equals(mData); + } + } +} diff --git a/src/net/i2p/android/wizard/model/Page.java b/src/net/i2p/android/wizard/model/Page.java index 0135f3312..01d7e60c9 100644 --- a/src/net/i2p/android/wizard/model/Page.java +++ b/src/net/i2p/android/wizard/model/Page.java @@ -21,6 +21,7 @@ import android.os.Bundle; import android.support.v4.app.Fragment; import java.util.ArrayList; +import java.util.List; /** * Represents a single page in the wizard. @@ -33,6 +34,24 @@ public abstract class Page implements PageTreeNode { protected ModelCallbacks mCallbacks; + /** + * Conditionals that rely on this page. + */ + protected List<ModelCallbacks> mConditionals = new ArrayList<ModelCallbacks>(); + + /** + * Conditions on whether this page should be used. + */ + protected List<Conditional.Condition> mConditions = new ArrayList<Conditional.Condition>(); + /** + * Should all conditions be satisfied, or any of them? + */ + protected boolean mConditionAnd = false; + /** + * The last condition status. + */ + protected boolean mSatisfied = true; + /** * Current wizard values/selections. */ @@ -54,8 +73,30 @@ public abstract class Page implements PageTreeNode { return mTitle; } + public boolean isSatisfied() { + boolean ret = true; + if (mConditions.size() > 0) { + ret = false; + for (Conditional.Condition c : mConditions) { + if (c.isSatisfied()) { + ret = true; + if (!mConditionAnd) break; + } else if (mConditionAnd) { + ret = false; + break; + } + } + } + // If the conditions have changed, update the page tree. + if (!(mSatisfied == ret)) { + mSatisfied = ret; + mCallbacks.onPageTreeChanged(); + } + return mSatisfied; + } + public boolean isRequired() { - return mRequired; + return isSatisfied() && mRequired; } void setParentKey(String parentKey) { @@ -67,7 +108,8 @@ public abstract class Page implements PageTreeNode { } public void flattenCurrentPageSequence(ArrayList<Page> dest) { - dest.add(this); + if (isSatisfied()) + dest.add(this); } public abstract Fragment createFragment(); @@ -88,6 +130,9 @@ public abstract class Page implements PageTreeNode { } public void notifyDataChanged() { + for (ModelCallbacks c : mConditionals) { + c.onPageDataChanged(this); + } mCallbacks.onPageDataChanged(this); } @@ -95,4 +140,20 @@ public abstract class Page implements PageTreeNode { mRequired = required; return this; } + + public Page makeConditional(Conditional conditional) { + mConditionals.add(conditional); + return this; + } + + public <T> Page setEqualCondition(Conditional conditional, T comp) { + Conditional.Condition c = conditional.new EqualCondition<T>(this, comp); + mConditions.add(c); + return this; + } + + public Page satisfyAllConditions(boolean conditionAnd) { + mConditionAnd = conditionAnd; + return this; + } } -- GitLab