Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #1946 Awesome bar copy url #2604

Merged
merged 1 commit into from Jan 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,7 +1,12 @@
package org.mozilla.vrbrowser.ui.widgets;

import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.net.Uri;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.StyleSpan;
Expand All @@ -12,21 +17,22 @@
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import androidx.annotation.NonNull;

import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.vrbrowser.R;
import org.mozilla.vrbrowser.audio.AudioEngine;
import org.mozilla.vrbrowser.ui.views.CustomListView;
import org.mozilla.vrbrowser.ui.widgets.dialogs.SelectionActionWidget;
import org.mozilla.vrbrowser.utils.ViewUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SuggestionsWidget extends UIWidget implements WidgetManagerDelegate.FocusChangeListener {
Expand All @@ -38,10 +44,12 @@ public class SuggestionsWidget extends UIWidget implements WidgetManagerDelegate
private URLBarPopupDelegate mURLBarDelegate;
private String mHighlightedText;
private AudioEngine mAudio;
private ClipboardManager mClipboard;
private SelectionActionWidget mSelectionMenu;

public interface URLBarPopupDelegate {
default void OnItemClicked(SuggestionItem item) {};
default void OnItemDeleted(SuggestionItem item) {};
default void OnItemClicked(SuggestionItem item) {}
default void OnItemLongClicked(SuggestionItem item) {}
}

public SuggestionsWidget(Context aContext) {
Expand Down Expand Up @@ -87,8 +95,12 @@ public void onAnimationRepeat(Animation animation) {

mAdapter = new SuggestionsAdapter(getContext(), R.layout.list_popup_window_item, new ArrayList<>());
mList.setAdapter(mAdapter);
mList.setOnItemClickListener(mClickListener);
mList.setOnItemLongClickListener(mLongClickListener);
mList.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> hideMenu());

mAudio = AudioEngine.fromContext(aContext);
mClipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);

mHighlightedText = "";
}
Expand Down Expand Up @@ -135,6 +147,7 @@ public void hideNoAnim(@HideFlags int aHideFlags) {
@Override
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
if (!ViewUtils.isEqualOrChildrenOf(this, newFocus)) {
hideMenu();
onDismiss();
}
}
Expand Down Expand Up @@ -200,7 +213,6 @@ private class ItemViewHolder {
ImageView favicon;
TextView title;
TextView url;
ImageButton delete;
View divider;
}

Expand All @@ -220,24 +232,18 @@ public View getView(int position, View convertView, ViewGroup parent) {

itemViewHolder.layout = listItem.findViewById(R.id.layout);
itemViewHolder.layout.setTag(R.string.position_tag, position);
itemViewHolder.layout.setOnClickListener(mRowListener);
itemViewHolder.favicon = listItem.findViewById(R.id.favicon);
itemViewHolder.title = listItem.findViewById(R.id.title);
itemViewHolder.url = listItem.findViewById(R.id.url);
itemViewHolder.delete = listItem.findViewById(R.id.delete);
itemViewHolder.delete.setTag(R.string.position_tag, position);
itemViewHolder.delete.setOnClickListener(mDeleteButtonListener);
itemViewHolder.divider = listItem.findViewById(R.id.divider);

listItem.setTag(R.string.list_item_view_tag, itemViewHolder);

listItem.setOnHoverListener(mHoverListener);
listItem.setOnTouchListener(mTouchListener);

} else {
itemViewHolder = (ItemViewHolder) listItem.getTag(R.string.list_item_view_tag);
itemViewHolder.layout.setTag(R.string.position_tag, position);
itemViewHolder.delete.setTag(R.string.position_tag, position);
}

SuggestionItem selectedItem = getItem(position);
Expand Down Expand Up @@ -274,7 +280,6 @@ public View getView(int position, View convertView, ViewGroup parent) {
itemViewHolder.favicon.setImageResource(R.drawable.ic_icon_bookmark);
}

itemViewHolder.delete.setVisibility(GONE);
itemViewHolder.favicon.setVisibility(VISIBLE);

if (position == 0) {
Expand All @@ -286,59 +291,6 @@ public View getView(int position, View convertView, ViewGroup parent) {
return listItem;
}

OnClickListener mDeleteButtonListener = v -> {
if (mAudio != null) {
mAudio.playSound(AudioEngine.Sound.CLICK);
}

int position = (Integer)v.getTag(R.string.position_tag);
SuggestionItem item = getItem(position);
mAdapter.remove(item);
mAdapter.notifyDataSetChanged();

if (mURLBarDelegate != null) {
mURLBarDelegate.OnItemDeleted(item);
}
};

OnClickListener mRowListener = v -> {
if (mAudio != null) {
mAudio.playSound(AudioEngine.Sound.CLICK);
}

hide(KEEP_WIDGET);

requestFocus();
requestFocusFromTouch();

if (mURLBarDelegate != null) {
int position = (Integer)v.getTag(R.string.position_tag);
SuggestionItem item = getItem(position);
mURLBarDelegate.OnItemClicked(item);
}
};

private OnTouchListener mTouchListener = (view, event) -> {
int position = (int)view.getTag(R.string.position_tag);
if (!isEnabled(position)) {
return false;
}

int ev = event.getActionMasked();
switch (ev) {
case MotionEvent.ACTION_UP:
view.setPressed(false);
view.performClick();
return true;

case MotionEvent.ACTION_DOWN:
view.setPressed(true);
return true;
}

return false;
};

private OnHoverListener mHoverListener = (view, motionEvent) -> {
int position = (int)view.getTag(R.string.position_tag);
if (!isEnabled(position)) {
Expand All @@ -348,7 +300,6 @@ public View getView(int position, View convertView, ViewGroup parent) {
View favicon = view.findViewById(R.id.favicon);
TextView title = view.findViewById(R.id.title);
View url = view.findViewById(R.id.url);
View delete = view.findViewById(R.id.delete);
int ev = motionEvent.getActionMasked();
switch (ev) {
case MotionEvent.ACTION_HOVER_ENTER:
Expand All @@ -357,7 +308,6 @@ public View getView(int position, View convertView, ViewGroup parent) {
title.setHovered(true);
title.setShadowLayer(title.getShadowRadius(), title.getShadowDx(), title.getShadowDy(), getContext().getColor(R.color.text_shadow_light));
url.setHovered(true);
delete.setHovered(true);
return true;

case MotionEvent.ACTION_HOVER_EXIT:
Expand All @@ -366,14 +316,97 @@ public View getView(int position, View convertView, ViewGroup parent) {
title.setHovered(false);
title.setShadowLayer(title.getShadowRadius(), title.getShadowDx(), title.getShadowDy(), getContext().getColor(R.color.text_shadow));
url.setHovered(false);
delete.setHovered(false);
return true;
}

return false;
};
}

private AdapterView.OnItemClickListener mClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (mAudio != null) {
mAudio.playSound(AudioEngine.Sound.CLICK);
}

hide(KEEP_WIDGET);

requestFocus();
requestFocusFromTouch();

if (mURLBarDelegate != null) {
SuggestionItem item = mAdapter.getItem(position);
mURLBarDelegate.OnItemClicked(item);
}
}
};

private AdapterView.OnItemLongClickListener mLongClickListener = new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
SuggestionItem item = mAdapter.getItem(position);

view.setHovered(true);

hideMenu();
if (item != null) {
showMenu(view, item);

return true;
}

return false;
}
};

private void showMenu(@NonNull View view, @NonNull SuggestionItem item) {
if (mSelectionMenu == null) {
mSelectionMenu = new SelectionActionWidget(getContext());
mSelectionMenu.mWidgetPlacement.parentHandle = getHandle();
mSelectionMenu.setActions(Collections.singleton(GeckoSession.SelectionActionDelegate.ACTION_COPY));
}

Rect offsetViewBounds = new Rect();
view.getDrawingRect(offsetViewBounds);
float ratio = WidgetPlacement.viewToWidgetRatio(getContext(), this);
offsetDescendantRectToMyCoords(view, offsetViewBounds);
RectF rectF = new RectF(
offsetViewBounds.left * ratio,
offsetViewBounds.top * ratio,
offsetViewBounds.right * ratio,
offsetViewBounds.bottom * ratio
);
mSelectionMenu.setSelectionRect(rectF);
mSelectionMenu.setDelegate(new SelectionActionWidget.Delegate() {
@Override
public void onAction(String action) {
hideMenu();
ClipData clip = ClipData.newRawUri(item.title, Uri.parse(item.url));
mClipboard.setPrimaryClip(clip);
}

@Override
public void onDismiss() {
hideMenu();
}
});
mSelectionMenu.show(KEEP_FOCUS);
}

private void hideMenu() {
if (mSelectionMenu != null) {
mSelectionMenu.setDelegate((SelectionActionWidget.Delegate)null);
if (!mSelectionMenu.isReleased()) {
if (mSelectionMenu.isVisible()) {
mSelectionMenu.hide(REMOVE_WIDGET);
}
mSelectionMenu.releaseWidget();
}
mSelectionMenu = null;
}
}

private SpannableStringBuilder createHighlightedText(@NonNull String text) {
final SpannableStringBuilder sb = new SpannableStringBuilder(text);
final StyleSpan bold = new StyleSpan(Typeface.BOLD);
Expand Down
Expand Up @@ -10,6 +10,7 @@
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.net.Uri;
import android.util.Log;
Expand Down Expand Up @@ -1726,7 +1727,17 @@ public void onShowActionRequest(@NonNull GeckoSession aSession, @NonNull Selecti
Matrix matrix = new Matrix();
aSession.getClientToSurfaceMatrix(matrix);
matrix.mapRect(aSelection.clientRect);
mSelectionMenu.setSelectionRect(aSelection.clientRect);
RectF selectionRect = null;
if (aSelection.clientRect != null) {
float ratio = WidgetPlacement.worldToWindowRatio(getContext());
selectionRect = new RectF(
aSelection.clientRect.left * ratio,
aSelection.clientRect.top* ratio,
aSelection.clientRect.right * ratio,
aSelection.clientRect.bottom * ratio
);
}
mSelectionMenu.setSelectionRect(selectionRect);
mSelectionMenu.setDelegate(new SelectionActionWidget.Delegate() {
@Override
public void onAction(String action) {
Expand Down
Expand Up @@ -16,11 +16,9 @@
import org.mozilla.vrbrowser.ui.widgets.UIWidget;
import org.mozilla.vrbrowser.ui.widgets.WidgetManagerDelegate;
import org.mozilla.vrbrowser.ui.widgets.WidgetPlacement;
import org.mozilla.vrbrowser.utils.StringUtils;
import org.mozilla.vrbrowser.utils.ViewUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

import static android.view.Gravity.CENTER_VERTICAL;
Expand Down Expand Up @@ -78,8 +76,8 @@ public void show(@ShowFlags int aShowFlags) {
if (mPosition != null) {
mWidgetPlacement.parentAnchorX = 0.0f;
mWidgetPlacement.parentAnchorY = 1.0f;
mWidgetPlacement.translationX = mPosition.x * WidgetPlacement.worldToWindowRatio(getContext());
mWidgetPlacement.translationY = -mPosition.y * WidgetPlacement.worldToWindowRatio(getContext());
mWidgetPlacement.translationX = mPosition.x;
mWidgetPlacement.translationY = -mPosition.y;
mWidgetPlacement.translationY += mWidgetPlacement.height * 0.5f;
}
super.show(aShowFlags);
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/drawable/selection_menu_background.xml
Expand Up @@ -3,5 +3,6 @@
android:shape="rectangle">
<corners android:radius="20dp" />
<stroke android:color="@color/asphalt_blur" android:width="@dimen/blur_radius" />
<stroke android:color="@color/iron" android:width="2dp"/>
<solid android:color="@color/asphalt"/>
</shape>
12 changes: 6 additions & 6 deletions app/src/main/res/drawable/selection_menu_background_triangle.xml
Expand Up @@ -9,22 +9,22 @@
android:name="trianglegroup"
android:pivotX="50"
android:pivotY="50"
android:scaleX="0.95"
android:scaleY="0.95"
android:scaleX="0.92"
android:scaleY="0.92"
android:translateY="-50"
android:rotation="180">
<path
android:name="triangle2"
android:pathData="M 50 0 L 100 50 L 0 50 Z"
android:strokeColor="@color/asphalt_blur"
android:strokeWidth="4"/>
android:strokeColor="@color/iron"
android:strokeWidth="6"/>
</group>
<group
android:name="trianglegroup2"
android:pivotX="50"
android:pivotY="50"
android:scaleX="0.90"
android:scaleY="0.90"
android:scaleX="0.85"
android:scaleY="0.85"
android:translateY="-50"
android:rotation="180">
<path
Expand Down