QSCustomizer.java revision b9c00197021ae0bf1172a1e332e047e30d3e4afa
1/* 2 * Copyright (C) 2015 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 */ 16package com.android.systemui.qs.customize; 17 18import android.animation.Animator; 19import android.content.ClipData; 20import android.content.Context; 21import android.util.AttributeSet; 22import android.util.TypedValue; 23import android.view.*; 24import android.view.View.OnClickListener; 25import android.widget.LinearLayout; 26import android.widget.Toolbar; 27import android.widget.Toolbar.OnMenuItemClickListener; 28import com.android.systemui.R; 29import com.android.systemui.SystemUIApplication; 30import com.android.systemui.qs.QSDetailClipper; 31import com.android.systemui.qs.QSTile.Host.Callback; 32import com.android.systemui.qs.customize.DropButton.OnDropListener; 33import com.android.systemui.statusbar.phone.PhoneStatusBar; 34import com.android.systemui.statusbar.phone.QSTileHost; 35import com.android.systemui.statusbar.phone.SystemUIDialog; 36import com.android.systemui.tuner.QSPagingSwitch; 37 38import java.util.ArrayList; 39 40/** 41 * Allows full-screen customization of QS, through show() and hide(). 42 * 43 * This adds itself to the status bar window, so it can appear on top of quick settings and 44 * *someday* do fancy animations to get into/out of it. 45 */ 46public class QSCustomizer extends LinearLayout implements OnMenuItemClickListener, Callback, 47 OnDropListener, OnClickListener, Animator.AnimatorListener { 48 49 private static final int MENU_SAVE = Menu.FIRST; 50 private static final int MENU_RESET = Menu.FIRST + 1; 51 private final QSDetailClipper mClipper; 52 53 private PhoneStatusBar mPhoneStatusBar; 54 55 private Toolbar mToolbar; 56 private ViewGroup mDragButtons; 57 private CustomQSPanel mQsPanel; 58 59 private boolean isShown; 60 private CustomQSTileHost mHost; 61 private DropButton mInfoButton; 62 private DropButton mRemoveButton; 63 private FloatingActionButton mFab; 64 65 public QSCustomizer(Context context, AttributeSet attrs) { 66 super(new ContextThemeWrapper(context, android.R.style.Theme_Material), attrs); 67 mPhoneStatusBar = ((SystemUIApplication) mContext.getApplicationContext()) 68 .getComponent(PhoneStatusBar.class); 69 mClipper = new QSDetailClipper(this); 70 } 71 72 public void setHost(QSTileHost host) { 73 mHost = new CustomQSTileHost(mContext, host); 74 mHost.setCallback(this); 75 mQsPanel.setTiles(mHost.getTiles()); 76 mQsPanel.setHost(mHost); 77 mHost.setSavedTiles(); 78 } 79 80 @Override 81 protected void onFinishInflate() { 82 super.onFinishInflate(); 83 mToolbar = (Toolbar) findViewById(com.android.internal.R.id.action_bar); 84 TypedValue value = new TypedValue(); 85 mContext.getTheme().resolveAttribute(android.R.attr.homeAsUpIndicator, value, true); 86 mToolbar.setNavigationIcon( 87 getResources().getDrawable(value.resourceId, mContext.getTheme())); 88 mToolbar.setNavigationOnClickListener(new OnClickListener() { 89 @Override 90 public void onClick(View v) { 91 hide(0, 0); 92 } 93 }); 94 mToolbar.setOnMenuItemClickListener(this); 95 mToolbar.getMenu().add(Menu.NONE, MENU_SAVE, 0, mContext.getString(R.string.save)) 96 .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 97 mToolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, 98 mContext.getString(com.android.internal.R.string.reset)); 99 100 mQsPanel = (CustomQSPanel) findViewById(R.id.quick_settings_panel); 101 102 mDragButtons = (ViewGroup) findViewById(R.id.drag_buttons); 103 setDragging(false); 104 105 mInfoButton = (DropButton) findViewById(R.id.info_button); 106 mInfoButton.setOnDropListener(this); 107 mRemoveButton = (DropButton) findViewById(R.id.remove_button); 108 mRemoveButton.setOnDropListener(this); 109 110 mFab = (FloatingActionButton) findViewById(R.id.fab); 111 mFab.setImageResource(R.drawable.ic_add); 112 mFab.setOnClickListener(this); 113 } 114 115 public void show(int x, int y) { 116 isShown = true; 117 mHost.setSavedTiles(); 118 mPhoneStatusBar.getStatusBarWindow().addView(this); 119 mQsPanel.setListening(true); 120 mClipper.animateCircularClip(x, y, true, this); 121 } 122 123 public void hide(int x, int y) { 124 isShown = false; 125 mQsPanel.setListening(false); 126 mClipper.animateCircularClip(x, y, false, this); 127 } 128 129 public boolean isCustomizing() { 130 return isShown; 131 } 132 133 private void reset() { 134 ArrayList<String> tiles = new ArrayList<>(); 135 for (String tile : QSPagingSwitch.QS_PAGE_TILES.split(",")) { 136 tiles.add(tile); 137 } 138 mHost.setTiles(tiles); 139 } 140 141 private void setDragging(boolean dragging) { 142 mToolbar.setVisibility(!dragging ? View.VISIBLE : View.INVISIBLE); 143 } 144 145 private void save() { 146 mHost.saveCurrentTiles(); 147 // TODO: At save button. 148 hide(0, 0); 149 } 150 151 @Override 152 public boolean onMenuItemClick(MenuItem item) { 153 switch (item.getItemId()) { 154 case MENU_SAVE: 155 save(); 156 break; 157 case MENU_RESET: 158 reset(); 159 break; 160 } 161 return true; 162 } 163 164 @Override 165 public void onTilesChanged() { 166 mQsPanel.setTiles(mHost.getTiles()); 167 } 168 169 public boolean onDragEvent(DragEvent event) { 170 switch (event.getAction()) { 171 case DragEvent.ACTION_DRAG_STARTED: 172 setDragging(true); 173 break; 174 case DragEvent.ACTION_DRAG_ENDED: 175 setDragging(false); 176 break; 177 } 178 return true; 179 } 180 181 public void onDrop(View v, ClipData data) { 182 if (v == mRemoveButton) { 183 mHost.remove(mQsPanel.getSpec(data)); 184 } else if (v == mInfoButton) { 185 mHost.unstashTiles(); 186 SystemUIDialog dialog = new SystemUIDialog(mContext); 187 dialog.setTitle(mQsPanel.getSpec(data)); 188 dialog.setPositiveButton(R.string.ok, null); 189 dialog.show(); 190 } 191 } 192 193 @Override 194 public void onClick(View v) { 195 if (mFab == v) { 196 // TODO: Show list of tiles. 197 } 198 } 199 200 @Override 201 public void onAnimationEnd(Animator animation) { 202 if (!isShown) { 203 mPhoneStatusBar.getStatusBarWindow().removeView(this); 204 } 205 } 206 207 @Override 208 public void onAnimationCancel(Animator animation) { 209 if (!isShown) { 210 mPhoneStatusBar.getStatusBarWindow().removeView(this); 211 } 212 } 213 214 @Override 215 public void onAnimationStart(Animator animation) { 216 // Don't care. 217 } 218 219 @Override 220 public void onAnimationRepeat(Animator animation) { 221 // Don't care. 222 } 223}