From 6bae3af294240a04e3c4494ebc4b19ca4d65d914 Mon Sep 17 00:00:00 2001 From: cyberarm Date: Wed, 4 Nov 2020 09:16:40 -0600 Subject: [PATCH] Added support for Group presets, can now manage presets and add (clone) them into config --- .../dialogs/ActionDialog.java | 10 +- .../dialogs/AddFromPresetDialog.java | 112 ++++++++++++ .../dialogs/CloneDialog.java | 171 ++++++++++++++++++ .../dialogs/GroupDialog.java | 4 +- .../dialogs/PresetDialog.java | 150 +++++++++++---- .../dialogs/VariableDialog.java | 11 +- .../ui/editor/ActionsFragment.java | 73 ++++++-- .../ui/editor/GroupsFragment.java | 89 ++++++++- .../ui/editor/VariablesFragment.java | 16 +- .../ui/settings/presets/PresetsFragment.java | 77 +++++++- .../res/layout/dialog_add_from_preset.xml | 20 ++ .../layout/fragment_part_add_from_preset.xml | 28 +++ app/src/main/res/layout/fragment_presets.xml | 19 +- app/src/main/res/menu/action_add_menu.xml | 7 + app/src/main/res/menu/group_extras_menu.xml | 10 + app/src/main/res/values/strings.xml | 3 + 16 files changed, 716 insertions(+), 84 deletions(-) create mode 100644 app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/AddFromPresetDialog.java create mode 100644 app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/CloneDialog.java create mode 100644 app/src/main/res/layout/dialog_add_from_preset.xml create mode 100644 app/src/main/res/layout/fragment_part_add_from_preset.xml create mode 100644 app/src/main/res/menu/action_add_menu.xml create mode 100644 app/src/main/res/menu/group_extras_menu.xml diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/ActionDialog.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/ActionDialog.java index 23529ee..da13acf 100644 --- a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/ActionDialog.java +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/ActionDialog.java @@ -37,7 +37,11 @@ public class ActionDialog extends TimeCraftersDialog { View root = super.onCreateView(inflater, container, savedInstanceState); if (getArguments() != null) { - this.group = Backend.instance().getConfig().getGroups().get(getArguments().getInt("group_index")); + if (getArguments().getBoolean("group_is_preset", false)) { + this.group = Backend.instance().getConfig().getPresets().getGroups().get(getArguments().getInt("group_index")); + } else { + this.group = Backend.instance().getConfig().getGroups().get(getArguments().getInt("group_index")); + } if (getArguments().getInt("action_index", -1) != -1) { this.action = group.getActions().get(getArguments().getInt("action_index")); @@ -65,7 +69,7 @@ public class ActionDialog extends TimeCraftersDialog { name.setText(action.name); comment.setText(action.comment); - mutate.setText("Update"); + mutate.setText(R.string.dialog_update); } else { title.setText("Add Action"); } @@ -127,7 +131,7 @@ public class ActionDialog extends TimeCraftersDialog { } } - if (!nameUnique && action == null) { + if (!nameUnique) { message += "Name is not unique!"; } else if (name.length() <= 0) { diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/AddFromPresetDialog.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/AddFromPresetDialog.java new file mode 100644 index 0000000..a434c6f --- /dev/null +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/AddFromPresetDialog.java @@ -0,0 +1,112 @@ +package org.timecrafters.TimeCraftersConfigurationTool.dialogs; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.timecrafters.TimeCraftersConfigurationTool.R; +import org.timecrafters.TimeCraftersConfigurationTool.backend.Backend; +import org.timecrafters.TimeCraftersConfigurationTool.backend.Config; +import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Action; +import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Group; +import org.timecrafters.TimeCraftersConfigurationTool.library.TimeCraftersDialog; +import org.timecrafters.TimeCraftersConfigurationTool.ui.editor.GroupsFragment; + +import java.util.ArrayList; + +public class AddFromPresetDialog extends TimeCraftersDialog { + final String TAG = "AddFromPresetDialog"; + LinearLayout container; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View root = super.onCreateView(inflater, container, savedInstanceState); + + final TextView title = root.findViewById(R.id.dialog_title); + final LinearLayout view = root.findViewById(R.id.dialog_content); + view.addView(getLayoutInflater().inflate(R.layout.dialog_add_from_preset, null)); + this.container = root.findViewById(R.id.container); + + title.setText(R.string.add_from_preset); + + if (getArguments().getBoolean("show_actions", false)) { + populateActionsOptions(); + } else { + populateGroupsOptions(); + } + + return root; + } + + public void populateGroupsOptions() { + container.removeAllViews(); + + int i = 0; + for (Group group : Backend.instance().getConfig().getPresets().getGroups()) { + final View view = View.inflate(getContext(), R.layout.fragment_part_add_from_preset, null); + Button name = view.findViewById(R.id.name); + TextView description = view.findViewById(R.id.description); + name.setText(group.name); + + if (i % 2 == 0) { // even + view.setBackgroundColor(getResources().getColor(R.color.list_even)); + } else { + view.setBackgroundColor(getResources().getColor(R.color.list_odd)); + } + + description.setVisibility(View.GONE); + + container.addView(view); + i++; + } + } + + public void populateActionsOptions() { + container.removeAllViews(); + + int i = 0; + for (Action action : Backend.instance().getConfig().getPresets().getActions()) { + final View view = View.inflate(getContext(), R.layout.fragment_part_add_from_preset, null); + Button name = view.findViewById(R.id.name); + TextView description = view.findViewById(R.id.description); + name.setText(action.name); + description.setText(action.comment); + + final int index = i; + name.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CloneDialog dialog = new CloneDialog(); + Bundle bundle = new Bundle(); + bundle.putBoolean("is_cloning_preset", true); + bundle.putInt("group_index", getArguments().getInt("group_index")); + bundle.putInt("action_index", index); + dialog.setArguments(bundle); + dialog.show(getFragmentManager(), "clone_action_preset"); + + dismiss(); + } + }); + + if (i % 2 == 0) { // even + view.setBackgroundColor(getResources().getColor(R.color.list_even)); + } else { + view.setBackgroundColor(getResources().getColor(R.color.list_odd)); + } + + if (action.comment.length() <= 0) { + description.setVisibility(View.GONE); + } + + container.addView(view); + i++; + } + } +} diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/CloneDialog.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/CloneDialog.java new file mode 100644 index 0000000..57372db --- /dev/null +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/CloneDialog.java @@ -0,0 +1,171 @@ +package org.timecrafters.TimeCraftersConfigurationTool.dialogs; + +import android.os.Bundle; +import android.text.Editable; +import android.text.TextWatcher; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.timecrafters.TimeCraftersConfigurationTool.R; +import org.timecrafters.TimeCraftersConfigurationTool.backend.Backend; +import org.timecrafters.TimeCraftersConfigurationTool.backend.Config; +import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Action; +import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Group; +import org.timecrafters.TimeCraftersConfigurationTool.library.TimeCraftersDialog; +import org.timecrafters.TimeCraftersConfigurationTool.ui.editor.ActionsFragment; +import org.timecrafters.TimeCraftersConfigurationTool.ui.editor.GroupsFragment; + +import java.util.ArrayList; + +public class CloneDialog extends TimeCraftersDialog { + private static final int HOST_ID = R.id.navigation_editor; + final String TAG = "CloneDialog"; + private Group group; + private Action action; + private TextView nameError; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + setCancelable(false); + + View root = super.onCreateView(inflater, container, savedInstanceState); + + if (getArguments().getBoolean("is_cloning_preset", false)) { + if (getArguments().getInt("action_index", -1) != -1) { + this.group = Backend.instance().getConfig().getGroups().get(getArguments().getInt("group_index")); + this.action = Backend.instance().getConfig().getPresets().getActions().get(getArguments().getInt("action_index")); + } else { + this.group = Backend.instance().getConfig().getPresets().getGroups().get(getArguments().getInt("group_index")); + } + + } else { + this.group = Backend.instance().getConfig().getGroups().get(getArguments().getInt("group_index")); + + if (getArguments().getInt("action_index", -1) != -1) { + this.action = group.getActions().get(getArguments().getInt("action_index")); + } + } + + final TextView title = root.findViewById(R.id.dialog_title); + final LinearLayout view = root.findViewById(R.id.dialog_content); + view.addView(getLayoutInflater().inflate(R.layout.dialog_edit_group, null)); + final EditText name = view.findViewById(R.id.name); + nameError = view.findViewById(R.id.name_error); + + final Button cancel = view.findViewById(R.id.cancel); + final Button mutate = view.findViewById(R.id.mutate); + cancel.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + dismiss(); + } + }); + + if (action != null) { + title.setText("Cloning action " + action.name); + name.setText(action.name); + } else { + title.setText("Cloning group " + group.name); + name.setText(group.name); + } + + name.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + validated(name.getText().toString().trim()); + } + + @Override + public void afterTextChanged(Editable s) { + + } + }); + + mutate.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + final String finalName = name.getText().toString().trim(); + if (validated(finalName)) { + if (action != null) { + String json = Backend.instance().gsonForConfig().toJson(action); + Action actionClone = Backend.instance().gsonForConfig().fromJson(json, Action.class); + actionClone.name = finalName; + + group.getActions().add(actionClone); + + Backend.instance().configChanged(); + ActionsFragment fragment = (ActionsFragment) getFragmentManager().getPrimaryNavigationFragment(); + if (fragment != null) { + fragment.populateActions(); + } + dismiss(); + } else { + String json = Backend.instance().gsonForConfig().toJson(group); + Group groupClone = Backend.instance().gsonForConfig().fromJson(json, Group.class); + groupClone.name = finalName; + + Backend.instance().getConfig().getGroups().add(groupClone); + + Backend.instance().configChanged(); + GroupsFragment fragment = (GroupsFragment) getFragmentManager().getPrimaryNavigationFragment(); + if (fragment != null) { + fragment.populateGroups(); + } + dismiss(); + } + } + } + }); + + return root; + } + + private boolean validated(String name) { + String message = ""; + Config config = Backend.instance().getConfig(); + boolean nameUnique = true; + + if (action != null) { + for (Action a : group.getActions()) { + if (a.name.equals(name)) { + nameUnique = false; + break; + } + } + } else { + for (Group g : config.getGroups()) { + if (g.name.equals(name)) { + nameUnique = false; + break; + } + } + } + + if (!nameUnique) { + message += "Name is not unique!"; + + } else if (name.length() <= 0) { + message += "Name cannot be blank!"; + + } + + if (message.length() > 0) { + nameError.setVisibility(View.VISIBLE); + nameError.setText(message); + return false; + } else { + nameError.setVisibility(View.GONE); + return true; + } + } +} diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/GroupDialog.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/GroupDialog.java index c39da31..42bcda9 100644 --- a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/GroupDialog.java +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/GroupDialog.java @@ -85,7 +85,7 @@ public class GroupDialog extends TimeCraftersDialog { dismiss(); } - if (validated(groupName)) { + if (validated(groupName) || (group != null && group.name.equals(groupName))) { if (group != null) { group.name = groupName; } else { @@ -119,7 +119,7 @@ public class GroupDialog extends TimeCraftersDialog { } } - if (!nameUnique && group == null) { + if (!nameUnique) { message += "Name is not unique!"; } else if (name.length() <= 0) { diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/PresetDialog.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/PresetDialog.java index 8d25f83..a31a687 100644 --- a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/PresetDialog.java +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/PresetDialog.java @@ -20,6 +20,7 @@ import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Action; import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Group; import org.timecrafters.TimeCraftersConfigurationTool.library.TimeCraftersDialog; import org.timecrafters.TimeCraftersConfigurationTool.ui.editor.ActionsFragment; +import org.timecrafters.TimeCraftersConfigurationTool.ui.editor.GroupsFragment; import org.timecrafters.TimeCraftersConfigurationTool.ui.settings.presets.PresetsFragment; import java.util.ArrayList; @@ -42,9 +43,16 @@ public class PresetDialog extends TimeCraftersDialog { if (isNewPreset) { this.group = Backend.instance().getConfig().getGroups().get(getArguments().getInt("group_index")); - this.action = group.getActions().get(getArguments().getInt("action_index")); + + if (getArguments().getInt("action_index", -1) != -1) { + this.action = group.getActions().get(getArguments().getInt("action_index")); + } } else { - this.action = Backend.instance().getConfig().getPresets().getActions().get(getArguments().getInt("action_index")); + if (getArguments().getInt("action_index", -1) != -1) { + this.action = Backend.instance().getConfig().getPresets().getActions().get(getArguments().getInt("action_index")); + } else { + this.group = Backend.instance().getConfig().getPresets().getGroups().get(getArguments().getInt("group_index")); + } } } @@ -64,8 +72,13 @@ public class PresetDialog extends TimeCraftersDialog { }); if (!isNewPreset) { - title.setText("Editing " + action.name); - name.setText(action.name); + if (action != null) { + title.setText("Editing " + action.name); + name.setText(action.name); + } else { + title.setText("Editing " + group.name); + name.setText(group.name); + } mutate.setText(getResources().getString(R.string.dialog_update)); } else { title.setText("Add Preset"); @@ -91,37 +104,13 @@ public class PresetDialog extends TimeCraftersDialog { mutate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - final String presetName = name.getText().toString().trim(); - Action actionClone = deepCopyAction(action); - if (!isNewPreset && actionClone.name.equals(presetName)) { - dismiss(); - } + final String presetName = name.getText().toString().trim(); - if (validated(presetName)) { - if (action.name != presetName) { - if (isNewPreset) { - actionClone.name = presetName; - } else { - action.name = presetName; - } - } - - if (isNewPreset) { - Backend.instance().getConfig().getPresets().getActions().add(actionClone); - - ActionsFragment fragment = (ActionsFragment) getFragmentManager().getPrimaryNavigationFragment(); - Snackbar.make(fragment.getActivity().findViewById(R.id.snackbar_host), "Saved preset: " + presetName, Snackbar.LENGTH_LONG).show(); - } else { // Don't repopulate presets when it is not possible - PresetsFragment fragment = (PresetsFragment) getFragmentManager().getPrimaryNavigationFragment(); - if (fragment != null) { - fragment.populatePresets(); - } - } - - Backend.instance().configChanged(); - - dismiss(); - } + if (action != null) { + handleAction(presetName); + } else { + handleGroup(presetName); + } } }); @@ -130,13 +119,25 @@ public class PresetDialog extends TimeCraftersDialog { private boolean validated(String name) { String message = ""; - ArrayList actions = Backend.instance().getConfig().getPresets().getActions(); boolean nameUnique = true; - for (Action a : actions) { - if (a.name.equals(name)) { - nameUnique = false; - break; + if (action != null) { + ArrayList actions = Backend.instance().getConfig().getPresets().getActions(); + + for (Action a : actions) { + if (a.name.equals(name)) { + nameUnique = false; + break; + } + } + } else { + ArrayList groups = Backend.instance().getConfig().getPresets().getGroups(); + + for (Group g : groups) { + if (g.name.equals(name)) { + nameUnique = false; + break; + } } } @@ -158,9 +159,80 @@ public class PresetDialog extends TimeCraftersDialog { } } + private Group deepCopyGroup(Group group) { + String json = Backend.instance().gsonForConfig().toJson(group); + + return Backend.instance().gsonForConfig().fromJson(json, Group.class); + } + private Action deepCopyAction(Action action) { String json = Backend.instance().gsonForConfig().toJson(action); return Backend.instance().gsonForConfig().fromJson(json, Action.class); } + + private void handleGroup(String presetName) { + Group groupClone = deepCopyGroup(group); + if (!isNewPreset && groupClone.name.equals(presetName)) { + dismiss(); + } + + if (validated(presetName)) { + if (group.name != presetName) { + if (isNewPreset) { + groupClone.name = presetName; + } else { + group.name = presetName; + } + } + + if (isNewPreset) { + Backend.instance().getConfig().getPresets().getGroups().add(groupClone); + + GroupsFragment fragment = (GroupsFragment) getFragmentManager().getPrimaryNavigationFragment(); + Snackbar.make(fragment.getActivity().findViewById(R.id.snackbar_host), "Saved group preset: " + presetName, Snackbar.LENGTH_LONG).show(); + } else { // Don't repopulate presets when it is not possible + PresetsFragment fragment = (PresetsFragment) getFragmentManager().getPrimaryNavigationFragment(); + if (fragment != null) { + fragment.populatePresets(); + } + } + + Backend.instance().configChanged(); + + dismiss(); + } + } + private void handleAction(String presetName) { + Action actionClone = deepCopyAction(action); + if (!isNewPreset && actionClone.name.equals(presetName)) { + dismiss(); + } + + if (validated(presetName)) { + if (action.name != presetName) { + if (isNewPreset) { + actionClone.name = presetName; + } else { + action.name = presetName; + } + } + + if (isNewPreset) { + Backend.instance().getConfig().getPresets().getActions().add(actionClone); + + ActionsFragment fragment = (ActionsFragment) getFragmentManager().getPrimaryNavigationFragment(); + Snackbar.make(fragment.getActivity().findViewById(R.id.snackbar_host), "Saved action preset: " + presetName, Snackbar.LENGTH_LONG).show(); + } else { // Don't repopulate presets when it is not possible + PresetsFragment fragment = (PresetsFragment) getFragmentManager().getPrimaryNavigationFragment(); + if (fragment != null) { + fragment.populatePresets(); + } + } + + Backend.instance().configChanged(); + + dismiss(); + } + } } diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/VariableDialog.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/VariableDialog.java index 971d71e..fd03b61 100644 --- a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/VariableDialog.java +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/dialogs/VariableDialog.java @@ -47,6 +47,9 @@ public class VariableDialog extends TimeCraftersDialog { if (getArguments() != null) { if (getArguments().getBoolean("action_is_preset")) { action = Backend.instance().getConfig().getPresets().getActions().get(getArguments().getInt("action_index")); + } else if (getArguments().getBoolean("group_is_preset")) { + Group group = Backend.instance().getConfig().getPresets().getGroups().get(getArguments().getInt("group_index")); + action = group.getActions().get(getArguments().getInt("action_index")); } else { Group group = Backend.instance().getConfig().getGroups().get(getArguments().getInt("group_index")); action = group.getActions().get(getArguments().getInt("action_index")); @@ -70,12 +73,6 @@ public class VariableDialog extends TimeCraftersDialog { showVariableTypeMenu(); } }); - variableType.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - getActivity().getMenuInflater().inflate(R.menu.variable_type_menu, menu); - } - }); variableValue = root.findViewById(R.id.variableValue); variableValueBoolean = root.findViewById(R.id.variableValueBoolean); @@ -101,7 +98,7 @@ public class VariableDialog extends TimeCraftersDialog { variableValue.setText(variable.value().toString()); } } else { - title.setText("Add Variable"); + title.setText(R.string.add_variable); setVariableType("Double"); } diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/ActionsFragment.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/ActionsFragment.java index 643552d..42197ff 100644 --- a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/ActionsFragment.java +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/ActionsFragment.java @@ -2,7 +2,6 @@ package org.timecrafters.TimeCraftersConfigurationTool.ui.editor; import android.content.Context; import android.os.Bundle; -import android.view.ContextMenu; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.MenuItem; @@ -15,7 +14,6 @@ import android.widget.PopupMenu; import android.widget.ScrollView; import android.widget.Switch; import android.widget.TextView; -import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -30,6 +28,8 @@ import org.timecrafters.TimeCraftersConfigurationTool.backend.Config; import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Action; import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Group; import org.timecrafters.TimeCraftersConfigurationTool.dialogs.ActionDialog; +import org.timecrafters.TimeCraftersConfigurationTool.dialogs.AddFromPresetDialog; +import org.timecrafters.TimeCraftersConfigurationTool.dialogs.CloneDialog; import org.timecrafters.TimeCraftersConfigurationTool.dialogs.ConfirmationDialog; import org.timecrafters.TimeCraftersConfigurationTool.dialogs.PresetDialog; import org.timecrafters.TimeCraftersConfigurationTool.library.TimeCraftersDialog; @@ -42,6 +42,7 @@ public class ActionsFragment extends TimeCraftersFragment { private Config config; private Group group; private LinearLayout container; + private boolean groupIsPreset = false; @Nullable @Override @@ -52,7 +53,12 @@ public class ActionsFragment extends TimeCraftersFragment { final ScrollView scrollView = root.findViewById(R.id.scrollview); this.config = Backend.instance().getConfig(); - this.group = config.getGroups().get(getArguments().getInt("group_index")); + this.groupIsPreset = getArguments().getBoolean("group_is_preset", false); + if (groupIsPreset) { + this.group = config.getPresets().getGroups().get(getArguments().getInt("group_index")); + } else { + this.group = config.getGroups().get(getArguments().getInt("group_index")); + } if (config != null) { ((AppCompatActivity)getActivity()).getSupportActionBar().setTitle("Group: " + group.name); @@ -65,12 +71,24 @@ public class ActionsFragment extends TimeCraftersFragment { public void onClick(View v) { ActionDialog dialog = new ActionDialog(); Bundle bundle = new Bundle(); + if (groupIsPreset) { + bundle.putBoolean("group_is_preset", true); + } bundle.putInt("group_index", getArguments().getInt("group_index")); dialog.setArguments(bundle); dialog.show(getFragmentManager(), "add_action"); } }); + actionButton.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + showAddMenu(actionButton); + + return true; + } + }); + return root; } @@ -108,22 +126,19 @@ public class ActionsFragment extends TimeCraftersFragment { name.setOnLongClickListener(new View.OnLongClickListener() { @Override public boolean onLongClick(View v) { - showContextMenu(name, index); + showActionExtrasMenu(name, index); return true; } }); - name.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { - @Override - public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { - getActivity().getMenuInflater().inflate(R.menu.action_extras_menu, menu); - } - }); edit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Bundle bundle = new Bundle(); + if (groupIsPreset) { + bundle.putBoolean("group_is_preset", true); + } bundle.putInt("group_index", getArguments().getInt("group_index")); bundle.putInt("action_index", group.getActions().indexOf(action)); Navigation.findNavController(v).navigate(R.id.variables_fragment, bundle); @@ -141,6 +156,9 @@ public class ActionsFragment extends TimeCraftersFragment { public void onClick(View v) { ActionDialog dialog = new ActionDialog(); Bundle bundle = new Bundle(); + if (groupIsPreset) { + bundle.putBoolean("group_is_preset", true); + } bundle.putInt("group_index", getArguments().getInt("group_index")); bundle.putInt("action_index", group.getActions().indexOf(action)); dialog.setArguments(bundle); @@ -181,7 +199,7 @@ public class ActionsFragment extends TimeCraftersFragment { } } - private void showContextMenu(View view, final int action_index) { + private void showActionExtrasMenu(View view, final int action_index) { Context context = new ContextThemeWrapper(getActivity(), R.style.PopUpMenu); PopupMenu menu = new PopupMenu(context, view); menu.getMenuInflater().inflate(R.menu.action_extras_menu, menu.getMenu()); @@ -191,7 +209,12 @@ public class ActionsFragment extends TimeCraftersFragment { public boolean onMenuItemClick(MenuItem item) { switch (item.getItemId()) { case R.id.clone: { - // SHOW CLONE DIALOG + CloneDialog dialog = new CloneDialog(); + Bundle bundle = new Bundle(); + bundle.putInt("group_index", getArguments().getInt("group_index")); + bundle.putInt("action_index", action_index); + dialog.setArguments(bundle); + dialog.show(getFragmentManager(), "clone_dialog"); return true; } case R.id.save_as_preset: { @@ -212,4 +235,30 @@ public class ActionsFragment extends TimeCraftersFragment { menu.show(); } + + private void showAddMenu(View view) { + Context context = new ContextThemeWrapper(getActivity(), R.style.PopUpMenu); + PopupMenu menu = new PopupMenu(context, view); + menu.getMenuInflater().inflate(R.menu.action_add_menu, menu.getMenu()); + + menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.add_from_preset: { + AddFromPresetDialog dialog = new AddFromPresetDialog(); + Bundle bundle = new Bundle(); + bundle.putBoolean("show_actions", true); + dialog.setArguments(bundle); + dialog.show(getFragmentManager(), "add_from_preset_dialog"); + return true; + } + default: + return false; + } + } + }); + + menu.show(); + } } diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/GroupsFragment.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/GroupsFragment.java index d1575bf..f637b2f 100644 --- a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/GroupsFragment.java +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/GroupsFragment.java @@ -1,13 +1,17 @@ package org.timecrafters.TimeCraftersConfigurationTool.ui.editor; +import android.content.Context; import android.os.Bundle; import android.util.Log; +import android.view.ContextThemeWrapper; import android.view.LayoutInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageButton; import android.widget.LinearLayout; +import android.widget.PopupMenu; import android.widget.ScrollView; import android.widget.TextView; @@ -22,8 +26,11 @@ import org.timecrafters.TimeCraftersConfigurationTool.R; import org.timecrafters.TimeCraftersConfigurationTool.backend.Backend; import org.timecrafters.TimeCraftersConfigurationTool.backend.Config; import org.timecrafters.TimeCraftersConfigurationTool.backend.config.Group; +import org.timecrafters.TimeCraftersConfigurationTool.dialogs.AddFromPresetDialog; +import org.timecrafters.TimeCraftersConfigurationTool.dialogs.CloneDialog; import org.timecrafters.TimeCraftersConfigurationTool.dialogs.ConfirmationDialog; import org.timecrafters.TimeCraftersConfigurationTool.dialogs.GroupDialog; +import org.timecrafters.TimeCraftersConfigurationTool.dialogs.PresetDialog; import org.timecrafters.TimeCraftersConfigurationTool.library.TimeCraftersDialog; import org.timecrafters.TimeCraftersConfigurationTool.library.TimeCraftersFragment; import org.timecrafters.TimeCraftersConfigurationTool.library.TimeCraftersDialogRunnable; @@ -59,6 +66,15 @@ public class GroupsFragment extends TimeCraftersFragment { } }); + actionButton.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + showAddMenu(actionButton); + + return true; + } + }); + floatingActionButtonAutoHide(actionButton, scrollView); if (Backend.instance() != null) { if (Backend.instance().getConfig() == null) { @@ -86,7 +102,7 @@ public class GroupsFragment extends TimeCraftersFragment { int i = 0; for (final Group group : config.getGroups()) { View view = View.inflate(getContext(), R.layout.fragment_part_groups, null); - Button name = view.findViewById(R.id.name); + final Button name = view.findViewById(R.id.name); ImageButton rename = view.findViewById(R.id.rename); ImageButton delete = view.findViewById(R.id.delete); @@ -96,6 +112,8 @@ public class GroupsFragment extends TimeCraftersFragment { view.setBackgroundColor(getResources().getColor(R.color.list_odd)); } + final int index = i; + name.setText(group.name); name.setOnClickListener(new View.OnClickListener() { @Override @@ -105,6 +123,14 @@ public class GroupsFragment extends TimeCraftersFragment { Navigation.findNavController(v).navigate(R.id.actions_fragment, bundle); } }); + name.setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + showActionExtrasMenu(name, index); + + return true; + } + }); rename.setOnClickListener(new View.OnClickListener() { @Override @@ -151,4 +177,65 @@ public class GroupsFragment extends TimeCraftersFragment { container.addView(view); } } + + private void showActionExtrasMenu(View view, final int group_index) { + Context context = new ContextThemeWrapper(getActivity(), R.style.PopUpMenu); + PopupMenu menu = new PopupMenu(context, view); + menu.getMenuInflater().inflate(R.menu.action_extras_menu, menu.getMenu()); + + menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.clone: { + CloneDialog dialog = new CloneDialog(); + Bundle bundle = new Bundle(); + bundle.putInt("group_index", group_index); + dialog.setArguments(bundle); + dialog.show(getFragmentManager(), "clone_dialog"); + return true; + } + case R.id.save_as_preset: { + PresetDialog dialog = new PresetDialog(); + Bundle bundle = new Bundle(); + bundle.putInt("group_index", group_index); + bundle.putBoolean("is_new_preset", true); + dialog.setArguments(bundle); + dialog.show(getFragmentManager(), "preset_dialog"); + return true; + } + default: + return false; + } + } + }); + + menu.show(); + } + + private void showAddMenu(View view) { + Context context = new ContextThemeWrapper(getActivity(), R.style.PopUpMenu); + PopupMenu menu = new PopupMenu(context, view); + menu.getMenuInflater().inflate(R.menu.action_add_menu, menu.getMenu()); + + menu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + switch (item.getItemId()) { + case R.id.add_from_preset: { + AddFromPresetDialog dialog = new AddFromPresetDialog(); + Bundle bundle = new Bundle(); + bundle.putBoolean("show_actions", false); + dialog.setArguments(bundle); + dialog.show(getFragmentManager(), "add_from_preset_dialog"); + return true; + } + default: + return false; + } + } + }); + + menu.show(); + } } \ No newline at end of file diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/VariablesFragment.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/VariablesFragment.java index 89ac7e9..c196025 100644 --- a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/VariablesFragment.java +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/editor/VariablesFragment.java @@ -33,7 +33,7 @@ public class VariablesFragment extends TimeCraftersFragment { private Config config; private LinearLayout container; - private boolean actionIsPreset = false; + private boolean groupIsPreset = false, actionIsPreset = false; private Group group; private Action action; @@ -45,9 +45,13 @@ public class VariablesFragment extends TimeCraftersFragment { final ScrollView scrollView = root.findViewById(R.id.scrollview); this.config = Backend.instance().getConfig(); + this.groupIsPreset = getArguments().getBoolean("group_is_preset", false); this.actionIsPreset = getArguments().getBoolean("action_is_preset", false); if (actionIsPreset) { this.action = config.getPresets().getActions().get(getArguments().getInt("action_index")); + } else if (groupIsPreset) { + this.group = config.getPresets().getGroups().get(getArguments().getInt("group_index")); + this.action = group.getActions().get(getArguments().getInt("action_index")); } else { this.group = config.getGroups().get(getArguments().getInt("group_index")); this.action = group.getActions().get(getArguments().getInt("action_index")); @@ -66,7 +70,10 @@ public class VariablesFragment extends TimeCraftersFragment { VariableDialog dialog = new VariableDialog(); Bundle bundle = new Bundle(); if (actionIsPreset) { - bundle.putBoolean("action_is_preset", actionIsPreset); + bundle.putBoolean("action_is_preset", true); + } else if (groupIsPreset) { + bundle.putBoolean("group_is_preset", true); + bundle.putInt("group_index", getArguments().getInt("group_index")); } else { bundle.putInt("group_index", getArguments().getInt("group_index")); } @@ -105,7 +112,10 @@ public class VariablesFragment extends TimeCraftersFragment { VariableDialog dialog = new VariableDialog(); Bundle bundle = new Bundle(); if (actionIsPreset) { - bundle.putBoolean("action_is_preset", actionIsPreset); + bundle.putBoolean("action_is_preset", true); + } else if (groupIsPreset) { + bundle.putBoolean("group_is_preset", true); + bundle.putInt("group_index", getArguments().getInt("group_index")); } else { bundle.putInt("group_index", getArguments().getInt("group_index")); } diff --git a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/settings/presets/PresetsFragment.java b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/settings/presets/PresetsFragment.java index 83e6705..c77a3fe 100644 --- a/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/settings/presets/PresetsFragment.java +++ b/app/src/main/java/org/timecrafters/TimeCraftersConfigurationTool/ui/settings/presets/PresetsFragment.java @@ -45,11 +45,16 @@ public class PresetsFragment extends TimeCraftersFragment { } public void populatePresets() { + populateGroups(); + populateActions(); + } + + private void populateGroups() { groupsContainer.removeAllViews(); - actionsContainer.removeAllViews(); int i = 0; - for (Group group : Backend.instance().getConfig().getPresets().getGroups()) { + for (final Group group : Backend.instance().getConfig().getPresets().getGroups()) { + final int group_index = i; View view = inflater.inflate(R.layout.fragment_part_presets, null); if (i % 2 == 0) { // even @@ -58,12 +63,74 @@ public class PresetsFragment extends TimeCraftersFragment { view.setBackgroundColor(getResources().getColor(R.color.list_odd)); } + Button name = view.findViewById(R.id.name); + ImageButton rename = view.findViewById(R.id.rename); + ImageButton delete = view.findViewById(R.id.delete); + + name.setText(group.name); + name.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Bundle bundle = new Bundle(); + bundle.putBoolean("group_is_preset", true); + bundle.putInt("group_index", group_index); + Navigation.findNavController(v).navigate(R.id.actions_fragment, bundle); + } + }); + + rename.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + PresetDialog dialog = new PresetDialog(); + Bundle bundle = new Bundle(); + bundle.putInt("group_index", group_index); + dialog.setArguments(bundle); + dialog.show(getFragmentManager(), "preset_dialog"); + } + }); + + delete.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ConfirmationDialog dialog = new ConfirmationDialog(); + Bundle bundle = new Bundle(); + + bundle.putString("message", "Delete group preset " + group.name + "?"); + bundle.putString("action", deletePresetKey); + TimeCraftersDialogRunnable action = new TimeCraftersDialogRunnable() { + @Override + public void run(TimeCraftersDialog dialog) { + Backend.getStorage().remove(deletePresetKey); + + if (Backend.instance().getConfig().getPresets().getGroups().get(group_index) != null) { + Backend.instance().getConfig().getPresets().getGroups().remove(group_index); + + Backend.instance().configChanged(); + } + + PresetsFragment fragment = (PresetsFragment) dialog.getFragmentManager().getPrimaryNavigationFragment(); + if (fragment != null) { + fragment.populatePresets(); + } + } + } ; + Backend.getStorage().put(deletePresetKey, action); + dialog.setArguments(bundle); + + dialog.show(getFragmentManager(), deletePresetKey); + } + }); + groupsContainer.addView(view); i++; } + } - i = 0; - for (Action action : Backend.instance().getConfig().getPresets().getActions()) { + private void populateActions() { + actionsContainer.removeAllViews(); + + int i = 0; + for (final Action action : Backend.instance().getConfig().getPresets().getActions()) { final int action_index = i; View view = inflater.inflate(R.layout.fragment_part_presets, null); @@ -105,7 +172,7 @@ public class PresetsFragment extends TimeCraftersFragment { ConfirmationDialog dialog = new ConfirmationDialog(); Bundle bundle = new Bundle(); - bundle.putString("message", "Delete Preset?"); + bundle.putString("message", "Delete action preset " + action.name + "?"); bundle.putString("action", deletePresetKey); TimeCraftersDialogRunnable action = new TimeCraftersDialogRunnable() { @Override diff --git a/app/src/main/res/layout/dialog_add_from_preset.xml b/app/src/main/res/layout/dialog_add_from_preset.xml new file mode 100644 index 0000000..d037dc3 --- /dev/null +++ b/app/src/main/res/layout/dialog_add_from_preset.xml @@ -0,0 +1,20 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_part_add_from_preset.xml b/app/src/main/res/layout/fragment_part_add_from_preset.xml new file mode 100644 index 0000000..1f31e5a --- /dev/null +++ b/app/src/main/res/layout/fragment_part_add_from_preset.xml @@ -0,0 +1,28 @@ + + + + + +