Home | History | Annotate | Download | only in testingcamera2
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.testingcamera2;
     18 
     19 import android.content.Context;
     20 import android.util.AttributeSet;
     21 import android.view.LayoutInflater;
     22 import android.view.View;
     23 import android.widget.Button;
     24 import android.widget.LinearLayout;
     25 import android.widget.TextView;
     26 import android.widget.ToggleButton;
     27 
     28 import org.xmlpull.v1.XmlPullParser;
     29 import org.xmlpull.v1.XmlPullParserException;
     30 
     31 /**
     32  * A base control pane, with standard abilities to collapse or remove itself.
     33  */
     34 public class ControlPane extends LinearLayout {
     35 
     36     private final StatusListener mStatusListener;
     37     private String mPaneName = "unnamed";
     38 
     39     protected final PaneTracker mPaneTracker;
     40 
     41     private View[] mHeaderViews;
     42 
     43     private OnClickListener mRemoveButtonListener = new OnClickListener() {
     44         @Override
     45         public void onClick(View v) {
     46             remove();
     47         }
     48     };
     49 
     50     private OnClickListener mCollapseButtonListener = new OnClickListener() {
     51         private boolean mCollapsed = false;
     52 
     53         @Override
     54         public void onClick(View v) {
     55             if (mCollapsed) {
     56                 mCollapsed = false;
     57                 // Unhide all pane items
     58                 for (int i = 0; i < ControlPane.this.getChildCount(); i++) {
     59                     ControlPane.this.getChildAt(i).setVisibility(VISIBLE);
     60                 }
     61             } else {
     62                 mCollapsed = true;
     63                 // Hide all pane items
     64                 for (int i = 0; i < ControlPane.this.getChildCount(); i++) {
     65                     ControlPane.this.getChildAt(i).setVisibility(GONE);
     66                 }
     67                 // Except for the header
     68                 for (int i = 0; i < mHeaderViews.length; i++) {
     69                     mHeaderViews[i].setVisibility(VISIBLE);
     70                 }
     71             }
     72         }
     73     };
     74 
     75     public ControlPane(Context context, AttributeSet attrs, StatusListener listener,
     76             PaneTracker paneTracker) {
     77         super(context, attrs);
     78         mStatusListener = listener;
     79         mPaneTracker = paneTracker;  // Parent takes care of adding pane to tracking
     80 
     81         this.setOrientation(VERTICAL);
     82 
     83         LayoutInflater inflater = (LayoutInflater)context.getSystemService
     84                 (Context.LAYOUT_INFLATER_SERVICE);
     85 
     86         inflater.inflate(R.layout.control_pane_header, this);
     87 
     88         // Add all header views into list to manage collapsing pane correctly
     89         mHeaderViews = new View[getChildCount()];
     90         for (int i = 0; i < getChildCount(); i++) {
     91             mHeaderViews[i] = getChildAt(i);
     92         }
     93 
     94         // Set up the header controls
     95         ToggleButton collapseButton = (ToggleButton)
     96                 findViewById(R.id.control_pane_collapse_button);
     97         collapseButton.setOnClickListener(mCollapseButtonListener);
     98 
     99         Button removeButton = (Button) findViewById(R.id.control_pane_remove_button);
    100         removeButton.setOnClickListener(mRemoveButtonListener);
    101     }
    102 
    103     /**
    104      * Add to pane tracking when the pane becomes part of the UI
    105      */
    106     @Override
    107     public void onAttachedToWindow() {
    108         super.onAttachedToWindow();
    109         if (mPaneTracker != null) {
    110             mPaneTracker.addPane(this);
    111         }
    112     }
    113 
    114     /**
    115      * Remove this pane from its list and clean up its state
    116      */
    117     public void remove() {
    118         if (mStatusListener != null) {
    119             mStatusListener.onRemoveRequested(ControlPane.this);
    120         }
    121         if (mPaneTracker != null ) {
    122             mPaneTracker.removePane(this);
    123         }
    124     }
    125 
    126     /**
    127      * Get a nice name for this pane.
    128      */
    129     public String getPaneName() {
    130         return mPaneName;
    131     }
    132 
    133     /**
    134      * Listener to be implemented by an application service that handles removing this
    135      * pane from the UI. Called when the pane is ready to be destroyed.
    136      */
    137     public interface StatusListener {
    138         public void onRemoveRequested(ControlPane p);
    139     }
    140 
    141     /**
    142      * Set the name for this pane, also used as the header title.
    143      */
    144     protected void setName(String name) {
    145         mPaneName = name;
    146         ((TextView) findViewById(R.id.control_pane_title_text)).setText(name);
    147     }
    148 
    149     /**
    150      * Get an XML attribute as a integer; if the attribute does not exist, return the default value.
    151      *
    152      * @throws XmlPullParserException if parser not at a START_TAG event, or the attribute is not
    153      *   formatted as a string.
    154      */
    155     protected static int getAttributeInt(XmlPullParser configParser,
    156             String attributeName, int defaultValue) throws XmlPullParserException {
    157         String value = configParser.getAttributeValue(null, attributeName);
    158         if (value == null ) return defaultValue;
    159 
    160         try {
    161             int v = Integer.parseInt(value);
    162             return v;
    163         } catch (NumberFormatException e) {
    164             throw new XmlPullParserException("Expected integer attribute",
    165                     configParser, e);
    166         }
    167     }
    168 
    169     /**
    170      * Get an XML attribute as a String; if the attribute does not exist, return the default value.
    171      *
    172      * @throws XmlPullParserException if parser not at a START_TAG event.
    173      */
    174     protected static String getAttributeString(
    175             XmlPullParser configParser,
    176             String attributeName, String defaultValue) throws XmlPullParserException {
    177         String value = configParser.getAttributeValue(null, attributeName);
    178         return (value == null) ? defaultValue : value;
    179     }
    180 
    181     /**
    182      * Called when other panes want to inform the rest of the app of interesting events
    183      *
    184      * @param sourcePane the source pane of the event
    185      * @param event the type of event
    186      */
    187     public void notifyPaneEvent(ControlPane sourcePane, PaneTracker.PaneEvent event) {
    188         // Default empty implementation
    189     }
    190 
    191     /**
    192      * Called when the app's UI orientation changes.
    193      *
    194      * @param orientation one of the Surface.ROTATION_* constants
    195      */
    196     public void onOrientationChange(int orientation) {
    197         // Default empty implementation
    198     }
    199 
    200 }
    201