mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
Smooth transition for custom keyboards and softkey
Closes #3786 Fixes #3780 // FREEBIE
This commit is contained in:
parent
24e14cbc73
commit
13bad6dfed
@ -1,72 +1,59 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer
|
<org.thoughtcrime.securesms.components.InputAwareLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:id="@+id/quick_attachment_drawer"
|
android:id="@+id/layout_container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:background="@color/black">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout
|
<org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer
|
||||||
android:id="@+id/layout_container"
|
android:id="@+id/quick_attachment_drawer"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical"
|
||||||
|
android:background="@color/black">
|
||||||
|
|
||||||
<RelativeLayout android:layout_width="fill_parent"
|
<LinearLayout android:layout_width="match_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:orientation="vertical"
|
||||||
android:orientation="vertical"
|
android:background="?conversation_background"
|
||||||
android:background="?conversation_background"
|
android:paddingTop="?attr/actionBarSize"
|
||||||
android:paddingTop="?attr/actionBarSize"
|
android:gravity="bottom">
|
||||||
android:gravity="bottom">
|
|
||||||
|
|
||||||
<FrameLayout android:id="@+id/fragment_content"
|
<FrameLayout android:id="@+id/fragment_content"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="0dp"
|
||||||
android:layout_above="@+id/bottom_container" />
|
android:layout_weight="1" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout android:id="@+id/bottom_container"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_width="fill_parent"
|
||||||
android:id="@id/bottom_container"
|
android:layout_height="wrap_content"
|
||||||
android:layout_width="fill_parent"
|
android:orientation="vertical">
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical">
|
|
||||||
|
|
||||||
<ScrollView android:layout_width="fill_parent"
|
<FrameLayout
|
||||||
android:layout_height="0dp"
|
android:id="@+id/attachment_editor"
|
||||||
android:layout_weight="1">
|
android:layout_width="wrap_content"
|
||||||
<FrameLayout
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/attachment_editor"
|
android:layout_gravity="center_horizontal"
|
||||||
android:layout_width="wrap_content"
|
android:paddingTop="10dp"
|
||||||
android:layout_height="wrap_content"
|
android:visibility="gone">
|
||||||
android:layout_gravity="center_horizontal"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
<FrameLayout
|
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||||
android:paddingLeft="10dp"
|
android:id="@+id/attachment_thumbnail"
|
||||||
android:paddingTop="10dp"
|
android:layout_width="230dp"
|
||||||
android:layout_width="fill_parent"
|
android:layout_height="150dp"
|
||||||
android:layout_height="fill_parent">
|
android:contentDescription="@string/conversation_activity__attachment_thumbnail"
|
||||||
|
app:backgroundColorHint="?conversation_background" />
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
<ImageView android:id="@+id/remove_image_button"
|
||||||
android:id="@+id/attachment_thumbnail"
|
android:layout_width="wrap_content"
|
||||||
android:layout_width="230dp"
|
android:layout_height="wrap_content"
|
||||||
android:layout_height="150dp"
|
android:src="@drawable/conversation_attachment_close_circle"
|
||||||
android:contentDescription="@string/conversation_activity__attachment_thumbnail"
|
android:layout_gravity="top|left"/>
|
||||||
app:backgroundColorHint="?conversation_background" />
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
<ImageView android:id="@+id/remove_image_button"
|
</FrameLayout>
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:src="@drawable/conversation_attachment_close_circle"
|
|
||||||
android:layout_gravity="top|left"/>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
</ScrollView>
|
|
||||||
|
|
||||||
<LinearLayout android:id="@+id/bottom_panel"
|
<LinearLayout android:id="@+id/bottom_panel"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
@ -157,12 +144,12 @@
|
|||||||
android:text="160/160 (1)" />
|
android:text="160/160 (1)" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
|
||||||
|
<org.thoughtcrime.securesms.components.emoji.EmojiDrawer
|
||||||
<ViewStub android:id="@+id/emoji_drawer_stub"
|
android:id="@+id/emoji_drawer"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content" />
|
||||||
android:inflatedId="@+id/emoji_drawer"
|
|
||||||
android:layout="@layout/emoji_drawer_stub" />
|
</LinearLayout>
|
||||||
</org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout>
|
|
||||||
</org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer>
|
</org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer>
|
||||||
|
</org.thoughtcrime.securesms.components.InputAwareLayout>
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<org.thoughtcrime.securesms.components.emoji.EmojiDrawer
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_weight="1.1" />
|
|
@ -37,7 +37,6 @@ import android.provider.ContactsContract;
|
|||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.view.WindowCompat;
|
import android.support.v4.view.WindowCompat;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.InputType;
|
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@ -48,9 +47,7 @@ import android.view.View;
|
|||||||
import android.view.View.OnClickListener;
|
import android.view.View.OnClickListener;
|
||||||
import android.view.View.OnFocusChangeListener;
|
import android.view.View.OnFocusChangeListener;
|
||||||
import android.view.View.OnKeyListener;
|
import android.view.View.OnKeyListener;
|
||||||
import android.view.ViewStub;
|
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
@ -67,6 +64,8 @@ import org.thoughtcrime.securesms.components.ComposeText;
|
|||||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
||||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
|
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
|
||||||
import org.thoughtcrime.securesms.components.SendButton;
|
import org.thoughtcrime.securesms.components.SendButton;
|
||||||
|
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer.DrawerState;
|
||||||
|
import org.thoughtcrime.securesms.components.InputAwareLayout;
|
||||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiEventListener;
|
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiEventListener;
|
||||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer;
|
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer;
|
||||||
import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
|
import org.thoughtcrime.securesms.components.emoji.EmojiToggle;
|
||||||
@ -113,13 +112,11 @@ import org.thoughtcrime.securesms.util.DirectoryHelper;
|
|||||||
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
import org.thoughtcrime.securesms.util.DynamicLanguage;
|
||||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||||
import org.thoughtcrime.securesms.util.GroupUtil;
|
import org.thoughtcrime.securesms.util.GroupUtil;
|
||||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
|
||||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||||
import org.thoughtcrime.securesms.util.Util;
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||||
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
import org.thoughtcrime.securesms.util.concurrent.SettableFuture;
|
||||||
import org.whispersystems.libaxolotl.InvalidMessageException;
|
import org.whispersystems.libaxolotl.InvalidMessageException;
|
||||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@ -161,24 +158,24 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
private static final int GROUP_EDIT = 5;
|
private static final int GROUP_EDIT = 5;
|
||||||
private static final int TAKE_PHOTO = 6;
|
private static final int TAKE_PHOTO = 6;
|
||||||
|
|
||||||
private MasterSecret masterSecret;
|
private MasterSecret masterSecret;
|
||||||
protected ComposeText composeText;
|
protected ComposeText composeText;
|
||||||
private AnimatingToggle buttonToggle;
|
private AnimatingToggle buttonToggle;
|
||||||
private SendButton sendButton;
|
private SendButton sendButton;
|
||||||
private ImageButton attachButton;
|
private ImageButton attachButton;
|
||||||
protected ConversationTitleView titleView;
|
protected ConversationTitleView titleView;
|
||||||
private TextView charactersLeft;
|
private TextView charactersLeft;
|
||||||
private ConversationFragment fragment;
|
private ConversationFragment fragment;
|
||||||
private Button unblockButton;
|
private Button unblockButton;
|
||||||
private KeyboardAwareLinearLayout container;
|
private InputAwareLayout container;
|
||||||
private View composePanel;
|
private View composePanel;
|
||||||
private View composeBubble;
|
private View composeBubble;
|
||||||
|
|
||||||
private AttachmentTypeSelectorAdapter attachmentAdapter;
|
private AttachmentTypeSelectorAdapter attachmentAdapter;
|
||||||
private AttachmentManager attachmentManager;
|
private AttachmentManager attachmentManager;
|
||||||
private BroadcastReceiver securityUpdateReceiver;
|
private BroadcastReceiver securityUpdateReceiver;
|
||||||
private BroadcastReceiver groupUpdateReceiver;
|
private BroadcastReceiver groupUpdateReceiver;
|
||||||
private Optional<EmojiDrawer> emojiDrawer = Optional.absent();
|
private EmojiDrawer emojiDrawer;
|
||||||
private EmojiToggle emojiToggle;
|
private EmojiToggle emojiToggle;
|
||||||
protected HidingImageButton quickAttachmentToggle;
|
protected HidingImageButton quickAttachmentToggle;
|
||||||
private QuickAttachmentDrawer quickAttachmentDrawer;
|
private QuickAttachmentDrawer quickAttachmentDrawer;
|
||||||
@ -265,19 +262,19 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override public void onConfigurationChanged(Configuration newConfig) {
|
@Override public void onConfigurationChanged(Configuration newConfig) {
|
||||||
|
Log.w(TAG, "onConfigurationChanged(" + newConfig.orientation + ")");
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
composeText.setTransport(sendButton.getSelectedTransport());
|
composeText.setTransport(sendButton.getSelectedTransport());
|
||||||
quickAttachmentDrawer.onConfigurationChanged();
|
quickAttachmentDrawer.onConfigurationChanged();
|
||||||
hideEmojiDrawer(false);
|
if (container.getCurrentInput() == emojiDrawer) container.hideAttachedInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
saveDraft();
|
saveDraft();
|
||||||
if (recipients != null) recipients.removeListener(this);
|
if (recipients != null) recipients.removeListener(this);
|
||||||
if (securityUpdateReceiver != null) unregisterReceiver(securityUpdateReceiver);
|
if (securityUpdateReceiver != null) unregisterReceiver(securityUpdateReceiver);
|
||||||
if (groupUpdateReceiver != null) unregisterReceiver(groupUpdateReceiver);
|
if (groupUpdateReceiver != null) unregisterReceiver(groupUpdateReceiver);
|
||||||
if (isEmojiDrawerOpen()) hideEmojiDrawer(false);
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -386,19 +383,13 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
Log.w(TAG, "onBackPressed()");
|
Log.w(TAG, "onBackPressed()");
|
||||||
if (isEmojiDrawerOpen()) {
|
if (container.isInputOpen()) container.hideCurrentInput(composeText);
|
||||||
Log.w(TAG, "hiding emoji popup");
|
else super.onBackPressed();
|
||||||
hideEmojiDrawer(false);
|
|
||||||
} else if (quickAttachmentDrawer.isOpen()) {
|
|
||||||
quickAttachmentDrawer.close();
|
|
||||||
} else {
|
|
||||||
super.onBackPressed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onKeyboardShown() {
|
public void onKeyboardShown() {
|
||||||
hideEmojiDrawer(true);
|
emojiToggle.setToEmoji();
|
||||||
}
|
}
|
||||||
|
|
||||||
//////// Event Handlers
|
//////// Event Handlers
|
||||||
@ -758,17 +749,18 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void initializeViews() {
|
private void initializeViews() {
|
||||||
titleView = (ConversationTitleView) getSupportActionBar().getCustomView();
|
titleView = (ConversationTitleView) getSupportActionBar().getCustomView();
|
||||||
buttonToggle = (AnimatingToggle) findViewById(R.id.button_toggle);
|
buttonToggle = (AnimatingToggle) findViewById(R.id.button_toggle);
|
||||||
sendButton = (SendButton) findViewById(R.id.send_button);
|
sendButton = (SendButton) findViewById(R.id.send_button);
|
||||||
attachButton = (ImageButton) findViewById(R.id.attach_button);
|
attachButton = (ImageButton) findViewById(R.id.attach_button);
|
||||||
composeText = (ComposeText) findViewById(R.id.embedded_text_editor);
|
composeText = (ComposeText) findViewById(R.id.embedded_text_editor);
|
||||||
charactersLeft = (TextView) findViewById(R.id.space_left);
|
charactersLeft = (TextView) findViewById(R.id.space_left);
|
||||||
emojiToggle = (EmojiToggle) findViewById(R.id.emoji_toggle);
|
emojiToggle = (EmojiToggle) findViewById(R.id.emoji_toggle);
|
||||||
unblockButton = (Button) findViewById(R.id.unblock_button);
|
emojiDrawer = (EmojiDrawer) findViewById(R.id.emoji_drawer);
|
||||||
composePanel = findViewById(R.id.bottom_panel);
|
unblockButton = (Button) findViewById(R.id.unblock_button);
|
||||||
composeBubble = findViewById(R.id.compose_bubble);
|
composePanel = findViewById(R.id.bottom_panel);
|
||||||
container = (KeyboardAwareLinearLayout) findViewById(R.id.layout_container);
|
composeBubble = findViewById(R.id.compose_bubble);
|
||||||
|
container = (InputAwareLayout) findViewById(R.id.layout_container);
|
||||||
|
|
||||||
container.addOnKeyboardShownListener(this);
|
container.addOnKeyboardShownListener(this);
|
||||||
|
|
||||||
@ -780,7 +772,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
emojiToggle = (EmojiToggle) findViewById(R.id.emoji_toggle);
|
emojiToggle = (EmojiToggle) findViewById(R.id.emoji_toggle);
|
||||||
titleView = (ConversationTitleView) getSupportActionBar().getCustomView();
|
titleView = (ConversationTitleView) getSupportActionBar().getCustomView();
|
||||||
unblockButton = (Button) findViewById(R.id.unblock_button);
|
unblockButton = (Button) findViewById(R.id.unblock_button);
|
||||||
composePanel = findViewById(R.id.bottom_panel);
|
composePanel = findViewById(R.id.bottom_panel);
|
||||||
quickAttachmentDrawer = (QuickAttachmentDrawer) findViewById(R.id.quick_attachment_drawer);
|
quickAttachmentDrawer = (QuickAttachmentDrawer) findViewById(R.id.quick_attachment_drawer);
|
||||||
quickAttachmentToggle = (HidingImageButton) findViewById(R.id.quick_attachment_toggle);
|
quickAttachmentToggle = (HidingImageButton) findViewById(R.id.quick_attachment_toggle);
|
||||||
|
|
||||||
@ -796,6 +788,18 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
SendButtonListener sendButtonListener = new SendButtonListener();
|
SendButtonListener sendButtonListener = new SendButtonListener();
|
||||||
ComposeKeyPressedListener composeKeyPressedListener = new ComposeKeyPressedListener();
|
ComposeKeyPressedListener composeKeyPressedListener = new ComposeKeyPressedListener();
|
||||||
|
|
||||||
|
emojiToggle.attach(emojiDrawer);
|
||||||
|
emojiToggle.setOnClickListener(new EmojiToggleListener());
|
||||||
|
emojiDrawer.setEmojiEventListener(new EmojiEventListener() {
|
||||||
|
@Override public void onKeyEvent(KeyEvent keyEvent) {
|
||||||
|
composeText.dispatchKeyEvent(keyEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void onEmojiSelected(String emoji) {
|
||||||
|
composeText.insertEmoji(emoji);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
composeText.setOnEditorActionListener(sendButtonListener);
|
composeText.setOnEditorActionListener(sendButtonListener);
|
||||||
attachButton.setOnClickListener(new AttachButtonListener());
|
attachButton.setOnClickListener(new AttachButtonListener());
|
||||||
sendButton.setOnClickListener(sendButtonListener);
|
sendButton.setOnClickListener(sendButtonListener);
|
||||||
@ -831,7 +835,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
composeText.setOnEditorActionListener(sendButtonListener);
|
composeText.setOnEditorActionListener(sendButtonListener);
|
||||||
composeText.setOnClickListener(composeKeyPressedListener);
|
composeText.setOnClickListener(composeKeyPressedListener);
|
||||||
composeText.setOnFocusChangeListener(composeKeyPressedListener);
|
composeText.setOnFocusChangeListener(composeKeyPressedListener);
|
||||||
emojiToggle.setOnClickListener(new EmojiToggleListener());
|
|
||||||
|
|
||||||
if (QuickAttachmentDrawer.isDeviceSupported(this)) {
|
if (QuickAttachmentDrawer.isDeviceSupported(this)) {
|
||||||
quickAttachmentDrawer.setListener(this);
|
quickAttachmentDrawer.setListener(this);
|
||||||
@ -848,48 +851,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
getSupportActionBar().setDisplayShowTitleEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private EmojiDrawer getEmojiDrawer() {
|
|
||||||
if (!emojiDrawer.isPresent()) {
|
|
||||||
EmojiDrawer emojiDrawer = (EmojiDrawer)((ViewStub)findViewById(R.id.emoji_drawer_stub)).inflate();
|
|
||||||
emojiDrawer.setEmojiEventListener(new EmojiEventListener() {
|
|
||||||
@Override public void onKeyEvent(KeyEvent keyEvent) {
|
|
||||||
composeText.dispatchKeyEvent(keyEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void onEmojiSelected(String emoji) {
|
|
||||||
Log.w(TAG, "onEmojiSelected()");
|
|
||||||
composeText.insertEmoji(emoji);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.emojiDrawer = Optional.of(emojiDrawer);
|
|
||||||
}
|
|
||||||
return emojiDrawer.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showEmojiDrawer() {
|
|
||||||
getEmojiDrawer().show(container);
|
|
||||||
emojiToggle.setToIme();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void hideEmojiDrawer(boolean expectingKeyboard) {
|
|
||||||
if (isEmojiDrawerOpen()) {
|
|
||||||
if (!expectingKeyboard || container.isLandscape()) {
|
|
||||||
getEmojiDrawer().dismiss();
|
|
||||||
} else {
|
|
||||||
container.postOnKeyboardOpen(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
getEmojiDrawer().dismiss();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emojiToggle.setToEmoji();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isEmojiDrawerOpen() {
|
|
||||||
return emojiDrawer.isPresent() && emojiDrawer.get().isShowing();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initializeResources() {
|
private void initializeResources() {
|
||||||
recipients = RecipientFactory.getRecipientsForIds(this, getIntent().getLongArrayExtra(RECIPIENTS_EXTRA), true);
|
recipients = RecipientFactory.getRecipientsForIds(this, getIntent().getLongArrayExtra(RECIPIENTS_EXTRA), true);
|
||||||
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
threadId = getIntent().getLongExtra(THREAD_ID_EXTRA, -1);
|
||||||
@ -1302,26 +1263,25 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttachmentDrawerClosed() {
|
public void onAttachmentDrawerStateChanged(DrawerState drawerState) {
|
||||||
getSupportActionBar().show();
|
if (drawerState == DrawerState.FULL_EXPANDED) {
|
||||||
}
|
getSupportActionBar().hide();
|
||||||
|
} else {
|
||||||
@Override
|
getSupportActionBar().show();
|
||||||
public void onAttachmentDrawerOpened() {
|
}
|
||||||
getSupportActionBar().hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onImageCapture(@NonNull final byte[] imageBytes) {
|
public void onImageCapture(@NonNull final byte[] imageBytes) {
|
||||||
attachmentManager.setCaptureUri(CaptureProvider.getInstance(this).create(masterSecret, recipients, imageBytes));
|
attachmentManager.setCaptureUri(CaptureProvider.getInstance(this).create(masterSecret, recipients, imageBytes));
|
||||||
addAttachmentImage(masterSecret, attachmentManager.getCaptureUri());
|
addAttachmentImage(masterSecret, attachmentManager.getCaptureUri());
|
||||||
quickAttachmentDrawer.close();
|
quickAttachmentDrawer.hide(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCameraFail(FailureReason reason) {
|
public void onCameraFail(FailureReason reason) {
|
||||||
Toast.makeText(this, R.string.quick_camera_unavailable, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.quick_camera_unavailable, Toast.LENGTH_SHORT).show();
|
||||||
quickAttachmentDrawer.close();
|
quickAttachmentDrawer.hide(false);
|
||||||
quickAttachmentToggle.disable();
|
quickAttachmentToggle.disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1335,46 +1295,19 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openKeyboardForComposition() {
|
|
||||||
composeText.post(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
composeText.requestFocus();
|
|
||||||
ServiceUtil.getInputMethodManager(ConversationActivity.this).showSoftInput(composeText, 0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void hideKeyboard() {
|
|
||||||
ServiceUtil.getInputMethodManager(this).hideSoftInputFromWindow(composeText.getWindowToken(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class EmojiToggleListener implements OnClickListener {
|
private class EmojiToggleListener implements OnClickListener {
|
||||||
@Override
|
|
||||||
public void onClick(View v) {
|
@Override public void onClick(View v) {
|
||||||
Log.w(TAG, "EmojiToggleListener onClick()");
|
if (container.getCurrentInput() == emojiDrawer) container.showSoftkey(composeText);
|
||||||
if (isEmojiDrawerOpen()) {
|
else container.show(composeText, emojiDrawer);
|
||||||
hideEmojiDrawer(true);
|
|
||||||
openKeyboardForComposition();
|
|
||||||
} else {
|
|
||||||
container.postOnKeyboardClose(new Runnable() {
|
|
||||||
@Override public void run() {
|
|
||||||
showEmojiDrawer();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
quickAttachmentDrawer.close();
|
|
||||||
hideKeyboard();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class QuickAttachmentToggleListener implements OnClickListener {
|
private class QuickAttachmentToggleListener implements OnClickListener {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
InputMethodManager input = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
|
|
||||||
input.hideSoftInputFromWindow(composeText.getWindowToken(), 0);
|
|
||||||
composeText.clearFocus();
|
composeText.clearFocus();
|
||||||
hideEmojiDrawer(false);
|
container.show(composeText, quickAttachmentDrawer);
|
||||||
quickAttachmentDrawer.open();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1421,7 +1354,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
hideEmojiDrawer(true);
|
container.showSoftkey(composeText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1447,13 +1380,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||||||
public void onTextChanged(CharSequence s, int start, int before,int count) {}
|
public void onTextChanged(CharSequence s, int start, int before,int count) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFocusChange(View v, boolean hasFocus) {
|
public void onFocusChange(View v, boolean hasFocus) {}
|
||||||
if (hasFocus && isEmojiDrawerOpen()) {
|
|
||||||
hideEmojiDrawer(true);
|
|
||||||
} else if (hasFocus && quickAttachmentDrawer.isOpen()) {
|
|
||||||
quickAttachmentDrawer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -113,11 +113,6 @@ public class ConversationPopupActivity extends ConversationActivity {
|
|||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void hideEmojiDrawer(boolean expectingKeyboard) {
|
|
||||||
super.hideEmojiDrawer(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void sendComplete(long threadId) {
|
protected void sendComplete(long threadId) {
|
||||||
super.sendComplete(threadId);
|
super.sendComplete(threadId);
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
package org.thoughtcrime.securesms.components;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout.OnKeyboardShownListener;
|
||||||
|
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||||
|
|
||||||
|
public class InputAwareLayout extends KeyboardAwareLinearLayout implements OnKeyboardShownListener {
|
||||||
|
private InputView current;
|
||||||
|
|
||||||
|
public InputAwareLayout(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputAwareLayout(Context context, AttributeSet attrs) {
|
||||||
|
this(context, attrs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputAwareLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
addOnKeyboardShownListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void onKeyboardShown() {
|
||||||
|
hideAttachedInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show(@NonNull final EditText imeTarget, @NonNull final InputView input) {
|
||||||
|
if (isKeyboardOpen()) {
|
||||||
|
hideSoftkey(imeTarget, new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
input.show(getKeyboardHeight(), true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (current != null && current.isShowing()) {
|
||||||
|
current.hide(true);
|
||||||
|
input.show(getKeyboardHeight(), true);
|
||||||
|
} else {
|
||||||
|
input.show(getKeyboardHeight(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
current = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputView getCurrentInput() {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideCurrentInput(EditText imeTarget) {
|
||||||
|
if (isKeyboardOpen()) hideSoftkey(imeTarget, null);
|
||||||
|
else hideAttachedInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideAttachedInput() {
|
||||||
|
if (current != null) current.hide(true);
|
||||||
|
current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInputOpen() {
|
||||||
|
return (isKeyboardOpen() || (current != null && current.isShowing()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showSoftkey(final EditText inputTarget) {
|
||||||
|
postOnKeyboardOpen(new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
hideAttachedInput();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
inputTarget.post(new Runnable() {
|
||||||
|
@Override public void run() {
|
||||||
|
inputTarget.requestFocus();
|
||||||
|
ServiceUtil.getInputMethodManager(inputTarget.getContext()).showSoftInput(inputTarget, 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void hideSoftkey(final EditText inputTarget, @Nullable Runnable runAfterClose) {
|
||||||
|
if (runAfterClose != null) postOnKeyboardClose(runAfterClose);
|
||||||
|
|
||||||
|
ServiceUtil.getInputMethodManager(inputTarget.getContext())
|
||||||
|
.hideSoftInputFromWindow(inputTarget.getWindowToken(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface InputView {
|
||||||
|
void show(int height, boolean immediate);
|
||||||
|
void hide(boolean immediate);
|
||||||
|
boolean isShowing();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,6 +16,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.components;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@ -42,14 +43,17 @@ import java.util.Set;
|
|||||||
public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
||||||
private static final String TAG = KeyboardAwareLinearLayout.class.getSimpleName();
|
private static final String TAG = KeyboardAwareLinearLayout.class.getSimpleName();
|
||||||
|
|
||||||
private final Rect oldRect = new Rect();
|
private final Rect oldRect = new Rect();
|
||||||
private final Rect newRect = new Rect();
|
private final Rect newRect = new Rect();
|
||||||
private final Set<OnKeyboardHiddenListener> hiddenListeners = new HashSet<>();
|
private final Set<OnKeyboardHiddenListener> hiddenListeners = new HashSet<>();
|
||||||
private final Set<OnKeyboardShownListener> shownListeners = new HashSet<>();
|
private final Set<OnKeyboardShownListener> shownListeners = new HashSet<>();
|
||||||
private final int minKeyboardSize;
|
private final int minKeyboardSize;
|
||||||
private final int minCustomKeyboardSize;
|
private final int minCustomKeyboardSize;
|
||||||
private final int defaultCustomKeyboardSize;
|
private final int defaultCustomKeyboardSize;
|
||||||
private final int minCustomKeyboardTopMargin;
|
private final int minCustomKeyboardTopMargin;
|
||||||
|
private final int statusBarHeight;
|
||||||
|
|
||||||
|
private int viewInset;
|
||||||
|
|
||||||
private boolean keyboardOpen = false;
|
private boolean keyboardOpen = false;
|
||||||
private int rotation = -1;
|
private int rotation = -1;
|
||||||
@ -64,16 +68,19 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
|||||||
|
|
||||||
public KeyboardAwareLinearLayout(Context context, AttributeSet attrs, int defStyle) {
|
public KeyboardAwareLinearLayout(Context context, AttributeSet attrs, int defStyle) {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
|
final int statusBarRes = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
||||||
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);
|
minCustomKeyboardSize = getResources().getDimensionPixelSize(R.dimen.min_custom_keyboard_size);
|
||||||
defaultCustomKeyboardSize = getResources().getDimensionPixelSize(R.dimen.default_custom_keyboard_size);
|
defaultCustomKeyboardSize = getResources().getDimensionPixelSize(R.dimen.default_custom_keyboard_size);
|
||||||
minCustomKeyboardTopMargin = getResources().getDimensionPixelSize(R.dimen.min_custom_keyboard_top_margin);
|
minCustomKeyboardTopMargin = getResources().getDimensionPixelSize(R.dimen.min_custom_keyboard_top_margin);
|
||||||
|
statusBarHeight = statusBarRes > 0 ? getResources().getDimensionPixelSize(statusBarRes) : 0;
|
||||||
|
viewInset = getViewInset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
updateRotation();
|
updateRotation();
|
||||||
updateKeyboardState();
|
updateKeyboardState();
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateRotation() {
|
private void updateRotation() {
|
||||||
@ -86,10 +93,8 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateKeyboardState() {
|
private void updateKeyboardState() {
|
||||||
int res = getResources().getIdentifier("status_bar_height", "dimen", "android");
|
if (viewInset == 0 && Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) viewInset = getViewInset();
|
||||||
int statusBarHeight = res > 0 ? getResources().getDimensionPixelSize(res) : 0;
|
final int availableHeight = this.getRootView().getHeight() - statusBarHeight - viewInset;
|
||||||
|
|
||||||
final int availableHeight = this.getRootView().getHeight() - statusBarHeight - getViewInset();
|
|
||||||
getWindowVisibleDisplayFrame(newRect);
|
getWindowVisibleDisplayFrame(newRect);
|
||||||
|
|
||||||
final int oldKeyboardHeight = availableHeight - (oldRect.bottom - oldRect.top);
|
final int oldKeyboardHeight = availableHeight - (oldRect.bottom - oldRect.top);
|
||||||
@ -104,11 +109,8 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
|||||||
oldRect.set(newRect);
|
oldRect.set(newRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TargetApi(VERSION_CODES.LOLLIPOP)
|
||||||
private int getViewInset() {
|
private int getViewInset() {
|
||||||
if (Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Field attachInfoField = View.class.getDeclaredField("mAttachInfo");
|
Field attachInfoField = View.class.getDeclaredField("mAttachInfo");
|
||||||
attachInfoField.setAccessible(true);
|
attachInfoField.setAccessible(true);
|
||||||
@ -141,6 +143,10 @@ public class KeyboardAwareLinearLayout extends LinearLayoutCompat {
|
|||||||
notifyHiddenListeners();
|
notifyHiddenListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isKeyboardOpen() {
|
||||||
|
return keyboardOpen;
|
||||||
|
}
|
||||||
|
|
||||||
public int getKeyboardHeight() {
|
public int getKeyboardHeight() {
|
||||||
return isLandscape() ? getKeyboardLandscapeHeight() : getKeyboardPortraitHeight();
|
return isLandscape() ? getKeyboardLandscapeHeight() : getKeyboardPortraitHeight();
|
||||||
}
|
}
|
||||||
|
@ -21,32 +21,31 @@ import android.view.ViewGroup;
|
|||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.components.InputManager.InputView;
|
||||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
||||||
import org.thoughtcrime.securesms.components.camera.QuickCamera.QuickCameraListener;
|
import org.thoughtcrime.securesms.components.camera.QuickCamera.QuickCameraListener;
|
||||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||||
|
import org.thoughtcrime.securesms.util.Util;
|
||||||
|
|
||||||
public class QuickAttachmentDrawer extends ViewGroup {
|
public class QuickAttachmentDrawer extends ViewGroup implements InputView {
|
||||||
private static final String TAG = QuickAttachmentDrawer.class.getSimpleName();
|
private static final String TAG = QuickAttachmentDrawer.class.getSimpleName();
|
||||||
private static final float FULL_EXPANDED_ANCHOR_POINT = 1.f;
|
|
||||||
private static final float COLLAPSED_ANCHOR_POINT = 0.f;
|
|
||||||
|
|
||||||
private final ViewDragHelper dragHelper;
|
private final ViewDragHelper dragHelper;
|
||||||
|
|
||||||
private QuickCamera quickCamera;
|
private QuickCamera quickCamera;
|
||||||
private int coverViewPosition;
|
private int coverViewPosition;
|
||||||
private KeyboardAwareLinearLayout coverView;
|
private KeyboardAwareLinearLayout container;
|
||||||
|
private View coverView;
|
||||||
private View controls;
|
private View controls;
|
||||||
private ImageButton fullScreenButton;
|
private ImageButton fullScreenButton;
|
||||||
private ImageButton swapCameraButton;
|
private ImageButton swapCameraButton;
|
||||||
private ImageButton shutterButton;
|
private ImageButton shutterButton;
|
||||||
private float slideOffset;
|
private int slideOffset;
|
||||||
private float initialMotionX;
|
private float initialMotionX;
|
||||||
private float initialMotionY;
|
private float initialMotionY;
|
||||||
private int rotation;
|
private int rotation;
|
||||||
private int slideRange;
|
|
||||||
private AttachmentDrawerListener listener;
|
private AttachmentDrawerListener listener;
|
||||||
private int halfExpandedHeight;
|
private int halfExpandedHeight;
|
||||||
private float halfExpandedAnchorPoint;
|
|
||||||
|
|
||||||
private DrawerState drawerState = DrawerState.COLLAPSED;
|
private DrawerState drawerState = DrawerState.COLLAPSED;
|
||||||
private boolean halfModeUnsupported = VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
private boolean halfModeUnsupported = VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
||||||
@ -82,16 +81,19 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
Camera.getNumberOfCameras() > 0;
|
Camera.getNumberOfCameras() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOpen() {
|
@Override
|
||||||
|
public boolean isShowing() {
|
||||||
return drawerState.isVisible();
|
return drawerState.isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void close() {
|
@Override
|
||||||
setDrawerStateAndAnimate(DrawerState.COLLAPSED);
|
public void hide(boolean immediate) {
|
||||||
|
setDrawerStateAndUpdate(DrawerState.COLLAPSED, immediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void open() {
|
@Override
|
||||||
setDrawerStateAndAnimate(DrawerState.HALF_EXPANDED);
|
public void show(int height, boolean immediate) {
|
||||||
|
setDrawerStateAndUpdate(DrawerState.HALF_EXPANDED, immediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onConfigurationChanged() {
|
public void onConfigurationChanged() {
|
||||||
@ -99,11 +101,11 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
final boolean rotationChanged = this.rotation != rotation;
|
final boolean rotationChanged = this.rotation != rotation;
|
||||||
this.rotation = rotation;
|
this.rotation = rotation;
|
||||||
if (rotationChanged) {
|
if (rotationChanged) {
|
||||||
if (isOpen()) {
|
if (isShowing()) {
|
||||||
quickCamera.onPause();
|
quickCamera.onPause();
|
||||||
}
|
}
|
||||||
updateControlsView();
|
updateControlsView();
|
||||||
setDrawerStateAndAnimate(drawerState);
|
setDrawerStateAndUpdate(drawerState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,23 +136,19 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
return isLandscape() || halfModeUnsupported;
|
return isLandscape() || halfModeUnsupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeyboardAwareLinearLayout getCoverView() {
|
private View getCoverView() {
|
||||||
if (coverView != null) return coverView;
|
if (coverView == null) coverView = getChildAt(coverViewPosition);
|
||||||
|
|
||||||
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;
|
return coverView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private KeyboardAwareLinearLayout getContainer() {
|
||||||
|
if (container == null) container = (KeyboardAwareLinearLayout)getParent();
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateHalfExpandedAnchorPoint() {
|
private void updateHalfExpandedAnchorPoint() {
|
||||||
if (getCoverView() != null) {
|
if (getContainer() != null) {
|
||||||
slideRange = getMeasuredHeight();
|
halfExpandedHeight = getContainer().getKeyboardHeight();
|
||||||
halfExpandedHeight = coverView.getKeyboardHeight();
|
|
||||||
halfExpandedAnchorPoint = computeSlideOffsetFromCoverBottom(slideRange - halfExpandedHeight);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,8 +157,6 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
final int paddingLeft = getPaddingLeft();
|
final int paddingLeft = getPaddingLeft();
|
||||||
final int paddingTop = getPaddingTop();
|
final int paddingTop = getPaddingTop();
|
||||||
|
|
||||||
updateHalfExpandedAnchorPoint();
|
|
||||||
|
|
||||||
for (int i = 0; i < getChildCount(); i++) {
|
for (int i = 0; i < getChildCount(); i++) {
|
||||||
final View child = getChildAt(i);
|
final View child = getChildAt(i);
|
||||||
final int childHeight = child.getMeasuredHeight();
|
final int childHeight = child.getMeasuredHeight();
|
||||||
@ -177,8 +173,8 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
} else if (child == controls) {
|
} else if (child == controls) {
|
||||||
childBottom = getMeasuredHeight();
|
childBottom = getMeasuredHeight();
|
||||||
} else {
|
} else {
|
||||||
childBottom = computeCoverBottomPosition(slideOffset);
|
childTop = computeCoverTopPosition(slideOffset);
|
||||||
childTop = childBottom - childHeight;
|
childBottom = childTop + childHeight;
|
||||||
}
|
}
|
||||||
final int childRight = childLeft + child.getMeasuredWidth();
|
final int childRight = childLeft + child.getMeasuredWidth();
|
||||||
|
|
||||||
@ -233,7 +229,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
default:
|
default:
|
||||||
childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
|
childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
child.measure(childWidthSpec, childHeightSpec);
|
child.measure(childWidthSpec, childHeightSpec);
|
||||||
}
|
}
|
||||||
@ -269,11 +265,11 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
ViewCompat.postInvalidateOnAnimation(this);
|
ViewCompat.postInvalidateOnAnimation(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slideOffset == COLLAPSED_ANCHOR_POINT && quickCamera.isStarted()) {
|
if (slideOffset == 0 && quickCamera.isStarted()) {
|
||||||
quickCamera.onPause();
|
quickCamera.onPause();
|
||||||
controls.setVisibility(INVISIBLE);
|
controls.setVisibility(INVISIBLE);
|
||||||
quickCamera.setVisibility(INVISIBLE);
|
quickCamera.setVisibility(INVISIBLE);
|
||||||
} else if (slideOffset != COLLAPSED_ANCHOR_POINT && !quickCamera.isStarted() & !paused) {
|
} else if (slideOffset != 0 && !quickCamera.isStarted() & !paused) {
|
||||||
controls.setVisibility(VISIBLE);
|
controls.setVisibility(VISIBLE);
|
||||||
quickCamera.setVisibility(VISIBLE);
|
quickCamera.setVisibility(VISIBLE);
|
||||||
quickCamera.onResume();
|
quickCamera.onResume();
|
||||||
@ -284,7 +280,6 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
switch (drawerState) {
|
switch (drawerState) {
|
||||||
case COLLAPSED:
|
case COLLAPSED:
|
||||||
fullScreenButton.setImageResource(R.drawable.quick_camera_fullscreen);
|
fullScreenButton.setImageResource(R.drawable.quick_camera_fullscreen);
|
||||||
if (listener != null) listener.onAttachmentDrawerClosed();
|
|
||||||
break;
|
break;
|
||||||
case HALF_EXPANDED:
|
case HALF_EXPANDED:
|
||||||
if (isFullscreenOnly()) {
|
if (isFullscreenOnly()) {
|
||||||
@ -292,30 +287,37 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fullScreenButton.setImageResource(R.drawable.quick_camera_fullscreen);
|
fullScreenButton.setImageResource(R.drawable.quick_camera_fullscreen);
|
||||||
if (listener != null) listener.onAttachmentDrawerOpened();
|
|
||||||
break;
|
break;
|
||||||
case FULL_EXPANDED:
|
case FULL_EXPANDED:
|
||||||
fullScreenButton.setImageResource(isFullscreenOnly() ? R.drawable.quick_camera_hide
|
fullScreenButton.setImageResource(isFullscreenOnly() ? R.drawable.quick_camera_hide
|
||||||
: R.drawable.quick_camera_exit_fullscreen);
|
: R.drawable.quick_camera_exit_fullscreen);
|
||||||
if (listener != null) listener.onAttachmentDrawerOpened();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
this.drawerState = drawerState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getTargetSlideOffset() {
|
if (listener != null && drawerState != this.drawerState) {
|
||||||
switch (drawerState) {
|
this.drawerState = drawerState;
|
||||||
case FULL_EXPANDED: return FULL_EXPANDED_ANCHOR_POINT;
|
listener.onAttachmentDrawerStateChanged(drawerState);
|
||||||
case HALF_EXPANDED: return halfExpandedAnchorPoint;
|
|
||||||
default: return COLLAPSED_ANCHOR_POINT;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDrawerStateAndAnimate(final DrawerState requestedDrawerState) {
|
public int getTargetSlideOffset() {
|
||||||
|
switch (drawerState) {
|
||||||
|
case FULL_EXPANDED: return getMeasuredHeight();
|
||||||
|
case HALF_EXPANDED: return halfExpandedHeight;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrawerStateAndUpdate(final DrawerState requestedDrawerState) {
|
||||||
|
setDrawerStateAndUpdate(requestedDrawerState, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrawerStateAndUpdate(final DrawerState requestedDrawerState, boolean instant) {
|
||||||
DrawerState oldDrawerState = this.drawerState;
|
DrawerState oldDrawerState = this.drawerState;
|
||||||
setDrawerState(requestedDrawerState);
|
setDrawerState(requestedDrawerState);
|
||||||
if (oldDrawerState != drawerState) {
|
if (oldDrawerState != drawerState) {
|
||||||
slideTo(getTargetSlideOffset());
|
updateHalfExpandedAnchorPoint();
|
||||||
|
slideTo(getTargetSlideOffset(), instant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,8 +327,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface AttachmentDrawerListener extends QuickCameraListener {
|
public interface AttachmentDrawerListener extends QuickCameraListener {
|
||||||
void onAttachmentDrawerClosed();
|
void onAttachmentDrawerStateChanged(DrawerState drawerState);
|
||||||
void onAttachmentDrawerOpened();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ViewDragHelperCallback extends ViewDragHelper.Callback {
|
private class ViewDragHelperCallback extends ViewDragHelper.Callback {
|
||||||
@ -351,10 +352,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
|
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
|
||||||
final int expandedTop = computeCoverBottomPosition(FULL_EXPANDED_ANCHOR_POINT) - coverView.getHeight();
|
slideOffset = Util.clamp(slideOffset - dy, 0, getMeasuredHeight());
|
||||||
final int collapsedTop = computeCoverBottomPosition(COLLAPSED_ANCHOR_POINT) - coverView.getHeight();
|
|
||||||
final int newTop = Math.min(Math.max(coverView.getTop() + dy, expandedTop), collapsedTop);
|
|
||||||
slideOffset = computeSlideOffsetFromCoverBottom(newTop + coverView.getHeight());
|
|
||||||
requestLayout();
|
requestLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,25 +365,20 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
if (direction > 1) {
|
if (direction > 1) {
|
||||||
drawerState = DrawerState.FULL_EXPANDED;
|
drawerState = DrawerState.FULL_EXPANDED;
|
||||||
} else if (direction < -1) {
|
} else if (direction < -1) {
|
||||||
boolean halfExpand = (slideOffset > halfExpandedAnchorPoint && !isLandscape());
|
boolean halfExpand = (slideOffset > halfExpandedHeight && !isLandscape());
|
||||||
drawerState = halfExpand ? DrawerState.HALF_EXPANDED : DrawerState.COLLAPSED;
|
drawerState = halfExpand ? DrawerState.HALF_EXPANDED : DrawerState.COLLAPSED;
|
||||||
} else if (!isLandscape()) {
|
} else if (!isLandscape()) {
|
||||||
if (halfExpandedAnchorPoint != 1 && slideOffset >= (1.f + halfExpandedAnchorPoint) / 2) {
|
if (slideOffset >= (halfExpandedHeight + getMeasuredHeight()) / 2) {
|
||||||
drawerState = DrawerState.FULL_EXPANDED;
|
drawerState = DrawerState.FULL_EXPANDED;
|
||||||
} else if (halfExpandedAnchorPoint == 1 && slideOffset >= 0.5f) {
|
} else if (slideOffset >= halfExpandedHeight / 2) {
|
||||||
drawerState = DrawerState.FULL_EXPANDED;
|
|
||||||
} else if (halfExpandedAnchorPoint != 1 && slideOffset >= halfExpandedAnchorPoint) {
|
|
||||||
drawerState = DrawerState.HALF_EXPANDED;
|
|
||||||
} else if (halfExpandedAnchorPoint != 1 && slideOffset >= halfExpandedAnchorPoint / 2) {
|
|
||||||
drawerState = DrawerState.HALF_EXPANDED;
|
drawerState = DrawerState.HALF_EXPANDED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setDrawerState(drawerState);
|
setDrawerState(drawerState);
|
||||||
float slideOffset = getTargetSlideOffset();
|
int slideOffset = getTargetSlideOffset();
|
||||||
dragHelper.captureChildView(coverView, 0);
|
dragHelper.captureChildView(coverView, 0);
|
||||||
Log.w(TAG, String.format("setting cover at %d", computeCoverBottomPosition(slideOffset) - coverView.getHeight()));
|
dragHelper.settleCapturedViewAt(coverView.getLeft(), computeCoverTopPosition(slideOffset));
|
||||||
dragHelper.settleCapturedViewAt(coverView.getLeft(), computeCoverBottomPosition(slideOffset) - coverView.getHeight());
|
|
||||||
dragHelper.captureChildView(quickCamera, 0);
|
dragHelper.captureChildView(quickCamera, 0);
|
||||||
dragHelper.settleCapturedViewAt(quickCamera.getLeft(), computeCameraTopPosition(slideOffset));
|
dragHelper.settleCapturedViewAt(quickCamera.getLeft(), computeCameraTopPosition(slideOffset));
|
||||||
ViewCompat.postInvalidateOnAnimation(QuickAttachmentDrawer.this);
|
ViewCompat.postInvalidateOnAnimation(QuickAttachmentDrawer.this);
|
||||||
@ -394,7 +387,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getViewVerticalDragRange(View child) {
|
public int getViewVerticalDragRange(View child) {
|
||||||
return slideRange;
|
return getMeasuredHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -465,28 +458,22 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
screenY >= viewLocation[1] && screenY < viewLocation[1] + quickCamera.getHeight();
|
screenY >= viewLocation[1] && screenY < viewLocation[1] + quickCamera.getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int computeCameraTopPosition(float slideOffset) {
|
private int computeCameraTopPosition(int slideOffset) {
|
||||||
float clampedOffset = slideOffset - halfExpandedAnchorPoint;
|
final int baseCameraTop = (quickCamera.getMeasuredHeight() - halfExpandedHeight) / 2;
|
||||||
if (clampedOffset < COLLAPSED_ANCHOR_POINT) {
|
final int baseOffset = getMeasuredHeight() - slideOffset - baseCameraTop;
|
||||||
clampedOffset = COLLAPSED_ANCHOR_POINT;
|
final float slop = Util.clamp((float)(slideOffset - halfExpandedHeight) / (getMeasuredHeight() - halfExpandedHeight),
|
||||||
} else {
|
0f,
|
||||||
clampedOffset = clampedOffset / (FULL_EXPANDED_ANCHOR_POINT - halfExpandedAnchorPoint);
|
1f);
|
||||||
}
|
return baseOffset + (int)(slop * baseCameraTop);
|
||||||
float slidePixelOffset = slideOffset * slideRange +
|
|
||||||
(quickCamera.getMeasuredHeight() - coverView.getKeyboardHeight()) / 2 *
|
|
||||||
(FULL_EXPANDED_ANCHOR_POINT - clampedOffset);
|
|
||||||
float marginPixelOffset = (getMeasuredHeight() - quickCamera.getMeasuredHeight()) / 2 * clampedOffset;
|
|
||||||
return (int) (getMeasuredHeight() - slidePixelOffset + marginPixelOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int computeCoverBottomPosition(float slideOffset) {
|
private int computeCoverTopPosition(int slideOffset) {
|
||||||
int slidePixelOffset = (int) (slideOffset * slideRange);
|
return getMeasuredHeight() - getPaddingBottom() - slideOffset - getCoverView().getMeasuredHeight();
|
||||||
return getMeasuredHeight() - getPaddingBottom() - slidePixelOffset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void slideTo(float slideOffset) {
|
private void slideTo(int slideOffset, boolean forceInstant) {
|
||||||
if (dragHelper != null && !halfModeUnsupported) {
|
if (dragHelper != null && !halfModeUnsupported && !forceInstant) {
|
||||||
dragHelper.smoothSlideViewTo(coverView, coverView.getLeft(), computeCoverBottomPosition(slideOffset) - coverView.getHeight());
|
dragHelper.smoothSlideViewTo(coverView, coverView.getLeft(), computeCoverTopPosition(slideOffset));
|
||||||
dragHelper.smoothSlideViewTo(quickCamera, quickCamera.getLeft(), computeCameraTopPosition(slideOffset));
|
dragHelper.smoothSlideViewTo(quickCamera, quickCamera.getLeft(), computeCameraTopPosition(slideOffset));
|
||||||
ViewCompat.postInvalidateOnAnimation(this);
|
ViewCompat.postInvalidateOnAnimation(this);
|
||||||
} else {
|
} else {
|
||||||
@ -497,11 +484,6 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float computeSlideOffsetFromCoverBottom(int topPosition) {
|
|
||||||
final int topBoundCollapsed = computeCoverBottomPosition(0);
|
|
||||||
return (float) (topBoundCollapsed - topPosition) / slideRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
paused = true;
|
paused = true;
|
||||||
quickCamera.onPause();
|
quickCamera.onPause();
|
||||||
@ -524,7 +506,7 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
boolean crop = drawerState != DrawerState.FULL_EXPANDED;
|
boolean crop = drawerState != DrawerState.FULL_EXPANDED;
|
||||||
int imageHeight = crop ? coverView.getKeyboardHeight() : quickCamera.getMeasuredHeight();
|
int imageHeight = crop ? getContainer().getKeyboardHeight() : quickCamera.getMeasuredHeight();
|
||||||
Rect previewRect = new Rect(0, 0, quickCamera.getMeasuredWidth(), imageHeight);
|
Rect previewRect = new Rect(0, 0, quickCamera.getMeasuredWidth(), imageHeight);
|
||||||
quickCamera.takePicture(previewRect);
|
quickCamera.takePicture(previewRect);
|
||||||
}
|
}
|
||||||
@ -543,11 +525,11 @@ public class QuickAttachmentDrawer extends ViewGroup {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (drawerState != DrawerState.FULL_EXPANDED) {
|
if (drawerState != DrawerState.FULL_EXPANDED) {
|
||||||
setDrawerStateAndAnimate(DrawerState.FULL_EXPANDED);
|
setDrawerStateAndUpdate(DrawerState.FULL_EXPANDED);
|
||||||
} else if (isFullscreenOnly()) {
|
} else if (isFullscreenOnly()) {
|
||||||
setDrawerStateAndAnimate(DrawerState.COLLAPSED);
|
setDrawerStateAndUpdate(DrawerState.COLLAPSED);
|
||||||
} else {
|
} else {
|
||||||
setDrawerStateAndAnimate(DrawerState.HALF_EXPANDED);
|
setDrawerStateAndUpdate(DrawerState.HALF_EXPANDED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package org.thoughtcrime.securesms.components.emoji;
|
package org.thoughtcrime.securesms.components.emoji;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.view.PagerAdapter;
|
import android.support.v4.view.PagerAdapter;
|
||||||
@ -18,7 +19,7 @@ import android.widget.LinearLayout;
|
|||||||
import com.astuetz.PagerSlidingTabStrip;
|
import com.astuetz.PagerSlidingTabStrip;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
import org.thoughtcrime.securesms.components.KeyboardAwareLinearLayout;
|
import org.thoughtcrime.securesms.components.InputManager.InputView;
|
||||||
import org.thoughtcrime.securesms.components.RepeatableImageKey;
|
import org.thoughtcrime.securesms.components.RepeatableImageKey;
|
||||||
import org.thoughtcrime.securesms.components.RepeatableImageKey.KeyEventListener;
|
import org.thoughtcrime.securesms.components.RepeatableImageKey.KeyEventListener;
|
||||||
import org.thoughtcrime.securesms.components.emoji.EmojiPageView.EmojiSelectionListener;
|
import org.thoughtcrime.securesms.components.emoji.EmojiPageView.EmojiSelectionListener;
|
||||||
@ -27,7 +28,7 @@ import org.thoughtcrime.securesms.util.ResUtil;
|
|||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class EmojiDrawer extends LinearLayout {
|
public class EmojiDrawer extends LinearLayout implements InputView {
|
||||||
private static final KeyEvent DELETE_KEY_EVENT = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
|
private static final KeyEvent DELETE_KEY_EVENT = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
|
||||||
|
|
||||||
private ViewPager pager;
|
private ViewPager pager;
|
||||||
@ -35,6 +36,7 @@ public class EmojiDrawer extends LinearLayout {
|
|||||||
private PagerSlidingTabStrip strip;
|
private PagerSlidingTabStrip strip;
|
||||||
private RecentEmojiPageModel recentModel;
|
private RecentEmojiPageModel recentModel;
|
||||||
private EmojiEventListener listener;
|
private EmojiEventListener listener;
|
||||||
|
private EmojiDrawerListener drawerListener;
|
||||||
|
|
||||||
public EmojiDrawer(Context context) {
|
public EmojiDrawer(Context context) {
|
||||||
this(context, null);
|
this(context, null);
|
||||||
@ -43,6 +45,9 @@ public class EmojiDrawer extends LinearLayout {
|
|||||||
public EmojiDrawer(Context context, AttributeSet attrs) {
|
public EmojiDrawer(Context context, AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
setOrientation(VERTICAL);
|
setOrientation(VERTICAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initView() {
|
||||||
final View v = LayoutInflater.from(getContext()).inflate(R.layout.emoji_drawer, this, true);
|
final View v = LayoutInflater.from(getContext()).inflate(R.layout.emoji_drawer, this, true);
|
||||||
initializeResources(v);
|
initializeResources(v);
|
||||||
initializePageModels();
|
initializePageModels();
|
||||||
@ -53,6 +58,10 @@ public class EmojiDrawer extends LinearLayout {
|
|||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setDrawerListener(EmojiDrawerListener listener) {
|
||||||
|
this.drawerListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
private void initializeResources(View v) {
|
private void initializeResources(View v) {
|
||||||
Log.w("EmojiDrawer", "initializeResources()");
|
Log.w("EmojiDrawer", "initializeResources()");
|
||||||
this.pager = (ViewPager) v.findViewById(R.id.emoji_pager);
|
this.pager = (ViewPager) v.findViewById(R.id.emoji_pager);
|
||||||
@ -66,20 +75,27 @@ public class EmojiDrawer extends LinearLayout {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public boolean isShowing() {
|
public boolean isShowing() {
|
||||||
return getVisibility() == VISIBLE;
|
return getVisibility() == VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void show(KeyboardAwareLinearLayout container) {
|
@Override
|
||||||
|
public void show(int height, boolean immediate) {
|
||||||
|
if (this.pager == null) initView();
|
||||||
ViewGroup.LayoutParams params = getLayoutParams();
|
ViewGroup.LayoutParams params = getLayoutParams();
|
||||||
params.height = container.getKeyboardHeight();
|
params.height = height;
|
||||||
Log.w("EmojiDrawer", "showing emoji drawer with height " + params.height);
|
Log.w("EmojiDrawer", "showing emoji drawer with height " + params.height);
|
||||||
setLayoutParams(params);
|
setLayoutParams(params);
|
||||||
setVisibility(VISIBLE);
|
setVisibility(VISIBLE);
|
||||||
|
if (drawerListener != null) drawerListener.onShown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dismiss() {
|
@Override
|
||||||
|
public void hide(boolean immediate) {
|
||||||
setVisibility(GONE);
|
setVisibility(GONE);
|
||||||
|
if (drawerListener != null) drawerListener.onHidden();
|
||||||
|
Log.w("EmojiDrawer", "hide()");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeEmojiGrid() {
|
private void initializeEmojiGrid() {
|
||||||
@ -161,4 +177,9 @@ public class EmojiDrawer extends LinearLayout {
|
|||||||
public interface EmojiEventListener extends EmojiSelectionListener {
|
public interface EmojiEventListener extends EmojiSelectionListener {
|
||||||
void onKeyEvent(KeyEvent keyEvent);
|
void onKeyEvent(KeyEvent keyEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface EmojiDrawerListener {
|
||||||
|
void onShown();
|
||||||
|
void onHidden();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,9 @@ import android.util.AttributeSet;
|
|||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.R;
|
import org.thoughtcrime.securesms.R;
|
||||||
|
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer.EmojiDrawerListener;
|
||||||
|
|
||||||
public class EmojiToggle extends ImageButton {
|
public class EmojiToggle extends ImageButton implements EmojiDrawerListener {
|
||||||
|
|
||||||
private Drawable emojiToggle;
|
private Drawable emojiToggle;
|
||||||
private Drawable imeToggle;
|
private Drawable imeToggle;
|
||||||
@ -48,4 +49,16 @@ public class EmojiToggle extends ImageButton {
|
|||||||
drawables.recycle();
|
drawables.recycle();
|
||||||
setToEmoji();
|
setToEmoji();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void attach(EmojiDrawer drawer) {
|
||||||
|
drawer.setDrawerListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void onShown() {
|
||||||
|
setToIme();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void onHidden() {
|
||||||
|
setToEmoji();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,4 +348,8 @@ public class Util {
|
|||||||
public static int clamp(int value, int min, int max) {
|
public static int clamp(int value, int min, int max) {
|
||||||
return Math.min(Math.max(value, min), max);
|
return Math.min(Math.max(value, min), max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float clamp(float value, float min, float max) {
|
||||||
|
return Math.min(Math.max(value, min), max);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user