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