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