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 }