summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Gunn <tgunn@google.com>2014-03-04 21:18:29 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2014-03-04 21:18:29 +0000
commit4e0dede09d96862ed4fcfa5a30ad8742aea12414 (patch)
tree7e233fd77906c4a96d4da52503f731dacd7132d0
parent2d0bb562c9985aa0fe26ae1c9649413ce2dac999 (diff)
parente2129528a1bd5bf99163026cbd4e01f97b0877ac (diff)
am e2129528: am 1a31e343: Adding "Speed Dial" title to dialer favorites list and moving "All Contacts" affordance.
* commit 'e2129528a1bd5bf99163026cbd4e01f97b0877ac': Adding "Speed Dial" title to dialer favorites list and moving "All Contacts" affordance.
-rw-r--r--res/drawable/background_favorites_menu.xml29
-rw-r--r--res/layout/phone_favorites_menu.xml58
-rw-r--r--res/values/colors.xml13
-rw-r--r--res/values/dimens.xml13
-rw-r--r--res/values/strings.xml18
-rw-r--r--src/com/android/dialer/list/PhoneFavoriteFragment.java43
-rw-r--r--src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java146
7 files changed, 228 insertions, 92 deletions
diff --git a/res/drawable/background_favorites_menu.xml b/res/drawable/background_favorites_menu.xml
new file mode 100644
index 000000000..fc2669b10
--- /dev/null
+++ b/res/drawable/background_favorites_menu.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2014 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="false">
+ <shape android:shape="rectangle" >
+ <solid android:color="@color/background_dialer_list_items" />
+ </shape>
+ </item>
+ <item android:state_pressed="true">
+ <shape android:shape="rectangle" >
+ <solid android:color="@color/favorites_menu_pressed_color" />
+ </shape>
+ </item>
+</selector> \ No newline at end of file
diff --git a/res/layout/phone_favorites_menu.xml b/res/layout/phone_favorites_menu.xml
new file mode 100644
index 000000000..d8f2f32c7
--- /dev/null
+++ b/res/layout/phone_favorites_menu.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2014 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<!-- The phone favorites menu appears on the main dialer screen above the favorite callers area,
+ and provides access to the All Contacts list. -->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/phone_favorites_menu"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="@dimen/favorites_menu_margin"
+ android:paddingRight="@dimen/favorites_menu_margin"
+ android:paddingTop="@dimen/favorites_menu_margin"
+ android:paddingBottom="@dimen/favorites_menu_margin"
+ android:background="@drawable/background_favorites_menu"
+ android:addStatesFromChildren="true"
+ >
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/favorites_menu_speed_dial_height"
+ android:fontFamily="@string/favorites_menu_speed_dial_font_family"
+ android:text="@string/favorites_menu_speed_dial"
+ android:textSize="@dimen/favorites_menu_speed_dial_text_size"
+ android:textColor="@color/speed_dial_text_color"
+ android:layout_alignParentLeft="true"
+ android:layout_centerVertical="true"
+ android:gravity="center"
+ />
+ <TextView
+ android:id="@+id/all_contacts_button"
+ android:fontFamily="@string/favorites_menu_all_contacts_font_family"
+ android:layout_width="wrap_content"
+ android:layout_height="@dimen/favorites_menu_all_contacts_height"
+ android:paddingLeft="@dimen/favorites_menu_padding"
+ android:paddingRight="@dimen/favorites_menu_padding"
+ android:text="@string/favorites_menu_all_contacts"
+ android:textSize="@dimen/favorites_menu_all_contacts_text_size"
+ android:background="@color/all_contacts_button_color"
+ android:textColor="@color/all_contacts_button_text_color"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:gravity="center"
+ android:focusable="true"
+ />
+</RelativeLayout> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index b2d4bc560..370bdfeb6 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -70,4 +70,17 @@
<!-- Text color for no favorites message -->
<color name="nofavorite_text_color">#777777</color>
+
+ <!-- Text color for the "speed dial" label in the favorites menu. -->
+ <color name="speed_dial_text_color">#555555</color>
+
+ <!-- Background color for the "All Contacts" button in the favorites menu. -->
+ <color name="all_contacts_button_color">#999999</color>
+
+ <!-- Background color for the favorites menu when pressed. -->
+ <color name="favorites_menu_pressed_color">#d6d6d6</color>
+
+ <!-- Text color for the "All Contacts" button above the favorite callers -->
+ <color name="all_contacts_button_text_color">#ffffff</color>
+
</resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 942698741..3c856d2e6 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -83,4 +83,17 @@
<!-- Padding for the tooltip -->
<dimen name="dismiss_button_padding_start">20dip</dimen>
<dimen name="dismiss_button_padding_end">28dip</dimen>
+
+ <!-- Margin around the favorites menu. -->
+ <dimen name="favorites_menu_margin">6dp</dimen>
+ <!-- Padding within the favorites menu. -->
+ <dimen name="favorites_menu_padding">4dp</dimen>
+ <!-- Text size for the "speed dial" text in the favorites menu. -->
+ <dimen name="favorites_menu_speed_dial_text_size">18sp</dimen>
+ <!-- Height of the speed dial TextView in the favorites menu. -->
+ <dimen name="favorites_menu_speed_dial_height">24dp</dimen>
+ <!-- Text size for the "All Contacts" text in the favorites menu. -->
+ <dimen name="favorites_menu_all_contacts_text_size">12sp</dimen>
+ <!-- Height of the all contacts Button in the favorites menu. -->
+ <dimen name="favorites_menu_all_contacts_height">24dp</dimen>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e84834113..2564cd7bd 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -719,4 +719,22 @@
<!-- Content description for dismiss button on badge. [CHAR LIMIT=NONE] -->
<string name="description_dismiss">Dismiss</string>
+
+ <!-- Header text displayed on the main dialer screen above the list of favorite phone numbers.
+ [CHAR LIMIT=21] -->
+ <string name="favorites_menu_speed_dial">Speed Dial</string>
+
+ <!-- Button text for the "all contacts" button displayed on the main dialer screen above the
+ list of favorite phone numbers. Navigates the user to the "All Contacts" list.
+ This text represents the same action as the text in string "menu_allContacts".
+ [CHAR LIMIT=21] -->
+ <string name="favorites_menu_all_contacts">ALL CONTACTS</string>
+
+ <!-- The font-family to use for the "speed dial" label on the favorites menu.
+ Do not translate. -->
+ <string name="favorites_menu_speed_dial_font_family">sans-serif-light</string>
+
+ <!-- The font-family to use for the "all contacts" label on the favorites menu.
+ Do not translate. -->
+ <string name="favorites_menu_all_contacts_font_family">sans-serif</string>
</resources>
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
index 027674a96..860f9dc2a 100644
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java
@@ -25,7 +25,6 @@ import android.content.Context;
import android.content.CursorLoader;
import android.content.Loader;
import android.content.SharedPreferences;
-import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Rect;
import android.net.Uri;
@@ -40,6 +39,7 @@ import android.view.ViewTreeObserver;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
+import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
@@ -195,8 +195,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
private PhoneFavoriteListView mListView;
- private View mShowAllContactsButton;
- private View mShowAllContactsInEmptyViewButton;
+ private View mPhoneFavoritesMenu;
private View mContactTileFrame;
private TileInteractionTeaserView mTileInteractionTeaserView;
@@ -288,14 +287,8 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
mEmptyView = mParentView.findViewById(R.id.phone_no_favorites_view);
- mShowAllContactsInEmptyViewButton = mParentView.findViewById(
- R.id.show_all_contact_button_in_nofav);
- prepareAllContactsButton(mShowAllContactsInEmptyViewButton);
-
- mShowAllContactsButton = inflater.inflate(R.layout.show_all_contact_button, mListView,
- false);
-
- prepareAllContactsButton(mShowAllContactsButton);
+ mPhoneFavoritesMenu = inflater.inflate(R.layout.phone_favorites_menu, mListView, false);
+ prepareFavoritesMenu(mPhoneFavoritesMenu);
mContactTileFrame = mParentView.findViewById(R.id.contact_tile_frame);
@@ -303,7 +296,7 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
R.layout.tile_interactions_teaser_view, mListView, false);
mAdapter = new PhoneFavoriteMergedAdapter(getActivity(), this, mContactTileAdapter,
- mCallLogAdapter, mShowAllContactsButton, mTileInteractionTeaserView);
+ mCallLogAdapter, mPhoneFavoritesMenu, mTileInteractionTeaserView);
mTileInteractionTeaserView.setAdapter(mAdapter);
@@ -666,31 +659,17 @@ public class PhoneFavoriteFragment extends Fragment implements OnItemClickListen
}
/**
- * Returns a view that is laid out and styled to look like a regular contact, with the correct
- * click behavior (to launch the all contacts activity when it is clicked).
+ * Prepares the favorites menu which contains the static label "Speed Dial" and the
+ * "All Contacts" button. Taps anywhere in the view take the user to "All Contacts".
+ * This emulates how the headers in Play Store work.
*/
- private View prepareAllContactsButton(View v) {
- final ContactListItemView view = (ContactListItemView) v;
- view.setOnClickListener(new OnClickListener() {
+ private void prepareFavoritesMenu(View favoritesMenu) {
+ // Set the onClick listener for the view to bring up the all contacts view.
+ favoritesMenu.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
showAllContacts();
}
});
-
- view.setPhotoPosition(ContactListItemView.PhotoPosition.LEFT);
- final Resources resources = getResources();
- view.setBackgroundResource(R.drawable.contact_list_item_background);
-
- view.setPaddingRelative(
- resources.getDimensionPixelSize(R.dimen.favorites_row_start_padding),
- resources.getDimensionPixelSize(R.dimen.favorites_row_end_padding),
- resources.getDimensionPixelSize(R.dimen.favorites_row_top_padding),
- resources.getDimensionPixelSize(R.dimen.favorites_row_bottom_padding));
-
- view.setDisplayName(resources.getString(R.string.show_all_contacts_button_text));
- view.setDrawableResource(R.drawable.list_item_avatar_bg,
- R.drawable.ic_menu_all_contacts_dk);
- return view;
}
}
diff --git a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
index daba39e6d..1c871e82f 100644
--- a/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoriteMergedAdapter.java
@@ -49,12 +49,12 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter {
private static final String TAG = PhoneFavoriteMergedAdapter.class.getSimpleName();
- private static final int TILE_INTERACTION_TEASER_VIEW_POSITION = 2;
+ private static final int TILE_INTERACTION_TEASER_VIEW_POSITION = 3;
private static final int TILE_INTERACTION_TEASER_VIEW_ID = -2;
- private static final int ALL_CONTACTS_BUTTON_ITEM_ID = -1;
+ private static final int FAVORITES_MENU_ITEM_ID = -3;
private final PhoneFavoritesTileAdapter mContactTileAdapter;
private final CallLogAdapter mCallLogAdapter;
- private final View mShowAllContactsButton;
+ private final View mPhoneFavoritesMenu;
private final PhoneFavoriteFragment mFragment;
private final TileInteractionTeaserView mTileInteractionTeaserView;
@@ -103,7 +103,7 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter {
PhoneFavoriteFragment fragment,
PhoneFavoritesTileAdapter contactTileAdapter,
CallLogAdapter callLogAdapter,
- View showAllContactsButton,
+ View phoneFavoritesMenu,
TileInteractionTeaserView tileInteractionTeaserView) {
final Resources resources = context.getResources();
mContext = context;
@@ -114,20 +114,24 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter {
mObserver = new CustomDataSetObserver();
mCallLogAdapter.registerDataSetObserver(mObserver);
mContactTileAdapter.registerDataSetObserver(mObserver);
- mShowAllContactsButton = showAllContactsButton;
+ mPhoneFavoritesMenu = phoneFavoritesMenu;
mTileInteractionTeaserView = tileInteractionTeaserView;
mCallLogQueryHandler = new CallLogQueryHandler(mContext.getContentResolver(),
mCallLogQueryHandlerListener);
}
+ /**
+ * Determines the number of items in the adapter.
+ * mCallLogAdapter contains the item for the most recent caller.
+ * mContactTileAdapter contains the starred contacts.
+ * The +1 is to account for the presence of the favorites menu.
+ *
+ * @return Number of items in the adapter.
+ */
@Override
public int getCount() {
- if (mContactTileAdapter.getCount() > 0) {
- return mContactTileAdapter.getCount() + mCallLogAdapter.getCount() + 1 +
- getTeaserViewCount();
- } else {
- return mCallLogAdapter.getCount();
- }
+ return mContactTileAdapter.getCount() + mCallLogAdapter.getCount() + getTeaserViewCount()
+ + 1;
}
@Override
@@ -151,9 +155,9 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter {
*
* These are the ranges of IDs reserved for each item type.
*
- * -(N + 1) to -3: CallLogAdapterItems, where N is equal to the number of call log items
+ * -4 and lower: CallLogAdapterItems representing most recent call.
+ * -3: Favorites menu
* -2: Teaser
- * -1: All contacts button
* 0 to (N -1): Rows of tiled contacts, where N is equal to the max rows of tiled contacts
* N to infinity: Rows of regular contacts. Their item id is calculated by N + contact_id,
* where contact_id is guaranteed to never be negative.
@@ -163,17 +167,19 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter {
final int callLogAdapterCount = mCallLogAdapter.getCount();
if (position < callLogAdapterCount) {
// Call log items are not animated, so reusing their position for IDs is fine.
- return ALL_CONTACTS_BUTTON_ITEM_ID - 2 - position;
+ return FAVORITES_MENU_ITEM_ID - 1 - position;
} else if (position == TILE_INTERACTION_TEASER_VIEW_POSITION + callLogAdapterCount &&
- mTileInteractionTeaserView.getShouldDisplayInList()){
+ mTileInteractionTeaserView.getShouldDisplayInList()) {
return TILE_INTERACTION_TEASER_VIEW_ID;
+ } else if (position == callLogAdapterCount) {
+ return FAVORITES_MENU_ITEM_ID;
} else if (position < (callLogAdapterCount + mContactTileAdapter.getCount() +
- getTeaserViewCount())) {
+ getTeaserViewCount() + 1)) {
return mContactTileAdapter.getItemId(
getAdjustedFavoritePosition(position, callLogAdapterCount));
} else {
- // All contacts button
- return ALL_CONTACTS_BUTTON_ITEM_ID;
+ // Default fallback. We don't normally get here.
+ return FAVORITES_MENU_ITEM_ID;
}
}
@@ -182,12 +188,15 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter {
return true;
}
+ /**
+ * Determine the number of view types present.
+ */
@Override
public int getViewTypeCount() {
return (mContactTileAdapter.getViewTypeCount() + /* Favorite and frequent */
mCallLogAdapter.getViewTypeCount() + /* Recent call log */
getTeaserViewCount() + /* Teaser */
- 1); /* Show all contacts button. */
+ 1); /* Favorites menu. */
}
@Override
@@ -200,60 +209,66 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter {
return mContactTileAdapter.getViewTypeCount();
} else if (position == TILE_INTERACTION_TEASER_VIEW_POSITION + callLogAdapterCount &&
mTileInteractionTeaserView.getShouldDisplayInList()) {
- // View type of the teaser row is the last view type of the contact tile adapter + 3
+ // View type of the teaser row is the last view type of the contact tile adapter +2
return mContactTileAdapter.getViewTypeCount() + 2;
- } else if (position < getCount() - 1) {
+ } else if (position == callLogAdapterCount) {
+ // View type of the favorites menu is last view type of contact tile adapter +3
+ return mContactTileAdapter.getViewTypeCount() + 3;
+ } else if (position < getCount()) {
return mContactTileAdapter.getItemViewType(
getAdjustedFavoritePosition(position, callLogAdapterCount));
} else {
- // View type of the show all contact button is the last view type of the contact tile
- // adapter + 2
- return mContactTileAdapter.getViewTypeCount() + 1;
+ // Catch-all - we shouldn't get here but if we do use the same as the favorites menu.
+ return mContactTileAdapter.getViewTypeCount() + 3;
}
}
+ /**
+ * Determines the view for a specified position.
+ *
+ * @param position Position for which to retrieve view.
+ * @return view corresponding to position.
+ */
@Override
public View getView(int position, View convertView, ViewGroup parent) {
final int callLogAdapterCount = mCallLogAdapter.getCount();
- if ((position == getCount() - 1) && (mContactTileAdapter.getCount() > 0)) {
- return mShowAllContactsButton;
- }
-
- if (mTileInteractionTeaserView.getShouldDisplayInList()) {
- if (position == TILE_INTERACTION_TEASER_VIEW_POSITION + callLogAdapterCount) {
- return mTileInteractionTeaserView;
+ // Get the view for the "teaser view" which describes how to re-arrange favorites.
+ if (mTileInteractionTeaserView.getShouldDisplayInList()
+ && position == TILE_INTERACTION_TEASER_VIEW_POSITION + callLogAdapterCount) {
+ return mTileInteractionTeaserView;
+ } else if (callLogAdapterCount > 0 && position < callLogAdapterCount) {
+ // Handle case where we are requesting the view for the "most recent caller".
+
+ final SwipeableCallLogRow wrapper;
+ if (convertView == null) {
+ wrapper = new SwipeableCallLogRow(mContext);
+ wrapper.setOnItemSwipeListener(mCallLogOnItemSwipeListener);
+ } else {
+ wrapper = (SwipeableCallLogRow) convertView;
}
- }
- if (callLogAdapterCount > 0) {
- if (position == 0) {
- final SwipeableCallLogRow wrapper;
- if (convertView == null) {
- wrapper = new SwipeableCallLogRow(mContext);
- wrapper.setOnItemSwipeListener(mCallLogOnItemSwipeListener);
- } else {
- wrapper = (SwipeableCallLogRow) convertView;
- }
-
- // Special case wrapper view for the most recent call log item. This allows
- // us to create a card-like effect for the more recent call log item in
- // the PhoneFavoriteMergedAdapter, but keep the original look of the item in
- // the CallLogAdapter.
- final View view = mCallLogAdapter.getView(position, convertView == null ?
- null : wrapper.getChildAt(0), parent);
- wrapper.removeAllViews();
- final View callLogItem = view.findViewById(R.id.call_log_list_item);
- // Reset the internal call log item view if it is being recycled
- callLogItem.setTranslationX(0);
- callLogItem.setAlpha(1);
- wrapper.addView(view);
- return wrapper;
- }
+ // Special case wrapper view for the most recent call log item. This allows
+ // us to create a card-like effect for the more recent call log item in
+ // the PhoneFavoriteMergedAdapter, but keep the original look of the item in
+ // the CallLogAdapter.
+ final View view = mCallLogAdapter.getView(position, convertView == null ?
+ null : wrapper.getChildAt(0), parent);
+ wrapper.removeAllViews();
+ final View callLogItem = view.findViewById(R.id.call_log_list_item);
+ // Reset the internal call log item view if it is being recycled
+ callLogItem.setTranslationX(0);
+ callLogItem.setAlpha(1);
+ wrapper.addView(view);
+ return wrapper;
+ } else if (position == callLogAdapterCount) {
+ // If position is just after the entries in the mCallLogAdapter (most recent call),
+ // return the favorites menu.
+ return mPhoneFavoritesMenu;
}
- // Set position to the position of the actual favorite contact in the
- // favorites adapter
+ // Set position to the position of the actual favorite contact in the favorites adapter.
+ // Adjusts based on the presence of other views, such as the favorites menu.
position = getAdjustedFavoritePosition(position, callLogAdapterCount);
// Favorites section
@@ -285,15 +300,26 @@ public class PhoneFavoriteMergedAdapter extends BaseAdapter {
}
}
+ /**
+ * Determines the index into the mContactTileAdapter for the current position.
+ *
+ * @param position current position in the overall adapter.
+ * @param callLogAdapterCount number of entries in "last calls" list (ie 0 or 1).
+ * @return position in the mContactTileAdapter.
+ */
private int getAdjustedFavoritePosition(int position, int callLogAdapterCount) {
if (position - callLogAdapterCount > TILE_INTERACTION_TEASER_VIEW_POSITION &&
mTileInteractionTeaserView.getShouldDisplayInList()) {
- return position - callLogAdapterCount - 1;
+ return position - callLogAdapterCount - 2;
} else {
- return position - callLogAdapterCount;
+ return position - callLogAdapterCount - 1;
}
}
+ /**
+ * Determines the number of teaser views visible.
+ * @return 1 or 0 depending on if the teaser view is showing.
+ */
private int getTeaserViewCount() {
return (mContactTileAdapter.getCount() > TILE_INTERACTION_TEASER_VIEW_POSITION &&
mTileInteractionTeaserView.getShouldDisplayInList() ? 1 : 0);