com.harrcharr.reverb.StreamNodeFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.harrcharr.reverb.StreamNodeFragment.java

Source

/*******************************************************************************
 * Copyright (c) 2012 Harrison Chapman.
 * 
 * This file is part of Reverb.
 * 
 *     Reverb is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU General Public License as published by
 *     the Free Software Foundation, either version 2 of the License, or
 *     (at your option) any later version.
 * 
 *     Reverb is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU General Public License for more details.
 * 
 *     You should have received a copy of the GNU General Public License
 *     along with Reverb.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * Contributors:
 *     Harrison Chapman - initial API and implementation
 ******************************************************************************/
package com.harrcharr.reverb;

import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.LinearLayout;

import com.actionbarsherlock.app.SherlockFragment;
import com.harrcharr.pulse.StreamNode;
import com.harrcharr.reverb.pulseutil.HasPulseManager;
import com.harrcharr.reverb.pulseutil.PulseConnectionListener;
import com.harrcharr.reverb.pulseutil.PulseManager;
import com.harrcharr.reverb.widgets.StreamNodeView;

import java.util.ArrayList;

public abstract class StreamNodeFragment<T extends StreamNode> extends SherlockFragment
        implements PulseConnectionListener, HasPulseManager, SharedPreferences.OnSharedPreferenceChangeListener {
    protected ViewGroup mNodeHolder;
    private MarginLayoutParams mLayoutParams;
    private ArrayList<StreamNodeView<T>> mNodeViews = new ArrayList<StreamNodeView<T>>();

    public StreamNodeFragment() {
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.stream_node_fragment, container, false);
        mNodeHolder = (ViewGroup) v.findViewById(R.id.nodeHolder);

        PulseManager p = (getActivity() == null ? null : ((HasPulseManager) getActivity()).getPulseManager());

        if (p != null) {
            synchronized (p) {
                SparseArray<T> nodes = getNodesFromManager(p);
                for (int i = 0; i < nodes.size(); i++) {
                    T node = nodes.get(nodes.keyAt(i));
                    if (node != null) {
                        updateNode(node);
                    }
                }
            }
        }

        ReverbSharedPreferences.registerOnSharedPreferenceChangeListener(getActivity(), this);

        return v;
    }

    protected void updateNode(final T node) {
        if (getViewGroup() != null) {
            StreamNodeView<T> v = getStreamNodeViewByIndex(node.getIndex());

            FragmentActivity activity = getActivity();

            if (activity == null)
                return;

            if (v == null) {
                activity.runOnUiThread(new Runnable() {
                    public void run() {
                        final StreamNodeView<T> nodeView = makeNewStreamNodeView();

                        setNewNode(nodeView, node);
                    }
                });
            } else {
                final StreamNodeView<T> nodeView = v;

                activity.runOnUiThread(new Runnable() {
                    public void run() {
                        setNode(nodeView, node);
                    }
                });
            }
        }
    }

    protected void setNewNode(StreamNodeView<T> nodeView, final T node) {
        if (mLayoutParams == null) {
            mLayoutParams = new LinearLayout.LayoutParams(getViewGroup().getLayoutParams());
            mLayoutParams.setMargins(0, 0, 0, 10);
        }

        getViewGroup().addView(nodeView, mLayoutParams);
        mNodeViews.add(nodeView);
        nodeView.setNode(node);
    }

    protected void setNode(StreamNodeView<T> nodeView, final T node) {
        nodeView.setNode(node);
    }

    protected void removeNode(final int index) {
        if (getViewGroup() != null) {
            final StreamNodeView<T> v = getStreamNodeViewByIndex(index);
            if (v != null) {
                getActivity().runOnUiThread(new Runnable() {
                    public void run() {
                        getViewGroup().removeView(v);
                    }
                });

                // Destroy the StreamNode, and anything it might be holding on to
                mNodeViews.remove(v);
                v.disconnect();
            }
        }
    }

    protected ViewGroup getViewGroup() {
        return mNodeHolder;
    }

    protected StreamNodeView<T> getStreamNodeViewByIndex(int idx) {
        if (getViewGroup() == null)
            return null;

        try {
            return (StreamNodeView<T>) getViewGroup().findViewById(idx);
        } catch (ClassCastException e) {
            return null;
        }
    }

    public void onAttach(Activity activity) {
        super.onAttach(activity);

        try {
            PulseManager p = ((HasPulseManager) activity).getPulseManager();
            p.addOnPulseConnectionListener(this);
            onManagerAttached(p);
        } catch (ClassCastException e) {
            Log.e("StreamNodeFragment",
                    "Activity to which this fragment " + "is attached must have a PulseManager");
            throw (new Error("A stream node fragment must be attached to" + "an activity with a pulsemanager."));
        }
    }

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        for (StreamNodeView<T> v : mNodeViews) {
            v.disconnect();
        }
        mNodeViews = new ArrayList<StreamNodeView<T>>();
        ReverbSharedPreferences.unregisterOnSharedPreferenceChangeListener(getActivity(), this);
    }

    public abstract void onManagerAttached(PulseManager p);

    public abstract SparseArray<T> getNodesFromManager(PulseManager p);

    protected abstract StreamNodeView<T> makeNewStreamNodeView();

    public void onPulseConnectionReady(final PulseManager p) {
        if (getActivity() != null) {
            getActivity().runOnUiThread(new Runnable() {
                public void run() {
                    try {
                        getViewGroup().removeAllViews();
                        Log.d("Reverb", "Removed stale nodes");
                    } catch (Exception e) {
                        Log.e("Reverb", e.getMessage());
                    }

                    synchronized (p) {
                        SparseArray<T> nodes = getNodesFromManager(p);
                        for (int i = 0; i < nodes.size(); i++) {
                            T node = nodes.get(nodes.keyAt(i));
                            if (node != null) {
                                updateNode(node);
                            }
                        }
                    }
                }
            });

        }

    }

    public void onPulseConnectionFailed(PulseManager p) {
        // Right now we do nothing on failed connect.
    }

    public PulseManager getPulseManager() {
        return ((HasPulseManager) getActivity()).getPulseManager();
    }

    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        if (key.equals(getActivity().getString(R.string.prefs_key_display_vol_peaks))) {
            synchronized (mNodeViews) {
                for (StreamNodeView nodeView : mNodeViews) {
                    nodeView.setDisplayPeaks(ReverbSharedPreferences.displayPeaks(getActivity()));
                }
            }
        }
    }
}