From 4799c9304470964c1e9deb43c45edbc1cb57207e Mon Sep 17 00:00:00 2001 From: "Rui Zhao (renyuneyun)" Date: Wed, 9 May 2018 23:14:18 +0100 Subject: [PATCH] Add UI for editing ConditionData && enable / disable ConditionPlugin --- app/src/main/AndroidManifest.xml | 2 + .../java/ryey/easer/core/ui/MainActivity.java | 9 + .../core/ui/edit/ConditionListFragment.java | 42 +++++ .../ConditionPluginViewContainerFragment.java | 103 ++++++++++++ .../ui/edit/ConditionPluginViewPager.java | 155 ++++++++++++++++++ .../core/ui/edit/EditConditionActivity.java | 70 ++++++++ .../PluginSettingsPreferenceFragment.java | 6 + .../res/layout/activity_edit_condition.xml | 53 ++++++ .../res/layout/activity_edit_scenario.xml | 6 +- .../main/res/layout/activity_edit_script.xml | 2 +- .../layout/fragment_pluginview_condition.xml | 10 ++ .../main/res/menu/activity_main_drawer.xml | 3 + app/src/main/res/values-v17/styles.xml | 2 +- app/src/main/res/values-zh/strings.xml | 3 + app/src/main/res/values/keys.xml | 1 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/styles.xml | 2 +- app/src/main/res/xml/plugins_preference.xml | 8 + 18 files changed, 474 insertions(+), 6 deletions(-) create mode 100644 app/src/main/java/ryey/easer/core/ui/edit/ConditionListFragment.java create mode 100644 app/src/main/java/ryey/easer/core/ui/edit/ConditionPluginViewContainerFragment.java create mode 100644 app/src/main/java/ryey/easer/core/ui/edit/ConditionPluginViewPager.java create mode 100644 app/src/main/java/ryey/easer/core/ui/edit/EditConditionActivity.java create mode 100644 app/src/main/res/layout/activity_edit_condition.xml create mode 100644 app/src/main/res/layout/fragment_pluginview_condition.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a70451b0..4e8d2739 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -124,6 +124,8 @@ + + \ No newline at end of file diff --git a/app/src/main/java/ryey/easer/core/ui/MainActivity.java b/app/src/main/java/ryey/easer/core/ui/MainActivity.java index f10107f3..1ae03f45 100644 --- a/app/src/main/java/ryey/easer/core/ui/MainActivity.java +++ b/app/src/main/java/ryey/easer/core/ui/MainActivity.java @@ -40,6 +40,7 @@ import ryey.easer.R; import ryey.easer.core.data.storage.StorageHelper; +import ryey.easer.core.ui.edit.ConditionListFragment; import ryey.easer.core.ui.edit.ProfileListFragment; import ryey.easer.core.ui.edit.ScenarioListFragment; import ryey.easer.core.ui.edit.ScriptListFragment; @@ -55,6 +56,7 @@ public class MainActivity extends AppCompatActivity private static final String FRAGMENT_PROFILE = "ryey.easer.FRAGMENT.PROFILE"; private static final String FRAGMENT_EVENT = "ryey.easer.FRAGMENT.EVENT"; private static final String FRAGMENT_SCENARIO = "ryey.easer.FRAGMENT.SCENARIO"; + private static final String FRAGMENT_CONDITION = "ryey.easer.FRAGMENT.CONDITION"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -157,6 +159,13 @@ public boolean onNavigationItemSelected(@NonNull MenuItem item) { manager.beginTransaction() .replace(R.id.content_main, fragment, FRAGMENT_SCENARIO) .commit(); + } else if (id == R.id.nav_condition) { + fragment = manager.findFragmentByTag(FRAGMENT_CONDITION); + if (fragment == null) + fragment = new ConditionListFragment(); + manager.beginTransaction() + .replace(R.id.content_main, fragment, FRAGMENT_CONDITION) + .commit(); } else if (id == R.id.nav_about) { Intent intent = new Intent(this, AboutActivity.class); startActivity(intent); diff --git a/app/src/main/java/ryey/easer/core/ui/edit/ConditionListFragment.java b/app/src/main/java/ryey/easer/core/ui/edit/ConditionListFragment.java new file mode 100644 index 00000000..be9e0f6e --- /dev/null +++ b/app/src/main/java/ryey/easer/core/ui/edit/ConditionListFragment.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2016 - 2018 Rui Zhao + * + * This file is part of Easer. + * + * Easer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Easer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Easer. If not, see . + */ + +package ryey.easer.core.ui.edit; + +import android.content.Intent; + +import ryey.easer.R; +import ryey.easer.core.data.storage.ConditionDataStorage; + +public class ConditionListFragment extends AbstractDataListFragment { + @Override + protected String title() { + return getString(R.string.title_condition); + } + + @Override + protected ConditionDataStorage retmStorage() { + return ConditionDataStorage.getInstance(getContext()); + } + + @Override + protected Intent intentForEditDataActivity() { + return new Intent(getContext(), EditConditionActivity.class); + } +} diff --git a/app/src/main/java/ryey/easer/core/ui/edit/ConditionPluginViewContainerFragment.java b/app/src/main/java/ryey/easer/core/ui/edit/ConditionPluginViewContainerFragment.java new file mode 100644 index 00000000..7a8eb198 --- /dev/null +++ b/app/src/main/java/ryey/easer/core/ui/edit/ConditionPluginViewContainerFragment.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016 - 2018 Rui Zhao + * + * This file is part of Easer. + * + * Easer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Easer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Easer. If not, see . + */ + +package ryey.easer.core.ui.edit; + +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import ryey.easer.R; +import ryey.easer.commons.plugindef.InvalidDataInputException; +import ryey.easer.commons.plugindef.conditionplugin.ConditionData; +import ryey.easer.commons.plugindef.conditionplugin.ConditionPlugin; +import ryey.easer.plugins.PluginRegistry; + +public class ConditionPluginViewContainerFragment extends PluginViewContainerFragment { + + private static final String EXTRA_PLUGIN = "plugin"; + + static ConditionPluginViewContainerFragment createInstance(ConditionPlugin plugin) { + Bundle bundle = new Bundle(); + bundle.putString(EXTRA_PLUGIN, plugin.id()); + ConditionPluginViewContainerFragment fragment = new ConditionPluginViewContainerFragment<>(); + fragment.setArguments(bundle); + return fragment; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + String plugin_id = getArguments().getString(EXTRA_PLUGIN); + @SuppressWarnings("unchecked") ConditionPlugin plugin = PluginRegistry.getInstance().condition().findPlugin(plugin_id); + pluginViewFragment = plugin.view(); + } + + @NonNull + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.fragment_pluginview_condition, container, false); + getChildFragmentManager().beginTransaction() + .replace(R.id.content_pluginview, pluginViewFragment) + .commit(); + return v; + } + + @Override + public void onStart() { + super.onStart(); + ConditionPlugin plugin = PluginRegistry.getInstance().condition().findPlugin(pluginViewFragment); + //noinspection ConstantConditions + if (!plugin.checkPermissions(getContext())) { + setEnabled(false); + //noinspection ConstantConditions + plugin.requestPermissions(getActivity(), 1); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + if (requestCode == 1) { + for (int i = 0; i < grantResults.length; i++) { + if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { + return; + } + } + setEnabled(true); + } + } + + /*** + * {@inheritDoc} + * Explicitly override and call back through to snooze compiler data type checking + */ + @NonNull + @Override + T getData() throws InvalidDataInputException { + return super.getData(); + } + + private void setEnabled(boolean enabled) { + pluginViewFragment.setEnabled(enabled); + } +} diff --git a/app/src/main/java/ryey/easer/core/ui/edit/ConditionPluginViewPager.java b/app/src/main/java/ryey/easer/core/ui/edit/ConditionPluginViewPager.java new file mode 100644 index 00000000..d859dc27 --- /dev/null +++ b/app/src/main/java/ryey/easer/core/ui/edit/ConditionPluginViewPager.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016 - 2018 Rui Zhao + * + * This file is part of Easer. + * + * Easer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Easer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Easer. If not, see . + */ + +package ryey.easer.core.ui.edit; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentStatePagerAdapter; +import android.support.v4.view.ViewPager; +import android.support.v7.app.AppCompatActivity; +import android.util.AttributeSet; +import android.util.SparseArray; +import android.view.ViewGroup; + +import java.util.ArrayList; +import java.util.List; + +import ryey.easer.commons.plugindef.InvalidDataInputException; +import ryey.easer.commons.plugindef.conditionplugin.ConditionData; +import ryey.easer.commons.plugindef.conditionplugin.ConditionPlugin; +import ryey.easer.plugins.PluginRegistry; + +public class ConditionPluginViewPager extends ViewPager { + + MyPagerAdapter mPagerAdapter; + + final List conditionPluginList = new ArrayList<>(); + + Integer initial_position = null; + ConditionData initial_condition_data = null; + + public ConditionPluginViewPager(Context context) { + super(context); + } + + public ConditionPluginViewPager(Context context, AttributeSet attrs) { + super(context, attrs); + } + + void init(AppCompatActivity activity) { + conditionPluginList.clear(); + conditionPluginList.addAll(PluginRegistry.getInstance().condition().getEnabledPlugins(activity)); + mPagerAdapter = new MyPagerAdapter(activity.getSupportFragmentManager(), getContext()); + setAdapter(mPagerAdapter); + } + + void setConditionData(T conditionData) { + initial_condition_data = conditionData; + int i = getPluginIndex(conditionData); + initial_position = i; + if (getCurrentItem() == i) { + synchronized (this) { + //noinspection unchecked + ConditionPluginViewContainerFragment fragment = mPagerAdapter.getRegisteredFragment(i); + if (fragment != null) + //noinspection unchecked + fragment.fill((T) initial_condition_data); + } + } else { + setCurrentItem(i); + } + } + + ConditionData getConditionData() throws InvalidDataInputException { + return getConditionData(getCurrentItem()); + } + + ConditionData getConditionData(int position) throws InvalidDataInputException { + return mPagerAdapter.getRegisteredFragment(position).getData(); + } + + private int getPluginIndex(ConditionData conditionData) { + for (int i = 0; i < conditionPluginList.size(); i++) { + if (conditionData.getClass() == conditionPluginList.get(i).dataFactory().dataClass()) + return i; + } + throw new IllegalAccessError("Plugin not found???"); + } + + class MyPagerAdapter extends FragmentStatePagerAdapter { + + SparseArray registeredFragments = new SparseArray<>(); + + private final Context context; + final String[] titles; + + public MyPagerAdapter(FragmentManager fm, Context context) { + super(fm); + this.context = context; + titles = new String[conditionPluginList.size()]; + for (int i = 0; i < conditionPluginList.size(); i++) { + titles[i] = conditionPluginList.get(i).view().desc(getResources()); + } + } + + @Override + public Fragment getItem(int position) { + PluginViewContainerFragment fragment = ConditionPluginViewContainerFragment.createInstance( + conditionPluginList.get(position)); + return fragment; + } + + @Override + public int getCount() { + return titles.length; + } + + @Override + public CharSequence getPageTitle(int position) { + return titles[position]; + } + + @NonNull + @Override + public Object instantiateItem(ViewGroup container, int position) { + ConditionPluginViewContainerFragment fragment = (ConditionPluginViewContainerFragment) super.instantiateItem(container, position); + synchronized (ConditionPluginViewPager.this) { + if ((initial_position != null) && (position == initial_position)) { + //noinspection unchecked + fragment.fill(initial_condition_data); + } + } + registeredFragments.put(position, fragment); + return fragment; + } + + @Override + public void destroyItem(ViewGroup container, int position, Object object) { + registeredFragments.remove(position); + super.destroyItem(container, position, object); + } + + public ConditionPluginViewContainerFragment getRegisteredFragment(int position) { + return registeredFragments.get(position); + } + } +} diff --git a/app/src/main/java/ryey/easer/core/ui/edit/EditConditionActivity.java b/app/src/main/java/ryey/easer/core/ui/edit/EditConditionActivity.java new file mode 100644 index 00000000..89e69bda --- /dev/null +++ b/app/src/main/java/ryey/easer/core/ui/edit/EditConditionActivity.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016 - 2018 Rui Zhao + * + * This file is part of Easer. + * + * Easer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Easer is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Easer. If not, see . + */ + +package ryey.easer.core.ui.edit; + +import android.widget.EditText; + +import ryey.easer.R; +import ryey.easer.commons.C; +import ryey.easer.commons.plugindef.InvalidDataInputException; +import ryey.easer.commons.plugindef.conditionplugin.ConditionData; +import ryey.easer.core.data.ConditionStructure; +import ryey.easer.core.data.storage.ConditionDataStorage; + +public class EditConditionActivity extends AbstractEditDataActivity { + + EditText mEditText_name = null; + ConditionPluginViewPager mViewPager; + + @Override + protected ConditionDataStorage retDataStorage() { + return ConditionDataStorage.getInstance(this); + } + + @Override + protected String title() { + return getString(R.string.title_edit_condition); + } + + @Override + protected int contentViewRes() { + return R.layout.activity_edit_condition; + } + + @Override + void init() { + mEditText_name = findViewById(R.id.editText_name); + mViewPager = findViewById(R.id.pager); + mViewPager.init(this); + } + + @Override + protected void loadFromData(ConditionStructure condition) { + oldName = condition.getName(); + mEditText_name.setText(condition.getName()); + mViewPager.setConditionData(condition.getData()); + } + + @Override + protected ConditionStructure saveToData() throws InvalidDataInputException { + ConditionData conditionData = mViewPager.getConditionData(); + return new ConditionStructure(C.VERSION_CREATED_IN_RUNTIME, mEditText_name.getText().toString(), conditionData); + } +} diff --git a/app/src/main/java/ryey/easer/core/ui/setting/PluginSettingsPreferenceFragment.java b/app/src/main/java/ryey/easer/core/ui/setting/PluginSettingsPreferenceFragment.java index dc828d35..2df3d11e 100644 --- a/app/src/main/java/ryey/easer/core/ui/setting/PluginSettingsPreferenceFragment.java +++ b/app/src/main/java/ryey/easer/core/ui/setting/PluginSettingsPreferenceFragment.java @@ -45,5 +45,11 @@ public void onCreate(@Nullable Bundle savedInstanceState) { PluginEnabledPreference preference = new PluginEnabledPreference(getActivity(), plugin); preferenceCategory.addPreference(preference); } + + preferenceCategory = (PreferenceCategory) getPreferenceScreen().findPreference(getString(R.string.key_pref_enabled_condition_plugins)); + for (PluginDef plugin : PluginRegistry.getInstance().condition().getAllPlugins()) { + PluginEnabledPreference preference = new PluginEnabledPreference(getActivity(), plugin); + preferenceCategory.addPreference(preference); + } } } diff --git a/app/src/main/res/layout/activity_edit_condition.xml b/app/src/main/res/layout/activity_edit_condition.xml new file mode 100644 index 00000000..c9910d2c --- /dev/null +++ b/app/src/main/res/layout/activity_edit_condition.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_edit_scenario.xml b/app/src/main/res/layout/activity_edit_scenario.xml index 5d0faf0b..65bb966f 100644 --- a/app/src/main/res/layout/activity_edit_scenario.xml +++ b/app/src/main/res/layout/activity_edit_scenario.xml @@ -7,7 +7,7 @@ tools:context="ryey.easer.core.ui.edit.EditScenarioActivity"> + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/activity_main_drawer.xml b/app/src/main/res/menu/activity_main_drawer.xml index 41e99f7f..89d928ff 100644 --- a/app/src/main/res/menu/activity_main_drawer.xml +++ b/app/src/main/res/menu/activity_main_drawer.xml @@ -14,6 +14,9 @@ + diff --git a/app/src/main/res/values-v17/styles.xml b/app/src/main/res/values-v17/styles.xml index 9b197823..42d36ea5 100644 --- a/app/src/main/res/values-v17/styles.xml +++ b/app/src/main/res/values-v17/styles.xml @@ -13,7 +13,7 @@ @dimen/lr_padding_outer - -