Iconify as a module (no support library)
This commit is contained in:
parent
41c424c9f5
commit
38e12b845b
29 changed files with 1759 additions and 3 deletions
|
@ -169,6 +169,7 @@ allprojects {
|
|||
dependencies {
|
||||
wearApp project(':wear')
|
||||
|
||||
implementation project(':iconify')
|
||||
implementation project(':shared')
|
||||
implementation project(':core')
|
||||
implementation project(':automation')
|
||||
|
|
|
@ -15,4 +15,5 @@ android {
|
|||
dependencies {
|
||||
implementation project(':core')
|
||||
implementation project(':shared')
|
||||
implementation project(':iconify')
|
||||
}
|
|
@ -69,8 +69,6 @@ dependencies {
|
|||
api "com.squareup.retrofit2:adapter-rxjava3:$retrofit2_version"
|
||||
api "com.squareup.retrofit2:converter-gson:$retrofit2_version"
|
||||
|
||||
api "com.joanzapata.iconify:android-iconify-fontawesome:2.2.2"
|
||||
|
||||
api "androidx.fragment:fragment-ktx:$fragmentktx_version"
|
||||
api "androidx.constraintlayout:constraintlayout:$constraintlayout_version"
|
||||
api "androidx.navigation:navigation-runtime-ktx:$nav_version"
|
||||
|
|
|
@ -25,6 +25,7 @@ android {
|
|||
dependencies {
|
||||
implementation project(':core')
|
||||
implementation project(':shared')
|
||||
implementation project(':iconify')
|
||||
|
||||
api "androidx.room:room-ktx:$room_version"
|
||||
api "androidx.room:room-runtime:$room_version"
|
||||
|
|
|
@ -25,6 +25,7 @@ android {
|
|||
dependencies {
|
||||
implementation project(':core')
|
||||
implementation project(':shared')
|
||||
implementation project(':iconify')
|
||||
|
||||
api "androidx.room:room-ktx:$room_version"
|
||||
api "androidx.room:room-runtime:$room_version"
|
||||
|
|
1
iconify/.gitignore
vendored
Normal file
1
iconify/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/build
|
20
iconify/build.gradle
Normal file
20
iconify/build.gradle
Normal file
|
@ -0,0 +1,20 @@
|
|||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'kotlin-allopen'
|
||||
apply plugin: 'com.hiya.jacoco-android'
|
||||
apply plugin: 'kotlinx-serialization'
|
||||
|
||||
apply from: "${project.rootDir}/core/android_dependencies.gradle"
|
||||
apply from: "${project.rootDir}/core/android_module_dependencies.gradle"
|
||||
apply from: "${project.rootDir}/core/test_dependencies.gradle"
|
||||
apply from: "${project.rootDir}/core/jacoco_global.gradle"
|
||||
|
||||
android {
|
||||
|
||||
namespace 'com.joanzapata.iconify'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api "androidx.core:core-ktx:$core_version"
|
||||
}
|
0
iconify/consumer-rules.pro
Normal file
0
iconify/consumer-rules.pro
Normal file
21
iconify/proguard-rules.pro
vendored
Normal file
21
iconify/proguard-rules.pro
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
4
iconify/src/main/AndroidManifest.xml
Normal file
4
iconify/src/main/AndroidManifest.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
BIN
iconify/src/main/assets/iconify/android-iconify-fontawesome.ttf
Normal file
BIN
iconify/src/main/assets/iconify/android-iconify-fontawesome.ttf
Normal file
Binary file not shown.
14
iconify/src/main/java/com/joanzapata/iconify/Icon.java
Normal file
14
iconify/src/main/java/com/joanzapata/iconify/Icon.java
Normal file
|
@ -0,0 +1,14 @@
|
|||
package com.joanzapata.iconify;
|
||||
|
||||
/**
|
||||
* Icon represents one icon in an icon font.
|
||||
*/
|
||||
public interface Icon {
|
||||
|
||||
/** The key of icon, for example 'fa-ok' */
|
||||
String key();
|
||||
|
||||
/** The character matching the key in the font, for example '\u4354' */
|
||||
char character();
|
||||
|
||||
}
|
229
iconify/src/main/java/com/joanzapata/iconify/IconDrawable.java
Normal file
229
iconify/src/main/java/com/joanzapata/iconify/IconDrawable.java
Normal file
|
@ -0,0 +1,229 @@
|
|||
package com.joanzapata.iconify;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.graphics.*;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.text.TextPaint;
|
||||
import android.util.TypedValue;
|
||||
import com.joanzapata.iconify.internal.IconFontDescriptorWrapper;
|
||||
|
||||
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
||||
|
||||
/**
|
||||
* Embed an icon into a Drawable that can be used as TextView icons, or ActionBar icons.
|
||||
* <pre>
|
||||
* new IconDrawable(context, IconValue.icon_star)
|
||||
* .colorRes(R.color.white)
|
||||
* .actionBarSize();
|
||||
* </pre>
|
||||
* If you don't set the size of the drawable, it will use the size
|
||||
* that is given to him. Note that in an ActionBar, if you don't
|
||||
* set the size explicitly it uses 0, so please use actionBarSize().
|
||||
*/
|
||||
public class IconDrawable extends Drawable {
|
||||
|
||||
public static final int ANDROID_ACTIONBAR_ICON_SIZE_DP = 24;
|
||||
|
||||
private Context context;
|
||||
|
||||
private Icon icon;
|
||||
|
||||
private TextPaint paint;
|
||||
|
||||
private int size = -1;
|
||||
|
||||
private int alpha = 255;
|
||||
|
||||
/**
|
||||
* Create an IconDrawable.
|
||||
* @param context Your activity or application context.
|
||||
* @param iconKey The icon key you want this drawable to display.
|
||||
* @throws IllegalArgumentException if the key doesn't match any icon.
|
||||
*/
|
||||
public IconDrawable(Context context, String iconKey) {
|
||||
Icon icon = Iconify.findIconForKey(iconKey);
|
||||
if (icon == null) {
|
||||
throw new IllegalArgumentException("No icon with that key \"" + iconKey + "\".");
|
||||
}
|
||||
init(context, icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an IconDrawable.
|
||||
* @param context Your activity or application context.
|
||||
* @param icon The icon you want this drawable to display.
|
||||
*/
|
||||
public IconDrawable(Context context, Icon icon) {
|
||||
init(context, icon);
|
||||
}
|
||||
|
||||
private void init(Context context, Icon icon) {
|
||||
this.context = context;
|
||||
this.icon = icon;
|
||||
paint = new TextPaint();
|
||||
IconFontDescriptorWrapper descriptor = Iconify.findTypefaceOf(icon);
|
||||
if (descriptor == null) {
|
||||
throw new IllegalStateException("Unable to find the module associated " +
|
||||
"with icon " + icon.key() + ", have you registered the module " +
|
||||
"you are trying to use with Iconify.with(...) in your Application?");
|
||||
}
|
||||
paint.setTypeface(descriptor.getTypeface(context));
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
paint.setTextAlign(Paint.Align.CENTER);
|
||||
paint.setUnderlineText(false);
|
||||
paint.setColor(Color.BLACK);
|
||||
paint.setAntiAlias(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of this icon to the standard Android ActionBar.
|
||||
* @return The current IconDrawable for chaining.
|
||||
*/
|
||||
public IconDrawable actionBarSize() {
|
||||
return sizeDp(ANDROID_ACTIONBAR_ICON_SIZE_DP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of the drawable.
|
||||
* @param dimenRes The dimension resource.
|
||||
* @return The current IconDrawable for chaining.
|
||||
*/
|
||||
public IconDrawable sizeRes(int dimenRes) {
|
||||
return sizePx(context.getResources().getDimensionPixelSize(dimenRes));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of the drawable.
|
||||
* @param size The size in density-independent pixels (dp).
|
||||
* @return The current IconDrawable for chaining.
|
||||
*/
|
||||
public IconDrawable sizeDp(int size) {
|
||||
return sizePx(convertDpToPx(context, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the size of the drawable.
|
||||
* @param size The size in pixels (px).
|
||||
* @return The current IconDrawable for chaining.
|
||||
*/
|
||||
public IconDrawable sizePx(int size) {
|
||||
this.size = size;
|
||||
setBounds(0, 0, size, size);
|
||||
invalidateSelf();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of the drawable.
|
||||
* @param color The color, usually from android.graphics.Color or 0xFF012345.
|
||||
* @return The current IconDrawable for chaining.
|
||||
*/
|
||||
public IconDrawable color(int color) {
|
||||
paint.setColor(color);
|
||||
invalidateSelf();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of the drawable.
|
||||
* @param colorRes The color resource, from your R file.
|
||||
* @return The current IconDrawable for chaining.
|
||||
*/
|
||||
public IconDrawable colorRes(int colorRes) {
|
||||
paint.setColor(context.getColor(colorRes));
|
||||
invalidateSelf();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the alpha of this drawable.
|
||||
* @param alpha The alpha, between 0 (transparent) and 255 (opaque).
|
||||
* @return The current IconDrawable for chaining.
|
||||
*/
|
||||
public IconDrawable alpha(int alpha) {
|
||||
setAlpha(alpha);
|
||||
invalidateSelf();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicHeight() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntrinsicWidth() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
Rect bounds = getBounds();
|
||||
int height = bounds.height();
|
||||
paint.setTextSize(height);
|
||||
Rect textBounds = new Rect();
|
||||
String textValue = String.valueOf(icon.character());
|
||||
paint.getTextBounds(textValue, 0, 1, textBounds);
|
||||
int textHeight = textBounds.height();
|
||||
float textBottom = bounds.top + (height - textHeight) / 2f + textHeight - textBounds.bottom;
|
||||
canvas.drawText(textValue, bounds.exactCenterX(), textBottom, paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStateful() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setState(int[] stateSet) {
|
||||
int oldValue = paint.getAlpha();
|
||||
int newValue = isEnabled(stateSet) ? alpha : alpha / 2;
|
||||
paint.setAlpha(newValue);
|
||||
return oldValue != newValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlpha(int alpha) {
|
||||
this.alpha = alpha;
|
||||
paint.setAlpha(alpha);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorFilter(ColorFilter cf) {
|
||||
paint.setColorFilter(cf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearColorFilter() {
|
||||
paint.setColorFilter(null);
|
||||
}
|
||||
|
||||
@SuppressLint("WrongConstant") @Override
|
||||
public int getOpacity() {
|
||||
return this.alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets paint style.
|
||||
* @param style to be applied
|
||||
*/
|
||||
public void setStyle(Paint.Style style) {
|
||||
paint.setStyle(style);
|
||||
}
|
||||
|
||||
// Util
|
||||
private boolean isEnabled(int[] stateSet) {
|
||||
for (int state : stateSet)
|
||||
if (state == android.R.attr.state_enabled)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Util
|
||||
private int convertDpToPx(Context context, float dp) {
|
||||
return (int) TypedValue.applyDimension(
|
||||
COMPLEX_UNIT_DIP, dp,
|
||||
context.getResources().getDisplayMetrics());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.joanzapata.iconify;
|
||||
|
||||
/**
|
||||
* An IconFontDescriptor defines a TTF font file
|
||||
* and is able to map keys with characters in this file.
|
||||
*/
|
||||
public interface IconFontDescriptor {
|
||||
|
||||
/**
|
||||
* The TTF file name.
|
||||
* @return a name with no slash, present in the assets.
|
||||
*/
|
||||
String ttfFileName();
|
||||
|
||||
Icon[] characters();
|
||||
|
||||
}
|
111
iconify/src/main/java/com/joanzapata/iconify/Iconify.java
Normal file
111
iconify/src/main/java/com/joanzapata/iconify/Iconify.java
Normal file
|
@ -0,0 +1,111 @@
|
|||
package com.joanzapata.iconify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.widget.TextView;
|
||||
import com.joanzapata.iconify.internal.IconFontDescriptorWrapper;
|
||||
import com.joanzapata.iconify.internal.ParsingUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Iconify {
|
||||
|
||||
/** List of icon font descriptors */
|
||||
private static List<IconFontDescriptorWrapper> iconFontDescriptors = new ArrayList<IconFontDescriptorWrapper>();
|
||||
|
||||
/**
|
||||
* Add support for a new icon font.
|
||||
* @param iconFontDescriptor The IconDescriptor holding the ttf file reference and its mappings.
|
||||
* @return An initializer instance for chain calls.
|
||||
*/
|
||||
public static IconifyInitializer with(IconFontDescriptor iconFontDescriptor) {
|
||||
return new IconifyInitializer(iconFontDescriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace "{}" tags in the given text views with actual icons, requesting the IconFontDescriptors
|
||||
* one after the others.<p>
|
||||
* <strong>This is a one time call.</strong> If you call {@link TextView#setText(CharSequence)} after this,
|
||||
* you'll need to call it again.
|
||||
* @param textViews The TextView(s) to enhance.
|
||||
*/
|
||||
public static void addIcons(TextView... textViews) {
|
||||
for (TextView textView : textViews) {
|
||||
if (textView == null) continue;
|
||||
textView.setText(compute(textView.getContext(), textView.getText(), textView));
|
||||
}
|
||||
}
|
||||
|
||||
private static void addIconFontDescriptor(IconFontDescriptor iconFontDescriptor) {
|
||||
|
||||
// Prevent duplicates
|
||||
for (IconFontDescriptorWrapper wrapper : iconFontDescriptors) {
|
||||
if (wrapper.getIconFontDescriptor().ttfFileName()
|
||||
.equals(iconFontDescriptor.ttfFileName())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add to the list
|
||||
iconFontDescriptors.add(new IconFontDescriptorWrapper(iconFontDescriptor));
|
||||
|
||||
}
|
||||
|
||||
public static CharSequence compute(Context context, CharSequence text) {
|
||||
return compute(context, text, null);
|
||||
}
|
||||
|
||||
public static CharSequence compute(Context context, CharSequence text, TextView target) {
|
||||
return ParsingUtil.parse(context, iconFontDescriptors, text, target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows chain calls on {@link Iconify#with(IconFontDescriptor)}.
|
||||
*/
|
||||
public static class IconifyInitializer {
|
||||
|
||||
public IconifyInitializer(IconFontDescriptor iconFontDescriptor) {
|
||||
Iconify.addIconFontDescriptor(iconFontDescriptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add support for a new icon font.
|
||||
* @param iconFontDescriptor The IconDescriptor holding the ttf file reference and its mappings.
|
||||
* @return An initializer instance for chain calls.
|
||||
*/
|
||||
public IconifyInitializer with(IconFontDescriptor iconFontDescriptor) {
|
||||
Iconify.addIconFontDescriptor(iconFontDescriptor);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the Typeface to apply for a given icon.
|
||||
* @param icon The icon for which you need the typeface.
|
||||
* @return The font descriptor which contains info about the typeface to apply, or null
|
||||
* if the icon cannot be found. In that case, check that you properly added the modules
|
||||
* using {@link #with(IconFontDescriptor)}} prior to calling this method.
|
||||
*/
|
||||
public static IconFontDescriptorWrapper findTypefaceOf(Icon icon) {
|
||||
for (IconFontDescriptorWrapper iconFontDescriptor : iconFontDescriptors) {
|
||||
if (iconFontDescriptor.hasIcon(icon)) {
|
||||
return iconFontDescriptor;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve an icon from a key,
|
||||
* @return The icon, or null if no icon matches the key.
|
||||
*/
|
||||
public static Icon findIconForKey(String iconKey) {
|
||||
for (int i = 0, iconFontDescriptorsSize = iconFontDescriptors.size(); i < iconFontDescriptorsSize; i++) {
|
||||
IconFontDescriptorWrapper iconFontDescriptor = iconFontDescriptors.get(i);
|
||||
Icon icon = iconFontDescriptor.getIcon(iconKey);
|
||||
if (icon != null) return icon;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,716 @@
|
|||
package com.joanzapata.iconify.fonts;
|
||||
|
||||
import com.joanzapata.iconify.Icon;
|
||||
|
||||
public enum FontAwesomeIcons implements Icon {
|
||||
fa_glass('\uf000'),
|
||||
fa_music('\uf001'),
|
||||
fa_search('\uf002'),
|
||||
fa_envelope_o('\uf003'),
|
||||
fa_heart('\uf004'),
|
||||
fa_star('\uf005'),
|
||||
fa_star_o('\uf006'),
|
||||
fa_user('\uf007'),
|
||||
fa_film('\uf008'),
|
||||
fa_th_large('\uf009'),
|
||||
fa_th('\uf00a'),
|
||||
fa_th_list('\uf00b'),
|
||||
fa_check('\uf00c'),
|
||||
fa_remove('\uf00d'),
|
||||
fa_close('\uf00d'),
|
||||
fa_times('\uf00d'),
|
||||
fa_search_plus('\uf00e'),
|
||||
fa_search_minus('\uf010'),
|
||||
fa_power_off('\uf011'),
|
||||
fa_signal('\uf012'),
|
||||
fa_gear('\uf013'),
|
||||
fa_cog('\uf013'),
|
||||
fa_trash_o('\uf014'),
|
||||
fa_home('\uf015'),
|
||||
fa_file_o('\uf016'),
|
||||
fa_clock_o('\uf017'),
|
||||
fa_road('\uf018'),
|
||||
fa_download('\uf019'),
|
||||
fa_arrow_circle_o_down('\uf01a'),
|
||||
fa_arrow_circle_o_up('\uf01b'),
|
||||
fa_inbox('\uf01c'),
|
||||
fa_play_circle_o('\uf01d'),
|
||||
fa_rotate_right('\uf01e'),
|
||||
fa_repeat('\uf01e'),
|
||||
fa_refresh('\uf021'),
|
||||
fa_list_alt('\uf022'),
|
||||
fa_lock('\uf023'),
|
||||
fa_flag('\uf024'),
|
||||
fa_headphones('\uf025'),
|
||||
fa_volume_off('\uf026'),
|
||||
fa_volume_down('\uf027'),
|
||||
fa_volume_up('\uf028'),
|
||||
fa_qrcode('\uf029'),
|
||||
fa_barcode('\uf02a'),
|
||||
fa_tag('\uf02b'),
|
||||
fa_tags('\uf02c'),
|
||||
fa_book('\uf02d'),
|
||||
fa_bookmark('\uf02e'),
|
||||
fa_print('\uf02f'),
|
||||
fa_camera('\uf030'),
|
||||
fa_font('\uf031'),
|
||||
fa_bold('\uf032'),
|
||||
fa_italic('\uf033'),
|
||||
fa_text_height('\uf034'),
|
||||
fa_text_width('\uf035'),
|
||||
fa_align_left('\uf036'),
|
||||
fa_align_center('\uf037'),
|
||||
fa_align_right('\uf038'),
|
||||
fa_align_justify('\uf039'),
|
||||
fa_list('\uf03a'),
|
||||
fa_dedent('\uf03b'),
|
||||
fa_outdent('\uf03b'),
|
||||
fa_indent('\uf03c'),
|
||||
fa_video_camera('\uf03d'),
|
||||
fa_photo('\uf03e'),
|
||||
fa_image('\uf03e'),
|
||||
fa_picture_o('\uf03e'),
|
||||
fa_pencil('\uf040'),
|
||||
fa_map_marker('\uf041'),
|
||||
fa_adjust('\uf042'),
|
||||
fa_tint('\uf043'),
|
||||
fa_edit('\uf044'),
|
||||
fa_pencil_square_o('\uf044'),
|
||||
fa_share_square_o('\uf045'),
|
||||
fa_check_square_o('\uf046'),
|
||||
fa_arrows('\uf047'),
|
||||
fa_step_backward('\uf048'),
|
||||
fa_fast_backward('\uf049'),
|
||||
fa_backward('\uf04a'),
|
||||
fa_play('\uf04b'),
|
||||
fa_pause('\uf04c'),
|
||||
fa_stop('\uf04d'),
|
||||
fa_forward('\uf04e'),
|
||||
fa_fast_forward('\uf050'),
|
||||
fa_step_forward('\uf051'),
|
||||
fa_eject('\uf052'),
|
||||
fa_chevron_left('\uf053'),
|
||||
fa_chevron_right('\uf054'),
|
||||
fa_plus_circle('\uf055'),
|
||||
fa_minus_circle('\uf056'),
|
||||
fa_times_circle('\uf057'),
|
||||
fa_check_circle('\uf058'),
|
||||
fa_question_circle('\uf059'),
|
||||
fa_info_circle('\uf05a'),
|
||||
fa_crosshairs('\uf05b'),
|
||||
fa_times_circle_o('\uf05c'),
|
||||
fa_check_circle_o('\uf05d'),
|
||||
fa_ban('\uf05e'),
|
||||
fa_arrow_left('\uf060'),
|
||||
fa_arrow_right('\uf061'),
|
||||
fa_arrow_up('\uf062'),
|
||||
fa_arrow_down('\uf063'),
|
||||
fa_mail_forward('\uf064'),
|
||||
fa_share('\uf064'),
|
||||
fa_expand('\uf065'),
|
||||
fa_compress('\uf066'),
|
||||
fa_plus('\uf067'),
|
||||
fa_minus('\uf068'),
|
||||
fa_asterisk('\uf069'),
|
||||
fa_exclamation_circle('\uf06a'),
|
||||
fa_gift('\uf06b'),
|
||||
fa_leaf('\uf06c'),
|
||||
fa_fire('\uf06d'),
|
||||
fa_eye('\uf06e'),
|
||||
fa_eye_slash('\uf070'),
|
||||
fa_warning('\uf071'),
|
||||
fa_exclamation_triangle('\uf071'),
|
||||
fa_plane('\uf072'),
|
||||
fa_calendar('\uf073'),
|
||||
fa_random('\uf074'),
|
||||
fa_comment('\uf075'),
|
||||
fa_magnet('\uf076'),
|
||||
fa_chevron_up('\uf077'),
|
||||
fa_chevron_down('\uf078'),
|
||||
fa_retweet('\uf079'),
|
||||
fa_shopping_cart('\uf07a'),
|
||||
fa_folder('\uf07b'),
|
||||
fa_folder_open('\uf07c'),
|
||||
fa_arrows_v('\uf07d'),
|
||||
fa_arrows_h('\uf07e'),
|
||||
fa_bar_chart_o('\uf080'),
|
||||
fa_bar_chart('\uf080'),
|
||||
fa_twitter_square('\uf081'),
|
||||
fa_facebook_square('\uf082'),
|
||||
fa_camera_retro('\uf083'),
|
||||
fa_key('\uf084'),
|
||||
fa_gears('\uf085'),
|
||||
fa_cogs('\uf085'),
|
||||
fa_comments('\uf086'),
|
||||
fa_thumbs_o_up('\uf087'),
|
||||
fa_thumbs_o_down('\uf088'),
|
||||
fa_star_half('\uf089'),
|
||||
fa_heart_o('\uf08a'),
|
||||
fa_sign_out('\uf08b'),
|
||||
fa_linkedin_square('\uf08c'),
|
||||
fa_thumb_tack('\uf08d'),
|
||||
fa_external_link('\uf08e'),
|
||||
fa_sign_in('\uf090'),
|
||||
fa_trophy('\uf091'),
|
||||
fa_github_square('\uf092'),
|
||||
fa_upload('\uf093'),
|
||||
fa_lemon_o('\uf094'),
|
||||
fa_phone('\uf095'),
|
||||
fa_square_o('\uf096'),
|
||||
fa_bookmark_o('\uf097'),
|
||||
fa_phone_square('\uf098'),
|
||||
fa_twitter('\uf099'),
|
||||
fa_facebook_f('\uf09a'),
|
||||
fa_facebook('\uf09a'),
|
||||
fa_github('\uf09b'),
|
||||
fa_unlock('\uf09c'),
|
||||
fa_credit_card('\uf09d'),
|
||||
fa_feed('\uf09e'),
|
||||
fa_rss('\uf09e'),
|
||||
fa_hdd_o('\uf0a0'),
|
||||
fa_bullhorn('\uf0a1'),
|
||||
fa_bell('\uf0f3'),
|
||||
fa_certificate('\uf0a3'),
|
||||
fa_hand_o_right('\uf0a4'),
|
||||
fa_hand_o_left('\uf0a5'),
|
||||
fa_hand_o_up('\uf0a6'),
|
||||
fa_hand_o_down('\uf0a7'),
|
||||
fa_arrow_circle_left('\uf0a8'),
|
||||
fa_arrow_circle_right('\uf0a9'),
|
||||
fa_arrow_circle_up('\uf0aa'),
|
||||
fa_arrow_circle_down('\uf0ab'),
|
||||
fa_globe('\uf0ac'),
|
||||
fa_wrench('\uf0ad'),
|
||||
fa_tasks('\uf0ae'),
|
||||
fa_filter('\uf0b0'),
|
||||
fa_briefcase('\uf0b1'),
|
||||
fa_arrows_alt('\uf0b2'),
|
||||
fa_group('\uf0c0'),
|
||||
fa_users('\uf0c0'),
|
||||
fa_chain('\uf0c1'),
|
||||
fa_link('\uf0c1'),
|
||||
fa_cloud('\uf0c2'),
|
||||
fa_flask('\uf0c3'),
|
||||
fa_cut('\uf0c4'),
|
||||
fa_scissors('\uf0c4'),
|
||||
fa_copy('\uf0c5'),
|
||||
fa_files_o('\uf0c5'),
|
||||
fa_paperclip('\uf0c6'),
|
||||
fa_save('\uf0c7'),
|
||||
fa_floppy_o('\uf0c7'),
|
||||
fa_square('\uf0c8'),
|
||||
fa_navicon('\uf0c9'),
|
||||
fa_reorder('\uf0c9'),
|
||||
fa_bars('\uf0c9'),
|
||||
fa_list_ul('\uf0ca'),
|
||||
fa_list_ol('\uf0cb'),
|
||||
fa_strikethrough('\uf0cc'),
|
||||
fa_underline('\uf0cd'),
|
||||
fa_table('\uf0ce'),
|
||||
fa_magic('\uf0d0'),
|
||||
fa_truck('\uf0d1'),
|
||||
fa_pinterest('\uf0d2'),
|
||||
fa_pinterest_square('\uf0d3'),
|
||||
fa_google_plus_square('\uf0d4'),
|
||||
fa_google_plus('\uf0d5'),
|
||||
fa_money('\uf0d6'),
|
||||
fa_caret_down('\uf0d7'),
|
||||
fa_caret_up('\uf0d8'),
|
||||
fa_caret_left('\uf0d9'),
|
||||
fa_caret_right('\uf0da'),
|
||||
fa_columns('\uf0db'),
|
||||
fa_unsorted('\uf0dc'),
|
||||
fa_sort('\uf0dc'),
|
||||
fa_sort_down('\uf0dd'),
|
||||
fa_sort_desc('\uf0dd'),
|
||||
fa_sort_up('\uf0de'),
|
||||
fa_sort_asc('\uf0de'),
|
||||
fa_envelope('\uf0e0'),
|
||||
fa_linkedin('\uf0e1'),
|
||||
fa_rotate_left('\uf0e2'),
|
||||
fa_undo('\uf0e2'),
|
||||
fa_legal('\uf0e3'),
|
||||
fa_gavel('\uf0e3'),
|
||||
fa_dashboard('\uf0e4'),
|
||||
fa_tachometer('\uf0e4'),
|
||||
fa_comment_o('\uf0e5'),
|
||||
fa_comments_o('\uf0e6'),
|
||||
fa_flash('\uf0e7'),
|
||||
fa_bolt('\uf0e7'),
|
||||
fa_sitemap('\uf0e8'),
|
||||
fa_umbrella('\uf0e9'),
|
||||
fa_paste('\uf0ea'),
|
||||
fa_clipboard('\uf0ea'),
|
||||
fa_lightbulb_o('\uf0eb'),
|
||||
fa_exchange('\uf0ec'),
|
||||
fa_cloud_download('\uf0ed'),
|
||||
fa_cloud_upload('\uf0ee'),
|
||||
fa_user_md('\uf0f0'),
|
||||
fa_stethoscope('\uf0f1'),
|
||||
fa_suitcase('\uf0f2'),
|
||||
fa_bell_o('\uf0a2'),
|
||||
fa_coffee('\uf0f4'),
|
||||
fa_cutlery('\uf0f5'),
|
||||
fa_file_text_o('\uf0f6'),
|
||||
fa_building_o('\uf0f7'),
|
||||
fa_hospital_o('\uf0f8'),
|
||||
fa_ambulance('\uf0f9'),
|
||||
fa_medkit('\uf0fa'),
|
||||
fa_fighter_jet('\uf0fb'),
|
||||
fa_beer('\uf0fc'),
|
||||
fa_h_square('\uf0fd'),
|
||||
fa_plus_square('\uf0fe'),
|
||||
fa_angle_double_left('\uf100'),
|
||||
fa_angle_double_right('\uf101'),
|
||||
fa_angle_double_up('\uf102'),
|
||||
fa_angle_double_down('\uf103'),
|
||||
fa_angle_left('\uf104'),
|
||||
fa_angle_right('\uf105'),
|
||||
fa_angle_up('\uf106'),
|
||||
fa_angle_down('\uf107'),
|
||||
fa_desktop('\uf108'),
|
||||
fa_laptop('\uf109'),
|
||||
fa_tablet('\uf10a'),
|
||||
fa_mobile_phone('\uf10b'),
|
||||
fa_mobile('\uf10b'),
|
||||
fa_circle_o('\uf10c'),
|
||||
fa_quote_left('\uf10d'),
|
||||
fa_quote_right('\uf10e'),
|
||||
fa_spinner('\uf110'),
|
||||
fa_circle('\uf111'),
|
||||
fa_mail_reply('\uf112'),
|
||||
fa_reply('\uf112'),
|
||||
fa_github_alt('\uf113'),
|
||||
fa_folder_o('\uf114'),
|
||||
fa_folder_open_o('\uf115'),
|
||||
fa_smile_o('\uf118'),
|
||||
fa_frown_o('\uf119'),
|
||||
fa_meh_o('\uf11a'),
|
||||
fa_gamepad('\uf11b'),
|
||||
fa_keyboard_o('\uf11c'),
|
||||
fa_flag_o('\uf11d'),
|
||||
fa_flag_checkered('\uf11e'),
|
||||
fa_terminal('\uf120'),
|
||||
fa_code('\uf121'),
|
||||
fa_mail_reply_all('\uf122'),
|
||||
fa_reply_all('\uf122'),
|
||||
fa_star_half_empty('\uf123'),
|
||||
fa_star_half_full('\uf123'),
|
||||
fa_star_half_o('\uf123'),
|
||||
fa_location_arrow('\uf124'),
|
||||
fa_crop('\uf125'),
|
||||
fa_code_fork('\uf126'),
|
||||
fa_unlink('\uf127'),
|
||||
fa_chain_broken('\uf127'),
|
||||
fa_question('\uf128'),
|
||||
fa_info('\uf129'),
|
||||
fa_exclamation('\uf12a'),
|
||||
fa_superscript('\uf12b'),
|
||||
fa_subscript('\uf12c'),
|
||||
fa_eraser('\uf12d'),
|
||||
fa_puzzle_piece('\uf12e'),
|
||||
fa_microphone('\uf130'),
|
||||
fa_microphone_slash('\uf131'),
|
||||
fa_shield('\uf132'),
|
||||
fa_calendar_o('\uf133'),
|
||||
fa_fire_extinguisher('\uf134'),
|
||||
fa_rocket('\uf135'),
|
||||
fa_maxcdn('\uf136'),
|
||||
fa_chevron_circle_left('\uf137'),
|
||||
fa_chevron_circle_right('\uf138'),
|
||||
fa_chevron_circle_up('\uf139'),
|
||||
fa_chevron_circle_down('\uf13a'),
|
||||
fa_html5('\uf13b'),
|
||||
fa_css3('\uf13c'),
|
||||
fa_anchor('\uf13d'),
|
||||
fa_unlock_alt('\uf13e'),
|
||||
fa_bullseye('\uf140'),
|
||||
fa_ellipsis_h('\uf141'),
|
||||
fa_ellipsis_v('\uf142'),
|
||||
fa_rss_square('\uf143'),
|
||||
fa_play_circle('\uf144'),
|
||||
fa_ticket('\uf145'),
|
||||
fa_minus_square('\uf146'),
|
||||
fa_minus_square_o('\uf147'),
|
||||
fa_level_up('\uf148'),
|
||||
fa_level_down('\uf149'),
|
||||
fa_check_square('\uf14a'),
|
||||
fa_pencil_square('\uf14b'),
|
||||
fa_external_link_square('\uf14c'),
|
||||
fa_share_square('\uf14d'),
|
||||
fa_compass('\uf14e'),
|
||||
fa_toggle_down('\uf150'),
|
||||
fa_caret_square_o_down('\uf150'),
|
||||
fa_toggle_up('\uf151'),
|
||||
fa_caret_square_o_up('\uf151'),
|
||||
fa_toggle_right('\uf152'),
|
||||
fa_caret_square_o_right('\uf152'),
|
||||
fa_euro('\uf153'),
|
||||
fa_eur('\uf153'),
|
||||
fa_gbp('\uf154'),
|
||||
fa_dollar('\uf155'),
|
||||
fa_usd('\uf155'),
|
||||
fa_rupee('\uf156'),
|
||||
fa_inr('\uf156'),
|
||||
fa_cny('\uf157'),
|
||||
fa_rmb('\uf157'),
|
||||
fa_yen('\uf157'),
|
||||
fa_jpy('\uf157'),
|
||||
fa_ruble('\uf158'),
|
||||
fa_rouble('\uf158'),
|
||||
fa_rub('\uf158'),
|
||||
fa_won('\uf159'),
|
||||
fa_krw('\uf159'),
|
||||
fa_bitcoin('\uf15a'),
|
||||
fa_btc('\uf15a'),
|
||||
fa_file('\uf15b'),
|
||||
fa_file_text('\uf15c'),
|
||||
fa_sort_alpha_asc('\uf15d'),
|
||||
fa_sort_alpha_desc('\uf15e'),
|
||||
fa_sort_amount_asc('\uf160'),
|
||||
fa_sort_amount_desc('\uf161'),
|
||||
fa_sort_numeric_asc('\uf162'),
|
||||
fa_sort_numeric_desc('\uf163'),
|
||||
fa_thumbs_up('\uf164'),
|
||||
fa_thumbs_down('\uf165'),
|
||||
fa_youtube_square('\uf166'),
|
||||
fa_youtube('\uf167'),
|
||||
fa_xing('\uf168'),
|
||||
fa_xing_square('\uf169'),
|
||||
fa_youtube_play('\uf16a'),
|
||||
fa_dropbox('\uf16b'),
|
||||
fa_stack_overflow('\uf16c'),
|
||||
fa_instagram('\uf16d'),
|
||||
fa_flickr('\uf16e'),
|
||||
fa_adn('\uf170'),
|
||||
fa_bitbucket('\uf171'),
|
||||
fa_bitbucket_square('\uf172'),
|
||||
fa_tumblr('\uf173'),
|
||||
fa_tumblr_square('\uf174'),
|
||||
fa_long_arrow_down('\uf175'),
|
||||
fa_long_arrow_up('\uf176'),
|
||||
fa_long_arrow_left('\uf177'),
|
||||
fa_long_arrow_right('\uf178'),
|
||||
fa_apple('\uf179'),
|
||||
fa_windows('\uf17a'),
|
||||
fa_android('\uf17b'),
|
||||
fa_linux('\uf17c'),
|
||||
fa_dribbble('\uf17d'),
|
||||
fa_skype('\uf17e'),
|
||||
fa_foursquare('\uf180'),
|
||||
fa_trello('\uf181'),
|
||||
fa_female('\uf182'),
|
||||
fa_male('\uf183'),
|
||||
fa_gittip('\uf184'),
|
||||
fa_gratipay('\uf184'),
|
||||
fa_sun_o('\uf185'),
|
||||
fa_moon_o('\uf186'),
|
||||
fa_archive('\uf187'),
|
||||
fa_bug('\uf188'),
|
||||
fa_vk('\uf189'),
|
||||
fa_weibo('\uf18a'),
|
||||
fa_renren('\uf18b'),
|
||||
fa_pagelines('\uf18c'),
|
||||
fa_stack_exchange('\uf18d'),
|
||||
fa_arrow_circle_o_right('\uf18e'),
|
||||
fa_arrow_circle_o_left('\uf190'),
|
||||
fa_toggle_left('\uf191'),
|
||||
fa_caret_square_o_left('\uf191'),
|
||||
fa_dot_circle_o('\uf192'),
|
||||
fa_wheelchair('\uf193'),
|
||||
fa_vimeo_square('\uf194'),
|
||||
fa_turkish_lira('\uf195'),
|
||||
fa_try('\uf195'),
|
||||
fa_plus_square_o('\uf196'),
|
||||
fa_space_shuttle('\uf197'),
|
||||
fa_slack('\uf198'),
|
||||
fa_envelope_square('\uf199'),
|
||||
fa_wordpress('\uf19a'),
|
||||
fa_openid('\uf19b'),
|
||||
fa_institution('\uf19c'),
|
||||
fa_bank('\uf19c'),
|
||||
fa_university('\uf19c'),
|
||||
fa_mortar_board('\uf19d'),
|
||||
fa_graduation_cap('\uf19d'),
|
||||
fa_yahoo('\uf19e'),
|
||||
fa_google('\uf1a0'),
|
||||
fa_reddit('\uf1a1'),
|
||||
fa_reddit_square('\uf1a2'),
|
||||
fa_stumbleupon_circle('\uf1a3'),
|
||||
fa_stumbleupon('\uf1a4'),
|
||||
fa_delicious('\uf1a5'),
|
||||
fa_digg('\uf1a6'),
|
||||
fa_pied_piper('\uf1a7'),
|
||||
fa_pied_piper_alt('\uf1a8'),
|
||||
fa_drupal('\uf1a9'),
|
||||
fa_joomla('\uf1aa'),
|
||||
fa_language('\uf1ab'),
|
||||
fa_fax('\uf1ac'),
|
||||
fa_building('\uf1ad'),
|
||||
fa_child('\uf1ae'),
|
||||
fa_paw('\uf1b0'),
|
||||
fa_spoon('\uf1b1'),
|
||||
fa_cube('\uf1b2'),
|
||||
fa_cubes('\uf1b3'),
|
||||
fa_behance('\uf1b4'),
|
||||
fa_behance_square('\uf1b5'),
|
||||
fa_steam('\uf1b6'),
|
||||
fa_steam_square('\uf1b7'),
|
||||
fa_recycle('\uf1b8'),
|
||||
fa_automobile('\uf1b9'),
|
||||
fa_car('\uf1b9'),
|
||||
fa_cab('\uf1ba'),
|
||||
fa_taxi('\uf1ba'),
|
||||
fa_tree('\uf1bb'),
|
||||
fa_spotify('\uf1bc'),
|
||||
fa_deviantart('\uf1bd'),
|
||||
fa_soundcloud('\uf1be'),
|
||||
fa_database('\uf1c0'),
|
||||
fa_file_pdf_o('\uf1c1'),
|
||||
fa_file_word_o('\uf1c2'),
|
||||
fa_file_excel_o('\uf1c3'),
|
||||
fa_file_powerpoint_o('\uf1c4'),
|
||||
fa_file_photo_o('\uf1c5'),
|
||||
fa_file_picture_o('\uf1c5'),
|
||||
fa_file_image_o('\uf1c5'),
|
||||
fa_file_zip_o('\uf1c6'),
|
||||
fa_file_archive_o('\uf1c6'),
|
||||
fa_file_sound_o('\uf1c7'),
|
||||
fa_file_audio_o('\uf1c7'),
|
||||
fa_file_movie_o('\uf1c8'),
|
||||
fa_file_video_o('\uf1c8'),
|
||||
fa_file_code_o('\uf1c9'),
|
||||
fa_vine('\uf1ca'),
|
||||
fa_codepen('\uf1cb'),
|
||||
fa_jsfiddle('\uf1cc'),
|
||||
fa_life_bouy('\uf1cd'),
|
||||
fa_life_buoy('\uf1cd'),
|
||||
fa_life_saver('\uf1cd'),
|
||||
fa_support('\uf1cd'),
|
||||
fa_life_ring('\uf1cd'),
|
||||
fa_circle_o_notch('\uf1ce'),
|
||||
fa_ra('\uf1d0'),
|
||||
fa_rebel('\uf1d0'),
|
||||
fa_ge('\uf1d1'),
|
||||
fa_empire('\uf1d1'),
|
||||
fa_git_square('\uf1d2'),
|
||||
fa_git('\uf1d3'),
|
||||
fa_y_combinator_square('\uf1d4'),
|
||||
fa_yc_square('\uf1d4'),
|
||||
fa_hacker_news('\uf1d4'),
|
||||
fa_tencent_weibo('\uf1d5'),
|
||||
fa_qq('\uf1d6'),
|
||||
fa_wechat('\uf1d7'),
|
||||
fa_weixin('\uf1d7'),
|
||||
fa_send('\uf1d8'),
|
||||
fa_paper_plane('\uf1d8'),
|
||||
fa_send_o('\uf1d9'),
|
||||
fa_paper_plane_o('\uf1d9'),
|
||||
fa_history('\uf1da'),
|
||||
fa_circle_thin('\uf1db'),
|
||||
fa_header('\uf1dc'),
|
||||
fa_paragraph('\uf1dd'),
|
||||
fa_sliders('\uf1de'),
|
||||
fa_share_alt('\uf1e0'),
|
||||
fa_share_alt_square('\uf1e1'),
|
||||
fa_bomb('\uf1e2'),
|
||||
fa_soccer_ball_o('\uf1e3'),
|
||||
fa_futbol_o('\uf1e3'),
|
||||
fa_tty('\uf1e4'),
|
||||
fa_binoculars('\uf1e5'),
|
||||
fa_plug('\uf1e6'),
|
||||
fa_slideshare('\uf1e7'),
|
||||
fa_twitch('\uf1e8'),
|
||||
fa_yelp('\uf1e9'),
|
||||
fa_newspaper_o('\uf1ea'),
|
||||
fa_wifi('\uf1eb'),
|
||||
fa_calculator('\uf1ec'),
|
||||
fa_paypal('\uf1ed'),
|
||||
fa_google_wallet('\uf1ee'),
|
||||
fa_cc_visa('\uf1f0'),
|
||||
fa_cc_mastercard('\uf1f1'),
|
||||
fa_cc_discover('\uf1f2'),
|
||||
fa_cc_amex('\uf1f3'),
|
||||
fa_cc_paypal('\uf1f4'),
|
||||
fa_cc_stripe('\uf1f5'),
|
||||
fa_bell_slash('\uf1f6'),
|
||||
fa_bell_slash_o('\uf1f7'),
|
||||
fa_trash('\uf1f8'),
|
||||
fa_copyright('\uf1f9'),
|
||||
fa_at('\uf1fa'),
|
||||
fa_eyedropper('\uf1fb'),
|
||||
fa_paint_brush('\uf1fc'),
|
||||
fa_birthday_cake('\uf1fd'),
|
||||
fa_area_chart('\uf1fe'),
|
||||
fa_pie_chart('\uf200'),
|
||||
fa_line_chart('\uf201'),
|
||||
fa_lastfm('\uf202'),
|
||||
fa_lastfm_square('\uf203'),
|
||||
fa_toggle_off('\uf204'),
|
||||
fa_toggle_on('\uf205'),
|
||||
fa_bicycle('\uf206'),
|
||||
fa_bus('\uf207'),
|
||||
fa_ioxhost('\uf208'),
|
||||
fa_angellist('\uf209'),
|
||||
fa_cc('\uf20a'),
|
||||
fa_shekel('\uf20b'),
|
||||
fa_sheqel('\uf20b'),
|
||||
fa_ils('\uf20b'),
|
||||
fa_meanpath('\uf20c'),
|
||||
fa_buysellads('\uf20d'),
|
||||
fa_connectdevelop('\uf20e'),
|
||||
fa_dashcube('\uf210'),
|
||||
fa_forumbee('\uf211'),
|
||||
fa_leanpub('\uf212'),
|
||||
fa_sellsy('\uf213'),
|
||||
fa_shirtsinbulk('\uf214'),
|
||||
fa_simplybuilt('\uf215'),
|
||||
fa_skyatlas('\uf216'),
|
||||
fa_cart_plus('\uf217'),
|
||||
fa_cart_arrow_down('\uf218'),
|
||||
fa_diamond('\uf219'),
|
||||
fa_ship('\uf21a'),
|
||||
fa_user_secret('\uf21b'),
|
||||
fa_motorcycle('\uf21c'),
|
||||
fa_street_view('\uf21d'),
|
||||
fa_heartbeat('\uf21e'),
|
||||
fa_venus('\uf221'),
|
||||
fa_mars('\uf222'),
|
||||
fa_mercury('\uf223'),
|
||||
fa_intersex('\uf224'),
|
||||
fa_transgender('\uf224'),
|
||||
fa_transgender_alt('\uf225'),
|
||||
fa_venus_double('\uf226'),
|
||||
fa_mars_double('\uf227'),
|
||||
fa_venus_mars('\uf228'),
|
||||
fa_mars_stroke('\uf229'),
|
||||
fa_mars_stroke_v('\uf22a'),
|
||||
fa_mars_stroke_h('\uf22b'),
|
||||
fa_neuter('\uf22c'),
|
||||
fa_genderless('\uf22d'),
|
||||
fa_facebook_official('\uf230'),
|
||||
fa_pinterest_p('\uf231'),
|
||||
fa_whatsapp('\uf232'),
|
||||
fa_server('\uf233'),
|
||||
fa_user_plus('\uf234'),
|
||||
fa_user_times('\uf235'),
|
||||
fa_hotel('\uf236'),
|
||||
fa_bed('\uf236'),
|
||||
fa_viacoin('\uf237'),
|
||||
fa_train('\uf238'),
|
||||
fa_subway('\uf239'),
|
||||
fa_medium('\uf23a'),
|
||||
fa_yc('\uf23b'),
|
||||
fa_y_combinator('\uf23b'),
|
||||
fa_optin_monster('\uf23c'),
|
||||
fa_opencart('\uf23d'),
|
||||
fa_expeditedssl('\uf23e'),
|
||||
fa_battery_4('\uf240'),
|
||||
fa_battery_full('\uf240'),
|
||||
fa_battery_3('\uf241'),
|
||||
fa_battery_three_quarters('\uf241'),
|
||||
fa_battery_2('\uf242'),
|
||||
fa_battery_half('\uf242'),
|
||||
fa_battery_1('\uf243'),
|
||||
fa_battery_quarter('\uf243'),
|
||||
fa_battery_0('\uf244'),
|
||||
fa_battery_empty('\uf244'),
|
||||
fa_mouse_pointer('\uf245'),
|
||||
fa_i_cursor('\uf246'),
|
||||
fa_object_group('\uf247'),
|
||||
fa_object_ungroup('\uf248'),
|
||||
fa_sticky_note('\uf249'),
|
||||
fa_sticky_note_o('\uf24a'),
|
||||
fa_cc_jcb('\uf24b'),
|
||||
fa_cc_diners_club('\uf24c'),
|
||||
fa_clone('\uf24d'),
|
||||
fa_balance_scale('\uf24e'),
|
||||
fa_hourglass_o('\uf250'),
|
||||
fa_hourglass_1('\uf251'),
|
||||
fa_hourglass_start('\uf251'),
|
||||
fa_hourglass_2('\uf252'),
|
||||
fa_hourglass_half('\uf252'),
|
||||
fa_hourglass_3('\uf253'),
|
||||
fa_hourglass_end('\uf253'),
|
||||
fa_hourglass('\uf254'),
|
||||
fa_hand_grab_o('\uf255'),
|
||||
fa_hand_rock_o('\uf255'),
|
||||
fa_hand_stop_o('\uf256'),
|
||||
fa_hand_paper_o('\uf256'),
|
||||
fa_hand_scissors_o('\uf257'),
|
||||
fa_hand_lizard_o('\uf258'),
|
||||
fa_hand_spock_o('\uf259'),
|
||||
fa_hand_pointer_o('\uf25a'),
|
||||
fa_hand_peace_o('\uf25b'),
|
||||
fa_trademark('\uf25c'),
|
||||
fa_registered('\uf25d'),
|
||||
fa_creative_commons('\uf25e'),
|
||||
fa_gg('\uf260'),
|
||||
fa_gg_circle('\uf261'),
|
||||
fa_tripadvisor('\uf262'),
|
||||
fa_odnoklassniki('\uf263'),
|
||||
fa_odnoklassniki_square('\uf264'),
|
||||
fa_get_pocket('\uf265'),
|
||||
fa_wikipedia_w('\uf266'),
|
||||
fa_safari('\uf267'),
|
||||
fa_chrome('\uf268'),
|
||||
fa_firefox('\uf269'),
|
||||
fa_opera('\uf26a'),
|
||||
fa_internet_explorer('\uf26b'),
|
||||
fa_tv('\uf26c'),
|
||||
fa_television('\uf26c'),
|
||||
fa_contao('\uf26d'),
|
||||
fa_500px('\uf26e'),
|
||||
fa_amazon('\uf270'),
|
||||
fa_calendar_plus_o('\uf271'),
|
||||
fa_calendar_minus_o('\uf272'),
|
||||
fa_calendar_times_o('\uf273'),
|
||||
fa_calendar_check_o('\uf274'),
|
||||
fa_industry('\uf275'),
|
||||
fa_map_pin('\uf276'),
|
||||
fa_map_signs('\uf277'),
|
||||
fa_map_o('\uf278'),
|
||||
fa_map('\uf279'),
|
||||
fa_commenting('\uf27a'),
|
||||
fa_commenting_o('\uf27b'),
|
||||
fa_houzz('\uf27c'),
|
||||
fa_vimeo('\uf27d'),
|
||||
fa_black_tie('\uf27e'),
|
||||
fa_fonticons('\uf280'),
|
||||
fa_reddit_alien('\uf281'),
|
||||
fa_edge('\uf282'),
|
||||
fa_credit_card_alt('\uf283'),
|
||||
fa_codiepie('\uf284'),
|
||||
fa_modx('\uf285'),
|
||||
fa_fort_awesome('\uf286'),
|
||||
fa_usb('\uf287'),
|
||||
fa_product_hunt('\uf288'),
|
||||
fa_mixcloud('\uf289'),
|
||||
fa_scribd('\uf28a'),
|
||||
fa_pause_circle('\uf28b'),
|
||||
fa_pause_circle_o('\uf28c'),
|
||||
fa_stop_circle('\uf28d'),
|
||||
fa_stop_circle_o('\uf28e'),
|
||||
fa_shopping_bag('\uf290'),
|
||||
fa_shopping_basket('\uf291'),
|
||||
fa_hashtag('\uf292'),
|
||||
fa_bluetooth('\uf293'),
|
||||
fa_bluetooth_b('\uf294'),
|
||||
fa_percent('\uf295');
|
||||
|
||||
char character;
|
||||
|
||||
FontAwesomeIcons(char character) {
|
||||
this.character = character;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String key() {
|
||||
return name().replace('_', '-');
|
||||
}
|
||||
|
||||
@Override
|
||||
public char character() {
|
||||
return character;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.joanzapata.iconify.fonts;
|
||||
|
||||
import com.joanzapata.iconify.Icon;
|
||||
import com.joanzapata.iconify.IconFontDescriptor;
|
||||
|
||||
public class FontAwesomeModule implements IconFontDescriptor {
|
||||
|
||||
@Override
|
||||
public String ttfFileName() {
|
||||
return "iconify/android-iconify-fontawesome.ttf";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Icon[] characters() {
|
||||
return FontAwesomeIcons.values();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package com.joanzapata.iconify.internal;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.text.style.ReplacementSpan;
|
||||
import com.joanzapata.iconify.Icon;
|
||||
|
||||
public class CustomTypefaceSpan extends ReplacementSpan {
|
||||
private static final int ROTATION_DURATION = 2000;
|
||||
private static final Rect TEXT_BOUNDS = new Rect();
|
||||
private static final Paint LOCAL_PAINT = new Paint();
|
||||
private static final float BASELINE_RATIO = 1 / 7f;
|
||||
|
||||
private final String icon;
|
||||
private final Typeface type;
|
||||
private final float iconSizePx;
|
||||
private final float iconSizeRatio;
|
||||
private final int iconColor;
|
||||
private final boolean rotate;
|
||||
private final boolean baselineAligned;
|
||||
private final long rotationStartTime;
|
||||
|
||||
public CustomTypefaceSpan(Icon icon, Typeface type,
|
||||
float iconSizePx, float iconSizeRatio, int iconColor,
|
||||
boolean rotate, boolean baselineAligned) {
|
||||
this.rotate = rotate;
|
||||
this.baselineAligned = baselineAligned;
|
||||
this.icon = String.valueOf(icon.character());
|
||||
this.type = type;
|
||||
this.iconSizePx = iconSizePx;
|
||||
this.iconSizeRatio = iconSizeRatio;
|
||||
this.iconColor = iconColor;
|
||||
this.rotationStartTime = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize(Paint paint, CharSequence text,
|
||||
int start, int end, Paint.FontMetricsInt fm) {
|
||||
LOCAL_PAINT.set(paint);
|
||||
applyCustomTypeFace(LOCAL_PAINT, type);
|
||||
LOCAL_PAINT.getTextBounds(icon, 0, 1, TEXT_BOUNDS);
|
||||
if (fm != null) {
|
||||
float baselineRatio = baselineAligned ? 0 : BASELINE_RATIO;
|
||||
fm.descent = (int) (TEXT_BOUNDS.height() * baselineRatio);
|
||||
fm.ascent = -(TEXT_BOUNDS.height() - fm.descent);
|
||||
fm.top = fm.ascent;
|
||||
fm.bottom = fm.descent;
|
||||
}
|
||||
return TEXT_BOUNDS.width();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas, CharSequence text,
|
||||
int start, int end, float x, int top, int y,
|
||||
int bottom, Paint paint) {
|
||||
applyCustomTypeFace(paint, type);
|
||||
paint.getTextBounds(icon, 0, 1, TEXT_BOUNDS);
|
||||
canvas.save();
|
||||
float baselineRatio = baselineAligned ? 0f : BASELINE_RATIO;
|
||||
if (rotate) {
|
||||
float rotation = (System.currentTimeMillis() - rotationStartTime) / (float) ROTATION_DURATION * 360f;
|
||||
float centerX = x + TEXT_BOUNDS.width() / 2f;
|
||||
float centerY = y - TEXT_BOUNDS.height() / 2f + TEXT_BOUNDS.height() * baselineRatio;
|
||||
canvas.rotate(rotation, centerX, centerY);
|
||||
}
|
||||
|
||||
canvas.drawText(icon,
|
||||
x - TEXT_BOUNDS.left,
|
||||
y - TEXT_BOUNDS.bottom + TEXT_BOUNDS.height() * baselineRatio, paint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
public boolean isAnimated() {
|
||||
return rotate;
|
||||
}
|
||||
|
||||
private void applyCustomTypeFace(Paint paint, Typeface tf) {
|
||||
paint.setFakeBoldText(false);
|
||||
paint.setTextSkewX(0f);
|
||||
paint.setTypeface(tf);
|
||||
if (rotate) paint.clearShadowLayer();
|
||||
if (iconSizeRatio > 0) paint.setTextSize(paint.getTextSize() * iconSizeRatio);
|
||||
else if (iconSizePx > 0) paint.setTextSize(iconSizePx);
|
||||
if (iconColor < Integer.MAX_VALUE) paint.setColor(iconColor);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package com.joanzapata.iconify.internal;
|
||||
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
/**
|
||||
* Any TextView subclass that wishes to call {@link com.joanzapata.iconify.Iconify#addIcons(TextView...)} on it
|
||||
* needs to implement this interface if it ever want to use spinning icons.
|
||||
* <br>
|
||||
* IconTextView, IconButton and IconToggleButton already implement it, but if you need to implement it
|
||||
* yourself, please use {@link com.joanzapata.iconify.internal.HasOnViewAttachListener.HasOnViewAttachListenerDelegate}
|
||||
* to help you.
|
||||
*/
|
||||
public interface HasOnViewAttachListener {
|
||||
void setOnViewAttachListener(OnViewAttachListener listener);
|
||||
|
||||
interface OnViewAttachListener {
|
||||
void onAttach();
|
||||
|
||||
void onDetach();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to implement {@link HasOnViewAttachListener}.
|
||||
* Usual implementation should look like this:
|
||||
* <pre>
|
||||
* {@code
|
||||
* class MyClass extends TextView implements HasOnViewAttachListener {
|
||||
*
|
||||
* private HasOnViewAttachListenerDelegate delegate
|
||||
*
|
||||
* @Override
|
||||
* public void setOnViewAttachListener(OnViewAttachListener listener) {
|
||||
* if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this);
|
||||
* delegate.setOnViewAttachListener(listener);
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* protected void onAttachedToWindow() {
|
||||
* super.onAttachedToWindow();
|
||||
* delegate.onAttachedToWindow();
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* protected void onDetachedFromWindow() {
|
||||
* super.onDetachedFromWindow();
|
||||
* delegate.onDetachedFromWindow();
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
class HasOnViewAttachListenerDelegate {
|
||||
|
||||
private final TextView view;
|
||||
private OnViewAttachListener listener;
|
||||
|
||||
public HasOnViewAttachListenerDelegate(TextView view) {
|
||||
this.view = view;
|
||||
}
|
||||
|
||||
public void setOnViewAttachListener(OnViewAttachListener listener) {
|
||||
if (this.listener != null)
|
||||
this.listener.onDetach();
|
||||
this.listener = listener;
|
||||
if (ViewCompat.isAttachedToWindow(view) && listener != null) {
|
||||
listener.onAttach();
|
||||
}
|
||||
}
|
||||
|
||||
public void onAttachedToWindow() {
|
||||
if (listener != null) listener.onAttach();
|
||||
}
|
||||
|
||||
public void onDetachedFromWindow() {
|
||||
if (listener != null) listener.onDetach();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.joanzapata.iconify.internal;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Typeface;
|
||||
import com.joanzapata.iconify.Icon;
|
||||
import com.joanzapata.iconify.IconFontDescriptor;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class IconFontDescriptorWrapper {
|
||||
|
||||
private final IconFontDescriptor iconFontDescriptor;
|
||||
|
||||
private final Map<String, Icon> iconsByKey;
|
||||
|
||||
private Typeface cachedTypeface;
|
||||
|
||||
public IconFontDescriptorWrapper(IconFontDescriptor iconFontDescriptor) {
|
||||
this.iconFontDescriptor = iconFontDescriptor;
|
||||
iconsByKey = new HashMap<String, Icon>();
|
||||
Icon[] characters = iconFontDescriptor.characters();
|
||||
for (int i = 0, charactersLength = characters.length; i < charactersLength; i++) {
|
||||
Icon icon = characters[i];
|
||||
iconsByKey.put(icon.key(), icon);
|
||||
}
|
||||
}
|
||||
|
||||
public Icon getIcon(String key) {
|
||||
return iconsByKey.get(key);
|
||||
}
|
||||
|
||||
public IconFontDescriptor getIconFontDescriptor() {
|
||||
return iconFontDescriptor;
|
||||
}
|
||||
|
||||
public Typeface getTypeface(Context context) {
|
||||
if (cachedTypeface != null) return cachedTypeface;
|
||||
synchronized (this) {
|
||||
if (cachedTypeface != null) return cachedTypeface;
|
||||
cachedTypeface = Typeface.createFromAsset(context.getAssets(), iconFontDescriptor.ttfFileName());
|
||||
return cachedTypeface;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasIcon(Icon icon) {
|
||||
return iconsByKey.values().contains(icon);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,217 @@
|
|||
package com.joanzapata.iconify.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.core.view.ViewCompat;
|
||||
|
||||
import com.joanzapata.iconify.Icon;
|
||||
import com.joanzapata.iconify.internal.HasOnViewAttachListener.OnViewAttachListener;
|
||||
|
||||
public final class ParsingUtil {
|
||||
|
||||
private static final String ANDROID_PACKAGE_NAME = "android";
|
||||
|
||||
// Prevents instantiation
|
||||
private ParsingUtil() {}
|
||||
|
||||
public static CharSequence parse(
|
||||
Context context,
|
||||
List<IconFontDescriptorWrapper> iconFontDescriptors,
|
||||
CharSequence text,
|
||||
final TextView target) {
|
||||
context = context.getApplicationContext();
|
||||
|
||||
// Don't do anything related to iconify if text is null
|
||||
if (text == null) return text;
|
||||
|
||||
// Analyse the text and replace {} blocks with the appropriate character
|
||||
// Retain all transformations in the accumulator
|
||||
final SpannableStringBuilder spannableBuilder = new SpannableStringBuilder(text);
|
||||
recursivePrepareSpannableIndexes(context,
|
||||
text.toString(), spannableBuilder,
|
||||
iconFontDescriptors, 0);
|
||||
boolean isAnimated = hasAnimatedSpans(spannableBuilder);
|
||||
|
||||
// If animated, periodically invalidate the TextView so that the
|
||||
// CustomTypefaceSpan can redraw itself
|
||||
if (isAnimated) {
|
||||
if (target == null)
|
||||
throw new IllegalArgumentException("You can't use \"spin\" without providing the target TextView.");
|
||||
if (!(target instanceof HasOnViewAttachListener))
|
||||
throw new IllegalArgumentException(target.getClass().getSimpleName() + " does not implement " +
|
||||
"HasOnViewAttachListener. Please use IconTextView, IconButton or IconToggleButton.");
|
||||
|
||||
((HasOnViewAttachListener) target).setOnViewAttachListener(new OnViewAttachListener() {
|
||||
boolean isAttached = false;
|
||||
|
||||
@Override
|
||||
public void onAttach() {
|
||||
isAttached = true;
|
||||
ViewCompat.postOnAnimation(target, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isAttached) {
|
||||
target.invalidate();
|
||||
ViewCompat.postOnAnimation(target, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
isAttached = false;
|
||||
}
|
||||
});
|
||||
|
||||
} else if (target instanceof HasOnViewAttachListener) {
|
||||
((HasOnViewAttachListener) target).setOnViewAttachListener(null);
|
||||
}
|
||||
|
||||
return spannableBuilder;
|
||||
}
|
||||
|
||||
private static boolean hasAnimatedSpans(SpannableStringBuilder spannableBuilder) {
|
||||
CustomTypefaceSpan[] spans = spannableBuilder.getSpans(0, spannableBuilder.length(), CustomTypefaceSpan.class);
|
||||
for (CustomTypefaceSpan span : spans) {
|
||||
if (span.isAnimated())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void recursivePrepareSpannableIndexes(
|
||||
Context context,
|
||||
String fullText,
|
||||
SpannableStringBuilder text,
|
||||
List<IconFontDescriptorWrapper> iconFontDescriptors,
|
||||
int start) {
|
||||
|
||||
// Try to find a {...} in the string and extract expression from it
|
||||
String stringText = text.toString();
|
||||
int startIndex = stringText.indexOf("{", start);
|
||||
if (startIndex == -1) return;
|
||||
int endIndex = stringText.indexOf("}", startIndex) + 1;
|
||||
if (endIndex == -1) return;
|
||||
String expression = stringText.substring(startIndex + 1, endIndex - 1);
|
||||
|
||||
// Split the expression and retrieve the icon key
|
||||
String[] strokes = expression.split(" ");
|
||||
String key = strokes[0];
|
||||
|
||||
// Loop through the descriptors to find a key match
|
||||
IconFontDescriptorWrapper iconFontDescriptor = null;
|
||||
Icon icon = null;
|
||||
for (int i = 0; i < iconFontDescriptors.size(); i++) {
|
||||
iconFontDescriptor = iconFontDescriptors.get(i);
|
||||
icon = iconFontDescriptor.getIcon(key);
|
||||
if (icon != null) break;
|
||||
}
|
||||
|
||||
// If no match, ignore and continue
|
||||
if (icon == null) {
|
||||
recursivePrepareSpannableIndexes(context, fullText, text, iconFontDescriptors, endIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
// See if any more stroke within {} should be applied
|
||||
float iconSizePx = -1;
|
||||
int iconColor = Integer.MAX_VALUE;
|
||||
float iconSizeRatio = -1;
|
||||
boolean spin = false;
|
||||
boolean baselineAligned = false;
|
||||
for (int i = 1; i < strokes.length; i++) {
|
||||
String stroke = strokes[i];
|
||||
|
||||
// Look for "spin"
|
||||
if (stroke.equalsIgnoreCase("spin")) {
|
||||
spin = true;
|
||||
}
|
||||
|
||||
// Look for "baseline"
|
||||
else if (stroke.equalsIgnoreCase("baseline")) {
|
||||
baselineAligned = true;
|
||||
}
|
||||
|
||||
// Look for an icon size
|
||||
else if (stroke.matches("([0-9]*(\\.[0-9]*)?)dp")) {
|
||||
iconSizePx = dpToPx(context, Float.valueOf(stroke.substring(0, stroke.length() - 2)));
|
||||
} else if (stroke.matches("([0-9]*(\\.[0-9]*)?)sp")) {
|
||||
iconSizePx = spToPx(context, Float.valueOf(stroke.substring(0, stroke.length() - 2)));
|
||||
} else if (stroke.matches("([0-9]*)px")) {
|
||||
iconSizePx = Integer.valueOf(stroke.substring(0, stroke.length() - 2));
|
||||
} else if (stroke.matches("@dimen/(.*)")) {
|
||||
iconSizePx = getPxFromDimen(context, context.getPackageName(), stroke.substring(7));
|
||||
if (iconSizePx < 0)
|
||||
throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\"");
|
||||
} else if (stroke.matches("@android:dimen/(.*)")) {
|
||||
iconSizePx = getPxFromDimen(context, ANDROID_PACKAGE_NAME, stroke.substring(15));
|
||||
if (iconSizePx < 0)
|
||||
throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\"");
|
||||
} else if (stroke.matches("([0-9]*(\\.[0-9]*)?)%")) {
|
||||
iconSizeRatio = Float.valueOf(stroke.substring(0, stroke.length() - 1)) / 100f;
|
||||
}
|
||||
|
||||
// Look for an icon color
|
||||
else if (stroke.matches("#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})")) {
|
||||
iconColor = Color.parseColor(stroke);
|
||||
} else if (stroke.matches("@color/(.*)")) {
|
||||
iconColor = getColorFromResource(context, context.getPackageName(), stroke.substring(7));
|
||||
if (iconColor == Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\"");
|
||||
} else if (stroke.matches("@android:color/(.*)")) {
|
||||
iconColor = getColorFromResource(context, ANDROID_PACKAGE_NAME, stroke.substring(15));
|
||||
if (iconColor == Integer.MAX_VALUE)
|
||||
throw new IllegalArgumentException("Unknown resource " + stroke + " in \"" + fullText + "\"");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unknown expression " + stroke + " in \"" + fullText + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
// Replace the character and apply the typeface
|
||||
text = text.replace(startIndex, endIndex, "" + icon.character());
|
||||
text.setSpan(new CustomTypefaceSpan(icon,
|
||||
iconFontDescriptor.getTypeface(context),
|
||||
iconSizePx, iconSizeRatio, iconColor, spin, baselineAligned),
|
||||
startIndex, startIndex + 1,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
|
||||
recursivePrepareSpannableIndexes(context, fullText, text, iconFontDescriptors, startIndex);
|
||||
}
|
||||
|
||||
public static float getPxFromDimen(Context context, String packageName, String resName) {
|
||||
Resources resources = context.getResources();
|
||||
int resId = resources.getIdentifier(
|
||||
resName, "dimen",
|
||||
packageName);
|
||||
if (resId <= 0) return -1;
|
||||
return resources.getDimension(resId);
|
||||
}
|
||||
|
||||
public static int getColorFromResource(Context context, String packageName, String resName) {
|
||||
Resources resources = context.getResources();
|
||||
int resId = resources.getIdentifier(
|
||||
resName, "color",
|
||||
packageName);
|
||||
if (resId <= 0) return Integer.MAX_VALUE;
|
||||
return resources.getColor(resId);
|
||||
}
|
||||
|
||||
public static float dpToPx(Context context, float dp) {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,
|
||||
context.getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
public static float spToPx(Context context, float sp) {
|
||||
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp,
|
||||
context.getResources().getDisplayMetrics());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.joanzapata.iconify.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.Button;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
import com.joanzapata.iconify.internal.HasOnViewAttachListener;
|
||||
|
||||
public class IconButton extends Button implements HasOnViewAttachListener {
|
||||
|
||||
private HasOnViewAttachListenerDelegate delegate;
|
||||
|
||||
public IconButton(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public IconButton(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public IconButton(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setTransformationMethod(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(CharSequence text, BufferType type) {
|
||||
super.setText(Iconify.compute(getContext(), text, this), type);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setOnViewAttachListener(HasOnViewAttachListener.OnViewAttachListener listener) {
|
||||
if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this);
|
||||
delegate.setOnViewAttachListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
delegate.onAttachedToWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
delegate.onDetachedFromWindow();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.joanzapata.iconify.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.TextView;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
import com.joanzapata.iconify.internal.HasOnViewAttachListener;
|
||||
|
||||
public class IconTextView extends TextView implements HasOnViewAttachListener {
|
||||
|
||||
private HasOnViewAttachListenerDelegate delegate;
|
||||
|
||||
public IconTextView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public IconTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public IconTextView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setTransformationMethod(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(CharSequence text, BufferType type) {
|
||||
super.setText(Iconify.compute(getContext(), text, this), type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnViewAttachListener(OnViewAttachListener listener) {
|
||||
if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this);
|
||||
delegate.setOnViewAttachListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
delegate.onAttachedToWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
delegate.onDetachedFromWindow();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.joanzapata.iconify.widget;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.ToggleButton;
|
||||
import com.joanzapata.iconify.Iconify;
|
||||
import com.joanzapata.iconify.internal.HasOnViewAttachListener;
|
||||
|
||||
public class IconToggleButton extends ToggleButton implements HasOnViewAttachListener {
|
||||
|
||||
private HasOnViewAttachListenerDelegate delegate;
|
||||
|
||||
public IconToggleButton(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public IconToggleButton(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public IconToggleButton(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setTransformationMethod(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(CharSequence text, BufferType type) {
|
||||
super.setText(Iconify.compute(getContext(), text, this), BufferType.NORMAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOnViewAttachListener(HasOnViewAttachListener.OnViewAttachListener listener) {
|
||||
if (delegate == null) delegate = new HasOnViewAttachListenerDelegate(this);
|
||||
delegate.setOnViewAttachListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
delegate.onAttachedToWindow();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
delegate.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
}
|
|
@ -17,4 +17,5 @@ dependencies {
|
|||
implementation project(':pump-common')
|
||||
implementation project(':rileylink')
|
||||
implementation project(':shared')
|
||||
implementation project(':iconify')
|
||||
}
|
||||
|
|
|
@ -16,4 +16,5 @@ android {
|
|||
dependencies {
|
||||
implementation project(':core')
|
||||
implementation project(':shared')
|
||||
implementation project(':iconify')
|
||||
}
|
|
@ -35,6 +35,7 @@ dependencies {
|
|||
implementation project(':omnipod-common')
|
||||
implementation project(':database')
|
||||
implementation project(':shared')
|
||||
implementation project(':iconify')
|
||||
|
||||
api "androidx.room:room-ktx:$room_version"
|
||||
api "androidx.room:room-runtime:$room_version"
|
||||
|
|
|
@ -29,7 +29,7 @@ dependencies {
|
|||
implementation project(':rileylink')
|
||||
implementation project(':database')
|
||||
implementation project(':shared')
|
||||
|
||||
implementation project(':iconify')
|
||||
|
||||
api "androidx.room:room-ktx:$room_version"
|
||||
api "androidx.room:room-runtime:$room_version"
|
||||
|
|
|
@ -18,3 +18,4 @@ include ':diaconn'
|
|||
|
||||
include ':openhumans'
|
||||
include ':shared'
|
||||
include ':iconify'
|
||||
|
|
Loading…
Reference in a new issue