blob: 79775919b05152d8d4e750a89d059239ccea2397 [file] [log] [blame]
Garfield, Tan61f564b2016-08-16 13:36:15 -07001/*
2 * Copyright (C) 2016 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
Steve McKayb70665f2016-09-06 15:35:19 -070017package com.android.documentsui.sorting;
Garfield, Tan61f564b2016-08-16 13:36:15 -070018
Garfield, Tan61f564b2016-08-16 13:36:15 -070019import android.annotation.StringRes;
20import android.view.Gravity;
21import android.view.Menu;
22import android.view.MenuItem;
23import android.view.View;
24import android.view.View.OnClickListener;
25import android.widget.ImageView;
26import android.widget.PopupMenu;
27import android.widget.TextView;
28
29import com.android.documentsui.R;
30import com.android.documentsui.sorting.SortController.WidgetController;
31import com.android.documentsui.sorting.SortDimension;
32import com.android.documentsui.sorting.SortDimension.SortDirection;
33import com.android.documentsui.sorting.SortModel;
34import com.android.documentsui.sorting.SortModel.SortDimensionId;
35import com.android.documentsui.sorting.SortModel.UpdateListener;
36import com.android.documentsui.sorting.SortModel.UpdateType;
37
38/**
39 * View controller for the sort widget in grid mode and in small screens.
40 */
41public final class DropdownSortWidgetController implements WidgetController {
42
43 private static final int LEVEL_UPWARD = 0;
44 private static final int LEVEL_DOWNWARD = 10000;
45
Steve McKay9de0da62016-08-25 15:18:23 -070046 private final SortModel mModel;
Garfield, Tan61f564b2016-08-16 13:36:15 -070047 private final View mWidget;
48 private final TextView mDimensionButton;
49 private final PopupMenu mMenu;
50 private final ImageView mArrow;
51
52 private final OnClickListener mDimensionButtonClickListener = this::showMenu;
53 private final OnClickListener mArrowClickListener = this::onChangeDirection;
54 private final UpdateListener mUpdateListener = this::onModelUpdate;
55
Steve McKay9de0da62016-08-25 15:18:23 -070056 public DropdownSortWidgetController(SortModel model, View widget) {
57 mModel = model;
Garfield, Tan61f564b2016-08-16 13:36:15 -070058 mWidget = widget;
59
60 mDimensionButton = (TextView) mWidget.findViewById(R.id.sort_dimen_dropdown);
61 mMenu = new PopupMenu(widget.getContext(), mDimensionButton, Gravity.END | Gravity.TOP);
62 mMenu.setOnMenuItemClickListener(this::onSelectDimension);
63
64 mArrow = (ImageView) mWidget.findViewById(R.id.sort_arrow);
Garfield, Tan61f564b2016-08-16 13:36:15 -070065
Steve McKay9de0da62016-08-25 15:18:23 -070066 populateMenuItems();
67 onModelUpdate(mModel, SortModel.UPDATE_TYPE_UNSPECIFIED);
Garfield, Tan61f564b2016-08-16 13:36:15 -070068
Steve McKay9de0da62016-08-25 15:18:23 -070069 mModel.addListener(mUpdateListener);
Garfield, Tan61f564b2016-08-16 13:36:15 -070070 }
71
72 @Override
73 public void setVisibility(int visibility) {
74 mWidget.setVisibility(visibility);
75 }
76
77 private void populateMenuItems() {
78 Menu menu = mMenu.getMenu();
79 menu.clear();
80 for (int i = 0; i < mModel.getSize(); ++i) {
81 SortDimension dimension = mModel.getDimensionAt(i);
82 if (dimension.getSortCapability() != SortDimension.SORT_CAPABILITY_NONE) {
83 menu.add(0, dimension.getId(), Menu.NONE, dimension.getLabelId());
84 }
85 }
86 }
87
88 private void showMenu(View v) {
89 mMenu.show();
90 }
91
92 private void onModelUpdate(SortModel model, @UpdateType int updateType) {
93 final @SortDimensionId int sortedId = model.getSortedDimensionId();
94
95 if ((updateType & SortModel.UPDATE_TYPE_STATUS) != 0) {
96 setEnabled(mModel.isSortEnabled());
97 }
98
99 if ((updateType & SortModel.UPDATE_TYPE_VISIBILITY) != 0) {
100 updateVisibility();
101 }
102
103 if ((updateType & SortModel.UPDATE_TYPE_SORTING) != 0) {
104 bindSortedDimension(sortedId);
105 bindSortDirection(sortedId);
106 }
107 }
108
109 private void setEnabled(boolean enabled) {
110 if (enabled) {
111 mDimensionButton.setOnClickListener(mDimensionButtonClickListener);
112 mArrow.setOnClickListener(mArrowClickListener);
113 } else {
114 mMenu.dismiss();
115 mDimensionButton.setOnClickListener(null);
116 mArrow.setOnClickListener(null);
117 }
118 }
119
120 private void updateVisibility() {
121 Menu menu = mMenu.getMenu();
122
123 for (int i = 0; i < menu.size(); ++i) {
124 MenuItem item = menu.getItem(i);
125 SortDimension dimension = mModel.getDimensionById(item.getItemId());
126 item.setVisible(dimension.getVisibility() == View.VISIBLE);
127 }
128 }
129
130 private void bindSortedDimension(@SortDimensionId int sortedId) {
131 if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
132 mDimensionButton.setText(R.string.not_sorted);
133 } else {
134 SortDimension dimension = mModel.getDimensionById(sortedId);
135 mDimensionButton.setText(dimension.getLabelId());
136 }
137 }
138
139 private void bindSortDirection(@SortDimensionId int sortedId) {
140 if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
141 mArrow.setVisibility(View.INVISIBLE);
142 } else {
143 final SortDimension dimension = mModel.getDimensionById(sortedId);
144 switch (dimension.getSortDirection()) {
145 case SortDimension.SORT_DIRECTION_NONE:
146 mArrow.setVisibility(View.INVISIBLE);
147 break;
148 case SortDimension.SORT_DIRECTION_ASCENDING:
149 showArrow(LEVEL_UPWARD, R.string.sort_direction_ascending);
150 break;
151 case SortDimension.SORT_DIRECTION_DESCENDING:
152 showArrow(LEVEL_DOWNWARD, R.string.sort_direction_descending);
153 break;
154 default:
155 throw new IllegalStateException(
156 "Unknown sort direction: " + dimension.getSortDirection() + ".");
157 }
158 }
159 }
160
161 private void showArrow(int level, @StringRes int descriptionId) {
162 mArrow.setVisibility(View.VISIBLE);
163
164 mArrow.getDrawable().mutate();
165 mArrow.setImageLevel(level);
166 mArrow.setContentDescription(mArrow.getContext().getString(descriptionId));
167 }
168
169 private boolean onSelectDimension(MenuItem item) {
170 final @SortDirection int preferredDirection = mModel.getCurrentSortDirection();
171
172 final SortDimension dimension = mModel.getDimensionById(item.getItemId());
173 final @SortDirection int direction;
174 if ((dimension.getSortCapability() & preferredDirection) > 0) {
175 direction = preferredDirection;
176 } else {
177 direction = dimension.getDefaultSortDirection();
178 }
179
180 mModel.sortByUser(dimension.getId(), direction);
181
182 return true;
183 }
184
185 private void onChangeDirection(View v) {
186 final @SortDimensionId int id = mModel.getSortedDimensionId();
187 assert(id != SortModel.SORT_DIMENSION_ID_UNKNOWN);
188
189 final SortDimension dimension = mModel.getDimensionById(id);
190 mModel.sortByUser(dimension.getId(), dimension.getNextDirection());
191 }
192}