From 7c1decdc04992ed7c64a4e06467cea063d66fcb9 Mon Sep 17 00:00:00 2001 From: hyb1996 <946994919@qq.com> Date: Mon, 6 Nov 2017 23:45:36 +0800 Subject: [PATCH] add: simple code generation --- app/build.gradle | 1 + .../ui/codegeneration/CodeGenerateDialog.java | 306 ++++++++++++++++++ .../LayoutBoundsFloatyWindow.java | 27 +- .../scriptdroid/ui/main/MainActivity.java | 5 +- .../res/layout/activity_code_generate.xml | 7 + .../main/res/layout/dialog_code_generate.xml | 11 + .../layout/dialog_code_generate_option.xml | 22 ++ .../dialog_code_generate_option_group.xml | 24 ++ app/src/main/res/values/strings.xml | 18 ++ autojs/build.gradle | 4 + .../codegeneration/AutoScriptGenerator.java | 10 - .../codegeneration/ReadOnlyUiObject.java | 226 +++++++++++++ .../codegeneration/UiSelectorGenerator.java | 149 +++++++++ .../stardust/automator/UiGlobalSelector.java | 6 +- .../java/com/stardust/automator/UiObject.java | 7 +- .../stardust/automator/filter/IdFilter.java | 4 +- .../stardust/automator/filter/TextFilter.java | 2 +- .../stardust/view/accessibility/NodeInfo.java | 33 +- 18 files changed, 822 insertions(+), 40 deletions(-) create mode 100644 app/src/main/java/com/stardust/scriptdroid/ui/codegeneration/CodeGenerateDialog.java create mode 100644 app/src/main/res/layout/activity_code_generate.xml create mode 100644 app/src/main/res/layout/dialog_code_generate.xml create mode 100644 app/src/main/res/layout/dialog_code_generate_option.xml create mode 100644 app/src/main/res/layout/dialog_code_generate_option_group.xml delete mode 100644 autojs/src/main/java/com/stardust/autojs/codegeneration/AutoScriptGenerator.java create mode 100644 autojs/src/main/java/com/stardust/autojs/codegeneration/ReadOnlyUiObject.java create mode 100644 autojs/src/main/java/com/stardust/autojs/codegeneration/UiSelectorGenerator.java diff --git a/app/build.gradle b/app/build.gradle index 6dfb48e2..aeaf501c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,6 +102,7 @@ dependencies { compile 'com.yqritc:recyclerview-flexibledivider:1.4.0' compile 'com.wang.avi:library:2.1.3' compile 'org.apache.commons:commons-lang3:3.6' + compile 'com.thoughtbot:expandablerecyclerview:1.3' compile 'com.github.hyb1996:FloatingCircularActionMenu:0.0.2' compile(name: 'apkbuilder-release', ext: 'aar') diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/codegeneration/CodeGenerateDialog.java b/app/src/main/java/com/stardust/scriptdroid/ui/codegeneration/CodeGenerateDialog.java new file mode 100644 index 00000000..ffdf9114 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/ui/codegeneration/CodeGenerateDialog.java @@ -0,0 +1,306 @@ +package com.stardust.scriptdroid.ui.codegeneration; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; +import android.widget.Toast; + +import com.bignerdranch.expandablerecyclerview.ChildViewHolder; +import com.bignerdranch.expandablerecyclerview.ExpandableRecyclerAdapter; +import com.bignerdranch.expandablerecyclerview.ParentViewHolder; +import com.bignerdranch.expandablerecyclerview.model.Parent; +import com.stardust.autojs.codegeneration.UiSelectorGenerator; +import com.stardust.scriptdroid.R; +import com.stardust.scriptdroid.ui.widget.CheckBoxCompat; +import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder; +import com.stardust.theme.util.ListBuilder; +import com.stardust.util.ClipboardUtil; +import com.stardust.view.accessibility.NodeInfo; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnCheckedChanged; + +/** + * Created by Stardust on 2017/11/6. + */ + +public class CodeGenerateDialog extends ThemeColorMaterialDialogBuilder { + + private final List mOptionGroups = new ListBuilder() + .add(new OptionGroup(R.string.text_options, false) + .addOption(R.string.text_using_id_selector, true) + .addOption(R.string.text_using_text_selector, true) + .addOption(R.string.text_using_desc_selector, true)) + .add(new OptionGroup(R.string.text_select) + .addOption(R.string.text_find_one, true) + .addOption(R.string.text_until_find) + .addOption(R.string.text_wait_for) + .addOption(R.string.text_selector_exists)) + .add(new OptionGroup(R.string.text_action) + .addOption(R.string.text_click) + .addOption(R.string.text_long_click) + .addOption(R.string.text_set_text) + .addOption(R.string.text_scroll_forward) + .addOption(R.string.text_scroll_backward)) + .list(); + + @BindView(R.id.options) + RecyclerView mOptionsRecyclerView; + + private NodeInfo mRootNode; + private NodeInfo mTargetNode; + private Adapter mAdapter; + + public CodeGenerateDialog(@NonNull Context context, NodeInfo rootNode, NodeInfo targetNode) { + super(context); + mRootNode = rootNode; + mTargetNode = targetNode; + positiveText(R.string.text_generate_and_copy); + neutralText(R.string.text_generate_and_open_editor); + onPositive(((dialog, which) -> generateCodeAndCopy())); + onNeutral(((dialog, which) -> generateCodeAndOpenEditor())); + setupViews(); + } + + private void generateCodeAndCopy() { + String code = generateCode(); + if (code == null) { + Toast.makeText(getContext(), R.string.text_generate_fail, Toast.LENGTH_SHORT).show(); + return; + } + ClipboardUtil.setClip(getContext(), code); + Toast.makeText(getContext(), R.string.text_already_copy_to_clip, Toast.LENGTH_SHORT).show(); + } + + private void generateCodeAndOpenEditor() { + + } + + private String generateCode() { + UiSelectorGenerator generator = new UiSelectorGenerator(mRootNode, mTargetNode); + OptionGroup settings = getOptionGroup(R.string.text_options); + generator.setUsingId(settings.getOption(R.string.text_using_id_selector).checked); + generator.setUsingText(settings.getOption(R.string.text_using_text_selector).checked); + generator.setUsingDesc(settings.getOption(R.string.text_using_desc_selector).checked); + generator.setSearchMode(getSearchMode()); + setAction(generator); + return generator.generate(); + } + + private void setAction(UiSelectorGenerator generator) { + OptionGroup action = getOptionGroup(R.string.text_action); + if (action.getOption(R.string.text_click).checked) { + generator.setAction(AccessibilityNodeInfoCompat.ACTION_CLICK); + } + if (action.getOption(R.string.text_long_click).checked) { + generator.setAction(AccessibilityNodeInfoCompat.ACTION_LONG_CLICK); + } + if (action.getOption(R.string.text_scroll_forward).checked) { + generator.setAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_FORWARD); + } + if (action.getOption(R.string.text_scroll_backward).checked) { + generator.setAction(AccessibilityNodeInfoCompat.ACTION_SCROLL_BACKWARD); + } + } + + private int getSearchMode() { + OptionGroup selectMode = getOptionGroup(R.string.text_select); + if (selectMode.getOption(R.string.text_find_one).checked) { + return UiSelectorGenerator.FIND_ONE; + } + if (selectMode.getOption(R.string.text_until_find).checked) { + return UiSelectorGenerator.UNTIL_FIND; + } + if (selectMode.getOption(R.string.text_wait_for).checked) { + return UiSelectorGenerator.WAIT_FOR; + } + if (selectMode.getOption(R.string.text_wait_for).checked) { + return UiSelectorGenerator.EXISTS; + } + return UiSelectorGenerator.FIND_ONE; + } + + private void setupViews() { + View view = View.inflate(context, R.layout.dialog_code_generate, null); + ButterKnife.bind(this, view); + customView(view, false); + mOptionsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + mAdapter = new Adapter(mOptionGroups); + mOptionsRecyclerView.setAdapter(mAdapter); + } + + + private OptionGroup getOptionGroup(int title) { + for (OptionGroup group : mOptionGroups) { + if (group.titleRes == title) { + return group; + } + } + throw new IllegalArgumentException(); + } + + + private void uncheckOthers(int parentAdapterPosition, Option child) { + boolean notify = false; + for (Option other : child.group.options) { + if (other != child) { + if (other.checked) { + other.checked = false; + notify = true; + } + } + } + if (notify) + mAdapter.notifyParentChanged(parentAdapterPosition); + } + + private static class Option { + int titleRes; + boolean checked; + OptionGroup group; + + Option(int titleRes, boolean checked) { + this.titleRes = titleRes; + this.checked = checked; + } + + } + + class OptionViewHolder extends ChildViewHolder