blob: 489e18452909585a5c4c0f57bc5bf2c822d71dd7 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.documentsui.sorting;
import android.annotation.StringRes;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import com.android.documentsui.R;
import com.android.documentsui.sorting.SortController.WidgetController;
import com.android.documentsui.sorting.SortDimension.SortDirection;
import com.android.documentsui.sorting.SortModel.SortDimensionId;
import com.android.documentsui.sorting.SortModel.UpdateType;
/**
* View controller for the sort widget in grid mode and in small screens.
*/
public final class DropdownSortWidgetController implements WidgetController {
private static final int LEVEL_UPWARD = 0;
private static final int LEVEL_DOWNWARD = 10000;
private final SortModel mModel;
private final View mWidget;
private final TextView mDimensionButton;
private final PopupMenu mMenu;
private final ImageView mArrow;
private final SortModel.UpdateListener mListener;
public DropdownSortWidgetController(SortModel model, View widget) {
mModel = model;
mWidget = widget;
mDimensionButton = (TextView) mWidget.findViewById(R.id.sort_dimen_dropdown);
mDimensionButton.setOnClickListener(this::showMenu);
mMenu = new PopupMenu(widget.getContext(), mDimensionButton, Gravity.END | Gravity.TOP);
mMenu.setOnMenuItemClickListener(this::onSelectDimension);
mArrow = (ImageView) mWidget.findViewById(R.id.sort_arrow);
mArrow.setOnClickListener(this::onChangeDirection);
populateMenuItems();
onModelUpdate(mModel, SortModel.UPDATE_TYPE_UNSPECIFIED);
mListener = this::onModelUpdate;
mModel.addListener(mListener);
}
@Override
public void setVisibility(int visibility) {
mWidget.setVisibility(visibility);
}
@Override
public void destroy() {
mModel.removeListener(mListener);
}
private void populateMenuItems() {
Menu menu = mMenu.getMenu();
menu.clear();
for (int i = 0; i < mModel.getSize(); ++i) {
SortDimension dimension = mModel.getDimensionAt(i);
if (dimension.getSortCapability() != SortDimension.SORT_CAPABILITY_NONE) {
menu.add(0, dimension.getId(), Menu.NONE, dimension.getLabelId());
}
}
}
private void showMenu(View v) {
mMenu.show();
}
private void onModelUpdate(SortModel model, @UpdateType int updateType) {
final @SortDimensionId int sortedId = model.getSortedDimensionId();
if ((updateType & SortModel.UPDATE_TYPE_VISIBILITY) != 0) {
updateVisibility();
}
if ((updateType & SortModel.UPDATE_TYPE_SORTING) != 0) {
bindSortedDimension(sortedId);
bindSortDirection(sortedId);
}
}
private void updateVisibility() {
Menu menu = mMenu.getMenu();
for (int i = 0; i < menu.size(); ++i) {
MenuItem item = menu.getItem(i);
SortDimension dimension = mModel.getDimensionById(item.getItemId());
item.setVisible(dimension.getVisibility() == View.VISIBLE);
}
}
private void bindSortedDimension(@SortDimensionId int sortedId) {
if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
mDimensionButton.setText(R.string.not_sorted);
} else {
SortDimension dimension = mModel.getDimensionById(sortedId);
mDimensionButton.setText(dimension.getLabelId());
}
}
private void bindSortDirection(@SortDimensionId int sortedId) {
if (sortedId == SortModel.SORT_DIMENSION_ID_UNKNOWN) {
mArrow.setVisibility(View.INVISIBLE);
} else {
final SortDimension dimension = mModel.getDimensionById(sortedId);
switch (dimension.getSortDirection()) {
case SortDimension.SORT_DIRECTION_NONE:
mArrow.setVisibility(View.INVISIBLE);
break;
case SortDimension.SORT_DIRECTION_ASCENDING:
showArrow(LEVEL_UPWARD, R.string.sort_direction_ascending);
break;
case SortDimension.SORT_DIRECTION_DESCENDING:
showArrow(LEVEL_DOWNWARD, R.string.sort_direction_descending);
break;
default:
throw new IllegalStateException(
"Unknown sort direction: " + dimension.getSortDirection() + ".");
}
}
}
private void showArrow(int level, @StringRes int descriptionId) {
mArrow.setVisibility(View.VISIBLE);
mArrow.getDrawable().mutate();
mArrow.setImageLevel(level);
mArrow.setContentDescription(mArrow.getContext().getString(descriptionId));
}
private boolean onSelectDimension(MenuItem item) {
final @SortDirection int preferredDirection = mModel.getCurrentSortDirection();
final SortDimension dimension = mModel.getDimensionById(item.getItemId());
final @SortDirection int direction;
if ((dimension.getSortCapability() & preferredDirection) > 0) {
direction = preferredDirection;
} else {
direction = dimension.getDefaultSortDirection();
}
mModel.sortByUser(dimension.getId(), direction);
return true;
}
private void onChangeDirection(View v) {
final @SortDimensionId int id = mModel.getSortedDimensionId();
assert(id != SortModel.SORT_DIMENSION_ID_UNKNOWN);
final SortDimension dimension = mModel.getDimensionById(id);
mModel.sortByUser(dimension.getId(), dimension.getNextDirection());
}
}