diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 20f3a38aef..6fb7404c4e 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -2,8 +2,9 @@ 32sp 50dp - 200dp - 170dp + 220dp + 110dp + 170dp 5dp 1.5dp 5dp diff --git a/src/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java b/src/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java index c2acb489ea..200a93aeb0 100644 --- a/src/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java +++ b/src/org/thoughtcrime/securesms/components/KeyboardAwareLinearLayout.java @@ -29,6 +29,7 @@ import android.view.View; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.util.ServiceUtil; +import org.thoughtcrime.securesms.util.Util; import java.lang.reflect.Field; import java.util.HashSet; @@ -46,6 +47,9 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { private final Set hiddenListeners = new HashSet<>(); private final Set shownListeners = new HashSet<>(); private final int minKeyboardSize; + private final int minCustomKeyboardSize; + private final int defaultCustomKeyboardSize; + private final int minCustomKeyboardTopMargin; private boolean keyboardOpen = false; private int rotation = -1; @@ -60,7 +64,10 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { public KeyboardAwareLinearLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - minKeyboardSize = getResources().getDimensionPixelSize(R.dimen.min_keyboard_size); + minKeyboardSize = getResources().getDimensionPixelSize(R.dimen.min_keyboard_size); + minCustomKeyboardSize = getResources().getDimensionPixelSize(R.dimen.min_custom_keyboard_size); + defaultCustomKeyboardSize = getResources().getDimensionPixelSize(R.dimen.default_custom_keyboard_size); + minCustomKeyboardTopMargin = getResources().getDimensionPixelSize(R.dimen.min_custom_keyboard_top_margin); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { @@ -134,10 +141,6 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { notifyHiddenListeners(); } - public boolean isKeyboardOpen() { - return keyboardOpen; - } - public int getKeyboardHeight() { return isLandscape() ? getKeyboardLandscapeHeight() : getKeyboardPortraitHeight(); } @@ -156,9 +159,8 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat { private int getKeyboardPortraitHeight() { int keyboardHeight = PreferenceManager.getDefaultSharedPreferences(getContext()) - .getInt("keyboard_height_portrait", - getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height)); - return Math.min(keyboardHeight, getRootView().getHeight() - getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_top_margin)); + .getInt("keyboard_height_portrait", defaultCustomKeyboardSize); + return Util.clamp(keyboardHeight, minCustomKeyboardSize, getRootView().getHeight() - minCustomKeyboardTopMargin); } private void setKeyboardPortraitHeight(int height) { diff --git a/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java b/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java index 9931d2c70a..9e6cf5de24 100644 --- a/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java +++ b/src/org/thoughtcrime/securesms/components/camera/QuickAttachmentDrawer.java @@ -18,13 +18,12 @@ import android.view.MotionEvent; import android.view.Surface; import android.view.View; import android.view.ViewGroup; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.view.WindowManager; import android.widget.ImageButton; import org.thoughtcrime.securesms.R; +import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout; import org.thoughtcrime.securesms.components.camera.QuickCamera.QuickCameraListener; -import org.thoughtcrime.securesms.util.SoftKeyboardUtil; +import org.thoughtcrime.securesms.util.ServiceUtil; public class QuickAttachmentDrawer extends ViewGroup { private static final String TAG = QuickAttachmentDrawer.class.getSimpleName(); @@ -33,23 +32,23 @@ public class QuickAttachmentDrawer extends ViewGroup { private final ViewDragHelper dragHelper; - private QuickCamera quickCamera; - private int coverViewPosition; - private View coverView; - private View controls; - private ImageButton fullScreenButton; - private ImageButton swapCameraButton; - private ImageButton shutterButton; - private float slideOffset; - private float initialMotionX; - private float initialMotionY; - private int rotation; - private int slideRange; - private int baseHalfHeight; - private AttachmentDrawerListener listener; + private QuickCamera quickCamera; + private int coverViewPosition; + private KeyboardAwareLinearLayout coverView; + private View controls; + private ImageButton fullScreenButton; + private ImageButton swapCameraButton; + private ImageButton shutterButton; + private float slideOffset; + private float initialMotionX; + private float initialMotionY; + private int rotation; + private int slideRange; + private AttachmentDrawerListener listener; + private int halfExpandedHeight; + private float halfExpandedAnchorPoint; private DrawerState drawerState = DrawerState.COLLAPSED; - private float halfExpandedAnchorPoint = COLLAPSED_ANCHOR_POINT; private boolean halfModeUnsupported = VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH; private Rect drawChildrenRect = new Rect(); private boolean paused = false; @@ -64,8 +63,7 @@ public class QuickAttachmentDrawer extends ViewGroup { public QuickAttachmentDrawer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - baseHalfHeight = SoftKeyboardUtil.getKeyboardHeight(getContext()); - dragHelper = ViewDragHelper.create(this, 1.f, new ViewDragHelperCallback()); + dragHelper = ViewDragHelper.create(this, 1.f, new ViewDragHelperCallback()); initializeView(); updateHalfExpandedAnchorPoint(); onConfigurationChanged(); @@ -79,10 +77,6 @@ public class QuickAttachmentDrawer extends ViewGroup { coverViewPosition = getChildCount(); } - private WindowManager getWindowManager() { - return (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); - } - public static boolean isDeviceSupported(Context context) { return context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA) && Camera.getNumberOfCameras() > 0; @@ -101,7 +95,7 @@ public class QuickAttachmentDrawer extends ViewGroup { } public void onConfigurationChanged() { - int rotation = getWindowManager().getDefaultDisplay().getRotation(); + int rotation = ServiceUtil.getWindowManager(getContext()).getDefaultDisplay().getRotation(); final boolean rotationChanged = this.rotation != rotation; this.rotation = rotation; if (rotationChanged) { @@ -140,24 +134,24 @@ public class QuickAttachmentDrawer extends ViewGroup { return isLandscape() || halfModeUnsupported; } - private void updateHalfExpandedAnchorPoint() { - Log.w(TAG, "updateHalfExpandedAnchorPoint()"); - getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { - @SuppressWarnings("deprecation") @Override public void onGlobalLayout() { - if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { - getViewTreeObserver().removeOnGlobalLayoutListener(this); - } else { - getViewTreeObserver().removeGlobalOnLayoutListener(this); - } + private KeyboardAwareLinearLayout getCoverView() { + if (coverView != null) return coverView; - coverView = getChildAt(coverViewPosition); - slideRange = getMeasuredHeight(); - halfExpandedAnchorPoint = computeSlideOffsetFromCoverBottom(slideRange - baseHalfHeight); - requestLayout(); - invalidate(); - Log.w(TAG, "updated halfExpandedAnchorPoint!"); - } - }); + final View coverViewChild = getChildAt(coverViewPosition); + if (coverViewChild != null && !(coverViewChild instanceof KeyboardAwareLinearLayout)) { + throw new IllegalStateException("cover view must be a KeyboardAwareLinearLayout"); + } + + coverView = (KeyboardAwareLinearLayout) coverViewChild; + return coverView; + } + + private void updateHalfExpandedAnchorPoint() { + if (getCoverView() != null) { + slideRange = getMeasuredHeight(); + halfExpandedHeight = coverView.getKeyboardHeight(); + halfExpandedAnchorPoint = computeSlideOffsetFromCoverBottom(slideRange - halfExpandedHeight); + } } @Override @@ -165,6 +159,8 @@ public class QuickAttachmentDrawer extends ViewGroup { final int paddingLeft = getPaddingLeft(); final int paddingTop = getPaddingTop(); + updateHalfExpandedAnchorPoint(); + for (int i = 0; i < getChildCount(); i++) { final View child = getChildAt(i); final int childHeight = child.getMeasuredHeight(); @@ -192,8 +188,8 @@ public class QuickAttachmentDrawer extends ViewGroup { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final int widthMode = MeasureSpec.getMode(widthMeasureSpec); - final int widthSize = MeasureSpec.getSize(widthMeasureSpec); + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + final int widthSize = MeasureSpec.getSize(widthMeasureSpec); final int heightMode = MeasureSpec.getMode(heightMeasureSpec); final int heightSize = MeasureSpec.getSize(heightMeasureSpec); @@ -477,7 +473,7 @@ public class QuickAttachmentDrawer extends ViewGroup { clampedOffset = clampedOffset / (FULL_EXPANDED_ANCHOR_POINT - halfExpandedAnchorPoint); } float slidePixelOffset = slideOffset * slideRange + - (quickCamera.getMeasuredHeight() - baseHalfHeight) / 2 * + (quickCamera.getMeasuredHeight() - coverView.getKeyboardHeight()) / 2 * (FULL_EXPANDED_ANCHOR_POINT - clampedOffset); float marginPixelOffset = (getMeasuredHeight() - quickCamera.getMeasuredHeight()) / 2 * clampedOffset; return (int) (getMeasuredHeight() - slidePixelOffset + marginPixelOffset); @@ -528,7 +524,7 @@ public class QuickAttachmentDrawer extends ViewGroup { @Override public void onClick(View v) { boolean crop = drawerState != DrawerState.FULL_EXPANDED; - int imageHeight = crop ? baseHalfHeight : quickCamera.getMeasuredHeight(); + int imageHeight = crop ? coverView.getKeyboardHeight() : quickCamera.getMeasuredHeight(); Rect previewRect = new Rect(0, 0, quickCamera.getMeasuredWidth(), imageHeight); quickCamera.takePicture(previewRect); } diff --git a/src/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java b/src/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java index 43560755d8..0ea5183618 100644 --- a/src/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java +++ b/src/org/thoughtcrime/securesms/components/emoji/EmojiDrawer.java @@ -73,6 +73,7 @@ public class EmojiDrawer extends LinearLayout { public void show(KeyboardAwareLinearLayout container) { ViewGroup.LayoutParams params = getLayoutParams(); params.height = container.getKeyboardHeight(); + Log.w("EmojiDrawer", "showing emoji drawer with height " + params.height); setLayoutParams(params); setVisibility(VISIBLE); } diff --git a/src/org/thoughtcrime/securesms/util/SoftKeyboardUtil.java b/src/org/thoughtcrime/securesms/util/SoftKeyboardUtil.java deleted file mode 100644 index 47f82158f5..0000000000 --- a/src/org/thoughtcrime/securesms/util/SoftKeyboardUtil.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.thoughtcrime.securesms.util; - -import android.app.Activity; -import android.content.Context; -import android.graphics.Rect; -import android.os.Build; -import android.os.Build.VERSION_CODES; -import android.preference.PreferenceManager; -import android.util.Log; -import android.view.Surface; -import android.view.View; -import android.view.ViewGroup; -import android.view.WindowManager; - -import org.thoughtcrime.securesms.R; - -import java.lang.reflect.Field; - -public class SoftKeyboardUtil { - private static final String TAG = SoftKeyboardUtil.class.getSimpleName(); - private static final Rect rect = new Rect(); - - public static int onMeasure(ViewGroup view) { - view.getWindowVisibleDisplayFrame(rect); - final int res = view.getResources().getIdentifier("status_bar_height", "dimen", "android"); - final int statusBarHeight = res > 0 ? view.getResources().getDimensionPixelSize(res) : 0; - final int availableHeight = view.getRootView().getHeight() - statusBarHeight - getViewInset(view); - final int keyboardHeight = availableHeight - (rect.bottom - rect.top); - final int minKeyboardHeight = view.getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height); - - if (keyboardHeight > minKeyboardHeight) { - onKeyboardShown(view.getContext(), keyboardHeight); - } - return Math.max(keyboardHeight, minKeyboardHeight); - } - - private static int getViewInset(ViewGroup view) { - if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) { - return 0; - } - - try { - Field attachInfoField = View.class.getDeclaredField("mAttachInfo"); - attachInfoField.setAccessible(true); - Object attachInfo = attachInfoField.get(view); - if (attachInfo != null) { - Field stableInsetsField = attachInfo.getClass().getDeclaredField("mStableInsets"); - stableInsetsField.setAccessible(true); - Rect insets = (Rect)stableInsetsField.get(attachInfo); - return insets.bottom; - } - } catch (NoSuchFieldException nsfe) { - Log.w(TAG, "field reflection error when measuring view inset", nsfe); - } catch (IllegalAccessException iae) { - Log.w(TAG, "access reflection error when measuring view inset", iae); - } - return 0; - } - - - private static void onKeyboardShown(Context context, int keyboardHeight) { - Log.w(TAG, "keyboard shown, height " + keyboardHeight); - - WindowManager wm = (WindowManager)context.getSystemService(Activity.WINDOW_SERVICE); - if (wm == null || wm.getDefaultDisplay() == null) { - return; - } - int rotation = wm.getDefaultDisplay().getRotation(); - - switch (rotation) { - case Surface.ROTATION_270: - case Surface.ROTATION_90: - setKeyboardLandscapeHeight(context, keyboardHeight); - break; - case Surface.ROTATION_0: - case Surface.ROTATION_180: - setKeyboardPortraitHeight(context, keyboardHeight); - } - } - - public static int getKeyboardHeight(Context context) { - WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE); - if (wm == null || wm.getDefaultDisplay() == null) { - throw new AssertionError("WindowManager was null or there is no default display"); - } - - int rotation = wm.getDefaultDisplay().getRotation(); - - switch (rotation) { - case Surface.ROTATION_270: - case Surface.ROTATION_90: - return getKeyboardLandscapeHeight(context); - case Surface.ROTATION_0: - case Surface.ROTATION_180: - default: - return getKeyboardPortraitHeight(context); - } - } - - private static int getKeyboardLandscapeHeight(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getInt("keyboard_height_landscape", - context.getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height)); - } - - private static int getKeyboardPortraitHeight(Context context) { - return PreferenceManager.getDefaultSharedPreferences(context) - .getInt("keyboard_height_portrait", - context.getResources().getDimensionPixelSize(R.dimen.min_emoji_drawer_height)); - } - - private static void setKeyboardLandscapeHeight(Context context, int height) { - PreferenceManager.getDefaultSharedPreferences(context) - .edit().putInt("keyboard_height_landscape", height).apply(); - } - - private static void setKeyboardPortraitHeight(Context context, int height) { - PreferenceManager.getDefaultSharedPreferences(context) - .edit().putInt("keyboard_height_portrait", height).apply(); - } -} diff --git a/src/org/thoughtcrime/securesms/util/Util.java b/src/org/thoughtcrime/securesms/util/Util.java index fc87e92e8e..fda6e4bd7f 100644 --- a/src/org/thoughtcrime/securesms/util/Util.java +++ b/src/org/thoughtcrime/securesms/util/Util.java @@ -344,4 +344,8 @@ public class Util { return (VERSION.SDK_INT >= VERSION_CODES.KITKAT && activityManager.isLowRamDevice()) || activityManager.getMemoryClass() <= 64; } + + public static int clamp(int value, int min, int max) { + return Math.min(Math.max(value, min), max); + } }