Created base files for UI Designer

This commit is contained in:
Akash Yadav
2021-12-13 15:37:47 +05:30
parent fa8d89743e
commit 7ae38c8369
737 changed files with 2833 additions and 1984 deletions
Regular → Executable
View File
Generated Regular → Executable
+3 -3
View File
@@ -1,3 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml
# Default ignored files
/shelf/
/workspace.xml
Generated Regular → Executable
View File
Generated Regular → Executable
+5 -5
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>
Generated Regular → Executable
+5 -5
View File
@@ -1,6 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value=" This file is part of AndroidIDE.&#10; &#10; AndroidIDE is free software: you can redistribute it and/or modify&#10; it under the terms of the GNU General Public License as published by&#10; the Free Software Foundation, either version 3 of the License, or&#10; (at your option) any later version.&#10; &#10; AndroidIDE is distributed in the hope that it will be useful,&#10; but WITHOUT ANY WARRANTY; without even the implied warranty of&#10; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10; GNU General Public License for more details.&#10; &#10; You should have received a copy of the GNU General Public License&#10; along with AndroidIDE. If not, see &lt;https://www.gnu.org/licenses/&gt;." />
<option name="myName" value="Akash Yadav" />
</copyright>
<component name="CopyrightManager">
<copyright>
<option name="notice" value=" This file is part of AndroidIDE.&#10; &#10; AndroidIDE is free software: you can redistribute it and/or modify&#10; it under the terms of the GNU General Public License as published by&#10; the Free Software Foundation, either version 3 of the License, or&#10; (at your option) any later version.&#10; &#10; AndroidIDE is distributed in the hope that it will be useful,&#10; but WITHOUT ANY WARRANTY; without even the implied warranty of&#10; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10; GNU General Public License for more details.&#10; &#10; You should have received a copy of the GNU General Public License&#10; along with AndroidIDE. If not, see &lt;https://www.gnu.org/licenses/&gt;." />
<option name="myName" value="Akash Yadav" />
</copyright>
</component>
Generated Regular → Executable
+12 -12
View File
@@ -1,13 +1,13 @@
<component name="CopyrightManager">
<settings>
<module2copyright>
<element module="Project Files" copyright="Akash Yadav" />
</module2copyright>
<LanguageOptions name="JAVA">
<option name="fileTypeOverride" value="3" />
</LanguageOptions>
<LanguageOptions name="XML">
<option name="fileTypeOverride" value="3" />
</LanguageOptions>
</settings>
<component name="CopyrightManager">
<settings>
<module2copyright>
<element module="Project Files" copyright="Akash Yadav" />
</module2copyright>
<LanguageOptions name="JAVA">
<option name="fileTypeOverride" value="3" />
</LanguageOptions>
<LanguageOptions name="XML">
<option name="fileTypeOverride" value="3" />
</LanguageOptions>
</settings>
</component>
Generated Regular → Executable
+39 -34
View File
@@ -1,35 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:/$PROJECT_DIR$/../../../Akash%20Yadav/.m2/repository/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenRepo" />
<option name="name" value="MavenRepo" />
<option name="url" value="https://repo.maven.apache.org/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:/$PROJECT_DIR$/../../../Akash%20Yadav/.m2/repository/" />
</remote-repository>
<remote-repository>
<option name="id" value="maven" />
<option name="name" value="maven" />
<option name="url" value="https://jitpack.io" />
</remote-repository>
<remote-repository>
<option name="id" value="Google" />
<option name="name" value="Google" />
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
</remote-repository>
<remote-repository>
<option name="id" value="MavenLocal" />
<option name="name" value="MavenLocal" />
<option name="url" value="file:/C:/Users/Akash%20Yadav/.m2/repository/" />
</remote-repository>
</component>
</project>
Generated Regular → Executable
+34 -17
View File
@@ -1,18 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/activity_main.xml" value="0.264" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_create_project.xml" value="0.20854700854700856" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_create_project_content.xml" value="0.33" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable/bg_ripple.xml" value="0.3105485232067511" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable/bg_ripple_pressed.xml" value="0.3105485232067511" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable/bg_widget_group_selected.xml" value="0.33" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable/ic_replace.xml" value="0.3105485232067511" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable/ic_widget_edittext.xml" value="0.3105485232067511" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/drawable/ic_widget_seekbar.xml" value="0.3105485232067511" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/layout/activity_designer.xml" value="0.33" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/layout/activity_download.xml" value="0.30128205128205127" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/layout/activity_editor.xml" value="0.30128205128205127" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_simple_icon_text.xml" value="0.30128205128205127" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_widget_group_item.xml" value="0.33" />
<entry key="..\:/Projects/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_widget_item.xml" value="0.33" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/drawable/ic_website.xml" value="0.2189873417721519" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/drawable/ic_widget_button.xml" value="0.22179487179487178" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/activity_designer.xml" value="0.264" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/activity_main.xml" value="0.33" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_create_project.xml" value="0.20854700854700856" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_create_project_content.xml" value="0.33" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/layout/layout_widget_item.xml" value="0.264" />
<entry key="..\:/Users/Akash Yadav/AndroidStudioProjects/android-ide/app/src/main/res/menu/menu_designer_widgets.xml" value="0.20854700854700856" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
+3 -1
View File
@@ -31,7 +31,9 @@ android {
"SmallSp"
}
buildFeatures.viewBinding true
buildFeatures {
viewBinding true
}
signingConfigs {
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Regular → Executable
View File
Vendored Regular → Executable
View File
Regular → Executable
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
Regular → Executable
View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File
+84 -14
View File
@@ -17,18 +17,43 @@
**************************************************************************************/
package com.itsaky.androidide;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.core.content.ContextCompat;
import com.blankj.utilcode.util.ThrowableUtils;
import com.itsaky.androidide.adapters.WidgetGroupItemAdapter;
import com.itsaky.androidide.adapters.WidgetItemAdapter;
import com.itsaky.androidide.app.StudioActivity;
import com.itsaky.androidide.databinding.ActivityDesignerBinding;
import com.itsaky.androidide.models.UIWidget;
import com.itsaky.androidide.models.UIWidgetGroup;
import com.itsaky.androidide.utils.Logger;
import com.itsaky.layoutinflater.ILayoutInflater;
import com.itsaky.layoutinflater.IView;
import com.itsaky.toaster.Toaster;
import org.jetbrains.annotations.Contract;
import java.util.ArrayList;
import java.util.List;
public class DesignerActivity extends StudioActivity {
@@ -36,7 +61,14 @@ public class DesignerActivity extends StudioActivity {
public static final String KEY_LAYOUT_PATH = "designer_layoutPath";
private static final Logger LOG = Logger.instance("DesignerActivity");
private final List<UIWidgetGroup> widgetGroups = new ArrayList<>();
private final WidgetItemAdapter.OnWidgetDragListener dragListener = (widget, v, event) -> {
getApp().toast("Dragging: " + widget.getName(), Toaster.Type.INFO);
return true;
};
@Override
protected View bindLayout() {
mBinding = ActivityDesignerBinding.inflate(getLayoutInflater());
@@ -46,10 +78,13 @@ public class DesignerActivity extends StudioActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final var toggle = new ActionBarDrawerToggle(this, mBinding.getRoot(), mBinding.toolbar, R.string.app_name, R.string.app_name);
mBinding.getRoot().addDrawerListener(toggle);
toggle.syncState();
setSupportActionBar(mBinding.toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mBinding.toolbar.setNavigationOnClickListener(v -> onBackPressed());
final Bundle extras = getIntent().getExtras();
final String path = extras.getString(KEY_LAYOUT_PATH, null);
@@ -57,25 +92,60 @@ public class DesignerActivity extends StudioActivity {
try {
final ILayoutInflater inflater = getApp().getLayoutInflater();
inflater.resetContextProvider(newContextProvider());
final IView view = inflater.inflatePath(path, mBinding.realContainer);
mBinding.realContainer.addView(view.asView());
final IView view = inflater.inflatePath(path, mBinding.layoutContainer);
mBinding.layoutContainer.addView(view.asView());
} catch (Throwable th) {
mBinding.realContainer.removeAllViews();
mBinding.realContainer.addView(createErrorText(th));
mBinding.layoutContainer.removeAllViews();
mBinding.layoutContainer.addView(createErrorText(th));
LOG.error (getString(R.string.err_cannot_inflate_layout));
}
setupWidgets();
}
private void setupWidgets() {
final var common = new UIWidgetGroup(getString(R.string.widget_group_android));
common.addChild(new UIWidget(getString(R.string.widget_button), R.drawable.ic_widget_button, Button.class));
common.addChild(new UIWidget(getString(R.string.widget_checkbox), R.drawable.ic_widget_checkbox, CheckBox.class));
common.addChild(new UIWidget(getString(R.string.widget_checked_textview), R.drawable.ic_widget_checked_textview, CheckedTextView.class));
common.addChild(new UIWidget(getString(R.string.widget_edittext), R.drawable.ic_widget_edittext, EditText.class));
common.addChild(new UIWidget(getString(R.string.widget_image_button), R.drawable.ic_widget_image, ImageButton.class));
common.addChild(new UIWidget(getString(R.string.widget_image_view), R.drawable.ic_widget_image, ImageView.class));
common.addChild(new UIWidget(getString(R.string.widget_progressbar), R.drawable.ic_widget_progress, ProgressBar.class));
common.addChild(new UIWidget(getString(R.string.widget_radio_button), R.drawable.ic_widget_radio_button, RadioButton.class));
common.addChild(new UIWidget(getString(R.string.widget_seekbar), R.drawable.ic_widget_seekbar, SeekBar.class));
common.addChild(new UIWidget(getString(R.string.widget_spinner), R.drawable.ic_widget_spinner, Spinner.class));
common.addChild(new UIWidget(getString(R.string.widget_textview), R.drawable.ic_widget_textview, TextView.class));
// IMPORTANT: Do not select any other groups here
common.setSelected(true);
widgetGroups.add(common);
final var layouts = new UIWidgetGroup("Layouts");
layouts.addChild(new UIWidget("LinearLayout", R.drawable.ic_widget_linear, LinearLayout.class));
layouts.addChild(new UIWidget("RelativeLayout", R.drawable.ic_widget_relative, RelativeLayout.class));
widgetGroups.add(layouts);
final var adapter = new WidgetGroupItemAdapter(widgetGroups, this::showWidgetGroup);
mBinding.groupItems.setAdapter(adapter);
showWidgetGroup(common);
}
private void showWidgetGroup (@NonNull UIWidgetGroup group) {
final var children = group.getChildren();
mBinding.widgetItems.setAdapter(new WidgetItemAdapter(children, dragListener));
}
@NonNull
@Contract(pure = true)
private ILayoutInflater.ContextProvider newContextProvider() {
return new ILayoutInflater.ContextProvider() {
@Override
public Context getContext() {
return DesignerActivity.this;
}
};
return () -> DesignerActivity.this;
}
@NonNull
private TextView createErrorText (Throwable th) {
final TextView error = new TextView (this);
error.setText(ThrowableUtils.getFullStackTrace(th));
View File
View File
View File
View File
View File
View File
View File
@@ -0,0 +1,105 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE 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.
*
* AndroidIDE 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 AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.itsaky.androidide.databinding.LayoutSimpleIconTextBinding;
import com.itsaky.androidide.models.IconTextListItem;
import java.util.List;
/**
* A RecyclerView.Adapter which can be used to show a list with an icon and a text.
*
* @author Akash Yadav
*/
public class SimpleIconTextAdapter extends RecyclerView.Adapter<SimpleIconTextAdapter.VH> {
private final List<? extends IconTextListItem> items;
private OnBindListener bindListener;
public SimpleIconTextAdapter(@NonNull List<? extends IconTextListItem> items) {
this.items = items;
}
public SimpleIconTextAdapter setOnBindListener (OnBindListener listener) {
this.bindListener = listener;
return this;
}
@NonNull
@Override
public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new VH (LayoutSimpleIconTextBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false));
}
@Override
public void onBindViewHolder(@NonNull VH holder, int position) {
final var binding = holder.binding;
final var item = items.get(position);
if (this.bindListener != null && this.bindListener.onBind(item, holder, position)) {
return;
}
final var icon = item.getIconResource();
if (icon == -1) {
binding.icon.setVisibility(View.GONE);
} else {
binding.icon.setImageResource(icon);
}
binding.text.setText(item.getText());
if (this.bindListener != null) {
this.bindListener.postBind(item, holder, position);
}
}
@Override
public int getItemCount() {
return items.size();
}
public IconTextListItem getItemAt (int index) {
return this.items.get(index);
}
public static class VH extends RecyclerView.ViewHolder {
public final LayoutSimpleIconTextBinding binding;
public VH(@NonNull LayoutSimpleIconTextBinding binding) {
super(binding.getRoot());
this.binding = binding;
}
}
public static interface OnBindListener {
boolean onBind (IconTextListItem item, VH holder, int position);
default void postBind (IconTextListItem item, VH holder, int position) {}
}
}
@@ -0,0 +1,60 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE 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.
*
* AndroidIDE 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 AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters;
import com.itsaky.androidide.models.IconTextListItem;
import com.itsaky.androidide.models.UIWidgetGroup;
import java.util.List;
public class WidgetGroupItemAdapter extends SimpleIconTextAdapter implements SimpleIconTextAdapter.OnBindListener {
private final OnGroupClickListener clickListener;
public WidgetGroupItemAdapter(List<UIWidgetGroup> groups, OnGroupClickListener clickListener) {
super(groups);
this.clickListener = clickListener;
}
@Override
public boolean onBind(IconTextListItem item, VH holder, int position) {
final var binding = holder.binding;
final var group = (UIWidgetGroup) getItemAt(position);
if (this.clickListener != null) {
binding.getRoot().setOnClickListener(v -> this.clickListener.onGroupClick(group));
}
return false;
}
@Override
public void postBind(IconTextListItem item, VH holder, int position) {
final var binding = holder.binding;
final var group = (UIWidgetGroup) item;
if (group.isSelected()) {
}
}
public interface OnGroupClickListener {
void onGroupClick(UIWidgetGroup group);
}
}
@@ -0,0 +1,58 @@
/*
* This file is part of AndroidIDE.
*
* AndroidIDE 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.
*
* AndroidIDE 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 AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
*/
package com.itsaky.androidide.adapters;
import android.view.DragEvent;
import android.view.View;
import androidx.annotation.NonNull;
import com.itsaky.androidide.models.IconTextListItem;
import com.itsaky.androidide.models.UIWidget;
import java.util.List;
public class WidgetItemAdapter extends SimpleIconTextAdapter implements SimpleIconTextAdapter.OnBindListener {
private final OnWidgetDragListener dragListener;
public WidgetItemAdapter(List<UIWidget> widgets, OnWidgetDragListener dragListener) {
super(widgets);
this.dragListener = dragListener;
setOnBindListener(this);
}
@Override
public boolean onBind(IconTextListItem item, @NonNull VH holder, int position) {
final var binding = holder.binding;
final var widget = (UIWidget) getItemAt(position);
if (this.dragListener != null) {
binding.getRoot().setOnDragListener((v, event) -> {
return this.dragListener.onDrag(widget, v, event);
});
}
return false; // Returning true will not set the text and icon
}
public static interface OnWidgetDragListener {
boolean onDrag(UIWidget widget, View v, DragEvent event);
}
}
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File
View File

Some files were not shown because too many files have changed in this diff Show More