Skip to content

Commit

Permalink
Each CalligraphyContext can have its own CalligraphyConfig
Browse files Browse the repository at this point in the history
Useful when Calligraphy is used in a library project where the default
configuration need not be changed, or when different defaults are needed
in multiple contexts.
  • Loading branch information
jankovd committed Oct 13, 2015
1 parent 417120b commit 8e55c65
Show file tree
Hide file tree
Showing 8 changed files with 194 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package uk.co.chrisjenx.calligraphy.sample;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
Expand All @@ -12,6 +13,8 @@

import butterknife.ButterKnife;
import butterknife.OnClick;
import uk.co.chrisjenx.calligraphy.CalligraphyConfig;
import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper;

/**
* A placeholder fragment containing a simple view.
Expand Down Expand Up @@ -57,4 +60,19 @@ public void onClick(DialogInterface dialog, int which) {
});
builder.create().show();
}

@OnClick(R.id.button_non_default_config)
public void onClickNonDefaultConfig() {
final Context calligraphyContext =
CalligraphyContextWrapper.wrap(getActivity(), new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/Oswald-Stencbab.ttf")
.setFontAttrId(R.attr.fontPath)
.addCustomViewWithSetTypeface(CustomViewWithTypefaceSupport.class)
.addCustomStyle(TextField.class, R.attr.textFieldStyle)
.build());
new android.support.v7.app.AlertDialog.Builder(calligraphyContext)
.setTitle(R.string.dialog_non_default_config_title)
.setView(R.layout.dialog_non_default_config)
.show();
}
}
109 changes: 109 additions & 0 deletions CalligraphySample/src/main/res/layout/dialog_non_default_config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="uk.co.chrisjenx.calligraphy.sample.PlaceholderFragment"
tools:ignore="MissingPrefix">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:text="@string/dialog_non_default_config_message"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/default_theme"/>

<TextView
fontPath="fonts/Roboto-Bold.ttf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/defined_fontpath_view"/>

<TextView
fontPath="fonts/Roboto-None.ttf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/defined_incorrect"/>

<TextView
style="@style/AppTheme.Widget.TextView.Style"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/defined_in_style"/>

<TextView
style="@style/AppTheme.Widget.TextViewAppearanceStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/defined_in_appears_style"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/defined_in_appears"
android:textAppearance="@style/TextAppearance.FontPathView"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/defined_in_appears"
android:textAppearance="@style/TextAppearance.FontPathView"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/defined_in_appears_caps"
android:textAllCaps="true"
android:textAppearance="@style/TextAppearance.FontPathView"/>

<uk.co.chrisjenx.calligraphy.sample.CustomTextView
fontPath="fonts/Oswald-Stencbab.ttf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/defined_custom_view"/>

<uk.co.chrisjenx.calligraphy.sample.CustomViewWithTypefaceSupport
fontPath="fonts/Oswald-Stencbab.ttf"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />

<CheckBox
fontPath="fonts/Oswald-Stencbab.ttf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp"
android:text="@string/checkbox_custom"/>

<EditText
android:id="@+id/edit_text"
fontPath="fonts/Roboto-Bold.ttf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp"
android:hint="@string/edit_text_hint"/>

<uk.co.chrisjenx.calligraphy.sample.TextField
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/custom_view_style_text"/>

</LinearLayout>
</ScrollView>
9 changes: 9 additions & 0 deletions CalligraphySample/src/main/res/layout/fragment_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,14 @@
android:layout_marginTop="12dp"
android:text="@string/button_defined"/>

<Button
android:id="@+id/button_non_default_config"
fontPath="fonts/Roboto-Bold.ttf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="12dp"
android:text="@string/button_non_default_config"/>

</LinearLayout>
</ScrollView>
3 changes: 3 additions & 0 deletions CalligraphySample/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,8 @@

<string name="button_default">Default Font (show dialog)</string>
<string name="button_defined">Bold Button (show toast)</string>
<string name="button_non_default_config">Context specific Calligraphy config (show dialog)</string>
<string name="dialog_non_default_config_title">Context specific Calligraphy config</string>
<string name="dialog_non_default_config_message">\nUsing non-global Calligraphy config for this dialog with Oswald as the default font.\n</string>

</resources>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package uk.co.chrisjenx.calligraphy;

import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
Expand Down Expand Up @@ -83,6 +84,19 @@ public static CalligraphyConfig get() {
return sInstance;
}

/**
* Obtains the CalligraphyConfig from the given context.
*/
public static CalligraphyConfig from(Context context) {
//noinspection ResourceType
final CalligraphyConfig config = (CalligraphyConfig) context
.getSystemService(CalligraphyContextWrapper.CALLIGRAPHY_CONFIG_SERVICE);
if (config == null) {
throw new AssertionError("CalligraphyConfig not found.");
}
return config;
}

/**
* Is a default font set?
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,38 @@
*/
public class CalligraphyContextWrapper extends ContextWrapper {

static final String CALLIGRAPHY_CONFIG_SERVICE = CalligraphyConfig.class.getName();

private CalligraphyLayoutInflater mInflater;

private final int mAttributeId;
private final CalligraphyConfig mCalligraphyConfig;

/**
* Uses the default configuration from {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig}
* Convenience for calling {@link #wrap(Context, CalligraphyConfig)} with the
* {@linkplain CalligraphyConfig#get default configuration}.
*
* Remember if you are defining default in the
* {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig} make sure this is initialised before
* the activity is created.
*
* @param base ContextBase to Wrap.
* @return ContextWrapper to pass back to the activity.
*/
public static ContextWrapper wrap(Context base) {
return new CalligraphyContextWrapper(base);
return wrap(base, CalligraphyConfig.get());
}

/**
* Configures Calligraphy to be used in the {@code context} with the provided {@code config}.
*
* <p>You would rarely need to use this method directly, so unless you need a different
* configuration in multiple contexts in you app, prefer defining a
* {@linkplain CalligraphyConfig#initDefault default configuration} and use
* {@link #wrap(Context)} instead.
*
* @return Context to use as the {@linkplain Activity#attachBaseContext base context} of your
* Activity or for initializing a view hierarchy.
*/
public static ContextWrapper wrap(Context base, CalligraphyConfig config) {
return new CalligraphyContextWrapper(base, config);
}

/**
Expand Down Expand Up @@ -72,18 +88,10 @@ static CalligraphyActivityFactory get(Activity activity) {
return (CalligraphyActivityFactory) activity.getLayoutInflater();
}

/**
* Uses the default configuration from {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig}
*
* Remember if you are defining default in the
* {@link uk.co.chrisjenx.calligraphy.CalligraphyConfig} make sure this is initialised before
* the activity is created.
*
* @param base ContextBase to Wrap
*/
CalligraphyContextWrapper(Context base) {
CalligraphyContextWrapper(Context base, CalligraphyConfig config) {
super(base);
mAttributeId = CalligraphyConfig.get().getAttrId();
mAttributeId = config.getAttrId();
mCalligraphyConfig = config;
}

/**
Expand All @@ -102,6 +110,7 @@ static CalligraphyActivityFactory get(Activity activity) {
public CalligraphyContextWrapper(Context base, int attributeId) {
super(base);
mAttributeId = attributeId;
mCalligraphyConfig = null;
}

@Override
Expand All @@ -112,6 +121,9 @@ public Object getSystemService(String name) {
}
return mInflater;
}
if (CALLIGRAPHY_CONFIG_SERVICE.equals(name)) {
return mCalligraphyConfig != null ? mCalligraphyConfig : CalligraphyConfig.get();
}
return super.getSystemService(name);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,10 @@ protected static int[] getStyleForTextView(TextView view) {
styleIds[1] = android.R.attr.subtitleTextStyle;
}
if (styleIds[0] == -1) {
final CalligraphyConfig config = CalligraphyConfig.from(view.getContext());
// Use TextAppearance as default style
styleIds[0] = CalligraphyConfig.get().getClassStyles().containsKey(view.getClass())
? CalligraphyConfig.get().getClassStyles().get(view.getClass())
styleIds[0] = config.getClassStyles().containsKey(view.getClass())
? config.getClassStyles().get(view.getClass())
: android.R.attr.textAppearance;
}
return styleIds;
Expand Down Expand Up @@ -117,6 +118,7 @@ public View onViewCreated(View view, Context context, AttributeSet attrs) {
}

void onViewCreatedInternal(View view, final Context context, AttributeSet attrs) {
final CalligraphyConfig config = CalligraphyConfig.from(context);
if (view instanceof TextView) {
// Fast path the setting of TextView's font, means if we do some delayed setting of font,
// which has already been set by use we skip this TextView (mainly for inflating custom,
Expand All @@ -142,7 +144,7 @@ void onViewCreatedInternal(View view, final Context context, AttributeSet attrs)
// Still need to defer the Native action bar, appcompat-v7:21+ uses the Toolbar underneath. But won't match these anyway.
final boolean deferred = matchesResourceIdName(view, ACTION_BAR_TITLE) || matchesResourceIdName(view, ACTION_BAR_SUBTITLE);

CalligraphyUtils.applyFontToTextView(context, (TextView) view, CalligraphyConfig.get(), textViewFont, deferred);
CalligraphyUtils.applyFontToTextView(context, (TextView) view, config, textViewFont, deferred);
}

// AppCompat API21+ The ActionBar doesn't inflate default Title/SubTitle, we need to scan the
Expand Down Expand Up @@ -178,7 +180,7 @@ public void onGlobalLayout() {
if (typeface != null) {
((HasTypeface) view).setTypeface(typeface);
}
} else if (CalligraphyConfig.get().isCustomViewTypefaceSupport() && CalligraphyConfig.get().isCustomViewHasTypeface(view)) {
} else if (config.isCustomViewTypefaceSupport() && config.isCustomViewHasTypeface(view)) {
final Method setTypeface = ReflectionUtils.getMethod(view.getClass(), "setTypeface");
String fontPath = resolveFontPath(context, attrs);
Typeface typeface = getDefaultTypeface(context, fontPath);
Expand All @@ -190,7 +192,7 @@ public void onGlobalLayout() {

private Typeface getDefaultTypeface(Context context, String fontPath) {
if (TextUtils.isEmpty(fontPath)) {
fontPath = CalligraphyConfig.get().getFontPath();
fontPath = CalligraphyConfig.from(context).getFontPath();
}
if (!TextUtils.isEmpty(fontPath)) {
return TypefaceUtils.load(context.getAssets(), fontPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
Expand All @@ -26,6 +27,7 @@ class CalligraphyLayoutInflater extends LayoutInflater implements CalligraphyAct

private final int mAttributeId;
private final CalligraphyFactory mCalligraphyFactory;
private final CalligraphyConfig mCalligraphyConfig;
// Reflection Hax
private boolean mSetPrivateFactory = false;
private Field mConstructorArgs = null;
Expand All @@ -34,12 +36,14 @@ protected CalligraphyLayoutInflater(Context context, int attributeId) {
super(context);
mAttributeId = attributeId;
mCalligraphyFactory = new CalligraphyFactory(attributeId);
mCalligraphyConfig = CalligraphyConfig.from(context);
setUpLayoutFactories(false);
}

protected CalligraphyLayoutInflater(LayoutInflater original, Context newContext, int attributeId, final boolean cloned) {
super(original, newContext);
mAttributeId = attributeId;
mCalligraphyConfig = CalligraphyConfig.from(newContext);
mCalligraphyFactory = new CalligraphyFactory(attributeId);
setUpLayoutFactories(cloned);
}
Expand Down Expand Up @@ -105,7 +109,7 @@ private void setPrivateFactoryInternal() {
// Already tried to set the factory.
if (mSetPrivateFactory) return;
// Reflection (Or Old Device) skip.
if (!CalligraphyConfig.get().isReflection()) return;
if (!mCalligraphyConfig.isReflection()) return;
// Skip if not attached to an activity.
if (!(getContext() instanceof Factory2)) {
mSetPrivateFactory = true;
Expand Down Expand Up @@ -195,7 +199,7 @@ private View createCustomViewInternal(View parent, View view, String name, Conte
// significant difference to performance on Android 4.0+.

// If CustomViewCreation is off skip this.
if (!CalligraphyConfig.get().isCustomViewCreation()) return view;
if (!mCalligraphyConfig.isCustomViewCreation()) return view;
if (view == null && name.indexOf('.') > -1) {
if (mConstructorArgs == null)
mConstructorArgs = ReflectionUtils.getField(LayoutInflater.class, "mConstructorArgs");
Expand Down

0 comments on commit 8e55c65

Please sign in to comment.