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.content.res.TypedArray;
21 import android.util.AttributeSet;
22 import android.view.LayoutInflater;
23 import android.view.View;
24 import android.widget.LinearLayout;
25 import android.widget.TextView;
26 import android.widget.ToggleButton;
27 
28 import java.util.List;
29 import java.util.ArrayList;
30 
31 import org.xmlpull.v1.XmlPullParser;
32 import org.xmlpull.v1.XmlPullParserException;
33 
34 import java.io.IOException;
35 
36 /**
37  * A simple linear layout to hold a set of control panes, with the ability to
38  * add more panes, and to serialize itself in/out of configurations.
39  */
40 public abstract class PaneLayout<T extends ControlPane> extends LinearLayout implements
41         ControlPane.StatusListener {
42 
43     private static final String DEFAULT_XML_PANE_NAME = "pane_layout";
44 
45     private List<T> mPanes = new ArrayList<T>();
46 
47     private List<T> mNewPanes = new ArrayList<T>();
48 
49     private final String mPaneXmlName;
50     private PaneTracker mPaneTracker;
51 
52     private OnClickListener mCollapseButtonListener = new OnClickListener() {
53         private boolean mCollapsed = false;
54 
55         @Override
56         public void onClick(View v) {
57             if (mCollapsed) {
58                 mCollapsed = false;
59                 // Unhide all panes
60                 for (T pane : mPanes) {
61                     pane.setVisibility(VISIBLE);
62                 }
63             } else {
64                 mCollapsed = true;
65                 // Hide all panes
66                 for (T pane : mPanes) {
67                     pane.setVisibility(GONE);
68                 }
69             }
70         }
71     };
72 
PaneLayout(Context context, AttributeSet attrs)73     public PaneLayout(Context context, AttributeSet attrs) {
74         super(context, attrs);
75 
76         mPaneXmlName = DEFAULT_XML_PANE_NAME;
77         mPaneTracker = null;
78 
79         setUpUI(context, attrs);
80     }
81 
PaneLayout(Context context, AttributeSet attrs, String paneXmlName)82     public PaneLayout(Context context, AttributeSet attrs, String paneXmlName) {
83         super(context, attrs);
84 
85         mPaneXmlName = paneXmlName;
86 
87         setUpUI(context, attrs);
88     }
89 
setPaneTracker(PaneTracker tracker)90     public void setPaneTracker(PaneTracker tracker) {
91         mPaneTracker = tracker;
92     }
93 
getXmlName()94     public String getXmlName() {
95         return mPaneXmlName;
96     }
97 
setUpUI(Context context, AttributeSet attrs)98     private void setUpUI(Context context, AttributeSet attrs) {
99 
100         LayoutInflater inflater =
101                 (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
102 
103         inflater.inflate(R.layout.pane_layout_header, this);
104 
105         TextView title = (TextView) findViewById(R.id.pane_layout_title_text);
106 
107         TypedArray a =
108                 context.getTheme().obtainStyledAttributes(attrs, R.styleable.PaneLayout, 0, 0);
109 
110         try {
111             title.setText(a.getString(R.styleable.PaneLayout_headerTitle));
112         } finally {
113             a.recycle();
114         }
115 
116         ToggleButton collapseButton = (ToggleButton) findViewById(R.id.pane_layout_collapse_button);
117         collapseButton.setOnClickListener(mCollapseButtonListener);
118     }
119 
readConfig(TestingCamera21 tc, XmlPullParser configParser)120     public void readConfig(TestingCamera21 tc, XmlPullParser configParser)
121             throws XmlPullParserException, IOException {
122 
123         configParser.require(XmlPullParser.START_TAG, XmlPullParser.NO_NAMESPACE, mPaneXmlName);
124         int eventType = configParser.next();
125         while (eventType != XmlPullParser.END_TAG) {
126             switch (eventType) {
127             case XmlPullParser.START_TAG:
128                 T pane = readControlPane(tc, configParser);
129                 mNewPanes.add(pane);
130                 break;
131             }
132             eventType = configParser.next();
133         }
134         configParser.require(XmlPullParser.END_TAG, XmlPullParser.NO_NAMESPACE, mPaneXmlName);
135     }
136 
clearConfig()137     public void clearConfig() {
138         mNewPanes.clear();
139     }
140 
activateConfig()141     public void activateConfig() {
142         ArrayList<T> oldPanes = new ArrayList<T>(mPanes);
143         for (T pane : oldPanes) {
144             // This will call back to onRemoveRequested
145             pane.remove();
146         }
147 
148         for (T newPane : mNewPanes) {
149             addPane(newPane);
150         }
151         clearConfig();
152     }
153 
addPane(TestingCamera21 tc)154     public void addPane(TestingCamera21 tc) {
155         T newPane = createControlPane(tc, null);
156         addPane(newPane);
157     }
158 
addPane(T newPane)159     private void addPane(T newPane) {
160         mPanes.add(newPane);
161         if (mPaneTracker != null) {
162             mPaneTracker.addPane(newPane);
163         }
164         addView(newPane);
165     }
166 
onRemoveRequested(ControlPane p)167     public void onRemoveRequested(ControlPane p) {
168         removeView(p);
169         if (mPaneTracker != null) {
170             mPaneTracker.removePane(p);
171         }
172         mPanes.remove(p);
173     }
174 
createControlPane(TestingCamera21 tc, AttributeSet attrs)175     protected abstract T createControlPane(TestingCamera21 tc, AttributeSet attrs);
176 
readControlPane(TestingCamera21 tc, XmlPullParser configParser)177     protected abstract T readControlPane(TestingCamera21 tc, XmlPullParser configParser)
178             throws XmlPullParserException, IOException;
179 
180     static class TargetPaneLayout extends PaneLayout<TargetControlPane> {
181         private static final String PANE_XML_NAME = "target_panes";
182 
TargetPaneLayout(Context context, AttributeSet attrs)183         public TargetPaneLayout(Context context, AttributeSet attrs) {
184             super(context, attrs, PANE_XML_NAME);
185         }
186 
createControlPane(TestingCamera21 tc, AttributeSet attrs)187         protected TargetControlPane createControlPane(TestingCamera21 tc, AttributeSet attrs) {
188             return new TargetControlPane(tc, attrs, this);
189         }
190 
readControlPane(TestingCamera21 tc, XmlPullParser configParser)191         protected TargetControlPane readControlPane(TestingCamera21 tc, XmlPullParser configParser)
192                 throws XmlPullParserException, IOException {
193             return new TargetControlPane(tc, configParser, this);
194         }
195     }
196 
197     static class CameraPaneLayout extends PaneLayout<CameraControlPane> {
198         private static final String PANE_XML_NAME = "camera_panes";
199 
CameraPaneLayout(Context context, AttributeSet attrs)200         public CameraPaneLayout(Context context, AttributeSet attrs) {
201             super(context, attrs, PANE_XML_NAME);
202         }
203 
createControlPane(TestingCamera21 tc, AttributeSet attrs)204         protected CameraControlPane createControlPane(TestingCamera21 tc, AttributeSet attrs) {
205             return new CameraControlPane(tc, attrs, this);
206         }
207 
readControlPane(TestingCamera21 tc, XmlPullParser configParser)208         protected CameraControlPane readControlPane(TestingCamera21 tc, XmlPullParser configParser)
209                 throws XmlPullParserException, IOException {
210             return new CameraControlPane(tc, configParser, this);
211         }
212     }
213 
214     static class RequestPaneLayout extends PaneLayout<RequestControlPane> {
215         private static final String PANE_XML_NAME = "request_panes";
216 
RequestPaneLayout(Context context, AttributeSet attrs)217         public RequestPaneLayout(Context context, AttributeSet attrs) {
218             super(context, attrs, PANE_XML_NAME);
219         }
220 
createControlPane(TestingCamera21 tc, AttributeSet attrs)221         protected RequestControlPane createControlPane(TestingCamera21 tc, AttributeSet attrs) {
222             return new RequestControlPane(tc, attrs, this);
223         }
224 
readControlPane(TestingCamera21 tc, XmlPullParser configParser)225         protected RequestControlPane readControlPane(TestingCamera21 tc, XmlPullParser configParser)
226                 throws XmlPullParserException, IOException {
227             return new RequestControlPane(tc, configParser, this);
228         }
229 
230     }
231 
232     static class BurstPaneLayout extends PaneLayout<BurstControlPane> {
233         private static final String PANE_XML_NAME = "burst_panes";
234 
BurstPaneLayout(Context context, AttributeSet attrs)235         public BurstPaneLayout(Context context, AttributeSet attrs) {
236             super(context, attrs, PANE_XML_NAME);
237         }
238 
createControlPane(TestingCamera21 tc, AttributeSet attrs)239         protected BurstControlPane createControlPane(TestingCamera21 tc, AttributeSet attrs) {
240             return new BurstControlPane(tc, attrs, this);
241         }
242 
readControlPane(TestingCamera21 tc, XmlPullParser configParser)243         protected BurstControlPane readControlPane(TestingCamera21 tc, XmlPullParser configParser)
244                 throws XmlPullParserException, IOException {
245             return new BurstControlPane(tc, configParser, this);
246         }
247     }
248 
249     static class UtilPaneLayout extends PaneLayout<UtilControlPane> {
250         private static final String PANE_XML_NAME = "util_panes";
251 
UtilPaneLayout(Context context, AttributeSet attrs)252         public UtilPaneLayout(Context context, AttributeSet attrs) {
253             super(context, attrs, PANE_XML_NAME);
254         }
255 
createControlPane(TestingCamera21 tc, AttributeSet attrs)256         public UtilControlPane createControlPane(TestingCamera21 tc, AttributeSet attrs) {
257             return new UtilControlPane(tc, attrs, this);
258         }
259 
readControlPane(TestingCamera21 tc, XmlPullParser configParser)260         protected UtilControlPane readControlPane(TestingCamera21 tc, XmlPullParser configParser)
261                 throws XmlPullParserException, IOException {
262             return new UtilControlPane(tc, configParser, this);
263         }
264     }
265 
266 }