Show SVG icons in button grid

Stephen Paul Weber created

Change summary

build.gradle                                                    |  1 
src/cheogram/res/layout/button_grid_item.xml                    |  2 
src/main/java/eu/siacs/conversations/entities/Conversation.java | 30 +++
src/main/java/eu/siacs/conversations/xmpp/forms/Option.java     | 25 ++
4 files changed, 57 insertions(+), 1 deletion(-)

Detailed changes

build.gradle 🔗

@@ -101,6 +101,7 @@ dependencies {
     implementation 'com.github.singpolyma:android-identicons:master-SNAPSHOT'
     implementation 'org.snikket:webrtc-android:107.0.0'
     implementation 'com.github.woltapp:blurhash:master'
+    implementation 'com.caverock:androidsvg-aar:1.4'
     // INSERT
 }
 

src/cheogram/res/layout/button_grid_item.xml 🔗

@@ -5,6 +5,8 @@
     <Button
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:paddingLeft="16dp"
+        android:paddingRight="16dp"
         android:textAllCaps="false" />
 
 </layout>

src/main/java/eu/siacs/conversations/entities/Conversation.java 🔗

@@ -5,6 +5,9 @@ import android.content.Context;
 import android.content.DialogInterface;
 import android.database.Cursor;
 import android.database.DataSetObserver;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.text.Editable;
@@ -34,6 +37,7 @@ import android.webkit.WebMessage;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.webkit.WebChromeClient;
+import android.util.DisplayMetrics;
 import android.util.Pair;
 import android.util.SparseArray;
 
@@ -49,6 +53,8 @@ import androidx.recyclerview.widget.RecyclerView;
 import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.viewpager.widget.ViewPager;
 
+import com.caverock.androidsvg.SVG;
+
 import com.google.android.material.tabs.TabLayout;
 import com.google.android.material.textfield.TextInputLayout;
 import com.google.common.base.Optional;
@@ -1858,6 +1864,18 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
                                 mValue.setContent(getItem(position).getValue());
                                 execute();
                             });
+
+                            final SVG icon = getItem(position).getIcon();
+                            if (icon != null) {
+                                 v.post(() -> {
+                                     icon.setDocumentPreserveAspectRatio(com.caverock.androidsvg.PreserveAspectRatio.TOP);
+                                     Bitmap bitmap = Bitmap.createBitmap(v.getHeight(), v.getHeight(), Bitmap.Config.ARGB_8888);
+                                     Canvas bmcanvas = new Canvas(bitmap);
+                                     icon.renderToCanvas(bmcanvas);
+                                     v.setCompoundDrawablesRelativeWithIntrinsicBounds(new BitmapDrawable(bitmap), null, null, null);
+                                 });
+                            }
+
                             return v;
                         }
                     };
@@ -1931,6 +1949,18 @@ public class Conversation extends AbstractEntity implements Blockable, Comparabl
                     } else {
                         theOptions.remove(defaultOption);
                         binding.defaultButton.setVisibility(View.VISIBLE);
+
+                        final SVG defaultIcon = defaultOption.getIcon();
+                        if (defaultIcon != null) {
+                             defaultIcon.setDocumentPreserveAspectRatio(com.caverock.androidsvg.PreserveAspectRatio.TOP);
+                             DisplayMetrics display = mPager.getContext().getResources().getDisplayMetrics();
+                             Bitmap bitmap = Bitmap.createBitmap((int)(display.heightPixels*display.density/4), (int)(display.heightPixels*display.density/4), Bitmap.Config.ARGB_8888);
+                             bitmap.setDensity(display.densityDpi);
+                             Canvas bmcanvas = new Canvas(bitmap);
+                             defaultIcon.renderToCanvas(bmcanvas);
+                             binding.defaultButton.setCompoundDrawablesRelativeWithIntrinsicBounds(null, new BitmapDrawable(bitmap), null, null);
+                        }
+
                         binding.defaultButton.setText(defaultOption.toString());
                         binding.defaultButton.setOnClickListener((view) -> {
                             mValue.setContent(defaultOption.getValue());

src/main/java/eu/siacs/conversations/xmpp/forms/Option.java 🔗

@@ -1,5 +1,7 @@
 package eu.siacs.conversations.xmpp.forms;
 
+import com.caverock.androidsvg.SVG;
+import com.caverock.androidsvg.SVGParseException;
 import java.util.ArrayList;
 import java.util.List;
 import eu.siacs.conversations.xml.Element;
@@ -7,6 +9,7 @@ import eu.siacs.conversations.xml.Element;
 public class Option {
     protected final String value;
     protected final String label;
+    protected final SVG icon;
 
     public static List<Option> forField(Element field) {
         List<Option> options = new ArrayList<>();
@@ -19,12 +22,21 @@ public class Option {
     }
 
     public Option(final Element option) {
-        this(option.findChildContent("value", "jabber:x:data"), option.getAttribute("label"));
+        this(
+            option.findChildContent("value", "jabber:x:data"),
+            option.getAttribute("label"),
+            parseSVG(option.findChild("svg", "http://www.w3.org/2000/svg"))
+        );
     }
 
     public Option(final String value, final String label) {
+        this(value, label, null);
+    }
+
+    public Option(final String value, final String label, final SVG icon) {
         this.value = value;
         this.label = label == null ? value : label;
+        this.icon = icon;
     }
 
     public boolean equals(Object o) {
@@ -38,4 +50,15 @@ public class Option {
     public String toString() { return label; }
 
     public String getValue() { return value; }
+
+    public SVG getIcon() { return icon; }
+
+    private static SVG parseSVG(final Element svg) {
+        if (svg == null) return null;
+        try {
+            return SVG.getFromString(svg.toString());
+        } catch (final SVGParseException e) {
+            return null;
+        }
+    }
 }