Skip to content

Commit

Permalink
Add AdaptiveActionsToolbar for better context bar controls.
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-signal committed Feb 5, 2020
1 parent ecf7a41 commit 7c729c2
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.concurrent.SimpleTask;
import org.thoughtcrime.securesms.util.task.ProgressDialogAsyncTask;
import org.thoughtcrime.securesms.util.views.AdaptiveActionsToolbar;
import org.whispersystems.libsignal.util.guava.Optional;

import java.io.IOException;
Expand Down Expand Up @@ -1211,6 +1212,7 @@ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
}

setCorrectMenuVisibility(menu);
AdaptiveActionsToolbar.adjustMenuActions(menu, 10, requireActivity().getWindow().getDecorView().getMeasuredWidth());
listener.onMessageActionToolbarOpened();
return true;
}
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/org/thoughtcrime/securesms/util/ViewUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.interpolator.view.animation.FastOutSlowInInterpolator;

import android.util.TypedValue;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
Expand Down Expand Up @@ -203,6 +205,14 @@ public static int dpToPx(int dp) {
return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
}

public static int dpToSp(int dp) {
return (int) (dpToPx(dp) / Resources.getSystem().getDisplayMetrics().scaledDensity);
}

public static int spToPx(float sp) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, Resources.getSystem().getDisplayMetrics());
}

public static void updateLayoutParams(@NonNull View view, int width, int height) {
view.getLayoutParams().width = width;
view.getLayoutParams().height = height;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package org.thoughtcrime.securesms.util.views;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Menu;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;

import org.thoughtcrime.securesms.R;
import org.thoughtcrime.securesms.util.ViewUtil;

/**
* AdaptiveActionsToolbar behaves like a normal {@link Toolbar} except in that it ignores the
* showAsAlways attributes of menu items added via menu inflation, opting for an adaptive algorithm
* instead. This algorithm will display as many icons as it can up to a specific percentage of the
* screen.
*
* Each ActionView icon is expected to occupy 48dp of space, including padding. Items are stacked one
* after the next with no margins.
*
* This view can be customized via attributes:
*
* aat_max_shown -- controls the max number of items to display.
* aat_percent_for_actions -- controls the max percent of screen width the buttons can occupy.
*/
public class AdaptiveActionsToolbar extends Toolbar {

private static final int NAVIGATION_SP = 48;
private static final int ACTION_VIEW_WIDTH_SP = 42;
private static final int OVERFLOW_VIEW_WIDTH_SP = 35;

private int maxShown;

public AdaptiveActionsToolbar(@NonNull Context context) {
this(context, null);
}

public AdaptiveActionsToolbar(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, R.attr.toolbarStyle);
}

public AdaptiveActionsToolbar(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);

TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.AdaptiveActionsToolbar);

maxShown = array.getInteger(R.styleable.AdaptiveActionsToolbar_aat_max_shown, 100);

array.recycle();
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
adjustMenuActions(getMenu(), maxShown, getMeasuredWidth());
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

public static void adjustMenuActions(@NonNull Menu menu, int maxToShow, int toolbarWidthPx) {
int menuSize = menu.size();

int widthAllowed = toolbarWidthPx - ViewUtil.spToPx(NAVIGATION_SP);
int nItemsToShow = Math.min(maxToShow, Math.round(widthAllowed / ViewUtil.spToPx(ACTION_VIEW_WIDTH_SP)));

if (nItemsToShow < menuSize) {
widthAllowed -= ViewUtil.spToPx(OVERFLOW_VIEW_WIDTH_SP);
}

nItemsToShow = Math.min(maxToShow, Math.round(widthAllowed / ViewUtil.spToPx(ACTION_VIEW_WIDTH_SP)));

for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
if (nItemsToShow > 0) {
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
} else {
item.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
}
nItemsToShow--;
}
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
<org.thoughtcrime.securesms.util.views.AdaptiveActionsToolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/action_mode_status_bar"
android:theme="@style/TextSecure.DarkActionBar.Conversation"
app:navigationIcon="@drawable/ic_x_conversation"
app:menu="@menu/conversation_reactions_long_press_menu">
app:menu="@menu/conversation_reactions_long_press_menu"
app:navigationIcon="@drawable/ic_x_conversation">

</androidx.appcompat.widget.Toolbar>
</org.thoughtcrime.securesms.util.views.AdaptiveActionsToolbar>
4 changes: 4 additions & 0 deletions app/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -454,4 +454,8 @@
<declare-styleable name="ReactionsConversationView">
<attr name="rcv_outgoing" format="boolean" />
</declare-styleable>

<declare-styleable name="AdaptiveActionsToolbar">
<attr name="aat_max_shown" format="integer" />
</declare-styleable>
</resources>

0 comments on commit 7c729c2

Please sign in to comment.