diff options
Diffstat (limited to 'src/org/cyanogenmod/launcher/home')
-rw-r--r-- | src/org/cyanogenmod/launcher/home/CMHomeAdapter.java | 252 | ||||
-rw-r--r-- | src/org/cyanogenmod/launcher/home/CMHomeCalendar.java | 26 | ||||
-rw-r--r-- | src/org/cyanogenmod/launcher/home/CMHomeCard.java | 7 | ||||
-rw-r--r-- | src/org/cyanogenmod/launcher/home/CMHomeContact.java | 22 | ||||
-rw-r--r-- | src/org/cyanogenmod/launcher/home/CMHomeNews.java | 29 | ||||
-rw-r--r-- | src/org/cyanogenmod/launcher/home/HomeLauncher.java | 61 | ||||
-rw-r--r-- | src/org/cyanogenmod/launcher/home/HomeLayout.java | 41 | ||||
-rw-r--r-- | src/org/cyanogenmod/launcher/home/HomeStub.java | 517 |
8 files changed, 955 insertions, 0 deletions
diff --git a/src/org/cyanogenmod/launcher/home/CMHomeAdapter.java b/src/org/cyanogenmod/launcher/home/CMHomeAdapter.java new file mode 100644 index 000000000..76656d2a1 --- /dev/null +++ b/src/org/cyanogenmod/launcher/home/CMHomeAdapter.java @@ -0,0 +1,252 @@ +package org.cyanogenmod.launcher.home; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.media.Image; +import android.net.Uri; +import android.os.AsyncTask; +import android.support.v7.widget.RecyclerView; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.launcher3.R; +import org.w3c.dom.Text; + +import java.io.InputStream; +import java.util.List; + +/** + * Created by Schoen on 7/25/15. + */ +public class CMHomeAdapter extends RecyclerView.Adapter<CMHomeAdapter.ViewHolder>{ + + Context mContext; + List<CMHomeCard> mCards; + + public static class ViewHolder extends RecyclerView.ViewHolder{ + //contact + LinearLayout contactCard; + ImageView contactImage1; + ImageView contactImage2; + ImageView contactImage3; + ImageView contactImage4; + + //calendar card + LinearLayout calendarCard; + LinearLayout eventContainer; + + //news card + LinearLayout newsCard; + ImageView newsImage; + TextView newsTitle; + TextView sourceAndTime; + + + ViewHolder(View cardView, int cardType){ + super(cardView); + + switch(cardType){ + case 0: + contactCard = (LinearLayout)itemView.findViewById(R.id.contact_card); + contactImage1 = (ImageView)itemView.findViewById(R.id.contact_image_one); + contactImage2 = (ImageView)itemView.findViewById(R.id.contact_image_two); + contactImage3 = (ImageView)itemView.findViewById(R.id.contact_image_three); + contactImage4 = (ImageView)itemView.findViewById(R.id.contact_image_four); + break; + case 1: + calendarCard = (LinearLayout)itemView.findViewById(R.id.calendar_card); + eventContainer = (LinearLayout)itemView.findViewById(R.id.event_container); + break; + case 2: + newsCard = (LinearLayout)itemView.findViewById(R.id.news_card); + newsImage = (ImageView)itemView.findViewById(R.id.news_image); + newsTitle = (TextView)itemView.findViewById(R.id.news_title); + sourceAndTime = (TextView)itemView.findViewById(R.id.news_source_time); + break; + case 3: + newsCard = (LinearLayout)itemView.findViewById(R.id.news_card); + newsImage = (ImageView)itemView.findViewById(R.id.news_image); + newsTitle = (TextView)itemView.findViewById(R.id.news_title); + sourceAndTime = (TextView)itemView.findViewById(R.id.news_source_time); + break; + } + } + + } + + CMHomeAdapter(Context context, List<CMHomeCard> cards){ + mContext = context; + mCards = cards; + } + + @Override + public void onAttachedToRecyclerView(RecyclerView recyclerView){ + super.onAttachedToRecyclerView(recyclerView); + } + + @Override + public int getItemViewType(int position) { + + Log.w("HAX", "get item view type"); + //default type + int viewType = 3; + + if(position == 0){ + //contact card + viewType = 0; + } + if(position == 1){ + //calendar card + viewType = 1; + } + if(position == 2){ + viewType = 2; + } + + return viewType; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int cardType){ + View v = null; + + switch(cardType){ + case 0: + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.contact_card, viewGroup, false); + Log.w("HAX","feature first"); + break; + case 1: + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.calendar_card, viewGroup, false); + Log.w("HAX","feature"); + break; + case 2: + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.news_card_first, viewGroup, false); + Log.w("HAX","item first"); + break; + case 3: + v = LayoutInflater.from(viewGroup.getContext()) + .inflate(R.layout.news_card, viewGroup, false); + Log.w("HAX","item"); + break; + } + + ViewHolder vh = new ViewHolder(v, cardType); + + return vh; + } + + @Override + public void onBindViewHolder(ViewHolder vh,int i){ + + if(i == 0){ + setupContact(vh.contactImage1); + setupContact(vh.contactImage2); + setupContact(vh.contactImage3); + setupContact(vh.contactImage4); + } + + if(i == 1){ + int numEvents = getUpcomingEventCount(); + getEventData(); + + for(int e = 0; e < numEvents; e++){ + createEventEntry(vh.eventContainer, e); + } + + } + + if(i > 1){ + createNewsCard(vh, i); + } + + + Log.w("HAX","we binded"); + } + + @Override + public int getItemCount(){ + return mCards.size(); + } + + private void setupContact(View view){ + ImageView iv = (ImageView)view; + iv.setImageResource(R.drawable.persona2); + iv.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + //launch the appropriate contact card + } + }); + } + + private int getUpcomingEventCount(){ + //get the upcoming calendar events here + //right now I am just returning an int representing the count available that maxes at 3 + + return 2; + } + + private void getEventData(){ + //doesn't do anything yet + } + + private void createEventEntry(View view, int eventNum){ + LinearLayout ll = (LinearLayout)view; + View v = LayoutInflater.from(mContext).inflate(R.layout.calendar_event_item,ll,false); + TextView startTime = (TextView)v.findViewById(R.id.start_time); + TextView endTime = (TextView)v.findViewById(R.id.end_time); + TextView title = (TextView)v.findViewById(R.id.event_title); + TextView location = (TextView)v.findViewById(R.id.event_location); + startTime.setText("12:00"); + endTime.setText("to 1:00"); + title.setText("Stand Up"); + location.setText("Conference Room"); + + ll.addView(v); + } + + private void createNewsCard(ViewHolder vh, int i){ + new DownloadImageTask(vh.newsImage) + .execute("http://slidell-independent.com/wp-content/uploads/2013/01/wsne.jpg");//need to get the url out of the spoof data + + vh.newsTitle.setText("This is a temp title"); + vh.sourceAndTime.setText("This is a temp source and time"); + + } + + private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { + ImageView bmImage; + + public DownloadImageTask(ImageView bmImage){ + this.bmImage = bmImage; + } + + protected Bitmap doInBackground(String... urls){ + String urldisplay = urls[0]; + Bitmap image = null; + try { + InputStream in = new java.net.URL(urldisplay).openStream(); + image = BitmapFactory.decodeStream(in); + } catch (Exception e) { + Log.e("Error", e.getMessage()); + e.printStackTrace(); + } + return image; + } + protected void onPostExecute(Bitmap result){ + bmImage.setImageBitmap(result); + } + } + +} diff --git a/src/org/cyanogenmod/launcher/home/CMHomeCalendar.java b/src/org/cyanogenmod/launcher/home/CMHomeCalendar.java new file mode 100644 index 000000000..c150a2dda --- /dev/null +++ b/src/org/cyanogenmod/launcher/home/CMHomeCalendar.java @@ -0,0 +1,26 @@ +package org.cyanogenmod.launcher.home; + +/** + * Created by Schoen on 7/24/15. + */ +public class CMHomeCalendar extends CMHomeCard { + + long startTime; + long endTime; + String title; + String location; + + public CMHomeCalendar( + long startTime, + long endTime, + String title, + String location){ + + this.startTime = startTime; + this.endTime = endTime; + this.title = title; + this.location = location; + + } + +} diff --git a/src/org/cyanogenmod/launcher/home/CMHomeCard.java b/src/org/cyanogenmod/launcher/home/CMHomeCard.java new file mode 100644 index 000000000..b2ece81b0 --- /dev/null +++ b/src/org/cyanogenmod/launcher/home/CMHomeCard.java @@ -0,0 +1,7 @@ +package org.cyanogenmod.launcher.home; + +/** + * Created by Schoen on 7/24/15. + */ +public class CMHomeCard { +} diff --git a/src/org/cyanogenmod/launcher/home/CMHomeContact.java b/src/org/cyanogenmod/launcher/home/CMHomeContact.java new file mode 100644 index 000000000..2194f0dc7 --- /dev/null +++ b/src/org/cyanogenmod/launcher/home/CMHomeContact.java @@ -0,0 +1,22 @@ +package org.cyanogenmod.launcher.home; + +/** + * Created by Schoen on 7/24/15. + */ +public class CMHomeContact extends CMHomeCard{ + String uri1; + String uri2; + String uri3; + String uri4; + + public CMHomeContact(String uri1, String uri2, String uri3, String uri4){ + + this.uri1 = uri1; + this.uri2 = uri2; + this.uri3 = uri3; + this.uri4 = uri4; + + + } + +} diff --git a/src/org/cyanogenmod/launcher/home/CMHomeNews.java b/src/org/cyanogenmod/launcher/home/CMHomeNews.java new file mode 100644 index 000000000..8cc087ee3 --- /dev/null +++ b/src/org/cyanogenmod/launcher/home/CMHomeNews.java @@ -0,0 +1,29 @@ +package org.cyanogenmod.launcher.home; + +/** + * Created by Schoen on 7/24/15. + */ +public class CMHomeNews extends CMHomeCard { + + String imageURL; + String title; + String source; + long time; + String url; + + public CMHomeNews( + String imageURL, + String title, + String source, + long time, + String url){ + + this.imageURL = imageURL; + this.title = title; + this.source = source; + this.time = time; + this.url = url; + + } + +} diff --git a/src/org/cyanogenmod/launcher/home/HomeLauncher.java b/src/org/cyanogenmod/launcher/home/HomeLauncher.java new file mode 100644 index 000000000..84f2388b5 --- /dev/null +++ b/src/org/cyanogenmod/launcher/home/HomeLauncher.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2014 The CyanogenMod 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. + */ + +package org.cyanogenmod.launcher.home; + +import android.app.Activity; +import android.os.Bundle; + +public class HomeLauncher extends Activity { + + private HomeStub mStub; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + mStub = new HomeStub(); + mStub.setHostActivityContext(this); + mStub.onStart(this); + setContentView(mStub.createCustomView(this)); + mStub.setShowContent(this, true); + mStub.onShow(this); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + @Override + protected void onStop() { + super.onStop(); + mStub.onDestroy(this); + } + + @Override + protected void onResume() { + super.onResume(); + mStub.onResume(this); + mStub.onShow(this); + } + + @Override + protected void onPause() { + super.onPause(); + mStub.onPause(this); + } +} diff --git a/src/org/cyanogenmod/launcher/home/HomeLayout.java b/src/org/cyanogenmod/launcher/home/HomeLayout.java new file mode 100644 index 000000000..c83fd94ec --- /dev/null +++ b/src/org/cyanogenmod/launcher/home/HomeLayout.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 The CyanogenMod 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. + */ + +package org.cyanogenmod.launcher.home; + +import android.content.Context; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +public class HomeLayout extends LinearLayout { + + public HomeLayout(Context context) { + this(context, null, 0); + } + + public HomeLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public HomeLayout(final Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onFinishInflate() { + } + +} diff --git a/src/org/cyanogenmod/launcher/home/HomeStub.java b/src/org/cyanogenmod/launcher/home/HomeStub.java new file mode 100644 index 000000000..808fe8e14 --- /dev/null +++ b/src/org/cyanogenmod/launcher/home/HomeStub.java @@ -0,0 +1,517 @@ +/* + * Copyright (C) 2014 The CyanogenMod 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. + */ + +package org.cyanogenmod.launcher.home; + +import android.content.Context; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.util.Log; +import android.os.AsyncTask; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.animation.AccelerateInterpolator; +import com.android.launcher.home.Home; +import com.android.launcher3.R; +import it.gmariotti.cardslib.library.internal.Card; +import it.gmariotti.cardslib.library.internal.CardArrayAdapter; +import it.gmariotti.cardslib.library.view.CardListView; +import it.gmariotti.cardslib.library.view.listener.dismiss.DefaultDismissableManager; +import org.cyanogenmod.launcher.cardprovider.CmHomeApiCardProvider; +import org.cyanogenmod.launcher.cardprovider.DashClockExtensionCardProvider; +import org.cyanogenmod.launcher.cardprovider.ICardProvider; +import org.cyanogenmod.launcher.cardprovider.ICardProvider.CardProviderUpdateResult; +import org.cyanogenmod.launcher.cards.CmCard; +import org.cyanogenmod.launcher.cards.SimpleMessageCard; + +import java.util.ArrayList; +import java.util.List; + +public class HomeStub implements Home { + + private static final String TAG = "HomeStub"; + private static final String NO_EXTENSIONS_CARD_ID = "noExtensions"; + private static final String BACKGROUND_THREAD_NAME = "CMHomeBackgroundThread"; + private HomeLayout mHomeLayout; + private RecyclerView mRecyclerView; + private Context mHostActivityContext; + private Context mCMHomeContext; + private boolean mShowContent = false; + private SimpleMessageCard mNoExtensionsCard; + private List<ICardProvider> mCardProviders = new ArrayList<ICardProvider>(); + private List<CMHomeCard> mCards; + private CMHomeCardArrayAdapter mCardArrayAdapter; + private LinearLayoutManager mLayoutManager; + + private HandlerThread mBackgroundHandlerThread; + private Handler mBackgroundHandler; + private Handler mUiThreadHandler; + + private final AccelerateInterpolator mAlphaInterpolator; + + private final ICardProvider.CardProviderUpdateListener mCardProviderUpdateListener = + new ICardProvider.CardProviderUpdateListener() { + @Override + public boolean onCardProviderUpdate(String cardId, boolean wasPending) { + return refreshCard(cardId); + } + + @Override + public void onCardDelete(String cardId) { + + } + }; + + private final Runnable mLoadAllCardsRunnable = new Runnable() { + @Override + public void run() { + loadAllCards(); + } + }; + + public HomeStub() { + super(); + mAlphaInterpolator = new AccelerateInterpolator(); + } + + @Override + public void setHostActivityContext(Context context) { + mHostActivityContext = context; + mUiThreadHandler = new Handler(mHostActivityContext.getMainLooper()); + } + + @Override + public void onStart(Context context) { + mCMHomeContext = context; + + // Start up a background thread to handle updating. + mBackgroundHandlerThread = new HandlerThread(BACKGROUND_THREAD_NAME); + mBackgroundHandlerThread.start(); + mBackgroundHandler = new Handler(mBackgroundHandlerThread.getLooper()); + + if(mShowContent) { + // Add any providers we wish to include, if we should show content + initProvidersIfNeeded(context); + } + } + + @Override + public void setShowContent(Context context, boolean showContent) { + mShowContent = showContent; + if(mShowContent) { + // Add any providers we wish to include, if we should show content + initProvidersIfNeeded(context); + if(mHomeLayout != null) { + loadCardsFromProviders(); + } + } else { + for(ICardProvider cardProvider : mCardProviders) { + cardProvider.onHide(context); + } + mCardProviders.clear(); + if(mHomeLayout != null) { + removeAllCards(context); + // Make sure that the Undo Bar is hidden if no content is to be shown. + hideUndoBar(); + } + } + } + + @Override + public void onDestroy(Context context) { + mHomeLayout = null; + } + + @Override + public void onResume(Context context) { + } + + @Override + public void onPause(Context context) { + } + + @Override + public void onShow(Context context) { + if (mHomeLayout != null) { + mHomeLayout.setAlpha(1.0f); + + if(mShowContent) { + for(ICardProvider cardProvider : mCardProviders) { + cardProvider.onShow(); + cardProvider.requestRefresh(); + } + } else { + hideUndoBar(); + } + } + } + + @Override + public void onScrollProgressChanged(Context context, float progress) { + if (mHomeLayout != null) { + mHomeLayout.setAlpha(mAlphaInterpolator.getInterpolation(progress)); + } + } + + @Override + public void onHide(Context context) { + if (mHomeLayout != null) { + mHomeLayout.setAlpha(0.0f); + } + for(ICardProvider cardProvider : mCardProviders) { + cardProvider.onHide(context); + } + } + + @Override + public void onInvalidate(Context context) { + if (mHomeLayout != null) { + mHomeLayout.removeAllViews(); + } + } + + @Override + public void onRequestSearch(Context context, int mode) { + + } + + @Override + public View createCustomView(Context context) { + if(mHomeLayout == null) { + LayoutInflater inflater = (LayoutInflater) context.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + mHomeLayout = (HomeLayout) inflater.inflate(R.layout.home_layout, null); + } + hideUndoBar(); + + mRecyclerView = (RecyclerView) mHomeLayout.findViewById(R.id.main_recycler_view); + + initData(); + + CMHomeAdapter adapter = new CMHomeAdapter(context, mCards); + mLayoutManager = new LinearLayoutManager(context); + mRecyclerView.setLayoutManager(mLayoutManager); + mRecyclerView.setHasFixedSize(true); + mRecyclerView.setAdapter(adapter); + + return mHomeLayout; + } + + private void initData(){ + Resources resources = mCMHomeContext.getResources(); + TypedArray typedArray = resources.obtainTypedArray(R.array.spoof_data); ; + int n = typedArray.length(); + String[][] dataArray = new String[n][]; + + for(int i = 0; i < n; i++){ + int id = typedArray.getResourceId(i,0); + if(id > 0){ + dataArray[i] = resources.getStringArray(id); + } else { + //something is wrong + } + } + + typedArray.recycle(); + + mCards = new ArrayList<>(); + + mCards.add(new CMHomeContact( + dataArray[0][0], + dataArray[0][1], + dataArray[0][2], + dataArray[0][3] + )); + + mCards.add(new CMHomeCalendar( + Long.parseLong(dataArray[1][0]), + Long.parseLong(dataArray[1][1]), + dataArray[1][2], + dataArray[1][3] + )); + + for(int i = 2; i < n; i++){ + mCards.add(new CMHomeNews( + dataArray[i][0], + dataArray[i][1], + dataArray[i][2], + Long.parseLong(dataArray[i][3]), + dataArray[i][4] + )); + } + + Log.w("HAX", "Making data"); + } + + @Override + public String getName(Context context) { + return "HomeStub"; + } + + @Override + public int getNotificationFlags() { + return Home.FLAG_NOTIFY_ALL; + } + + @Override + public int getOperationFlags() { + return Home.FLAG_OP_MASK; + } + + private void hideUndoBar() { + View undoLayout = mHomeLayout.findViewById(R.id.list_card_undobar); + if (undoLayout != null) { + undoLayout.setVisibility(View.GONE); + } + } + + public void initProvidersIfNeeded(Context context) { + if (mCardProviders.size() == 0) { + mCardProviders.add(new DashClockExtensionCardProvider(context, mHostActivityContext)); + mCardProviders.add(new CmHomeApiCardProvider(context, mHostActivityContext, + mBackgroundHandler)); + + for (ICardProvider cardProvider : mCardProviders) { + cardProvider.addOnUpdateListener(mCardProviderUpdateListener); + } + } + } + + /* + * Gets a list of all cards provided by each provider, + * and updates the UI to show them. + */ + private void loadCardsFromProviders() { + // If cards have been initialized already, just update them + if(mCardArrayAdapter != null + && mCardArrayAdapter.getCards().size() > 0 + && mHomeLayout != null) { + mBackgroundHandler.post(new RefreshAllCardsRunnable(true)); + } else { + mBackgroundHandler.post(mLoadAllCardsRunnable); + } + } + + /** + * Creates a card with a message to inform the user they have no extensions + * installed to publish content. + */ + private Card getNoExtensionsCard(final Context context) { + if (mNoExtensionsCard == null) { + mNoExtensionsCard = new SimpleMessageCard(context); + mNoExtensionsCard.setTitle(context.getResources().getString(R.string.no_extensions_card_title)); + mNoExtensionsCard.setBody(context.getResources().getString(R.string.no_extensions_card_body)); + mNoExtensionsCard.setId(NO_EXTENSIONS_CARD_ID); + } + + return mNoExtensionsCard; + } + + public boolean refreshCard(String cardId) { + boolean cardIsNew = false; + if (mCardArrayAdapter != null) { + CmCard card = mCardArrayAdapter.getCardWithId(cardId); + + // The card already exists in the list + if (card != null) { + // Allow each provider to update the card (if necessary) + for (ICardProvider cardProvider : mCardProviders) { + cardProvider.updateCard(card); + } + } else { + // The card is brand new, add it + CmCard newCard = null; + for (ICardProvider cardProvider : mCardProviders) { + newCard = cardProvider.createCardForId(cardId); + if (newCard != null) break; + } + + if (newCard != null) { + card = newCard; + cardIsNew = true; + } + } + + final boolean runnableCardIsNew = cardIsNew; + final CmCard runnableCard = card; + mUiThreadHandler.post(new Runnable() { + @Override + public void run() { + if (runnableCard != null) { + if (runnableCardIsNew) { + mCardArrayAdapter.add(runnableCard); + // Remove the "no cards" card, if it's there. + mCardArrayAdapter.remove(getNoExtensionsCard(mCMHomeContext)); + mCardArrayAdapter.notifyDataSetChanged(); + } else { + mCardArrayAdapter.updateCardViewIfVisible(runnableCard); + } + } + } + }); + } + return cardIsNew; + } + + private void removeAllCards(Context context) { + + } + + private void loadAllCards() { + final List<Card> cards = new ArrayList<Card>(); + for (ICardProvider provider : mCardProviders) { + for (Card card : provider.getCards()) { + cards.add(card); + } + } + + // If there aren't any cards, show the user a message about how to fix that! + if (cards.size() == 0) { + cards.add(getNoExtensionsCard(mCMHomeContext)); + } + + mUiThreadHandler.post(new Runnable() { + @Override + public void run() { + + } + }); + } + + /** + * Refresh all cards by asking the providers to update them. + * @param addNew If providers have new cards that have not + * been displayed yet, should they be added? + */ + private void refreshCards(final boolean addNew) { + boolean noExtensionsCardExists; + List<CmCard> originalCards = mCardArrayAdapter.getCards(); + int finalCardCount = 0; + + final CardProviderUpdateResult updateResult = + new CardProviderUpdateResult(new ArrayList<CmCard>(), + new ArrayList<CmCard>()); + // Allow each provider to update it's cards + for (ICardProvider cardProvider : mCardProviders) { + CardProviderUpdateResult tempResult; + tempResult = cardProvider.updateAndAddCards(originalCards); + updateResult.getCardsToAdd().addAll(tempResult.getCardsToAdd()); + updateResult.getCardsToRemove().addAll(tempResult.getCardsToRemove()); + } + + noExtensionsCardExists = originalCards.contains(mNoExtensionsCard); + + if (updateResult != null) { + finalCardCount += updateResult.getCardsToAdd().size(); + finalCardCount -= updateResult.getCardsToRemove().size(); + } + + final boolean runnableNoExtensionCard = noExtensionsCardExists; + final int runnableFinalCardCount = finalCardCount; + mUiThreadHandler.post(new Runnable() { + @Override + public void run() { + if (updateResult != null) { + if (addNew) { + mCardArrayAdapter.addAll(updateResult.getCardsToAdd()); + } + for (Card card : updateResult.getCardsToRemove()) { + mCardArrayAdapter.remove(card); + } + } + + if (runnableNoExtensionCard && runnableFinalCardCount > 1) { + mCardArrayAdapter.remove(mNoExtensionsCard); + } + } + }); + + } + + public class CMHomeCardArrayAdapter extends CardArrayAdapter { + + public CMHomeCardArrayAdapter(Context context, List<Card> cards) { + super(context, cards); + } + + public List<CmCard> getCards() { + List<CmCard> cardsToReturn = new ArrayList<CmCard>(); + for(int i = 0; i < getCount(); i++) { + cardsToReturn.add((CmCard)getItem(i)); + } + return cardsToReturn; + } + + public CmCard getCardWithId(String id) { + CmCard theCard = null; + for(int i = 0; i < getCount(); i++) { + CmCard card = (CmCard) getItem(i); + if (card.getId().equals(id)) { + theCard = card; + break; + } + } + return theCard; + } + + /** + * Find the CardView displaying the card that has changed + * and update it, if it is currently on screen. Otherwise, + * do nothing. + * @param card The card object to re-draw onscreen. + */ + public void updateCardViewIfVisible(Card card) { + CardListView listView = getCardListView(); + int start = listView.getFirstVisiblePosition(); + int last = listView.getLastVisiblePosition(); + for (int i = start; i <= last; i++) { + if (card == listView.getItemAtPosition(i)) { + View cardView = listView.getChildAt(i - start); + getView(i, cardView, listView); + break; + } + } + } + } + + private class RefreshAllCardsRunnable implements Runnable { + private boolean mAddNew = false; + + private RefreshAllCardsRunnable(boolean addNew) { + mAddNew = addNew; + } + + @Override + public void run() { + refreshCards(mAddNew); + } + } + + /** + * A DismissableManager implementation that only allows cards to be swiped to the right. + */ + private class RightDismissableManager extends DefaultDismissableManager { + @Override + public SwipeDirection getSwipeDirectionAllowed() { + return SwipeDirection.RIGHT; + } + } +} |