Skip to content

Commit

Permalink
Support default font options (#6613)
Browse files Browse the repository at this point in the history
This PR continues the work done in #6590 and adds support for declaring `fontWeight` and `fontFamily` for title and subtitle in default options.
  • Loading branch information
guyca authored Sep 29, 2020
1 parent 5750c42 commit 4cd40c1
Show file tree
Hide file tree
Showing 25 changed files with 215 additions and 145 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.reactnativenavigation.options;

import android.content.Context;
import android.graphics.Typeface;

import com.reactnativenavigation.options.params.Bool;
import com.reactnativenavigation.options.params.Colour;
Expand All @@ -13,15 +12,14 @@
import com.reactnativenavigation.options.params.Text;
import com.reactnativenavigation.options.parsers.BoolParser;
import com.reactnativenavigation.options.parsers.ColorParser;
import com.reactnativenavigation.options.parsers.FontParser;
import com.reactnativenavigation.options.parsers.IconParser;
import com.reactnativenavigation.options.parsers.NumberParser;
import com.reactnativenavigation.options.parsers.TextParser;
import com.reactnativenavigation.options.parsers.TypefaceLoader;

import org.json.JSONObject;

import androidx.annotation.Nullable;

public class BottomTabOptions {

public static BottomTabOptions parse(Context context, TypefaceLoader typefaceManager, JSONObject json) {
Expand All @@ -39,11 +37,7 @@ public static BottomTabOptions parse(Context context, TypefaceLoader typefaceMan
options.badgeColor = ColorParser.parse(context, json, "badgeColor");
options.animateBadge = BoolParser.parse(json, "animateBadge");
options.testId = TextParser.parse(json, "testID");
options.fontFamily = typefaceManager.getTypeFace(
json.optString("fontFamily", ""),
json.optString("fontStyle", ""),
json.optString("fontWeight", "")
);
options.font = FontParser.parse(json);
options.fontSize = NumberParser.parse(json, "fontSize");
options.selectedFontSize = NumberParser.parse(json, "selectedFontSize");
options.dotIndicator = DotIndicatorOptions.parse(context, json.optJSONObject("dotIndicator"));
Expand All @@ -67,7 +61,7 @@ public static BottomTabOptions parse(Context context, TypefaceLoader typefaceMan
public Number fontSize = new NullNumber();
public Number selectedFontSize = new NullNumber();
public Bool selectTabOnPress = new NullBool();
@Nullable public Typeface fontFamily;
public FontOptions font = new FontOptions();


void mergeWith(final BottomTabOptions other) {
Expand All @@ -84,7 +78,7 @@ void mergeWith(final BottomTabOptions other) {
if (other.testId.hasValue()) testId = other.testId;
if (other.fontSize.hasValue()) fontSize = other.fontSize;
if (other.selectedFontSize.hasValue()) selectedFontSize = other.selectedFontSize;
if (other.fontFamily != null) fontFamily = other.fontFamily;
font.mergeWith(other.font);
if (other.dotIndicator.hasValue()) dotIndicator = other.dotIndicator;
if (other.selectTabOnPress.hasValue()) selectTabOnPress = other.selectTabOnPress;
}
Expand All @@ -102,7 +96,7 @@ void mergeWithDefault(final BottomTabOptions defaultOptions) {
if (!animateBadge.hasValue()) animateBadge = defaultOptions.animateBadge;
if (!fontSize.hasValue()) fontSize = defaultOptions.fontSize;
if (!selectedFontSize.hasValue()) selectedFontSize = defaultOptions.selectedFontSize;
if (fontFamily == null) fontFamily = defaultOptions.fontFamily;
font.mergeWithDefault(defaultOptions.font);
if (!testId.hasValue()) testId = defaultOptions.testId;
if (!dotIndicator.hasValue()) dotIndicator = defaultOptions.dotIndicator;
if (!selectTabOnPress.hasValue()) selectTabOnPress = defaultOptions.selectTabOnPress;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.reactnativenavigation.options;

import android.content.Context;
import android.graphics.Typeface;
import android.view.MenuItem;

import com.reactnativenavigation.options.params.Bool;
Expand All @@ -16,20 +15,18 @@
import com.reactnativenavigation.options.params.Text;
import com.reactnativenavigation.options.parsers.BoolParser;
import com.reactnativenavigation.options.parsers.ColorParser;
import com.reactnativenavigation.options.parsers.FontParser;
import com.reactnativenavigation.options.parsers.FractionParser;
import com.reactnativenavigation.options.parsers.TextParser;
import com.reactnativenavigation.utils.CompatUtils;
import com.reactnativenavigation.utils.IdFactory;
import com.reactnativenavigation.options.parsers.TypefaceLoader;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Objects;

import androidx.annotation.Nullable;

import static com.reactnativenavigation.utils.ObjectUtils.take;

public class ButtonOptions {
Expand All @@ -45,7 +42,7 @@ public class ButtonOptions {
public Colour color = new NullColor();
public Colour disabledColor = new NullColor();
public Fraction fontSize = new NullFraction();
@Nullable public Typeface fontFamily;
public FontOptions font = new FontOptions();
public Text icon = new NullText();
public Text testId = new NullText();
public ComponentOptions component = new ComponentOptions();
Expand All @@ -61,13 +58,13 @@ public boolean equals(ButtonOptions other) {
color.equals(other.color) &&
disabledColor.equals(other.disabledColor) &&
fontSize.equals(other.fontSize) &&
Objects.equals(fontFamily, other.fontFamily) &&
font.equals(other.font) &&
icon.equals(other.icon) &&
testId.equals(other.testId) &&
component.equals(other.component);
}

private static ButtonOptions parseJson(Context context, JSONObject json, TypefaceLoader typefaceManager) {
private static ButtonOptions parseJson(Context context, JSONObject json) {
ButtonOptions button = new ButtonOptions();
button.id = take(json.optString("id"), "btn" + CompatUtils.generateViewId());
button.accessibilityLabel = TextParser.parse(json, "accessibilityLabel");
Expand All @@ -79,11 +76,7 @@ private static ButtonOptions parseJson(Context context, JSONObject json, Typefac
button.color = ColorParser.parse(context, json, "color");
button.disabledColor = ColorParser.parse(context, json, "disabledColor");
button.fontSize = FractionParser.parse(json, "fontSize");
button.fontFamily = typefaceManager.getTypeFace(
json.optString("fontFamily", ""),
json.optString("fontStyle", ""),
json.optString("fontWeight", "")
);
button.font = FontParser.parse(json);
button.testId = TextParser.parse(json, "testID");
button.component = ComponentOptions.parse(json.optJSONObject("component"));

Expand All @@ -94,26 +87,26 @@ private static ButtonOptions parseJson(Context context, JSONObject json, Typefac
return button;
}

public static ArrayList<ButtonOptions> parse(Context context, JSONObject json, String buttonsType, TypefaceLoader typefaceLoader) {
public static ArrayList<ButtonOptions> parse(Context context, JSONObject json, String buttonsType) {
ArrayList<ButtonOptions> buttons = new ArrayList<>();
if (!json.has(buttonsType)) {
return null;
}

JSONArray jsonArray = json.optJSONArray(buttonsType);
if (jsonArray != null) {
buttons.addAll(parseJsonArray(context, jsonArray, typefaceLoader));
buttons.addAll(parseJsonArray(context, jsonArray));
} else {
buttons.add(parseJson(context, json.optJSONObject(buttonsType), typefaceLoader));
buttons.add(parseJson(context, json.optJSONObject(buttonsType)));
}
return buttons;
}

private static ArrayList<ButtonOptions> parseJsonArray(Context context, JSONArray jsonArray, TypefaceLoader typefaceLoader) {
private static ArrayList<ButtonOptions> parseJsonArray(Context context, JSONArray jsonArray) {
ArrayList<ButtonOptions> buttons = new ArrayList<>();
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject json = jsonArray.optJSONObject(i);
ButtonOptions button = ButtonOptions.parseJson(context, json, typefaceLoader);
ButtonOptions button = ButtonOptions.parseJson(context, json);
buttons.add(button);
}
return buttons;
Expand Down Expand Up @@ -165,7 +158,7 @@ public void mergeWith(ButtonOptions other) {
if (other.color.hasValue()) color = other.color;
if (other.disabledColor.hasValue()) disabledColor = other.disabledColor;
if (other.fontSize.hasValue()) fontSize = other.fontSize;
if (other.fontFamily != null) fontFamily = other.fontFamily;
font.mergeWith(other.font);
if (other.testId.hasValue()) testId = other.testId;
if (other.component.hasValue()) component = other.component;
if (other.showAsAction.hasValue()) showAsAction = other.showAsAction;
Expand All @@ -183,7 +176,7 @@ public void mergeWithDefault(ButtonOptions defaultOptions) {
if (!color.hasValue()) color = defaultOptions.color;
if (!disabledColor.hasValue()) disabledColor = defaultOptions.disabledColor;
if (!fontSize.hasValue()) fontSize = defaultOptions.fontSize;
if (fontFamily == null) fontFamily = defaultOptions.fontFamily;
font.mergeWithDefault(defaultOptions.font);
if (!testId.hasValue()) testId = defaultOptions.testId;
if (!component.hasValue()) component = defaultOptions.component;
if (!showAsAction.hasValue()) showAsAction = defaultOptions.showAsAction;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.reactnativenavigation.options

import android.graphics.Typeface
import com.reactnativenavigation.options.params.NullText
import com.reactnativenavigation.options.params.Text
import com.reactnativenavigation.options.parsers.TypefaceLoader

class FontOptions {
private var isDirty = false
var fontFamily: Text = NullText()
set(value) {
field = value
isDirty = true
}
var fontStyle: Text = NullText()
set(value) {
field = value
isDirty = true
}
var fontWeight: Text = NullText()
set(value) {
field = value
isDirty = true
}
private var _typeface: Typeface? = null

@JvmOverloads fun getTypeface(typefaceLoader: TypefaceLoader, defaultTypeface: Typeface? = null): Typeface? {
if (isDirty) {
_typeface = typefaceLoader.getTypeFace(fontFamily.get(""), fontStyle.get(""), fontWeight.get(""))
isDirty = false
}
return _typeface
?: defaultTypeface?.let { typefaceLoader.getTypeFace(fontFamily.get(""), fontStyle.get(""), fontWeight.get(""), it) }
}

fun mergeWith(other: FontOptions) {
if (other.fontFamily.hasValue()) fontFamily = other.fontFamily
if (other.fontStyle.hasValue()) fontStyle = other.fontStyle
if (other.fontWeight.hasValue()) fontWeight = other.fontWeight
}

fun mergeWithDefault(defaultOptions: FontOptions) {
if (!fontFamily.hasValue()) fontFamily = defaultOptions.fontFamily
if (!fontStyle.hasValue()) fontStyle = defaultOptions.fontStyle
if (!fontWeight.hasValue()) fontWeight = defaultOptions.fontWeight
}

fun hasValue() = fontFamily.hasValue() || fontStyle.hasValue() || fontWeight.hasValue()

override fun equals(other: Any?) = (other as? FontOptions)?.let {
fontFamily.equals(other.fontFamily) &&
fontStyle.equals(other.fontStyle) &&
fontWeight.equals(other.fontWeight)
} ?: false
}
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ private ViewController createStack(ReactContext context, LayoutNode node) {
new TopBarBackgroundViewCreator(reactInstanceManager),
new TitleBarButtonCreator(reactInstanceManager),
new IconResolver(activity, new ImageLoader()),
new TypefaceLoader(activity),
new RenderChecker(),
defaultOptions
))
Expand Down Expand Up @@ -223,7 +224,7 @@ private ViewController createBottomTabs(ReactContext context, LayoutNode node) {
new Presenter(activity, defaultOptions),
new BottomTabsAttacher(tabs, bottomTabsPresenter, defaultOptions),
bottomTabsPresenter,
new BottomTabPresenter(activity, tabs, new ImageLoader(), defaultOptions));
new BottomTabPresenter(activity, tabs, new ImageLoader(), new TypefaceLoader(activity), defaultOptions));
}

private ViewController createTopTabs(ReactContext context, LayoutNode node) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.reactnativenavigation.options;

import android.content.Context;
import android.graphics.Typeface;
import androidx.annotation.Nullable;

import com.reactnativenavigation.options.params.Colour;
import com.reactnativenavigation.options.params.Fraction;
Expand All @@ -11,6 +9,7 @@
import com.reactnativenavigation.options.params.NullText;
import com.reactnativenavigation.options.params.Text;
import com.reactnativenavigation.options.parsers.ColorParser;
import com.reactnativenavigation.options.parsers.FontParser;
import com.reactnativenavigation.options.parsers.FractionParser;
import com.reactnativenavigation.options.parsers.TextParser;
import com.reactnativenavigation.options.parsers.TypefaceLoader;
Expand All @@ -27,11 +26,7 @@ public static SubtitleOptions parse(Context context, TypefaceLoader typefaceMana
options.text = TextParser.parse(json, "text");
options.color = ColorParser.parse(context, json, "color");
options.fontSize = FractionParser.parse(json, "fontSize");
options.fontFamily = typefaceManager.getTypeFace(
json.optString("fontFamily", ""),
json.optString("fontStyle", ""),
json.optString("fontWeight", "")
);
options.font = FontParser.parse(json);
options.alignment = Alignment.fromString(TextParser.parse(json, "alignment").get(""));

return options;
Expand All @@ -40,22 +35,22 @@ public static SubtitleOptions parse(Context context, TypefaceLoader typefaceMana
public Text text = new NullText();
public Colour color = new NullColor();
public Fraction fontSize = new NullFraction();
@Nullable public Typeface fontFamily;
public FontOptions font = new FontOptions();
public Alignment alignment = Alignment.Default;

void mergeWith(final SubtitleOptions other) {
if (other.text.hasValue()) text = other.text;
if (other.color.hasValue()) color = other.color;
if (other.fontSize.hasValue()) fontSize = other.fontSize;
if (other.fontFamily != null) fontFamily = other.fontFamily;
font.mergeWith(other.font);
if (other.alignment != Alignment.Default) alignment = other.alignment;
}

void mergeWithDefault(SubtitleOptions defaultOptions) {
if (!text.hasValue()) text = defaultOptions.text;
if (!color.hasValue()) color = defaultOptions.color;
if (!fontSize.hasValue()) fontSize = defaultOptions.fontSize;
if (fontFamily == null) fontFamily = defaultOptions.fontFamily;
font.mergeWithDefault(defaultOptions.font);
if (alignment == Alignment.Default) alignment = defaultOptions.alignment;
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.reactnativenavigation.options;

import android.content.Context;
import android.graphics.Typeface;
import androidx.annotation.Nullable;

import com.reactnativenavigation.options.params.Colour;
import com.reactnativenavigation.options.params.Fraction;
Expand All @@ -13,6 +11,7 @@
import com.reactnativenavigation.options.params.Number;
import com.reactnativenavigation.options.params.Text;
import com.reactnativenavigation.options.parsers.ColorParser;
import com.reactnativenavigation.options.parsers.FontParser;
import com.reactnativenavigation.options.parsers.FractionParser;
import com.reactnativenavigation.options.parsers.NumberParser;
import com.reactnativenavigation.options.parsers.TextParser;
Expand All @@ -30,11 +29,7 @@ public static TitleOptions parse(Context context, TypefaceLoader typefaceManager
options.text = TextParser.parse(json, "text");
options.color = ColorParser.parse(context, json, "color");
options.fontSize = FractionParser.parse(json, "fontSize");
options.fontFamily = typefaceManager.getTypeFace(
json.optString("fontFamily", ""),
json.optString("fontStyle", ""),
json.optString("fontWeight", "")
);
options.font = FontParser.parse(json);
options.alignment = Alignment.fromString(TextParser.parse(json, "alignment").get(""));
options.height = NumberParser.parse(json, "height");
options.topMargin = NumberParser.parse(json, "topMargin");
Expand All @@ -46,7 +41,7 @@ public static TitleOptions parse(Context context, TypefaceLoader typefaceManager
public Colour color = new NullColor();
public Fraction fontSize = new NullFraction();
public Alignment alignment = Alignment.Default;
@Nullable public Typeface fontFamily;
public FontOptions font = new FontOptions();
public ComponentOptions component = new ComponentOptions();
public Number height = new NullNumber();
public Number topMargin = new NullNumber();
Expand All @@ -55,7 +50,7 @@ void mergeWith(final TitleOptions other) {
if (other.text.hasValue()) text = other.text;
if (other.color.hasValue()) color = other.color;
if (other.fontSize.hasValue()) fontSize = other.fontSize;
if (other.fontFamily != null) fontFamily = other.fontFamily;
font.mergeWith(other.font);
if (other.alignment != Alignment.Default) alignment = other.alignment;
if (other.component.hasValue()) component = other.component;
if (other.height.hasValue()) height = other.height;
Expand All @@ -66,7 +61,7 @@ void mergeWithDefault(TitleOptions defaultOptions) {
if (!text.hasValue()) text = defaultOptions.text;
if (!color.hasValue()) color = defaultOptions.color;
if (!fontSize.hasValue()) fontSize = defaultOptions.fontSize;
if (fontFamily == null) fontFamily = defaultOptions.fontFamily;
font.mergeWithDefault(defaultOptions.font);
if (alignment == Alignment.Default) alignment = defaultOptions.alignment;
component.mergeWithDefault(defaultOptions.component);
if (!height.hasValue()) height = defaultOptions.height;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

import android.content.Context;

import androidx.annotation.Nullable;

import com.reactnativenavigation.utils.CollectionUtils;
import com.reactnativenavigation.options.parsers.TypefaceLoader;
import com.reactnativenavigation.utils.CollectionUtils;

import org.json.JSONObject;

import java.util.ArrayList;

import androidx.annotation.Nullable;

public class TopBarButtons {

public static TopBarButtons parse(Context context, TypefaceLoader typefaceLoader, JSONObject json) {
Expand All @@ -26,7 +26,7 @@ public static TopBarButtons parse(Context context, TypefaceLoader typefaceLoader

@Nullable
private static ArrayList<ButtonOptions> parseButtons(Context context, TypefaceLoader typefaceLoader, JSONObject json, String buttons) {
return ButtonOptions.parse(context, json, buttons, typefaceLoader);
return ButtonOptions.parse(context, json, buttons);
}

public BackButton back = new BackButton();
Expand Down
Loading

0 comments on commit 4cd40c1

Please sign in to comment.