() {
+ @Override
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ @Override
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+ }
+}
diff --git a/android-app/src/main/java/com/viewpagerindicator/PageIndicator.java b/android-app/src/main/java/com/viewpagerindicator/PageIndicator.java
new file mode 100644
index 00000000..c08c00ae
--- /dev/null
+++ b/android-app/src/main/java/com/viewpagerindicator/PageIndicator.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 Patrik Akerfeldt
+ * Copyright (C) 2011 Jake Wharton
+ *
+ * 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 com.viewpagerindicator;
+
+import android.support.v4.view.ViewPager;
+
+/**
+ * A PageIndicator is responsible to show an visual indicator on the total views
+ * number and the current visible view.
+ */
+public interface PageIndicator extends ViewPager.OnPageChangeListener {
+ /**
+ * Bind the indicator to a ViewPager.
+ *
+ * @param view
+ */
+ void setViewPager(ViewPager view);
+
+ /**
+ * Bind the indicator to a ViewPager.
+ *
+ * @param view
+ * @param initialPosition
+ */
+ void setViewPager(ViewPager view, int initialPosition);
+
+ /**
+ * Set the current page of both the ViewPager and indicator.
+ *
+ * This must be used if you need to set the page before
+ * the views are drawn on screen (e.g., default start page).
+ *
+ * @param item
+ */
+ void setCurrentItem(int item);
+
+ /**
+ * Set a page change listener which will receive forwarded events.
+ *
+ * @param listener
+ */
+ void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
+
+ /**
+ * Notify the indicator that the fragment list has changed.
+ */
+ void notifyDataSetChanged();
+}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizardActivity.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizardActivity.java
deleted file mode 100644
index 8c8796b2..00000000
--- a/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizardActivity.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2013 serso aka se.solovyev
- *
- * 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.
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * Contact details
- *
- * Email: se.solovyev@gmail.com
- * Site: http://se.solovyev.org
- */
-
-package org.solovyev.android.calculator.wizard;
-
-import org.solovyev.android.calculator.CalculatorApplication;
-import org.solovyev.android.calculator.R;
-import org.solovyev.android.wizard.BaseWizardActivity;
-import org.solovyev.android.wizard.Wizards;
-
-import javax.annotation.Nonnull;
-
-public final class CalculatorWizardActivity extends BaseWizardActivity {
-
- @Nonnull
- private Wizards wizards;
-
- public CalculatorWizardActivity() {
- super(R.layout.cpp_wizard);
- this.wizards = CalculatorApplication.getInstance().getWizards();
- }
-
- @Nonnull
- public Wizards getWizards() {
- return wizards;
- }
-
- public void setWizards(@Nonnull Wizards wizards) {
- this.wizards = wizards;
- }
-}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizards.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizards.java
index 4df8c546..2983ccc6 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizards.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/wizard/CalculatorWizards.java
@@ -27,7 +27,7 @@ public class CalculatorWizards implements Wizards {
@Nonnull
@Override
public Class extends Activity> getActivityClassName() {
- return CalculatorWizardActivity.class;
+ return WizardActivity.class;
}
@Nonnull
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/WelcomeWizardStep.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WelcomeWizardStep.java
index c209e02d..3961107c 100644
--- a/android-app/src/main/java/org/solovyev/android/calculator/wizard/WelcomeWizardStep.java
+++ b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WelcomeWizardStep.java
@@ -23,22 +23,23 @@
package org.solovyev.android.calculator.wizard;
import android.os.Bundle;
-import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-
import org.solovyev.android.calculator.R;
-/**
- * User: serso
- * Date: 6/16/13
- * Time: 9:44 PM
- */
-public final class WelcomeWizardStep extends Fragment {
+public final class WelcomeWizardStep extends WizardFragment {
+
+ @Override
+ protected int getViewResId() {
+ return R.layout.cpp_wizard_step_welcome;
+ }
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.cpp_wizard_step_welcome, null);
+ final View view = super.onCreateView(inflater, container, savedInstanceState);
+ setupNextButton(R.string.wizard_start);
+ setupPrevButton(R.string.wizard_skip);
+ return view;
}
}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java
new file mode 100644
index 00000000..ced1e682
--- /dev/null
+++ b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardActivity.java
@@ -0,0 +1,139 @@
+package org.solovyev.android.calculator.wizard;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentStatePagerAdapter;
+import android.support.v4.view.PagerAdapter;
+import android.support.v4.view.ViewPager;
+import com.viewpagerindicator.PageIndicator;
+import org.solovyev.android.calculator.BaseActivity;
+import org.solovyev.android.calculator.CalculatorApplication;
+import org.solovyev.android.calculator.R;
+import org.solovyev.android.wizard.*;
+
+import javax.annotation.Nonnull;
+
+public class WizardActivity extends BaseActivity implements WizardsAware {
+ @Nonnull
+ private final WizardUi wizardUi = new WizardUi(this, this, 0);
+
+ @Nonnull
+ private ViewPager pager;
+
+ @Nonnull
+ private PagerAdapter pagerAdapter;
+
+ public WizardActivity() {
+ super(R.layout.cpp_activity_wizard);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ wizardUi.onCreate(savedInstanceState);
+ getSupportActionBar().hide();
+ final ListWizardFlow flow = (ListWizardFlow) wizardUi.getFlow();
+
+ pager = (ViewPager) findViewById(R.id.pager);
+ pagerAdapter = new WizardPagerAdapter(flow, getSupportFragmentManager());
+ pager.setAdapter(pagerAdapter);
+ final PageIndicator titleIndicator = (PageIndicator) findViewById(R.id.pager_indicator);
+ titleIndicator.setViewPager(pager);
+ titleIndicator.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
+ @Override
+ public void onPageSelected(int position) {
+ wizardUi.setStep(flow.getStepAt(position));
+ }
+ });
+
+ if (savedInstanceState == null) {
+ final int position = flow.getPositionFor(wizardUi.getStep());
+ pager.setCurrentItem(position);
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ if (pager.getCurrentItem() == 0) {
+ super.onBackPressed();
+ } else {
+ pager.setCurrentItem(pager.getCurrentItem() - 1);
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ wizardUi.onSaveInstanceState(outState);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ wizardUi.onPause();
+ }
+
+ @Nonnull
+ @Override
+ public Wizards getWizards() {
+ return CalculatorApplication.getInstance().getWizards();
+ }
+
+ public void finishWizardAbruptly() {
+ wizardUi.finishWizardAbruptly();
+ finish();
+ }
+
+ public void finishWizard() {
+ wizardUi.finishWizard();
+ finish();
+ }
+
+ public boolean canGoNext() {
+ final int position = pager.getCurrentItem();
+ return position != pagerAdapter.getCount() - 1;
+ }
+
+ public boolean canGoPrev() {
+ final int position = pager.getCurrentItem();
+ return position != 0;
+ }
+
+ public void goNext() {
+ final int position = pager.getCurrentItem();
+ if (position < pagerAdapter.getCount() - 1) {
+ pager.setCurrentItem(position + 1, true);
+ }
+ }
+
+ public void goPrev() {
+ final int position = pager.getCurrentItem();
+ if (position > 0) {
+ pager.setCurrentItem(position - 1, true);
+ }
+ }
+
+ private class WizardPagerAdapter extends FragmentStatePagerAdapter {
+ @Nonnull
+ private final ListWizardFlow flow;
+
+ public WizardPagerAdapter(@Nonnull ListWizardFlow flow, @Nonnull FragmentManager fm) {
+ super(fm);
+ this.flow = flow;
+ }
+
+ @Override
+ public Fragment getItem(int position) {
+ final WizardStep step = flow.getStepAt(position);
+ final String className = step.getFragmentClass().getName();
+ final Bundle args = step.getFragmentArgs();
+ return Fragment.instantiate(WizardActivity.this, className, args);
+ }
+
+ @Override
+ public int getCount() {
+ return flow.getCount();
+ }
+ }
+}
diff --git a/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardFragment.java b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardFragment.java
new file mode 100644
index 00000000..73e7e899
--- /dev/null
+++ b/android-app/src/main/java/org/solovyev/android/calculator/wizard/WizardFragment.java
@@ -0,0 +1,72 @@
+package org.solovyev.android.calculator.wizard;
+
+import android.os.Bundle;
+import android.support.annotation.LayoutRes;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import org.solovyev.android.calculator.R;
+
+import javax.annotation.Nullable;
+
+public abstract class WizardFragment extends Fragment implements View.OnClickListener {
+
+ @Nullable
+ private TextView nextButton;
+
+ @Nullable
+ private TextView prevButton;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.fragment_wizard, container, false);
+
+ final ViewGroup content = (ViewGroup) view.findViewById(R.id.wizard_content);
+ inflater.inflate(getViewResId(), content, true);
+
+ nextButton = (TextView) view.findViewById(R.id.wizard_next);
+ if (nextButton != null) {
+ nextButton.setOnClickListener(this);
+ }
+ prevButton = (TextView) view.findViewById(R.id.wizard_prev);
+ if (prevButton != null) {
+ prevButton.setOnClickListener(this);
+ }
+
+ return view;
+ }
+
+ protected final void setupNextButton(int textResId) {
+ assert nextButton != null;
+ nextButton.setText(textResId);
+ }
+
+ protected final void setupPrevButton(int textResId) {
+ assert prevButton != null;
+ prevButton.setText(textResId);
+ }
+
+ @LayoutRes
+ protected abstract int getViewResId();
+
+ @Override
+ public void onClick(View v) {
+ final int id = v.getId();
+ final WizardActivity activity = (WizardActivity) getActivity();
+ if (id == R.id.wizard_next) {
+ if (activity.canGoNext()) {
+ activity.goNext();
+ } else {
+ activity.finishWizard();
+ }
+ } else if (id == R.id.wizard_prev) {
+ if (activity.canGoPrev()) {
+ activity.goPrev();
+ } else {
+ activity.finishWizardAbruptly();
+ }
+ }
+ }
+}
diff --git a/android-app/src/main/java/org/solovyev/android/wizard/BaseWizardActivity.java b/android-app/src/main/java/org/solovyev/android/wizard/BaseWizardActivity.java
deleted file mode 100644
index ca393151..00000000
--- a/android-app/src/main/java/org/solovyev/android/wizard/BaseWizardActivity.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package org.solovyev.android.wizard;
-
-import android.os.Bundle;
-import android.support.v7.app.ActionBarActivity;
-
-import javax.annotation.Nonnull;
-
-public abstract class BaseWizardActivity extends ActionBarActivity implements WizardsAware, FinishWizardConfirmationDialog.Listener {
-
- @Nonnull
- private WizardUi ui;
-
- protected BaseWizardActivity(int layoutResId) {
- ui = new WizardUi(this, this, layoutResId);
- }
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- ui.onCreate(savedInstanceState);
- }
-
- @Override
- protected void onSaveInstanceState(Bundle out) {
- super.onSaveInstanceState(out);
- ui.onSaveInstanceState(out);
- }
-
- @Override
- public void onPause() {
- super.onPause();
- ui.onPause();
- }
-
- @Override
- public void onBackPressed() {
- ui.onBackPressed();
- }
-
- @Override
- public void finishWizardAbruptly() {
- ui.finishWizardAbruptly();
- }
-}
diff --git a/android-app/src/main/java/org/solovyev/android/wizard/ListWizardFlow.java b/android-app/src/main/java/org/solovyev/android/wizard/ListWizardFlow.java
index d7699c5b..5177a0d5 100644
--- a/android-app/src/main/java/org/solovyev/android/wizard/ListWizardFlow.java
+++ b/android-app/src/main/java/org/solovyev/android/wizard/ListWizardFlow.java
@@ -22,33 +22,28 @@
package org.solovyev.android.wizard;
-import org.solovyev.common.JPredicate;
-
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
-import static org.solovyev.common.collections.Collections.find;
-
public final class ListWizardFlow implements WizardFlow {
@Nonnull
- private final List steps;
+ private final List extends WizardStep> steps;
- public ListWizardFlow(@Nonnull List steps) {
+ public ListWizardFlow(@Nonnull List extends WizardStep> steps) {
this.steps = steps;
}
@Nullable
@Override
public WizardStep getStepByName(@Nonnull final String name) {
- return find(steps, new JPredicate() {
- @Override
- public boolean apply(@Nullable WizardStep step) {
- assert step != null;
- return step.getName().equals(name);
+ for (WizardStep step : steps) {
+ if (step.getName().equals(name)) {
+ return step;
}
- });
+ }
+ return null;
}
@Nullable
@@ -78,4 +73,24 @@ public final class ListWizardFlow implements WizardFlow {
public WizardStep getFirstStep() {
return steps.get(0);
}
+
+ @Nonnull
+ public WizardStep getStepAt(int position) {
+ return steps.get(position);
+ }
+
+ public int getPositionFor(@Nonnull WizardStep step) {
+ for (int i = 0; i < steps.size(); i++) {
+ if (steps.get(i).equals(step)) {
+ return i;
+ }
+
+ }
+
+ return -1;
+ }
+
+ public int getCount() {
+ return steps.size();
+ }
}
diff --git a/android-app/src/main/java/org/solovyev/android/wizard/WizardUi.java b/android-app/src/main/java/org/solovyev/android/wizard/WizardUi.java
index 8dbac768..306b452c 100644
--- a/android-app/src/main/java/org/solovyev/android/wizard/WizardUi.java
+++ b/android-app/src/main/java/org/solovyev/android/wizard/WizardUi.java
@@ -6,63 +6,25 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
-import android.support.v4.app.FragmentTransaction;
-import android.view.View;
-import android.widget.Button;
-import org.solovyev.android.calculator.R;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
-import static android.view.View.GONE;
-import static android.view.View.VISIBLE;
-
-public class WizardUi {
-
- /*
- **********************************************************************
- *
- * CONSTANTS
- *
- **********************************************************************
- */
+public class WizardUi {
private static final String FLOW = "flow";
private static final String STEP = "step";
- /*
- **********************************************************************
- *
- * FIELDS
- *
- **********************************************************************
- */
-
- private WizardStep step;
-
- private Wizard wizard;
-
- /*
- **********************************************************************
- *
- * VIEWS
- *
- **********************************************************************
- */
-
- @Nullable
- private View prevButton;
+ protected WizardStep step;
+ protected Wizard wizard;
@Nonnull
- private Button nextButton;
+ protected final A activity;
@Nonnull
- private final A activity;
+ protected final WizardsAware wizardsAware;
- @Nonnull
- private final WizardsAware wizardsAware;
-
- private final int layoutResId;
+ protected final int layoutResId;
public WizardUi(@Nonnull A activity, @Nonnull WizardsAware wizardsAware, int layoutResId) {
this.activity = activity;
@@ -70,22 +32,14 @@ public class WizardUi
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android-app/src/main/res/layout/cpp_activity_wizard.xml b/android-app/src/main/res/layout/cpp_activity_wizard.xml
new file mode 100644
index 00000000..d76948ad
--- /dev/null
+++ b/android-app/src/main/res/layout/cpp_activity_wizard.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android-app/src/main/res/layout/cpp_wizard_step_welcome.xml b/android-app/src/main/res/layout/cpp_wizard_step_welcome.xml
index be126b5b..14418ffe 100644
--- a/android-app/src/main/res/layout/cpp_wizard_step_welcome.xml
+++ b/android-app/src/main/res/layout/cpp_wizard_step_welcome.xml
@@ -22,9 +22,13 @@
~ Site: http://se.solovyev.org
-->
-
+
diff --git a/android-app/src/main/res/layout/fragment_wizard.xml b/android-app/src/main/res/layout/fragment_wizard.xml
new file mode 100644
index 00000000..91d2b263
--- /dev/null
+++ b/android-app/src/main/res/layout/fragment_wizard.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android-app/src/main/res/layout/fragment_wizard_buttons.xml b/android-app/src/main/res/layout/fragment_wizard_buttons.xml
new file mode 100644
index 00000000..3eca995f
--- /dev/null
+++ b/android-app/src/main/res/layout/fragment_wizard_buttons.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android-app/src/main/res/values-ru/strings.xml b/android-app/src/main/res/values-ru/strings.xml
index ba8cd1ea..6f41d40e 100644
--- a/android-app/src/main/res/values-ru/strings.xml
+++ b/android-app/src/main/res/values-ru/strings.xml
@@ -8,4 +8,10 @@
Отчистить
Вся история будет отчищена
Отчистить историю?
+ Начать визард
+ Пропустить
+ Закончить
+ Далее
+ Назад
+ Приложение настроено и готово к использованию.
\ No newline at end of file
diff --git a/android-app/src/main/res/values-w820dp-v13/values.xml b/android-app/src/main/res/values-w820dp-v13/values.xml
new file mode 100644
index 00000000..3eda5f55
--- /dev/null
+++ b/android-app/src/main/res/values-w820dp-v13/values.xml
@@ -0,0 +1,4 @@
+
+
+ 64dp
+
\ No newline at end of file
diff --git a/android-app/src/main/res/values/colors.xml b/android-app/src/main/res/values/colors.xml
index 48dc0cf6..812517ab 100644
--- a/android-app/src/main/res/values/colors.xml
+++ b/android-app/src/main/res/values/colors.xml
@@ -41,4 +41,6 @@
#ddffffff
#89ffffff
#40ffffff
+
+ #707070
\ No newline at end of file
diff --git a/android-app/src/main/res/values/dimens.xml b/android-app/src/main/res/values/dimens.xml
index 0ee997ed..d965f28f 100644
--- a/android-app/src/main/res/values/dimens.xml
+++ b/android-app/src/main/res/values/dimens.xml
@@ -35,4 +35,8 @@
3dp
20dp
+
+ 5dp
+ 5dp
+ 5dp
\ No newline at end of file
diff --git a/android-app/src/main/res/values/strings.xml b/android-app/src/main/res/values/strings.xml
index d9baad14..1e0916e1 100644
--- a/android-app/src/main/res/values/strings.xml
+++ b/android-app/src/main/res/values/strings.xml
@@ -8,4 +8,9 @@
Clear history?
All history will be cleared.
Clear
+ Start wizard
+ Next
+ Back
+ The app is set up and ready to use.
+ Skip
\ No newline at end of file
diff --git a/android-app/src/main/res/values/styles.xml b/android-app/src/main/res/values/styles.xml
index 6a3dc5a3..db87f38b 100644
--- a/android-app/src/main/res/values/styles.xml
+++ b/android-app/src/main/res/values/styles.xml
@@ -145,4 +145,41 @@
- 1dp
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android-app/src/main/res/values/theme_metro_blue.xml b/android-app/src/main/res/values/theme_metro_blue.xml
index 0f5d301b..c5102d23 100644
--- a/android-app/src/main/res/values/theme_metro_blue.xml
+++ b/android-app/src/main/res/values/theme_metro_blue.xml
@@ -48,6 +48,11 @@
- 6dp
+
+