From f893e52e909e80e792d24754ea9ee138db4c6e3e Mon Sep 17 00:00:00 2001 From: Oluwadara Abijo Date: Tue, 18 Nov 2025 19:53:47 +0100 Subject: [PATCH 1/4] fix(ADFA-2128): Show error when navigation view is not a child of DrawerLayout --- .../palette/containers/NavigationViewDesign.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java index 54519dd11c..22458d1f7b 100644 --- a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java +++ b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java @@ -3,14 +3,19 @@ import com.google.android.material.navigation.NavigationView; import android.content.Context; import android.graphics.Canvas; + import org.appdevforall.codeonthego.layouteditor.utils.Constants; import org.appdevforall.codeonthego.layouteditor.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class NavigationViewDesign extends NavigationView { private boolean drawStrokeEnabled; private boolean isBlueprint; + private final Logger logger = LoggerFactory.getLogger(NavigationViewDesign.class); + public NavigationViewDesign(Context context) { super(context); } @@ -39,4 +44,13 @@ public void setBlueprint(boolean isBlueprint) { this.isBlueprint = isBlueprint; invalidate(); } + + @Override + protected void onAttachedToWindow() { + try { + super.onAttachedToWindow(); + } catch (IllegalArgumentException e) { + logger.error("NavigationView should be placed in a DrawerLayout"); + } + } } From ed7220ac02426e7433a58ec40da12e41da132944 Mon Sep 17 00:00:00 2001 From: Oluwadara Abijo Date: Tue, 18 Nov 2025 21:14:49 +0100 Subject: [PATCH 2/4] feat(ADFA-2128): Add support for DrawerLayout in layout editor --- .../src/main/assets/palette/layouts.json | 9 + .../src/main/assets/widgetclasses.json | 1 + .../containers/NavigationViewDesign.java | 91 +-- .../palette/layouts/DrawerLayoutDesign.kt | 56 ++ .../layouteditor/views/StructureView.kt | 536 +++++++++--------- 5 files changed, 392 insertions(+), 301 deletions(-) create mode 100644 layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt diff --git a/layouteditor/src/main/assets/palette/layouts.json b/layouteditor/src/main/assets/palette/layouts.json index 0f9cd17a90..d758b1a421 100644 --- a/layouteditor/src/main/assets/palette/layouts.json +++ b/layouteditor/src/main/assets/palette/layouts.json @@ -89,5 +89,14 @@ "android:layout_width": "match_parent", "android:padding": "8dp" } + }, + { + "name": "DrawerLayout", + "className": "org.appdevforall.codeonthego.layouteditor.editor.palette.layouts.DrawerLayoutDesign", + "iconName": "ic_palette_drawer_layout", + "defaultAttributes": { + "android:layout_width": "match_parent", + "android:padding": "8dp" + } } ] \ No newline at end of file diff --git a/layouteditor/src/main/assets/widgetclasses.json b/layouteditor/src/main/assets/widgetclasses.json index 992a4c4f7d..7507fe9f3a 100644 --- a/layouteditor/src/main/assets/widgetclasses.json +++ b/layouteditor/src/main/assets/widgetclasses.json @@ -31,6 +31,7 @@ "FrameLayout": "org.appdevforall.codeonthego.layouteditor.editor.palette.layouts.FrameLayoutDesign", "TableLayout": "org.appdevforall.codeonthego.layouteditor.editor.palette.layouts.TableLayoutDesign", "TableRow": "org.appdevforall.codeonthego.layouteditor.editor.palette.layouts.TableRowDesign", + "DrawerLayout":"org.appdevforall.codeonthego.layouteditor.editor.palette.layouts.DrawerLayoutDesign", "Space": "android.widget.Space", "GridLayout": "org.appdevforall.codeonthego.layouteditor.editor.palette.legacy.GridLayoutDesign", "TabHost": "org.appdevforall.codeonthego.layouteditor.editor.palette.legacy.TabHostDesign", diff --git a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java index 22458d1f7b..b88bb00458 100644 --- a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java +++ b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java @@ -1,56 +1,57 @@ package org.appdevforall.codeonthego.layouteditor.editor.palette.containers; -import com.google.android.material.navigation.NavigationView; import android.content.Context; import android.graphics.Canvas; - +import com.google.android.material.navigation.NavigationView; import org.appdevforall.codeonthego.layouteditor.utils.Constants; import org.appdevforall.codeonthego.layouteditor.utils.Utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class NavigationViewDesign extends NavigationView { - - private boolean drawStrokeEnabled; - private boolean isBlueprint; - - private final Logger logger = LoggerFactory.getLogger(NavigationViewDesign.class); - - public NavigationViewDesign(Context context) { - super(context); - } - - @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); - - if (drawStrokeEnabled) - Utils.drawDashPathStroke( - this, canvas, isBlueprint ? Constants.BLUEPRINT_DASH_COLOR : Constants.DESIGN_DASH_COLOR); - } - - public void setStrokeEnabled(boolean enabled) { - drawStrokeEnabled = enabled; - invalidate(); - } - - @Override - public void draw(Canvas canvas) { - if (isBlueprint) Utils.drawDashPathStroke(this, canvas, Constants.BLUEPRINT_DASH_COLOR); - else super.draw(canvas); - } - - public void setBlueprint(boolean isBlueprint) { - this.isBlueprint = isBlueprint; - invalidate(); - } - - @Override - protected void onAttachedToWindow() { - try { - super.onAttachedToWindow(); - } catch (IllegalArgumentException e) { - logger.error("NavigationView should be placed in a DrawerLayout"); - } - } + + private boolean drawStrokeEnabled; + private boolean isBlueprint; + + private final Logger logger = LoggerFactory.getLogger(NavigationViewDesign.class); + + public NavigationViewDesign(Context context) { + super(context); + } + + @Override + public void draw(Canvas canvas) { + if (isBlueprint) + Utils.drawDashPathStroke(this, canvas, Constants.BLUEPRINT_DASH_COLOR); + else + super.draw(canvas); + } + + public void setBlueprint(boolean isBlueprint) { + this.isBlueprint = isBlueprint; + invalidate(); + } + + public void setStrokeEnabled(boolean enabled) { + drawStrokeEnabled = enabled; + invalidate(); + } + + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + + if (drawStrokeEnabled) + Utils.drawDashPathStroke( + this, canvas, isBlueprint ? Constants.BLUEPRINT_DASH_COLOR : Constants.DESIGN_DASH_COLOR); + } + + @Override + protected void onAttachedToWindow() { + try { + super.onAttachedToWindow(); + } catch (IllegalArgumentException e) { + logger.error("NavigationView should be placed in a DrawerLayout"); + } + } } diff --git a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt new file mode 100644 index 0000000000..607a499650 --- /dev/null +++ b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt @@ -0,0 +1,56 @@ +package org.appdevforall.codeonthego.layouteditor.editor.palette.layouts + +import android.content.Context +import android.graphics.Canvas +import androidx.drawerlayout.widget.DrawerLayout +import org.appdevforall.codeonthego.layouteditor.utils.Constants +import org.appdevforall.codeonthego.layouteditor.utils.Utils +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +class DrawerLayoutDesign( + context: Context, +) : DrawerLayout(context) { + private var drawStrokeEnabled = false + private var isBlueprint = false + + private val logger: Logger = LoggerFactory.getLogger(DrawerLayoutDesign::class.java) + + override fun dispatchDraw(canvas: Canvas) { + super.dispatchDraw(canvas) + + if (drawStrokeEnabled) { + Utils.drawDashPathStroke( + this, + canvas, + if (isBlueprint) Constants.BLUEPRINT_DASH_COLOR else Constants.DESIGN_DASH_COLOR, + ) + } + } + + override fun draw(canvas: Canvas) { + if (isBlueprint) { + Utils.drawDashPathStroke(this, canvas, Constants.BLUEPRINT_DASH_COLOR) + } else { + super.draw(canvas) + } + } + + fun setStrokeEnabled(enabled: Boolean) { + drawStrokeEnabled = enabled + invalidate() + } + + fun setBlueprint(isBlueprint: Boolean) { + this.isBlueprint = isBlueprint + invalidate() + } + + override fun onAttachedToWindow() { + try { + super.onAttachedToWindow() + } catch (e: Exception) { + logger.error("Error in previewing DrawerLayoutDesign") + } + } +} diff --git a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/views/StructureView.kt b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/views/StructureView.kt index 213fa2b7bf..96576b78d7 100644 --- a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/views/StructureView.kt +++ b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/views/StructureView.kt @@ -50,6 +50,7 @@ import androidx.cardview.widget.CardView import androidx.constraintlayout.widget.ConstraintLayout import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.widget.NestedScrollView +import androidx.drawerlayout.widget.DrawerLayout import androidx.recyclerview.widget.RecyclerView import androidx.viewpager.widget.ViewPager import androidx.viewpager2.widget.ViewPager2 @@ -65,286 +66,309 @@ import org.appdevforall.codeonthego.layouteditor.R import org.appdevforall.codeonthego.layouteditor.databinding.LayoutStructureViewItemBinding import org.appdevforall.codeonthego.layouteditor.managers.IdManager.idMap -class StructureView(context: Context?, attrs: AttributeSet?) : LinearLayoutCompat( - context!!, attrs -), View.OnClickListener, View.OnLongClickListener { - private val inflater: LayoutInflater = LayoutInflater.from(context) - private val paint = Paint() - private val pointRadius: Int - private val textViewMap: MutableMap = HashMap() - private val viewTextMap: MutableMap = HashMap() +class StructureView( + context: Context?, + attrs: AttributeSet?, +) : LinearLayoutCompat( + context!!, + attrs, + ), + View.OnClickListener, + View.OnLongClickListener { + private val inflater: LayoutInflater = LayoutInflater.from(context) + private val paint = Paint() + private val pointRadius: Int + private val textViewMap: MutableMap = HashMap() + private val viewTextMap: MutableMap = HashMap() - var onItemClickListener: ((View) -> Unit)? = null - var onItemLongClickListener: ((View) -> Unit)? = null + var onItemClickListener: ((View) -> Unit)? = null + var onItemLongClickListener: ((View) -> Unit)? = null - /** - * This is the constructor of the StructureView class which takes context and attributeSet as - * parameters. It creates a new Paint object, sets its color and anti-alias. It also sets the - * orientation of this view to VERTICAL and sets the default OnItemClickListener. - */ - init { - val primaryColor = - MaterialColors.getColor(this, com.google.android.material.R.attr.colorPrimary) - paint.color = primaryColor - paint.isAntiAlias = true - paint.strokeWidth = getDip(1).toFloat() + /** + * This is the constructor of the StructureView class which takes context and attributeSet as + * parameters. It creates a new Paint object, sets its color and anti-alias. It also sets the + * orientation of this view to VERTICAL and sets the default OnItemClickListener. + */ + init { + val primaryColor = + MaterialColors.getColor(this, com.google.android.material.R.attr.colorPrimary) + paint.color = primaryColor + paint.isAntiAlias = true + paint.strokeWidth = getDip(1).toFloat() - pointRadius = getDip(3) + pointRadius = getDip(3) - orientation = VERTICAL - } + orientation = VERTICAL + } - /** This method clears all Views and HashMaps stored in this view. */ - fun clear() { - removeAllViews() - textViewMap.clear() - viewTextMap.clear() - } + /** This method clears all Views and HashMaps stored in this view. */ + fun clear() { + removeAllViews() + textViewMap.clear() + viewTextMap.clear() + } - /** - * This method sets a View to this view. It clears all the stored views and hashmaps, and then - * calls the peek() method to peek into the View. - */ - fun setView(view: View) { - textViewMap.clear() - viewTextMap.clear() - removeAllViews() - peek(view, 1) - } + /** + * This method sets a View to this view. It clears all the stored views and hashmaps, and then + * calls the peek() method to peek into the View. + */ + fun setView(view: View) { + textViewMap.clear() + viewTextMap.clear() + removeAllViews() + peek(view, 1) + } - /** - * This method recursively calls itself to add TextViews for each View inside the ViewGroup. It - * also stores the TextViews and Views in their respective hashmaps. - */ - private fun peek(view: View, depth: Int) { - var nextDepth = depth - val binding = - LayoutStructureViewItemBinding.inflate(inflater, null, false) - val viewName = binding.viewName - val viewId = binding.viewId - val icon = binding.icon - if (view.id == -1 || idMap[view] == null) { - viewId.visibility = GONE - viewName.translationY = 0f - viewId.translationY = 0f - } else { - viewName.translationY = getDip(-7).toFloat() - viewId.translationY = getDip(-3).toFloat() - viewId.visibility = VISIBLE - viewId.text = idMap[view] - } - if (view is LinearLayout && view !is RadioGroup) { - val orientation = - if (view.orientation == LinearLayout.HORIZONTAL) "horizontal" else "vertical" - val imgResId = imgMap[LinearLayout::class.java.simpleName + orientation]!! + /** + * This method recursively calls itself to add TextViews for each View inside the ViewGroup. It + * also stores the TextViews and Views in their respective hashmaps. + */ + private fun peek( + view: View, + depth: Int, + ) { + var nextDepth = depth + val binding = + LayoutStructureViewItemBinding.inflate(inflater, null, false) + val viewName = binding.viewName + val viewId = binding.viewId + val icon = binding.icon + if (view.id == -1 || idMap[view] == null) { + viewId.visibility = GONE + viewName.translationY = 0f + viewId.translationY = 0f + } else { + viewName.translationY = getDip(-7).toFloat() + viewId.translationY = getDip(-3).toFloat() + viewId.visibility = VISIBLE + viewId.text = idMap[view] + } + if (view is LinearLayout && view !is RadioGroup) { + val orientation = + if (view.orientation == LinearLayout.HORIZONTAL) "horizontal" else "vertical" + val imgResId = imgMap[LinearLayout::class.java.simpleName + orientation]!! - icon.setImageResource(imgResId) - viewName.text = String.format("%s (%s)", LinearLayout::class.java.simpleName, orientation) - } else { - val viewSimpleName = view.javaClass.superclass.simpleName - var imageResource = imgMap[viewSimpleName] - if (imageResource == null) { - imageResource = imgMap["_unknown"] - } - icon.setImageResource(imageResource!!) - viewName.text = viewSimpleName - } + icon.setImageResource(imgResId) + viewName.text = String.format("%s (%s)", LinearLayout::class.java.simpleName, orientation) + } else { + val viewSimpleName = view.javaClass.superclass.simpleName + var imageResource = imgMap[viewSimpleName] + if (imageResource == null) { + imageResource = imgMap["_unknown"] + } + icon.setImageResource(imageResource!!) + viewName.text = viewSimpleName + } - binding.mainView.setOnClickListener(this) - binding.mainView.setOnLongClickListener(this) + binding.mainView.setOnClickListener(this) + binding.mainView.setOnLongClickListener(this) - addView(binding.root) + addView(binding.root) - val params = - binding.root.layoutParams as LayoutParams - params.leftMargin = depth * getDip(15) + val params = + binding.root.layoutParams as LayoutParams + params.leftMargin = depth * getDip(15) - textViewMap[viewName] = view - viewTextMap[view] = viewName + textViewMap[viewName] = view + viewTextMap[view] = viewName - if (view is ViewGroup) { - val group = view - if (group !is CalendarView - && group !is SearchView - && group !is NavigationView - && group !is BottomNavigationView - && group !is TabLayout - ) { - nextDepth++ + if (view is ViewGroup) { + val group = view + if (group !is CalendarView && + group !is SearchView && + group !is NavigationView && + group !is BottomNavigationView && + group !is TabLayout + ) { + nextDepth++ - for (i in 0 until group.childCount) { - val child = group.getChildAt(i) - peek(child, nextDepth) - } - } - } - } + for (i in 0 until group.childCount) { + val child = group.getChildAt(i) + peek(child, nextDepth) + } + } + } + } - /** This method is called to draw rectangles, lines, and circles for each TextView in the view. */ - override fun dispatchDraw(canvas: Canvas) { - super.dispatchDraw(canvas) + /** This method is called to draw rectangles, lines, and circles for each TextView in the view. */ + override fun dispatchDraw(canvas: Canvas) { + super.dispatchDraw(canvas) - for (text in textViewMap.keys) { - val view = textViewMap[text] - val parent = text.parent.parent as ViewGroup + for (text in textViewMap.keys) { + val view = textViewMap[text] + val parent = text.parent.parent as ViewGroup - if (view is ViewGroup && view.childCount > 0) { - val x = parent.x - val y = parent.y + parent.height.toFloat() / 2 + if (view is ViewGroup && view.childCount > 0) { + val x = parent.x + val y = parent.y + parent.height.toFloat() / 2 - val group = view - if (group !is CalendarView - && group !is SearchView - && group !is NavigationView - && group !is BottomNavigationView - && group !is TabLayout - ) { - canvas.drawRect( - x - pointRadius, y - pointRadius, x + pointRadius, y + pointRadius, paint - ) - for (i in 0 until group.childCount) { - val current = viewTextMap[group.getChildAt(i)] - val currentParent = current!!.parent.parent as ViewGroup - canvas.drawLine( - parent.x, - parent.y + parent.height.toFloat() / 2, - parent.x, - currentParent.y + currentParent.height.toFloat() / 2, - paint - ) - canvas.drawLine( - parent.x, - currentParent.y + currentParent.height.toFloat() / 2, - currentParent.x, - currentParent.y + currentParent.height.toFloat() / 2, - paint - ) - } - } else { - canvas.drawCircle( - parent.x, parent.y + parent.height.toFloat() / 2, pointRadius.toFloat(), paint - ) - } - } else { - canvas.drawCircle( - parent.x, parent.y + parent.height.toFloat() / 2, pointRadius.toFloat(), paint - ) - } - } - } + val group = view + if (group !is CalendarView && + group !is SearchView && + group !is NavigationView && + group !is BottomNavigationView && + group !is TabLayout + ) { + canvas.drawRect( + x - pointRadius, + y - pointRadius, + x + pointRadius, + y + pointRadius, + paint, + ) + for (i in 0 until group.childCount) { + val current = viewTextMap[group.getChildAt(i)] + val currentParent = current!!.parent.parent as ViewGroup + canvas.drawLine( + parent.x, + parent.y + parent.height.toFloat() / 2, + parent.x, + currentParent.y + currentParent.height.toFloat() / 2, + paint, + ) + canvas.drawLine( + parent.x, + currentParent.y + currentParent.height.toFloat() / 2, + currentParent.x, + currentParent.y + currentParent.height.toFloat() / 2, + paint, + ) + } + } else { + canvas.drawCircle( + parent.x, + parent.y + parent.height.toFloat() / 2, + pointRadius.toFloat(), + paint, + ) + } + } else { + canvas.drawCircle( + parent.x, + parent.y + parent.height.toFloat() / 2, + pointRadius.toFloat(), + paint, + ) + } + } + } - /** - * This method is called when a TextView is clicked, and it calls the OnItemClickListener's - * onItemClick method. - */ - override fun onClick(v: View) { - if (v is ViewGroup) { - for (i in 0 until v.childCount) { - val child = v.getChildAt(i) - if (child.id == R.id.view_name) textViewMap[child as TextView]?.let { - onItemClickListener?.invoke( - it - ) - } - } - } - } + /** + * This method is called when a TextView is clicked, and it calls the OnItemClickListener's + * onItemClick method. + */ + override fun onClick(v: View) { + if (v is ViewGroup) { + for (i in 0 until v.childCount) { + val child = v.getChildAt(i) + if (child.id == R.id.view_name) { + textViewMap[child as TextView]?.let { + onItemClickListener?.invoke( + it, + ) + } + } + } + } + } - override fun onLongClick(view: View): Boolean { - val parent = view as? ViewGroup ?: return false - val textView = parent.findViewById(R.id.view_name) ?: return false + override fun onLongClick(view: View): Boolean { + val parent = view as? ViewGroup ?: return false + val textView = parent.findViewById(R.id.view_name) ?: return false - val associatedView = textViewMap[textView] ?: return false + val associatedView = textViewMap[textView] ?: return false - onItemLongClickListener?.invoke(associatedView) + onItemLongClickListener?.invoke(associatedView) - return true - } + return true + } + /** This method is used to convert the input into the equivalent dip value. */ + private fun getDip(input: Int): Int = + TypedValue + .applyDimension( + TypedValue.COMPLEX_UNIT_DIP, + input.toFloat(), + context.resources.displayMetrics, + ).toInt() - /** This method is used to convert the input into the equivalent dip value. */ - private fun getDip(input: Int): Int { - return TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, input.toFloat(), context.resources.displayMetrics - ).toInt() - } + companion object { + var imgMap: MutableMap = HashMap() - companion object { - var imgMap: MutableMap = HashMap() - - init { - imgMap["_unknown"] = R.mipmap.ic_palette_unknown_view - imgMap[TextView::class.java.simpleName] = R.mipmap.ic_palette_text_view - imgMap[EditText::class.java.simpleName] = R.mipmap.ic_palette_edit_text - imgMap[Button::class.java.simpleName] = - R.mipmap.ic_palette_button - imgMap[ImageButton::class.java.simpleName] = - R.mipmap.ic_palette_image_button - imgMap[ImageView::class.java.simpleName] = R.mipmap.ic_palette_image_view - imgMap[VideoView::class.java.simpleName] = R.mipmap.ic_palette_video_view - imgMap[AutoCompleteTextView::class.java.simpleName] = - R.mipmap.ic_palette_auto_complete_text_view - imgMap[MultiAutoCompleteTextView::class.java.simpleName] = - R.mipmap.ic_palette_multi_auto_complete_text_view - imgMap[CheckedTextView::class.java.simpleName] = - R.mipmap.ic_palette_checked_text_view - imgMap[CheckBox::class.java.simpleName] = R.mipmap.ic_palette_check_box - imgMap[RadioButton::class.java.simpleName] = R.mipmap.ic_palette_radio_button - imgMap[RadioGroup::class.java.simpleName] = - R.mipmap.ic_palette_radio_group - imgMap[ToggleButton::class.java.simpleName] = R.mipmap.ic_palette_toggle_button - imgMap[Switch::class.java.simpleName] = R.mipmap.ic_palette_switch - imgMap[View::class.java.simpleName] = R.mipmap.ic_palette_view - imgMap[WebView::class.java.simpleName] = R.mipmap.ic_palette_web_view - imgMap[CalendarView::class.java.simpleName] = R.mipmap.ic_palette_calendar_view - imgMap[ProgressBar::class.java.simpleName] = R.mipmap.ic_palette_progress_bar - imgMap[ProgressBar::class.java.simpleName + "horizontal"] = - R.mipmap.ic_palette_progress_bar_horizontal - imgMap[SeekBar::class.java.simpleName] = R.mipmap.ic_palette_seek_bar - imgMap[RatingBar::class.java.simpleName] = R.mipmap.ic_palette_rating_bar - imgMap[TextureView::class.java.simpleName] = - R.mipmap.ic_palette_texture_view - imgMap[SurfaceView::class.java.simpleName] = R.mipmap.ic_palette_surface_view - imgMap[SearchView::class.java.simpleName] = - R.mipmap.ic_palette_search_view - imgMap[LinearLayout::class.java.simpleName + "horizontal"] = - R.mipmap.ic_palette_linear_layout_horz - imgMap[LinearLayout::class.java.simpleName + "vertical"] = - R.mipmap.ic_palette_linear_layout_vert - imgMap[FrameLayout::class.java.simpleName] = R.mipmap.ic_palette_frame_layout - imgMap[TableLayout::class.java.simpleName] = R.mipmap.ic_palette_table_layout - imgMap[TableRow::class.java.simpleName] = R.mipmap.ic_palette_table_row - imgMap[Space::class.java.simpleName] = R.mipmap.ic_palette_space - imgMap[Spinner::class.java.simpleName] = R.mipmap.ic_palette_spinner - imgMap[ScrollView::class.java.simpleName] = R.mipmap.ic_palette_scroll_view - imgMap[HorizontalScrollView::class.java.simpleName] = - R.mipmap.ic_palette_horizontal_scroll_view - imgMap[ViewStub::class.java.simpleName] = R.mipmap.ic_palette_view_stub - imgMap["include"] = R.mipmap.ic_palette_include - imgMap[GridLayout::class.java.simpleName] = - R.mipmap.ic_palette_grid_layout - imgMap[GridView::class.java.simpleName] = R.mipmap.ic_palette_grid_view - imgMap[RecyclerView::class.java.simpleName] = R.mipmap.ic_palette_recycler_view - imgMap[ListView::class.java.simpleName] = R.mipmap.ic_palette_list_view - imgMap[TabHost::class.java.simpleName] = R.mipmap.ic_palette_tab_host - imgMap[RelativeLayout::class.java.simpleName] = R.mipmap.ic_palette_relative_layout - imgMap[Chip::class.java.simpleName] = R.mipmap.ic_palette_chip - imgMap[ChipGroup::class.java.simpleName] = R.mipmap.ic_palette_chip_group - imgMap[FloatingActionButton::class.java.simpleName] = - R.mipmap.ic_palette_floating_action_button - imgMap[NestedScrollView::class.java.simpleName] = R.mipmap.ic_palette_nested_scroll_view - imgMap[ViewPager::class.java.simpleName] = R.mipmap.ic_palette_view_pager - imgMap[ViewPager2::class.java.simpleName] = R.mipmap.ic_palette_view_pager - imgMap[CardView::class.java.simpleName] = R.mipmap.ic_palette_card_view - imgMap[TextClock::class.java.simpleName] = R.mipmap.ic_palette_text_clock - imgMap[AppBarLayout::class.java.simpleName] = R.mipmap.ic_palette_app_bar_layout - imgMap[NavigationView::class.java.simpleName] = R.mipmap.ic_palette_navigation_view - imgMap[ConstraintLayout::class.java.simpleName] = - R.mipmap.ic_palette_constraint_layout - imgMap[BottomNavigationView::class.java.simpleName] = - R.mipmap.ic_palette_bottom_navigation_view - imgMap[CoordinatorLayout::class.java.simpleName] = - R.mipmap.ic_palette_coordinator_layout - } - } + init { + imgMap["_unknown"] = R.mipmap.ic_palette_unknown_view + imgMap[TextView::class.java.simpleName] = R.mipmap.ic_palette_text_view + imgMap[EditText::class.java.simpleName] = R.mipmap.ic_palette_edit_text + imgMap[Button::class.java.simpleName] = + R.mipmap.ic_palette_button + imgMap[ImageButton::class.java.simpleName] = + R.mipmap.ic_palette_image_button + imgMap[ImageView::class.java.simpleName] = R.mipmap.ic_palette_image_view + imgMap[VideoView::class.java.simpleName] = R.mipmap.ic_palette_video_view + imgMap[AutoCompleteTextView::class.java.simpleName] = + R.mipmap.ic_palette_auto_complete_text_view + imgMap[MultiAutoCompleteTextView::class.java.simpleName] = + R.mipmap.ic_palette_multi_auto_complete_text_view + imgMap[CheckedTextView::class.java.simpleName] = + R.mipmap.ic_palette_checked_text_view + imgMap[CheckBox::class.java.simpleName] = R.mipmap.ic_palette_check_box + imgMap[RadioButton::class.java.simpleName] = R.mipmap.ic_palette_radio_button + imgMap[RadioGroup::class.java.simpleName] = + R.mipmap.ic_palette_radio_group + imgMap[ToggleButton::class.java.simpleName] = R.mipmap.ic_palette_toggle_button + imgMap[Switch::class.java.simpleName] = R.mipmap.ic_palette_switch + imgMap[View::class.java.simpleName] = R.mipmap.ic_palette_view + imgMap[WebView::class.java.simpleName] = R.mipmap.ic_palette_web_view + imgMap[CalendarView::class.java.simpleName] = R.mipmap.ic_palette_calendar_view + imgMap[ProgressBar::class.java.simpleName] = R.mipmap.ic_palette_progress_bar + imgMap[ProgressBar::class.java.simpleName + "horizontal"] = + R.mipmap.ic_palette_progress_bar_horizontal + imgMap[SeekBar::class.java.simpleName] = R.mipmap.ic_palette_seek_bar + imgMap[RatingBar::class.java.simpleName] = R.mipmap.ic_palette_rating_bar + imgMap[TextureView::class.java.simpleName] = + R.mipmap.ic_palette_texture_view + imgMap[SurfaceView::class.java.simpleName] = R.mipmap.ic_palette_surface_view + imgMap[SearchView::class.java.simpleName] = + R.mipmap.ic_palette_search_view + imgMap[LinearLayout::class.java.simpleName + "horizontal"] = + R.mipmap.ic_palette_linear_layout_horz + imgMap[LinearLayout::class.java.simpleName + "vertical"] = + R.mipmap.ic_palette_linear_layout_vert + imgMap[FrameLayout::class.java.simpleName] = R.mipmap.ic_palette_frame_layout + imgMap[TableLayout::class.java.simpleName] = R.mipmap.ic_palette_table_layout + imgMap[TableRow::class.java.simpleName] = R.mipmap.ic_palette_table_row + imgMap[Space::class.java.simpleName] = R.mipmap.ic_palette_space + imgMap[Spinner::class.java.simpleName] = R.mipmap.ic_palette_spinner + imgMap[ScrollView::class.java.simpleName] = R.mipmap.ic_palette_scroll_view + imgMap[HorizontalScrollView::class.java.simpleName] = + R.mipmap.ic_palette_horizontal_scroll_view + imgMap[ViewStub::class.java.simpleName] = R.mipmap.ic_palette_view_stub + imgMap["include"] = R.mipmap.ic_palette_include + imgMap[GridLayout::class.java.simpleName] = + R.mipmap.ic_palette_grid_layout + imgMap[GridView::class.java.simpleName] = R.mipmap.ic_palette_grid_view + imgMap[RecyclerView::class.java.simpleName] = R.mipmap.ic_palette_recycler_view + imgMap[ListView::class.java.simpleName] = R.mipmap.ic_palette_list_view + imgMap[TabHost::class.java.simpleName] = R.mipmap.ic_palette_tab_host + imgMap[RelativeLayout::class.java.simpleName] = R.mipmap.ic_palette_relative_layout + imgMap[Chip::class.java.simpleName] = R.mipmap.ic_palette_chip + imgMap[ChipGroup::class.java.simpleName] = R.mipmap.ic_palette_chip_group + imgMap[FloatingActionButton::class.java.simpleName] = + R.mipmap.ic_palette_floating_action_button + imgMap[NestedScrollView::class.java.simpleName] = R.mipmap.ic_palette_nested_scroll_view + imgMap[ViewPager::class.java.simpleName] = R.mipmap.ic_palette_view_pager + imgMap[ViewPager2::class.java.simpleName] = R.mipmap.ic_palette_view_pager + imgMap[CardView::class.java.simpleName] = R.mipmap.ic_palette_card_view + imgMap[TextClock::class.java.simpleName] = R.mipmap.ic_palette_text_clock + imgMap[AppBarLayout::class.java.simpleName] = R.mipmap.ic_palette_app_bar_layout + imgMap[NavigationView::class.java.simpleName] = R.mipmap.ic_palette_navigation_view + imgMap[ConstraintLayout::class.java.simpleName] = + R.mipmap.ic_palette_constraint_layout + imgMap[BottomNavigationView::class.java.simpleName] = + R.mipmap.ic_palette_bottom_navigation_view + imgMap[CoordinatorLayout::class.java.simpleName] = + R.mipmap.ic_palette_coordinator_layout + imgMap[DrawerLayout::class.java.simpleName] = R.mipmap.ic_palette_drawer_layout + } + } } From 1dab1c3462f0f4bb53a4ecd37c6619138eaeca60 Mon Sep 17 00:00:00 2001 From: Oluwadara Abijo Date: Wed, 19 Nov 2025 11:43:37 +0100 Subject: [PATCH 3/4] fix(ADFA-2128): Add missing resource --- .../src/main/res/mipmap-xhdpi/ic_palette_drawer_layout.xml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 layouteditor/src/main/res/mipmap-xhdpi/ic_palette_drawer_layout.xml diff --git a/layouteditor/src/main/res/mipmap-xhdpi/ic_palette_drawer_layout.xml b/layouteditor/src/main/res/mipmap-xhdpi/ic_palette_drawer_layout.xml new file mode 100644 index 0000000000..a928815923 --- /dev/null +++ b/layouteditor/src/main/res/mipmap-xhdpi/ic_palette_drawer_layout.xml @@ -0,0 +1,5 @@ + + + + + From 41debd7a8661d65846854bddb70ee9e019b0dca6 Mon Sep 17 00:00:00 2001 From: Oluwadara Abijo Date: Wed, 19 Nov 2025 12:52:12 +0100 Subject: [PATCH 4/4] Minor fixes --- layouteditor/src/main/assets/palette/layouts.json | 1 + .../editor/palette/containers/NavigationViewDesign.java | 2 +- .../layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/layouteditor/src/main/assets/palette/layouts.json b/layouteditor/src/main/assets/palette/layouts.json index d758b1a421..857631761e 100644 --- a/layouteditor/src/main/assets/palette/layouts.json +++ b/layouteditor/src/main/assets/palette/layouts.json @@ -96,6 +96,7 @@ "iconName": "ic_palette_drawer_layout", "defaultAttributes": { "android:layout_width": "match_parent", + "android:layout_height": "match_parent", "android:padding": "8dp" } } diff --git a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java index b88bb00458..75d27b6606 100644 --- a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java +++ b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/containers/NavigationViewDesign.java @@ -51,7 +51,7 @@ protected void onAttachedToWindow() { try { super.onAttachedToWindow(); } catch (IllegalArgumentException e) { - logger.error("NavigationView should be placed in a DrawerLayout"); + logger.error("NavigationView should be placed in a DrawerLayout", e); } } } diff --git a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt index 607a499650..3ab468ea8a 100644 --- a/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt +++ b/layouteditor/src/main/java/org/appdevforall/codeonthego/layouteditor/editor/palette/layouts/DrawerLayoutDesign.kt @@ -50,7 +50,7 @@ class DrawerLayoutDesign( try { super.onAttachedToWindow() } catch (e: Exception) { - logger.error("Error in previewing DrawerLayoutDesign") + logger.error("Error in previewing DrawerLayoutDesign", e) } } }