Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 790ad83

Browse files
keianhzobluemarvin
authored andcommittedJan 10, 2020
Awesome bar copy url (#2604)
1 parent 970212e commit 790ad83

File tree

6 files changed

+124
-91
lines changed

6 files changed

+124
-91
lines changed
 

‎app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/SuggestionsWidget.java

+102-69
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
package org.mozilla.vrbrowser.ui.widgets;
22

3+
import android.content.ClipData;
4+
import android.content.ClipboardManager;
35
import android.content.Context;
6+
import android.graphics.Rect;
7+
import android.graphics.RectF;
48
import android.graphics.Typeface;
9+
import android.net.Uri;
510
import android.text.Spannable;
611
import android.text.SpannableStringBuilder;
712
import android.text.style.StyleSpan;
@@ -12,21 +17,22 @@
1217
import android.view.ViewGroup;
1318
import android.view.animation.Animation;
1419
import android.view.animation.AnimationUtils;
20+
import android.widget.AdapterView;
1521
import android.widget.ArrayAdapter;
16-
import android.widget.ImageButton;
1722
import android.widget.ImageView;
18-
import android.widget.ListView;
1923
import android.widget.TextView;
2024

2125
import androidx.annotation.NonNull;
2226

23-
import org.mozilla.gecko.util.ThreadUtils;
27+
import org.mozilla.geckoview.GeckoSession;
2428
import org.mozilla.vrbrowser.R;
2529
import org.mozilla.vrbrowser.audio.AudioEngine;
2630
import org.mozilla.vrbrowser.ui.views.CustomListView;
31+
import org.mozilla.vrbrowser.ui.widgets.dialogs.SelectionActionWidget;
2732
import org.mozilla.vrbrowser.utils.ViewUtils;
2833

2934
import java.util.ArrayList;
35+
import java.util.Collections;
3036
import java.util.List;
3137

3238
public class SuggestionsWidget extends UIWidget implements WidgetManagerDelegate.FocusChangeListener {
@@ -38,10 +44,12 @@ public class SuggestionsWidget extends UIWidget implements WidgetManagerDelegate
3844
private URLBarPopupDelegate mURLBarDelegate;
3945
private String mHighlightedText;
4046
private AudioEngine mAudio;
47+
private ClipboardManager mClipboard;
48+
private SelectionActionWidget mSelectionMenu;
4149

4250
public interface URLBarPopupDelegate {
43-
default void OnItemClicked(SuggestionItem item) {};
44-
default void OnItemDeleted(SuggestionItem item) {};
51+
default void OnItemClicked(SuggestionItem item) {}
52+
default void OnItemLongClicked(SuggestionItem item) {}
4553
}
4654

4755
public SuggestionsWidget(Context aContext) {
@@ -87,8 +95,12 @@ public void onAnimationRepeat(Animation animation) {
8795

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

91102
mAudio = AudioEngine.fromContext(aContext);
103+
mClipboard = (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
92104

93105
mHighlightedText = "";
94106
}
@@ -135,6 +147,7 @@ public void hideNoAnim(@HideFlags int aHideFlags) {
135147
@Override
136148
public void onGlobalFocusChanged(View oldFocus, View newFocus) {
137149
if (!ViewUtils.isEqualOrChildrenOf(this, newFocus)) {
150+
hideMenu();
138151
onDismiss();
139152
}
140153
}
@@ -200,7 +213,6 @@ private class ItemViewHolder {
200213
ImageView favicon;
201214
TextView title;
202215
TextView url;
203-
ImageButton delete;
204216
View divider;
205217
}
206218

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

221233
itemViewHolder.layout = listItem.findViewById(R.id.layout);
222234
itemViewHolder.layout.setTag(R.string.position_tag, position);
223-
itemViewHolder.layout.setOnClickListener(mRowListener);
224235
itemViewHolder.favicon = listItem.findViewById(R.id.favicon);
225236
itemViewHolder.title = listItem.findViewById(R.id.title);
226237
itemViewHolder.url = listItem.findViewById(R.id.url);
227-
itemViewHolder.delete = listItem.findViewById(R.id.delete);
228-
itemViewHolder.delete.setTag(R.string.position_tag, position);
229-
itemViewHolder.delete.setOnClickListener(mDeleteButtonListener);
230238
itemViewHolder.divider = listItem.findViewById(R.id.divider);
231239

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

234242
listItem.setOnHoverListener(mHoverListener);
235-
listItem.setOnTouchListener(mTouchListener);
236243

237244
} else {
238245
itemViewHolder = (ItemViewHolder) listItem.getTag(R.string.list_item_view_tag);
239246
itemViewHolder.layout.setTag(R.string.position_tag, position);
240-
itemViewHolder.delete.setTag(R.string.position_tag, position);
241247
}
242248

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

277-
itemViewHolder.delete.setVisibility(GONE);
278283
itemViewHolder.favicon.setVisibility(VISIBLE);
279284

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

289-
OnClickListener mDeleteButtonListener = v -> {
290-
if (mAudio != null) {
291-
mAudio.playSound(AudioEngine.Sound.CLICK);
292-
}
293-
294-
int position = (Integer)v.getTag(R.string.position_tag);
295-
SuggestionItem item = getItem(position);
296-
mAdapter.remove(item);
297-
mAdapter.notifyDataSetChanged();
298-
299-
if (mURLBarDelegate != null) {
300-
mURLBarDelegate.OnItemDeleted(item);
301-
}
302-
};
303-
304-
OnClickListener mRowListener = v -> {
305-
if (mAudio != null) {
306-
mAudio.playSound(AudioEngine.Sound.CLICK);
307-
}
308-
309-
hide(KEEP_WIDGET);
310-
311-
requestFocus();
312-
requestFocusFromTouch();
313-
314-
if (mURLBarDelegate != null) {
315-
int position = (Integer)v.getTag(R.string.position_tag);
316-
SuggestionItem item = getItem(position);
317-
mURLBarDelegate.OnItemClicked(item);
318-
}
319-
};
320-
321-
private OnTouchListener mTouchListener = (view, event) -> {
322-
int position = (int)view.getTag(R.string.position_tag);
323-
if (!isEnabled(position)) {
324-
return false;
325-
}
326-
327-
int ev = event.getActionMasked();
328-
switch (ev) {
329-
case MotionEvent.ACTION_UP:
330-
view.setPressed(false);
331-
view.performClick();
332-
return true;
333-
334-
case MotionEvent.ACTION_DOWN:
335-
view.setPressed(true);
336-
return true;
337-
}
338-
339-
return false;
340-
};
341-
342294
private OnHoverListener mHoverListener = (view, motionEvent) -> {
343295
int position = (int)view.getTag(R.string.position_tag);
344296
if (!isEnabled(position)) {
@@ -348,7 +300,6 @@ public View getView(int position, View convertView, ViewGroup parent) {
348300
View favicon = view.findViewById(R.id.favicon);
349301
TextView title = view.findViewById(R.id.title);
350302
View url = view.findViewById(R.id.url);
351-
View delete = view.findViewById(R.id.delete);
352303
int ev = motionEvent.getActionMasked();
353304
switch (ev) {
354305
case MotionEvent.ACTION_HOVER_ENTER:
@@ -357,7 +308,6 @@ public View getView(int position, View convertView, ViewGroup parent) {
357308
title.setHovered(true);
358309
title.setShadowLayer(title.getShadowRadius(), title.getShadowDx(), title.getShadowDy(), getContext().getColor(R.color.text_shadow_light));
359310
url.setHovered(true);
360-
delete.setHovered(true);
361311
return true;
362312

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

373322
return false;
374323
};
375324
}
376325

326+
private AdapterView.OnItemClickListener mClickListener = new AdapterView.OnItemClickListener() {
327+
@Override
328+
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
329+
if (mAudio != null) {
330+
mAudio.playSound(AudioEngine.Sound.CLICK);
331+
}
332+
333+
hide(KEEP_WIDGET);
334+
335+
requestFocus();
336+
requestFocusFromTouch();
337+
338+
if (mURLBarDelegate != null) {
339+
SuggestionItem item = mAdapter.getItem(position);
340+
mURLBarDelegate.OnItemClicked(item);
341+
}
342+
}
343+
};
344+
345+
private AdapterView.OnItemLongClickListener mLongClickListener = new AdapterView.OnItemLongClickListener() {
346+
@Override
347+
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
348+
SuggestionItem item = mAdapter.getItem(position);
349+
350+
view.setHovered(true);
351+
352+
hideMenu();
353+
if (item != null) {
354+
showMenu(view, item);
355+
356+
return true;
357+
}
358+
359+
return false;
360+
}
361+
};
362+
363+
private void showMenu(@NonNull View view, @NonNull SuggestionItem item) {
364+
if (mSelectionMenu == null) {
365+
mSelectionMenu = new SelectionActionWidget(getContext());
366+
mSelectionMenu.mWidgetPlacement.parentHandle = getHandle();
367+
mSelectionMenu.setActions(Collections.singleton(GeckoSession.SelectionActionDelegate.ACTION_COPY));
368+
}
369+
370+
Rect offsetViewBounds = new Rect();
371+
view.getDrawingRect(offsetViewBounds);
372+
float ratio = WidgetPlacement.viewToWidgetRatio(getContext(), this);
373+
offsetDescendantRectToMyCoords(view, offsetViewBounds);
374+
RectF rectF = new RectF(
375+
offsetViewBounds.left * ratio,
376+
offsetViewBounds.top * ratio,
377+
offsetViewBounds.right * ratio,
378+
offsetViewBounds.bottom * ratio
379+
);
380+
mSelectionMenu.setSelectionRect(rectF);
381+
mSelectionMenu.setDelegate(new SelectionActionWidget.Delegate() {
382+
@Override
383+
public void onAction(String action) {
384+
hideMenu();
385+
ClipData clip = ClipData.newRawUri(item.title, Uri.parse(item.url));
386+
mClipboard.setPrimaryClip(clip);
387+
}
388+
389+
@Override
390+
public void onDismiss() {
391+
hideMenu();
392+
}
393+
});
394+
mSelectionMenu.show(KEEP_FOCUS);
395+
}
396+
397+
private void hideMenu() {
398+
if (mSelectionMenu != null) {
399+
mSelectionMenu.setDelegate((SelectionActionWidget.Delegate)null);
400+
if (!mSelectionMenu.isReleased()) {
401+
if (mSelectionMenu.isVisible()) {
402+
mSelectionMenu.hide(REMOVE_WIDGET);
403+
}
404+
mSelectionMenu.releaseWidget();
405+
}
406+
mSelectionMenu = null;
407+
}
408+
}
409+
377410
private SpannableStringBuilder createHighlightedText(@NonNull String text) {
378411
final SpannableStringBuilder sb = new SpannableStringBuilder(text);
379412
final StyleSpan bold = new StyleSpan(Typeface.BOLD);

‎app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/WindowWidget.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import android.graphics.Matrix;
1111
import android.graphics.PointF;
1212
import android.graphics.Rect;
13+
import android.graphics.RectF;
1314
import android.graphics.SurfaceTexture;
1415
import android.net.Uri;
1516
import android.util.Log;
@@ -1726,7 +1727,17 @@ public void onShowActionRequest(@NonNull GeckoSession aSession, @NonNull Selecti
17261727
Matrix matrix = new Matrix();
17271728
aSession.getClientToSurfaceMatrix(matrix);
17281729
matrix.mapRect(aSelection.clientRect);
1729-
mSelectionMenu.setSelectionRect(aSelection.clientRect);
1730+
RectF selectionRect = null;
1731+
if (aSelection.clientRect != null) {
1732+
float ratio = WidgetPlacement.worldToWindowRatio(getContext());
1733+
selectionRect = new RectF(
1734+
aSelection.clientRect.left * ratio,
1735+
aSelection.clientRect.top* ratio,
1736+
aSelection.clientRect.right * ratio,
1737+
aSelection.clientRect.bottom * ratio
1738+
);
1739+
}
1740+
mSelectionMenu.setSelectionRect(selectionRect);
17301741
mSelectionMenu.setDelegate(new SelectionActionWidget.Delegate() {
17311742
@Override
17321743
public void onAction(String action) {

‎app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/SelectionActionWidget.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616
import org.mozilla.vrbrowser.ui.widgets.UIWidget;
1717
import org.mozilla.vrbrowser.ui.widgets.WidgetManagerDelegate;
1818
import org.mozilla.vrbrowser.ui.widgets.WidgetPlacement;
19-
import org.mozilla.vrbrowser.utils.StringUtils;
2019
import org.mozilla.vrbrowser.utils.ViewUtils;
2120

2221
import java.util.ArrayList;
23-
import java.util.Arrays;
2422
import java.util.Collection;
2523

2624
import static android.view.Gravity.CENTER_VERTICAL;
@@ -78,8 +76,8 @@ public void show(@ShowFlags int aShowFlags) {
7876
if (mPosition != null) {
7977
mWidgetPlacement.parentAnchorX = 0.0f;
8078
mWidgetPlacement.parentAnchorY = 1.0f;
81-
mWidgetPlacement.translationX = mPosition.x * WidgetPlacement.worldToWindowRatio(getContext());
82-
mWidgetPlacement.translationY = -mPosition.y * WidgetPlacement.worldToWindowRatio(getContext());
79+
mWidgetPlacement.translationX = mPosition.x;
80+
mWidgetPlacement.translationY = -mPosition.y;
8381
mWidgetPlacement.translationY += mWidgetPlacement.height * 0.5f;
8482
}
8583
super.show(aShowFlags);

‎app/src/main/res/drawable/selection_menu_background.xml

+1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
android:shape="rectangle">
44
<corners android:radius="20dp" />
55
<stroke android:color="@color/asphalt_blur" android:width="@dimen/blur_radius" />
6+
<stroke android:color="@color/iron" android:width="2dp"/>
67
<solid android:color="@color/asphalt"/>
78
</shape>

‎app/src/main/res/drawable/selection_menu_background_triangle.xml

+6-6
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,22 @@
99
android:name="trianglegroup"
1010
android:pivotX="50"
1111
android:pivotY="50"
12-
android:scaleX="0.95"
13-
android:scaleY="0.95"
12+
android:scaleX="0.92"
13+
android:scaleY="0.92"
1414
android:translateY="-50"
1515
android:rotation="180">
1616
<path
1717
android:name="triangle2"
1818
android:pathData="M 50 0 L 100 50 L 0 50 Z"
19-
android:strokeColor="@color/asphalt_blur"
20-
android:strokeWidth="4"/>
19+
android:strokeColor="@color/iron"
20+
android:strokeWidth="6"/>
2121
</group>
2222
<group
2323
android:name="trianglegroup2"
2424
android:pivotX="50"
2525
android:pivotY="50"
26-
android:scaleX="0.90"
27-
android:scaleY="0.90"
26+
android:scaleX="0.85"
27+
android:scaleY="0.85"
2828
android:translateY="-50"
2929
android:rotation="180">
3030
<path

‎app/src/main/res/layout/list_popup_window_item.xml

+1-11
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
android:layout_centerHorizontal="false"
3737
android:layout_centerVertical="true"
3838
android:layout_gravity="center_vertical"
39-
android:layout_toLeftOf="@+id/delete"
39+
android:layout_alignParentEnd="true"
4040
android:layout_toRightOf="@+id/favicon"
4141
android:gravity="left|center_vertical"
4242
android:orientation="vertical">
@@ -66,16 +66,6 @@
6666
android:visibility="visible"
6767
tools:text="item URL" />
6868
</LinearLayout>
69-
70-
<ImageButton
71-
android:id="@+id/delete"
72-
android:layout_width="20dp"
73-
android:layout_height="20dp"
74-
android:layout_alignParentEnd="true"
75-
android:layout_centerVertical="true"
76-
android:layout_gravity="center_vertical"
77-
android:background="@drawable/ic_icon_clear"
78-
android:backgroundTint="@drawable/suggestion_icon_color" />
7969
</RelativeLayout>
8070

8171
<LinearLayout

0 commit comments

Comments
 (0)
This repository has been archived.