blob: 21c182c191418336c8953bc60aeb5264ca0ce2ad [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;
Garfield, Tan61f564b2016-08-16 13:36:15 -070024import android.widget.ImageView;
25import android.widget.PopupMenu;
26import android.widget.TextView;
27
28import com.android.documentsui.R;
29import com.android.documentsui.sorting.SortController.WidgetController;
Garfield, Tan61f564b2016-08-16 13:36:15 -070030import com.android.documentsui.sorting.SortDimension.SortDirection;
Garfield, Tan61f564b2016-08-16 13:36:15 -070031import com.android.documentsui.sorting.SortModel.SortDimensionId;
Garfield, Tan61f564b2016-08-16 13:36:15 -070032import com.android.documentsui.sorting.SortModel.UpdateType;
33
34/**
35 * View controller for the sort widget in grid mode and in small screens.
36 */
37public final class DropdownSortWidgetController implements WidgetController {
38
39 private static final int LEVEL_UPWARD = 0;
40 private static final int LEVEL_DOWNWARD = 10000;
41
Steve McKay9de0da62016-08-25 15:18:23 -070042 private final SortModel mModel;
Garfield, Tan61f564b2016-08-16 13:36:15 -070043 private final View mWidget;
44 private final TextView mDimensionButton;
45 private final PopupMenu mMenu;
46 private final ImageView mArrow;
47
Steve McKay9de0da62016-08-25 15:18:23 -070048 public DropdownSortWidgetController(SortModel model, View widget) {
49 mModel = model;
Garfield, Tan61f564b2016-08-16 13:36:15 -070050 mWidget = widget;
51
52 mDimensionButton = (TextView) mWidget.findViewById(R.id.sort_dimen_dropdown);
Garfield Tanfe199cb2016-10-03 11:46:10 -070053 mDimensionButton.setOnClickListener(this::showMenu);
54
Garfield, Tan61f564b2016-08-16 13:36:15 -070055 mMenu = new PopupMenu(widget.getContext(), mDimensionButton, Gravity.END | Gravity.TOP);
56 mMenu.setOnMenuItemClickListener(this::onSelectDimension);
57
58 mArrow = (ImageView) mWidget.findViewById(R.id.sort_arrow);
Garfield Tanfe199cb2016-10-03 11:46:10 -070059 mArrow.setOnClickListener(this::onChangeDirection);
Garfield, Tan61f564b2016-08-16 13:36:15 -070060
Steve McKay9de0da62016-08-25 15:18:23 -070061 populateMenuItems();
62 onModelUpdate(mModel, SortModel.UPDATE_TYPE_UNSPECIFIED);
Garfield, Tan61f564b2016-08-16 13:36:15 -070063
Garfield Tanfe199cb2016-10-03 11:46:10 -070064 mModel.addListener(this::onModelUpdate);
Garfield, Tan61f564b2016-08-16 13:36:15 -070065 }
66
67 @Override
68 public void setVisibility(int visibility) {
69 mWidget.setVisibility(visibility);
70 }
71
72 private void populateMenuItems() {
73 Menu menu = mMenu.getMenu();
74 menu.clear();
75 for (int i = 0; i < mModel.getSize(); ++i) {
76 SortDimension dimension = mModel.getDimensionAt(i);
77 if (dimension.getSortCapability() != SortDimension.SORT_CAPABILITY_NONE) {
78 menu.add(0, dimension.getId(), Menu.NONE, dimension.getLabelId());
79 }
80 }
81 }
82
83 private void showMenu(View v) {
84 mMenu.show();
85 }
86
87 private void onModelUpdate(SortModel model, @UpdateType int updateType) {
88 final @SortDimensionId int sortedId = model.getSortedDimensionId();
89
Garfield, Tan61f564b2016-08-16 13:36:15 -070090 if ((updateType & SortModel.UPDATE_TYPE_VISIBILITY) != 0) {
91 updateVisibility();
92 }
93
94 if ((updateType & SortModel.UPDATE_TYPE_SORTING) != 0) {
95 bindSortedDimension(sortedId);
96 bindSortDirection(sortedId);
97 }
98 }
99
Garfield, Tan61f564b2016-08-16 13:36:15 -0700100 private void updateVisibility() {
101 Menu menu = mMenu.getMenu();
102
103 for (int i = 0; i < menu.size(); ++i) {
104 MenuItem item = menu.getItem(i);
105 SortDimension dimension = mModel.getDimensionById(item.getItemId());
106 item.setVisible(dimension.getVisibility() == View.VISIBLE);
107 }
108 }
109
110 private void bindSortedDimension(@SortDimensionId int sortedId) {
111 if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
112 mDimensionButton.setText(R.string.not_sorted);
113 } else {
114 SortDimension dimension = mModel.getDimensionById(sortedId);
115 mDimensionButton.setText(dimension.getLabelId());
116 }
117 }
118
119 private void bindSortDirection(@SortDimensionId int sortedId) {
120 if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
121 mArrow.setVisibility(View.INVISIBLE);
122 } else {
123 final SortDimension dimension = mModel.getDimensionById(sortedId);
124 switch (dimension.getSortDirection()) {
125 case SortDimension.SORT_DIRECTION_NONE:
126 mArrow.setVisibility(View.INVISIBLE);
127 break;
128 case SortDimension.SORT_DIRECTION_ASCENDING:
129 showArrow(LEVEL_UPWARD, R.string.sort_direction_ascending);
130 break;
131 case SortDimension.SORT_DIRECTION_DESCENDING:
132 showArrow(LEVEL_DOWNWARD, R.string.sort_direction_descending);
133 break;
134 default:
135 throw new IllegalStateException(
136 "Unknown sort direction: " + dimension.getSortDirection() + ".");
137 }
138 }
139 }
140
141 private void showArrow(int level, @StringRes int descriptionId) {
142 mArrow.setVisibility(View.VISIBLE);
143
144 mArrow.getDrawable().mutate();
145 mArrow.setImageLevel(level);
146 mArrow.setContentDescription(mArrow.getContext().getString(descriptionId));
147 }
148
149 private boolean onSelectDimension(MenuItem item) {
150 final @SortDirection int preferredDirection = mModel.getCurrentSortDirection();
151
152 final SortDimension dimension = mModel.getDimensionById(item.getItemId());
153 final @SortDirection int direction;
154 if ((dimension.getSortCapability() & preferredDirection) > 0) {
155 direction = preferredDirection;
156 } else {
157 direction = dimension.getDefaultSortDirection();
158 }
159
160 mModel.sortByUser(dimension.getId(), direction);
161
162 return true;
163 }
164
165 private void onChangeDirection(View v) {
166 final @SortDimensionId int id = mModel.getSortedDimensionId();
167 assert(id != SortModel.SORT_DIMENSION_ID_UNKNOWN);
168
169 final SortDimension dimension = mModel.getDimensionById(id);
170 mModel.sortByUser(dimension.getId(), dimension.getNextDirection());
171 }
172}