blob: 4e9c550297c535ebc0b83f25fbd94150dd689ea8 [file] [log] [blame]
Fabian Kozynski8765d352020-04-06 21:16:02 -04001/*
2 * Copyright (C) 2020 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
17package com.android.systemui.controls.management
18
Fabian Kozynski8765d352020-04-06 21:16:02 -040019import android.content.ComponentName
20import android.content.Intent
21import android.os.Bundle
22import android.view.View
Matt Pietalf4b870b2020-04-17 17:11:36 -040023import android.view.ViewGroup
Fabian Kozynski8765d352020-04-06 21:16:02 -040024import android.view.ViewStub
25import android.widget.Button
26import android.widget.TextView
27import androidx.recyclerview.widget.GridLayoutManager
28import androidx.recyclerview.widget.ItemTouchHelper
29import androidx.recyclerview.widget.RecyclerView
30import com.android.systemui.R
31import com.android.systemui.broadcast.BroadcastDispatcher
32import com.android.systemui.controls.controller.ControlsControllerImpl
33import com.android.systemui.controls.controller.StructureInfo
Matt Pietald8a6ca62020-04-21 15:00:15 -040034import com.android.systemui.globalactions.GlobalActionsComponent
Fabian Kozynski8765d352020-04-06 21:16:02 -040035import com.android.systemui.settings.CurrentUserTracker
Matt Pietalf4b870b2020-04-17 17:11:36 -040036import com.android.systemui.util.LifecycleActivity
Fabian Kozynski8765d352020-04-06 21:16:02 -040037import javax.inject.Inject
38
39/**
40 * Activity for rearranging and removing controls for a given structure
41 */
42class ControlsEditingActivity @Inject constructor(
43 private val controller: ControlsControllerImpl,
Matt Pietald8a6ca62020-04-21 15:00:15 -040044 broadcastDispatcher: BroadcastDispatcher,
45 private val globalActionsComponent: GlobalActionsComponent
Matt Pietalf4b870b2020-04-17 17:11:36 -040046) : LifecycleActivity() {
Fabian Kozynski8765d352020-04-06 21:16:02 -040047
48 companion object {
49 private const val TAG = "ControlsEditingActivity"
50 private const val EXTRA_STRUCTURE = ControlsFavoritingActivity.EXTRA_STRUCTURE
51 private val SUBTITLE_ID = R.string.controls_favorite_rearrange
52 private val EMPTY_TEXT_ID = R.string.controls_favorite_removed
53 }
54
55 private lateinit var component: ComponentName
56 private lateinit var structure: CharSequence
57 private lateinit var model: FavoritesModel
58 private lateinit var subtitle: TextView
59 private lateinit var saveButton: View
60
61 private val currentUserTracker = object : CurrentUserTracker(broadcastDispatcher) {
62 private val startingUser = controller.currentUserId
63
64 override fun onUserSwitched(newUserId: Int) {
65 if (newUserId != startingUser) {
66 stopTracking()
67 finish()
68 }
69 }
70 }
71
Fabian Kozynski8765d352020-04-06 21:16:02 -040072 override fun onCreate(savedInstanceState: Bundle?) {
73 super.onCreate(savedInstanceState)
74
75 intent.getParcelableExtra<ComponentName>(Intent.EXTRA_COMPONENT_NAME)?.let {
76 component = it
77 } ?: run(this::finish)
78
79 intent.getCharSequenceExtra(EXTRA_STRUCTURE)?.let {
80 structure = it
81 } ?: run(this::finish)
82
83 bindViews()
84
85 bindButtons()
Matt Pietald8a6ca62020-04-21 15:00:15 -040086 }
Fabian Kozynski8765d352020-04-06 21:16:02 -040087
Matt Pietald8a6ca62020-04-21 15:00:15 -040088 override fun onStart() {
89 super.onStart()
Fabian Kozynski8765d352020-04-06 21:16:02 -040090 setUpList()
91
92 currentUserTracker.startTracking()
93 }
94
Matt Pietald8a6ca62020-04-21 15:00:15 -040095 override fun onStop() {
96 super.onStop()
97 currentUserTracker.stopTracking()
98 }
99
Fabian Kozynski5f561f02020-04-27 13:38:55 -0400100 override fun onBackPressed() {
101 globalActionsComponent.handleShowGlobalActionsMenu()
102 animateExitAndFinish()
103 }
104
105 private fun animateExitAndFinish() {
106 val rootView = requireViewById<ViewGroup>(R.id.controls_management_root)
107 ControlsAnimations.exitAnimation(
108 rootView,
109 object : Runnable {
110 override fun run() {
111 finish()
112 }
113 }
114 ).start()
115 }
116
Fabian Kozynski8765d352020-04-06 21:16:02 -0400117 private fun bindViews() {
118 setContentView(R.layout.controls_management)
Matt Pietalf4b870b2020-04-17 17:11:36 -0400119
120 getLifecycle().addObserver(
121 ControlsAnimations.observerForAnimations(
122 requireViewById<ViewGroup>(R.id.controls_management_root),
123 window,
124 intent
125 )
126 )
127
Fabian Kozynski8765d352020-04-06 21:16:02 -0400128 requireViewById<ViewStub>(R.id.stub).apply {
129 layoutResource = R.layout.controls_management_editing
130 inflate()
131 }
132 requireViewById<TextView>(R.id.title).text = structure
133 subtitle = requireViewById<TextView>(R.id.subtitle).apply {
134 setText(SUBTITLE_ID)
135 }
136 }
137
138 private fun bindButtons() {
Matt Pietald8a6ca62020-04-21 15:00:15 -0400139 val rootView = requireViewById<ViewGroup>(R.id.controls_management_root)
Fabian Kozynski8765d352020-04-06 21:16:02 -0400140 saveButton = requireViewById<Button>(R.id.done).apply {
141 isEnabled = false
142 setText(R.string.save)
143 setOnClickListener {
144 saveFavorites()
Fabian Kozynski5f561f02020-04-27 13:38:55 -0400145 animateExitAndFinish()
Matt Pietald8a6ca62020-04-21 15:00:15 -0400146 globalActionsComponent.handleShowGlobalActionsMenu()
Fabian Kozynski8765d352020-04-06 21:16:02 -0400147 }
148 }
149 }
150
151 private fun saveFavorites() {
152 controller.replaceFavoritesForStructure(
153 StructureInfo(component, structure, model.favorites))
154 }
155
156 private val favoritesModelCallback = object : FavoritesModel.FavoritesModelCallback {
157 override fun onNoneChanged(showNoFavorites: Boolean) {
158 if (showNoFavorites) {
159 subtitle.setText(EMPTY_TEXT_ID)
160 } else {
161 subtitle.setText(SUBTITLE_ID)
162 }
163 }
164
165 override fun onFirstChange() {
166 saveButton.isEnabled = true
167 }
168 }
169
170 private fun setUpList() {
171 val controls = controller.getFavoritesForStructure(component, structure)
172 model = FavoritesModel(component, controls, favoritesModelCallback)
173 val elevation = resources.getFloat(R.dimen.control_card_elevation)
Matt Pietalf4b870b2020-04-17 17:11:36 -0400174 val recyclerView = requireViewById<RecyclerView>(R.id.list)
175 recyclerView.alpha = 0.0f
176 val adapter = ControlAdapter(elevation).apply {
177 registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() {
178 var hasAnimated = false
179 override fun onChanged() {
180 if (!hasAnimated) {
181 hasAnimated = true
182 ControlsAnimations.enterAnimation(recyclerView).start()
183 }
184 }
185 })
186 }
187
Fabian Kozynski8765d352020-04-06 21:16:02 -0400188 val margin = resources
189 .getDimensionPixelSize(R.dimen.controls_card_margin)
190 val itemDecorator = MarginItemDecorator(margin, margin)
191
Matt Pietalf4b870b2020-04-17 17:11:36 -0400192 recyclerView.apply {
Fabian Kozynski8765d352020-04-06 21:16:02 -0400193 this.adapter = adapter
Matt Pietalf4b870b2020-04-17 17:11:36 -0400194 layoutManager = GridLayoutManager(recyclerView.context, 2).apply {
Fabian Kozynski8765d352020-04-06 21:16:02 -0400195 spanSizeLookup = adapter.spanSizeLookup
196 }
197 addItemDecoration(itemDecorator)
198 }
199 adapter.changeModel(model)
200 model.attachAdapter(adapter)
Matt Pietalf4b870b2020-04-17 17:11:36 -0400201 ItemTouchHelper(model.itemTouchHelperCallback).attachToRecyclerView(recyclerView)
Fabian Kozynski8765d352020-04-06 21:16:02 -0400202 }
203
204 override fun onDestroy() {
205 currentUserTracker.stopTracking()
206 super.onDestroy()
207 }
Matt Pietalf4b870b2020-04-17 17:11:36 -0400208}