/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.views.toolbar;
import javax.annotation.Nullable;
import java.util.Map;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.SystemClock;
import android.view.MenuItem;
import android.view.View;
import com.facebook.react.R;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.uimanager.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.facebook.react.views.toolbar.events.ToolbarClickEvent;
/**
* Manages instances of ReactToolbar.
*/
public class ReactToolbarManager extends ViewGroupManager<ReactToolbar> {
private static final String REACT_CLASS = "ToolbarAndroid";
@Override
public String getName() {
return REACT_CLASS;
}
@Override
protected ReactToolbar createViewInstance(ThemedReactContext reactContext) {
return new ReactToolbar(reactContext);
}
@ReactProp(name = "logo")
public void setLogo(ReactToolbar view, @Nullable ReadableMap logo) {
view.setLogoSource(logo);
}
@ReactProp(name = "navIcon")
public void setNavIcon(ReactToolbar view, @Nullable ReadableMap navIcon) {
view.setNavIconSource(navIcon);
}
@ReactProp(name = "overflowIcon")
public void setOverflowIcon(ReactToolbar view, @Nullable ReadableMap overflowIcon) {
view.setOverflowIconSource(overflowIcon);
}
@ReactProp(name = "subtitle")
public void setSubtitle(ReactToolbar view, @Nullable String subtitle) {
view.setSubtitle(subtitle);
}
@ReactProp(name = "subtitleColor", customType = "Color")
public void setSubtitleColor(ReactToolbar view, @Nullable Integer subtitleColor) {
int[] defaultColors = getDefaultColors(view.getContext());
if (subtitleColor != null) {
view.setSubtitleTextColor(subtitleColor);
} else {
view.setSubtitleTextColor(defaultColors[1]);
}
}
@ReactProp(name = "title")
public void setTitle(ReactToolbar view, @Nullable String title) {
view.setTitle(title);
}
@ReactProp(name = "titleColor", customType = "Color")
public void setTitleColor(ReactToolbar view, @Nullable Integer titleColor) {
int[] defaultColors = getDefaultColors(view.getContext());
if (titleColor != null) {
view.setTitleTextColor(titleColor);
} else {
view.setTitleTextColor(defaultColors[0]);
}
}
@ReactProp(name = "actions")
public void setActions(ReactToolbar view, @Nullable ReadableArray actions) {
view.setActions(actions);
}
@Override
protected void addEventEmitters(final ThemedReactContext reactContext, final ReactToolbar view) {
final EventDispatcher mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class)
.getEventDispatcher();
view.setNavigationOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
mEventDispatcher.dispatchEvent(
new ToolbarClickEvent(view.getId(), SystemClock.uptimeMillis(), -1));
}
});
view.setOnMenuItemClickListener(
new ReactToolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
mEventDispatcher.dispatchEvent(
new ToolbarClickEvent(
view.getId(),
SystemClock.uptimeMillis(),
menuItem.getOrder()));
return true;
}
});
}
@Nullable
@Override
public Map<String, Object> getExportedViewConstants() {
return MapBuilder.<String, Object>of(
"ShowAsAction",
MapBuilder.of(
"never", MenuItem.SHOW_AS_ACTION_NEVER,
"always", MenuItem.SHOW_AS_ACTION_ALWAYS,
"ifRoom", MenuItem.SHOW_AS_ACTION_IF_ROOM));
}
@Override
public boolean needsCustomLayoutForChildren() {
return true;
}
private static int[] getDefaultColors(Context context) {
Resources.Theme theme = context.getTheme();
TypedArray toolbarStyle = null;
TypedArray textAppearances = null;
TypedArray titleTextAppearance = null;
TypedArray subtitleTextAppearance = null;
try {
toolbarStyle = theme
.obtainStyledAttributes(new int[]{R.attr.toolbarStyle});
int toolbarStyleResId = toolbarStyle.getResourceId(0, 0);
textAppearances = theme.obtainStyledAttributes(
toolbarStyleResId, new int[]{
R.attr.titleTextAppearance,
R.attr.subtitleTextAppearance,
});
int titleTextAppearanceResId = textAppearances.getResourceId(0, 0);
int subtitleTextAppearanceResId = textAppearances.getResourceId(1, 0);
titleTextAppearance = theme
.obtainStyledAttributes(titleTextAppearanceResId, new int[]{android.R.attr.textColor});
subtitleTextAppearance = theme
.obtainStyledAttributes(subtitleTextAppearanceResId, new int[]{android.R.attr.textColor});
int titleTextColor = titleTextAppearance.getColor(0, Color.BLACK);
int subtitleTextColor = subtitleTextAppearance.getColor(0, Color.BLACK);
return new int[] {titleTextColor, subtitleTextColor};
} finally {
recycleQuietly(toolbarStyle);
recycleQuietly(textAppearances);
recycleQuietly(titleTextAppearance);
recycleQuietly(subtitleTextAppearance);
}
}
private static void recycleQuietly(@Nullable TypedArray style) {
if (style != null) {
style.recycle();
}
}
}