diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 6c34a5748..c6bd08e0f 100755
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -9,22 +9,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/assets/data/common/tooling-api-all.jar b/app/src/main/assets/data/common/tooling-api-all.jar
index 516489fed..befda621a 100644
Binary files a/app/src/main/assets/data/common/tooling-api-all.jar and b/app/src/main/assets/data/common/tooling-api-all.jar differ
diff --git a/app/src/main/java/com/itsaky/androidide/EditorActivity.java b/app/src/main/java/com/itsaky/androidide/EditorActivity.java
index 3871187cb..30afd9138 100755
--- a/app/src/main/java/com/itsaky/androidide/EditorActivity.java
+++ b/app/src/main/java/com/itsaky/androidide/EditorActivity.java
@@ -20,11 +20,12 @@
package com.itsaky.androidide;
import static com.blankj.utilcode.util.IntentUtils.getShareTextIntent;
+import static com.itsaky.androidide.R.color;
+import static com.itsaky.androidide.R.drawable;
+import static com.itsaky.androidide.R.string;
import static com.itsaky.androidide.preferences.internal.GeneralPreferencesKt.NO_OPENED_PROJECT;
import static com.itsaky.androidide.preferences.internal.GeneralPreferencesKt.setLastOpenedProject;
-import static com.itsaky.androidide.R.*;
import static com.itsaky.toaster.ToastUtilsKt.toast;
-import static com.itsaky.toaster.ToastUtilsKt.toastInfo;
import android.annotation.SuppressLint;
import android.content.ComponentName;
@@ -108,6 +109,7 @@ import com.itsaky.androidide.projects.builder.BuildService;
import com.itsaky.androidide.services.GradleBuildService;
import com.itsaky.androidide.services.LogReceiver;
import com.itsaky.androidide.shell.ShellServer;
+import com.itsaky.androidide.uidesigner.UIDesignerActivity;
import com.itsaky.androidide.utils.DialogUtils;
import com.itsaky.androidide.utils.EditorActivityActions;
import com.itsaky.androidide.utils.ILogger;
@@ -704,8 +706,8 @@ public class EditorActivity extends IDEActivity
}
public void previewLayout() {
- toastInfo(R.string.msg_feature_unimplemented);
- // startActivity(new Intent(this, UIDesignerActivity.class));
+ // toastInfo(R.string.msg_feature_unimplemented);
+ startActivity(new Intent(this, UIDesignerActivity.class));
}
public boolean saveAll(boolean notify) {
diff --git a/app/src/main/java/com/itsaky/androidide/views/DesignerLayoutContainer.java b/app/src/main/java/com/itsaky/androidide/views/DesignerLayoutContainer.java
deleted file mode 100644
index 87149b5b3..000000000
--- a/app/src/main/java/com/itsaky/androidide/views/DesignerLayoutContainer.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * 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 .
- */
-
-package com.itsaky.androidide.views;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.util.TypedValue;
-import android.view.Gravity;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.LinearLayout;
-import android.widget.TextView;
-
-import androidx.annotation.Nullable;
-
-import com.itsaky.androidide.resources.R;
-
-/**
- * A container used in UI Designer. This view holds the views inflated from an XML layout. When
- * there are no children in this layout, it shows a message.
- *
- * @author Akash Yadav
- */
-public class DesignerLayoutContainer extends LinearLayout {
-
- private final TextView mMessage;
-
- public DesignerLayoutContainer(Context context) {
- this(context, null);
- }
-
- public DesignerLayoutContainer(Context context, @Nullable AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public DesignerLayoutContainer(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
- this(context, attrs, defStyleAttr, 0);
- }
-
- public DesignerLayoutContainer(
- Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
- super(context, attrs, defStyleAttr, defStyleRes);
-
- this.mMessage = new TextView(context);
- this.mMessage.setText(context.getString(R.string.msg_empty_ui_layout));
- this.mMessage.setLayoutParams(
- new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
- this.mMessage.setGravity(Gravity.CENTER);
- this.mMessage.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
- }
-
- @Override
- public void onViewAdded(View child) {
- if (child != this.mMessage) {
- removeView(this.mMessage);
- } else {
- super.onViewAdded(child);
- }
- }
-
- @Override
- public void onViewRemoved(View child) {
- if (child != this.mMessage && getChildCount() <= 0) {
- addView(mMessage);
- } else {
- super.onViewRemoved(child);
- }
- }
-
- // This is needed by XMLLayoutInflater
- @Override
- protected LayoutParams generateDefaultLayoutParams() {
- return super.generateDefaultLayoutParams();
- }
-}
diff --git a/resources/src/main/res/drawable/ic_widget_auto_complete_textview.xml b/resources/src/main/res/drawable/ic_widget_auto_complete_textview.xml
new file mode 100644
index 000000000..6d691158e
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_auto_complete_textview.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_button.xml b/resources/src/main/res/drawable/ic_widget_button.xml
old mode 100755
new mode 100644
index 4f4c8cc20..2d9538a7f
--- a/resources/src/main/res/drawable/ic_widget_button.xml
+++ b/resources/src/main/res/drawable/ic_widget_button.xml
@@ -1,10 +1,21 @@
-
-
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_checkbox.xml b/resources/src/main/res/drawable/ic_widget_checkbox.xml
old mode 100755
new mode 100644
index 738c6892c..287a1a7c3
--- a/resources/src/main/res/drawable/ic_widget_checkbox.xml
+++ b/resources/src/main/res/drawable/ic_widget_checkbox.xml
@@ -1,10 +1,21 @@
-
-
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_checked_textview.xml b/resources/src/main/res/drawable/ic_widget_checked_textview.xml
old mode 100755
new mode 100644
index 92b83f17f..8951b4b71
--- a/resources/src/main/res/drawable/ic_widget_checked_textview.xml
+++ b/resources/src/main/res/drawable/ic_widget_checked_textview.xml
@@ -1,10 +1,4 @@
-
-
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_edittext.xml b/resources/src/main/res/drawable/ic_widget_edittext.xml
old mode 100755
new mode 100644
index 3f5e59806..3543b63d2
--- a/resources/src/main/res/drawable/ic_widget_edittext.xml
+++ b/resources/src/main/res/drawable/ic_widget_edittext.xml
@@ -1,10 +1,21 @@
-
-
-
-
\ No newline at end of file
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_frame_layout.xml b/resources/src/main/res/drawable/ic_widget_frame_layout.xml
new file mode 100644
index 000000000..a3140dbde
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_frame_layout.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_grid_layout.xml b/resources/src/main/res/drawable/ic_widget_grid_layout.xml
new file mode 100644
index 000000000..7ca3a7013
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_grid_layout.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_horizontal_scroll_view.xml b/resources/src/main/res/drawable/ic_widget_horizontal_scroll_view.xml
new file mode 100644
index 000000000..c269fcfb1
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_horizontal_scroll_view.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_image.xml b/resources/src/main/res/drawable/ic_widget_image.xml
deleted file mode 100755
index 0a221c919..000000000
--- a/resources/src/main/res/drawable/ic_widget_image.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
diff --git a/resources/src/main/res/drawable/ic_widget_imagebutton.xml b/resources/src/main/res/drawable/ic_widget_imagebutton.xml
new file mode 100644
index 000000000..b4978c680
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_imagebutton.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_imageview.xml b/resources/src/main/res/drawable/ic_widget_imageview.xml
new file mode 100644
index 000000000..48d82e90e
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_imageview.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_linear.xml b/resources/src/main/res/drawable/ic_widget_linear.xml
deleted file mode 100644
index 1d9e7b20c..000000000
--- a/resources/src/main/res/drawable/ic_widget_linear.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-
-
-
-
-
-
-
diff --git a/resources/src/main/res/drawable/ic_widget_relative.xml b/resources/src/main/res/drawable/ic_widget_linear_layout_horz.xml
similarity index 72%
rename from resources/src/main/res/drawable/ic_widget_relative.xml
rename to resources/src/main/res/drawable/ic_widget_linear_layout_horz.xml
index 1e5db7852..fb47f806c 100644
--- a/resources/src/main/res/drawable/ic_widget_relative.xml
+++ b/resources/src/main/res/drawable/ic_widget_linear_layout_horz.xml
@@ -18,10 +18,10 @@
-
+ android:viewportWidth="16"
+ android:viewportHeight="16">
+
diff --git a/resources/src/main/res/drawable/ic_widget_linear_layout_vert.xml b/resources/src/main/res/drawable/ic_widget_linear_layout_vert.xml
new file mode 100644
index 000000000..182d9a5a1
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_linear_layout_vert.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_button.xml b/resources/src/main/res/drawable/ic_widget_list_view.xml
similarity index 88%
rename from resources/src/main/res/drawable/ic_button.xml
rename to resources/src/main/res/drawable/ic_widget_list_view.xml
index 2d9538a7f..9c5f88ef3 100644
--- a/resources/src/main/res/drawable/ic_button.xml
+++ b/resources/src/main/res/drawable/ic_widget_list_view.xml
@@ -17,5 +17,5 @@
-
+
diff --git a/resources/src/main/res/drawable/ic_widget_progress.xml b/resources/src/main/res/drawable/ic_widget_progress.xml
deleted file mode 100755
index 605ea95cf..000000000
--- a/resources/src/main/res/drawable/ic_widget_progress.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/resources/src/main/res/drawable/ic_widget_progress_bar.xml b/resources/src/main/res/drawable/ic_widget_progress_bar.xml
new file mode 100644
index 000000000..3a6bf2c63
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_progress_bar.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_radio_button.xml b/resources/src/main/res/drawable/ic_widget_radio_button.xml
old mode 100755
new mode 100644
index cd02753b7..4c1b683bb
--- a/resources/src/main/res/drawable/ic_widget_radio_button.xml
+++ b/resources/src/main/res/drawable/ic_widget_radio_button.xml
@@ -1,10 +1,31 @@
+
+
-
+ android:viewportWidth="16"
+ android:viewportHeight="16">
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_radio_group.xml b/resources/src/main/res/drawable/ic_widget_radio_group.xml
new file mode 100644
index 000000000..156949e6c
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_radio_group.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_relative_layout.xml b/resources/src/main/res/drawable/ic_widget_relative_layout.xml
new file mode 100644
index 000000000..85d3a7f4f
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_relative_layout.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_scroll_view.xml b/resources/src/main/res/drawable/ic_widget_scroll_view.xml
new file mode 100644
index 000000000..64630715a
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_scroll_view.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_seek_bar.xml b/resources/src/main/res/drawable/ic_widget_seek_bar.xml
new file mode 100644
index 000000000..d8d93ec50
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_seek_bar.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_seekbar.xml b/resources/src/main/res/drawable/ic_widget_seekbar.xml
deleted file mode 100755
index ebc94f101..000000000
--- a/resources/src/main/res/drawable/ic_widget_seekbar.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/resources/src/main/res/drawable/ic_widget_spinner.xml b/resources/src/main/res/drawable/ic_widget_spinner.xml
old mode 100755
new mode 100644
index f5b891d07..0fb87a0d3
--- a/resources/src/main/res/drawable/ic_widget_spinner.xml
+++ b/resources/src/main/res/drawable/ic_widget_spinner.xml
@@ -1,10 +1,21 @@
-
-
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_surface_view.xml b/resources/src/main/res/drawable/ic_widget_surface_view.xml
new file mode 100644
index 000000000..75ad6c9b5
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_surface_view.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_switch.xml b/resources/src/main/res/drawable/ic_widget_switch.xml
new file mode 100644
index 000000000..7e82a2d09
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_switch.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_textureview.xml b/resources/src/main/res/drawable/ic_widget_textureview.xml
new file mode 100644
index 000000000..a2ce3c32c
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_textureview.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_textview.xml b/resources/src/main/res/drawable/ic_widget_textview.xml
old mode 100755
new mode 100644
index ee5982a93..764c5a294
--- a/resources/src/main/res/drawable/ic_widget_textview.xml
+++ b/resources/src/main/res/drawable/ic_widget_textview.xml
@@ -1,10 +1,21 @@
-
-
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_toggle_button.xml b/resources/src/main/res/drawable/ic_widget_toggle_button.xml
new file mode 100644
index 000000000..8dcfffdf9
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_toggle_button.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
diff --git a/resources/src/main/res/drawable/ic_widget_webview.xml b/resources/src/main/res/drawable/ic_widget_webview.xml
new file mode 100644
index 000000000..50db58336
--- /dev/null
+++ b/resources/src/main/res/drawable/ic_widget_webview.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/resources/src/main/res/values/strings.xml b/resources/src/main/res/values/strings.xml
index 7e6eaf952..9cb80a81e 100644
--- a/resources/src/main/res/values/strings.xml
+++ b/resources/src/main/res/values/strings.xml
@@ -470,7 +470,6 @@
TextView
Button
- Android
CheckBox
CheckedTextView
EditText
@@ -480,7 +479,17 @@
RadioButton
SeekBar
Spinner
- Layouts
LinearLayout
RelativeLayout
+ AutoCompleteTextView
+ ListView
+ SurfaceView
+ Switch
+ TextureView
+ ToggleButton
+ FrameLayout
+ GridLayout
+ LinearLayout (H)
+ RelativeLayout
+ LinearLayout (V)
\ No newline at end of file
diff --git a/tests/test-home/.androidide/init/model.jar b/tests/test-home/.androidide/init/model.jar
index 4b6741925..5a6c0afac 100644
Binary files a/tests/test-home/.androidide/init/model.jar and b/tests/test-home/.androidide/init/model.jar differ
diff --git a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/adapters/WidgetsCategoryAdapter.kt b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/adapters/WidgetsCategoryAdapter.kt
new file mode 100644
index 000000000..21da21960
--- /dev/null
+++ b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/adapters/WidgetsCategoryAdapter.kt
@@ -0,0 +1,57 @@
+/*
+ * 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 .
+ */
+
+package com.itsaky.androidide.uidesigner.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.itsaky.androidide.uidesigner.adapters.WidgetsCategoryAdapter.VH
+import com.itsaky.androidide.uidesigner.databinding.LayoutUiWidgetsCategoryBinding
+import com.itsaky.androidide.uidesigner.models.UiWidgetCategory
+
+/** @author Akash Yadav */
+class WidgetsCategoryAdapter(categories: List) : RecyclerView.Adapter() {
+
+ private val categories =
+ categories.let {
+ val mutable = it.toMutableList()
+ mutable.removeIf { category -> category.widgets.isEmpty() }
+ mutable
+ }
+
+ inner class VH(val binding: LayoutUiWidgetsCategoryBinding) :
+ RecyclerView.ViewHolder(binding.root)
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
+ return VH(
+ LayoutUiWidgetsCategoryBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ )
+ }
+
+ override fun getItemCount(): Int {
+ return categories.size
+ }
+
+ override fun onBindViewHolder(holder: VH, position: Int) {
+ val binding = holder.binding
+ val category = categories[position]
+ binding.name.setText(category.label)
+
+ binding.widgets.adapter = WidgetsItemAdapter(category.widgets)
+ }
+}
diff --git a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/adapters/WidgetsItemAdapter.kt b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/adapters/WidgetsItemAdapter.kt
new file mode 100644
index 000000000..6e30ffd06
--- /dev/null
+++ b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/adapters/WidgetsItemAdapter.kt
@@ -0,0 +1,49 @@
+/*
+ * 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 .
+ */
+
+package com.itsaky.androidide.uidesigner.adapters
+
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import com.itsaky.androidide.uidesigner.adapters.WidgetsItemAdapter.VH
+import com.itsaky.androidide.uidesigner.databinding.LayoutUiWidgetsItemBinding
+import com.itsaky.androidide.uidesigner.models.UiWidget
+
+/**
+ * @author Akash Yadav
+ */
+class WidgetsItemAdapter(private val widgets: List) : RecyclerView.Adapter(){
+
+ inner class VH(val binding: LayoutUiWidgetsItemBinding) : RecyclerView.ViewHolder(binding.root)
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): VH {
+ return VH(LayoutUiWidgetsItemBinding.inflate(LayoutInflater.from(parent.context), parent, false))
+ }
+
+ override fun getItemCount(): Int {
+ return widgets.size
+ }
+
+ override fun onBindViewHolder(holder: VH, position: Int) {
+ val binding = holder.binding
+ val widget = widgets[position]
+
+ binding.name.setText(widget.label)
+ binding.icon.setImageResource(widget.icon)
+ }
+}
\ No newline at end of file
diff --git a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/fragments/WidgetsListFragment.kt b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/fragments/WidgetsListFragment.kt
index d5abbfb50..97d1d6612 100644
--- a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/fragments/WidgetsListFragment.kt
+++ b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/fragments/WidgetsListFragment.kt
@@ -22,7 +22,9 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.itsaky.androidide.fragments.BaseFragment
+import com.itsaky.androidide.uidesigner.adapters.WidgetsCategoryAdapter
import com.itsaky.androidide.uidesigner.databinding.FragmentUiWidgetsBinding
+import com.itsaky.androidide.uidesigner.utils.Widgets
/**
* A fragment that shows the list of widgets available to use in the UI designer.
@@ -37,13 +39,15 @@ class WidgetsListFragment : BaseFragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
- ): View? {
+ ): View {
this.binding = FragmentUiWidgetsBinding.inflate(inflater, container, false)
return this.binding!!.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
+
+ this.binding!!.widgets.adapter = WidgetsCategoryAdapter(Widgets.categories)
}
override fun onDestroyView() {
diff --git a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/models/UiWidget.kt b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/models/UiWidget.kt
index 54f864851..613f15619 100644
--- a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/models/UiWidget.kt
+++ b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/models/UiWidget.kt
@@ -17,7 +17,41 @@
package com.itsaky.androidide.uidesigner.models
+import android.view.View
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
+import com.itsaky.androidide.inflater.IView
-data class UiWidget(val name: String, @StringRes val label: Int, @DrawableRes val icon: Int)
+open class UiWidget(val name: String, @StringRes val label: Int, @DrawableRes val icon: Int) {
+ constructor(
+ klass: Class,
+ @StringRes label: Int,
+ @DrawableRes icon: Int
+ ) : this(klass.name, label, icon)
+
+ fun createView(): IView {
+ TODO()
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) return true
+ if (other !is UiWidget) return false
+
+ if (name != other.name) return false
+ if (label != other.label) return false
+ if (icon != other.icon) return false
+
+ return true
+ }
+
+ override fun hashCode(): Int {
+ var result = name.hashCode()
+ result = 31 * result + label
+ result = 31 * result + icon
+ return result
+ }
+
+ override fun toString(): String {
+ return "UiWidget(name='$name', label=$label, icon=$icon)"
+ }
+}
diff --git a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/models/UiWidgetCategory.kt b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/models/UiWidgetCategory.kt
index a21fac187..0351da97e 100644
--- a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/models/UiWidgetCategory.kt
+++ b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/models/UiWidgetCategory.kt
@@ -19,4 +19,4 @@ package com.itsaky.androidide.uidesigner.models
import androidx.annotation.StringRes
-data class UiWidgetCategory(@StringRes val label: Int, val widgets: List = emptyList())
\ No newline at end of file
+data class UiWidgetCategory(@StringRes val label: Int, val widgets: MutableList = mutableListOf())
\ No newline at end of file
diff --git a/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/utils/Widgets.kt b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/utils/Widgets.kt
new file mode 100644
index 000000000..fbe0f6b53
--- /dev/null
+++ b/uidesigner/src/main/java/com/itsaky/androidide/uidesigner/utils/Widgets.kt
@@ -0,0 +1,179 @@
+/*
+ * 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 .
+ */
+
+package com.itsaky.androidide.uidesigner.utils
+
+import android.view.SurfaceView
+import android.view.TextureView
+import android.webkit.WebView
+import android.widget.AutoCompleteTextView
+import android.widget.Button
+import android.widget.CheckBox
+import android.widget.CheckedTextView
+import android.widget.EditText
+import android.widget.FrameLayout
+import android.widget.GridLayout
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.ListView
+import android.widget.ProgressBar
+import android.widget.RadioButton
+import android.widget.RelativeLayout
+import android.widget.SeekBar
+import android.widget.Switch
+import android.widget.ToggleButton
+import com.itsaky.androidide.uidesigner.R.drawable
+import com.itsaky.androidide.uidesigner.R.string
+import com.itsaky.androidide.uidesigner.models.UiWidget
+import com.itsaky.androidide.uidesigner.models.UiWidgetCategory
+
+internal object Widgets {
+
+ @JvmField val CATEGORY_WIDGETS = UiWidgetCategory(string.ui_category_widgets)
+ @JvmField val CATEGORY_LAYOUTS = UiWidgetCategory(string.ui_category_layouts)
+
+ private val internalCategories = mutableListOf()
+
+ val categories: List
+ get() = this.internalCategories
+
+ init {
+ internalCategories.add(getLayouts())
+ internalCategories.add(getWidgets())
+ }
+
+ private fun getWidgets(): UiWidgetCategory {
+ return CATEGORY_WIDGETS.apply {
+ if (widgets.isNotEmpty()) {
+ return@apply
+ }
+ widgets.apply {
+ add(
+ UiWidget(
+ AutoCompleteTextView::class.java,
+ string.widget_auto_complete_textview,
+ drawable.ic_widget_auto_complete_textview
+ )
+ )
+ add(UiWidget(Button::class.java, string.widget_button, drawable.ic_widget_button))
+ add(UiWidget(CheckBox::class.java, string.widget_checkbox, drawable.ic_widget_checkbox))
+ add(
+ UiWidget(
+ CheckedTextView::class.java,
+ string.widget_checked_textview,
+ drawable.ic_widget_checked_textview
+ )
+ )
+ add(UiWidget(EditText::class.java, string.widget_edittext, drawable.ic_widget_edittext))
+ add(
+ UiWidget(
+ ImageButton::class.java,
+ string.widget_image_button,
+ drawable.ic_widget_imagebutton
+ )
+ )
+ add(UiWidget(ImageView::class.java, string.widget_image_view, drawable.ic_widget_imageview))
+ add(UiWidget(ListView::class.java, string.widget_listview, drawable.ic_widget_list_view))
+ add(
+ UiWidget(
+ ProgressBar::class.java,
+ string.widget_progressbar,
+ drawable.ic_widget_progress_bar
+ )
+ )
+ add(
+ UiWidget(
+ RadioButton::class.java,
+ string.widget_radio_button,
+ drawable.ic_widget_radio_button
+ )
+ )
+ add(UiWidget(SeekBar::class.java, string.widget_seekbar, drawable.ic_widget_seek_bar))
+ add(
+ UiWidget(
+ SurfaceView::class.java,
+ string.widget_surfaceview,
+ drawable.ic_widget_surface_view
+ )
+ )
+ add(UiWidget(Switch::class.java, string.widget_switch, drawable.ic_widget_switch))
+ add(
+ UiWidget(
+ TextureView::class.java,
+ string.widget_textureview,
+ drawable.ic_widget_textureview
+ )
+ )
+ add(
+ UiWidget(
+ ToggleButton::class.java,
+ string.widget_togglebutton,
+ drawable.ic_widget_toggle_button
+ )
+ )
+ add(UiWidget(WebView::class.java, string.widget_webview, drawable.ic_widget_webview))
+ }
+ }
+ }
+
+ private fun getLayouts(): UiWidgetCategory {
+ return CATEGORY_LAYOUTS.apply {
+ if (widgets.isNotEmpty()) {
+ return@apply
+ }
+
+ widgets.apply {
+ add(
+ UiWidget(
+ FrameLayout::class.java,
+ string.widget_frame_layout,
+ drawable.ic_widget_frame_layout
+ )
+ )
+ add(
+ UiWidget(
+ GridLayout::class.java,
+ string.widget_grid_layout,
+ drawable.ic_widget_grid_layout
+ )
+ )
+ add(
+ UiWidget(
+ LinearLayout::class.java,
+ string.widget_linear_layout_horz,
+ drawable.ic_widget_linear_layout_horz
+ )
+ )
+ add(
+ UiWidget(
+ LinearLayout::class.java,
+ string.widget_linear_layout_vert,
+ drawable.ic_widget_linear_layout_vert
+ )
+ )
+ add(
+ UiWidget(
+ RelativeLayout::class.java,
+ string.widget_relative_layout,
+ drawable.ic_widget_relative_layout
+ )
+ )
+ }
+ }
+ }
+}
diff --git a/uidesigner/src/main/res/layout/activity_ui_designer.xml b/uidesigner/src/main/res/layout/activity_ui_designer.xml
index 7c6c02159..bbf74a049 100644
--- a/uidesigner/src/main/res/layout/activity_ui_designer.xml
+++ b/uidesigner/src/main/res/layout/activity_ui_designer.xml
@@ -22,8 +22,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
- tools:ignore="DuplicateIncludedIds"
- tools:openDrawer="start">
+ tools:ignore="DuplicateIncludedIds">
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="4dp">
+ tools:listitem="@layout/layout_ui_widgets_item" />
\ No newline at end of file
diff --git a/uidesigner/src/main/res/layout/fragment_ui_widgets_item.xml b/uidesigner/src/main/res/layout/layout_ui_widgets_item.xml
similarity index 51%
rename from uidesigner/src/main/res/layout/fragment_ui_widgets_item.xml
rename to uidesigner/src/main/res/layout/layout_ui_widgets_item.xml
index 7251cd3b3..e5cb37afd 100644
--- a/uidesigner/src/main/res/layout/fragment_ui_widgets_item.xml
+++ b/uidesigner/src/main/res/layout/layout_ui_widgets_item.xml
@@ -15,7 +15,7 @@
~ along with AndroidIDE. If not, see .
-->
-
+ android:foreground="?attr/selectableItemBackground"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"
+ android:padding="4dp">
-
+
+
+ android:layout_marginStart="8dp"
+ android:maxLines="1"
+ android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
+ tools:text="Button" />
-
-
-
-
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/uidesigner/src/main/res/values/strings.xml b/uidesigner/src/main/res/values/strings.xml
new file mode 100644
index 000000000..68dfa61cd
--- /dev/null
+++ b/uidesigner/src/main/res/values/strings.xml
@@ -0,0 +1,20 @@
+
+
+
+ WebView
+
\ No newline at end of file