This repository has been archived by the owner on Jul 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 220
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* Improve notification visibility/management * Rebase fixes
- release/12.1-rc1
- release/12-rc6
- release/12-rc5
- release/12-rc4
- release/12-rc3
- release/12-rc2
- release/12-rc1
- release/11.2-rc2
- release/11.1-rc1
- release/11-rc11
- release/10.5-rc1
- release/10.4-rc1
- release/10.3-rc1
- release/10.2-rc4
- release/10.1
- release/10-rc7
- release/10-rc6
- release/10-rc5
- release/10-rc4
- release/10-rc3
- release/10-rc2
- release/10-rc1
- release/9.1+oculusvrStore+oculusvr3dofStore
- release/9-rc10
- release/9-rc9
- release/9-rc8
- release/9-rc7
- release/9-rc6
- release/9-rc5
- release/9-rc4
- release/9-rc3
- release/9-rc2
- release/9-rc1
- preview/10.1.coil.2+oculusvrStore
- preview/10.1.coil+oculusvrStore
- preview/10p2+picovr
- preview/10p1+picovr
- preview/10.focus+oculusvrStore
- preview/9.coil+oculusvrStore
- 12.3
- 12.2
Showing
10 changed files
with
419 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
280 changes: 280 additions & 0 deletions
280
app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/NotificationManager.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,280 @@ | ||
package org.mozilla.vrbrowser.ui.widgets; | ||
|
||
import android.graphics.Rect; | ||
import android.view.View; | ||
|
||
import androidx.annotation.DimenRes; | ||
import androidx.annotation.LayoutRes; | ||
import androidx.annotation.NonNull; | ||
import androidx.annotation.StringRes; | ||
|
||
import org.mozilla.gecko.util.ThreadUtils; | ||
import org.mozilla.vrbrowser.R; | ||
import org.mozilla.vrbrowser.ui.views.UIButton; | ||
|
||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.Map; | ||
|
||
public class NotificationManager { | ||
|
||
private static final int DEFAULT_DURATION = 3000; | ||
|
||
private static HashMap<Integer, NotificationData> mData = new HashMap<>(); | ||
|
||
private static class NotificationData { | ||
|
||
private TooltipWidget mNotificationView; | ||
private Notification mNotification; | ||
private Runnable mHideTask; | ||
|
||
public NotificationData(@NonNull TooltipWidget view, @NonNull Notification notification, @NonNull Runnable hideTask) { | ||
mNotificationView = view; | ||
mNotification = notification; | ||
mHideTask = hideTask; | ||
} | ||
|
||
} | ||
|
||
public static class Notification { | ||
|
||
public static final int MIDDLE = 0; | ||
public static final int TOP = 1; | ||
public static final int BOTTOM = 2; | ||
public static final int LEFT = 4; | ||
public static final int RIGHT = 8; | ||
|
||
private UIWidget mParent; | ||
private View mView; | ||
private String mString; | ||
private float mMargin; | ||
private float mZTranslation; | ||
private int mPositionFlags; | ||
private @DimenRes int mDensity; | ||
private @LayoutRes int mLayoutRes; | ||
private int mDuration; | ||
private boolean mCurved; | ||
|
||
public Notification(@NonNull Builder builder) { | ||
mParent = builder.parent; | ||
mView = builder.view; | ||
mString = builder.string; | ||
mMargin = builder.margin; | ||
mZTranslation = builder.zTranslation; | ||
mPositionFlags = builder.positionFlags; | ||
mDensity = builder.density; | ||
mLayoutRes = builder.layoutRes; | ||
mDuration = builder.duration; | ||
mCurved = builder.curved; | ||
} | ||
} | ||
|
||
public static class Builder { | ||
|
||
private UIWidget parent; | ||
private View view = null; | ||
private String string; | ||
private float margin = 0.0f; | ||
private float zTranslation = 0.0f; | ||
private int positionFlags = Notification.MIDDLE; | ||
private @DimenRes int density; | ||
private @LayoutRes int layoutRes = R.layout.library_notification; | ||
private int duration = DEFAULT_DURATION; | ||
private boolean curved = false; | ||
|
||
public Builder(@NonNull UIWidget parent) { | ||
this.parent = parent; | ||
this.density = R.dimen.tooltip_default_density; | ||
} | ||
|
||
public Builder withString(@StringRes int res) { | ||
this.string = parent.getContext().getString(res); | ||
return this; | ||
} | ||
|
||
public Builder withString(String string) { | ||
this.string = string; | ||
return this; | ||
} | ||
|
||
public Builder withView(@NonNull View view) { | ||
this.view = view; | ||
return this; | ||
} | ||
|
||
public Builder withMargin(float margin){ | ||
this.margin = margin; | ||
return this; | ||
} | ||
|
||
public Builder withPosition(int positionFlags) { | ||
this.positionFlags = positionFlags; | ||
return this; | ||
} | ||
|
||
public Builder withZTranslation(float translation) { | ||
this.zTranslation = translation; | ||
return this; | ||
} | ||
|
||
public Builder withDensity(@DimenRes int density) { | ||
this.density = density; | ||
return this; | ||
} | ||
|
||
public Builder withLayout(@LayoutRes int res) { | ||
this.layoutRes = res; | ||
return this; | ||
} | ||
|
||
public Builder withDuration(int duration) { | ||
this.duration = duration; | ||
return this; | ||
} | ||
|
||
public Builder withCurved(boolean curved) { | ||
this.curved = curved; | ||
return this; | ||
} | ||
|
||
public Notification build(){ | ||
return new Notification(this); | ||
} | ||
} | ||
|
||
|
||
public static void show(int notificationId, @NonNull Notification notification) { | ||
if (mData.containsKey(notificationId)) { | ||
return; | ||
} | ||
|
||
TooltipWidget notificationView = new TooltipWidget(notification.mParent.getContext(), notification.mLayoutRes); | ||
|
||
notification.mParent.requestFocus(); | ||
notification.mParent.requestFocusFromTouch(); | ||
|
||
setPlacement(notificationView, notification); | ||
|
||
notificationView.setText(notification.mString); | ||
notificationView.setCurvedMode(false); | ||
notificationView.show(UIWidget.CLEAR_FOCUS); | ||
|
||
if (notification.mView instanceof UIButton) { | ||
((UIButton)notification.mView).setNotificationMode(true); | ||
} | ||
|
||
Runnable hideTask = () -> hide(notificationId); | ||
ThreadUtils.postDelayedToUiThread(hideTask, notification.mDuration); | ||
|
||
mData.put(notificationId, new NotificationData(notificationView, notification, hideTask)); | ||
} | ||
|
||
public static void hide(int notificationId) { | ||
if (!mData.containsKey(notificationId)) { | ||
return; | ||
} | ||
|
||
NotificationData data = mData.get(notificationId); | ||
if (data != null && data.mNotificationView.isVisible()) { | ||
ThreadUtils.removeCallbacksFromUiThread(data.mHideTask); | ||
|
||
data.mNotificationView.hide(UIWidget.REMOVE_WIDGET); | ||
|
||
if (data.mNotification.mView instanceof UIButton) { | ||
((UIButton)data.mNotification.mView).setNotificationMode(false); | ||
} | ||
|
||
mData.remove(notificationId); | ||
} | ||
} | ||
|
||
public static void hideAll() { | ||
Iterator<Map.Entry<Integer, NotificationData>> it = mData.entrySet().iterator(); | ||
while (it.hasNext()) { | ||
hide(it.next().getKey()); | ||
} | ||
} | ||
|
||
private static void setPlacement(@NonNull TooltipWidget notificationView, @NonNull Notification notification) { | ||
notificationView.getPlacement().parentHandle = notification.mParent.getHandle(); | ||
notificationView.getPlacement().density = WidgetPlacement.floatDimension(notification.mParent.getContext(), notification.mDensity); | ||
notificationView.getPlacement().translationZ = notification.mZTranslation; | ||
notificationView.getPlacement().cylinder = notification.mCurved; | ||
|
||
Rect offsetViewBounds = new Rect(); | ||
if (notification.mView != null) { | ||
notification.mParent.getDrawingRect(offsetViewBounds); | ||
notification.mParent.offsetDescendantRectToMyCoords(notification.mView, offsetViewBounds); | ||
} | ||
|
||
int width = 0; | ||
int height = 0; | ||
float ratio = 1.0f; | ||
if (notification.mView != null) { | ||
width = notification.mView.getWidth(); | ||
height = notification.mView.getHeight(); | ||
ratio = WidgetPlacement.viewToWidgetRatio(notification.mParent.getContext(), notification.mParent); | ||
} | ||
|
||
if (notification.mView == null) { | ||
notificationView.getPlacement().anchorX = 0.5f; | ||
notificationView.getPlacement().parentAnchorX = 0.5f; | ||
notificationView.getPlacement().anchorY = 0.5f; | ||
notificationView.getPlacement().parentAnchorY = 0.5f; | ||
|
||
if ((notification.mPositionFlags & Notification.TOP) == Notification.TOP) { | ||
notificationView.getPlacement().anchorY = 0.0f; | ||
notificationView.getPlacement().parentAnchorY = 1.0f; | ||
notificationView.getPlacement().translationY = notification.mMargin; | ||
} | ||
|
||
if ((notification.mPositionFlags & Notification.BOTTOM) == Notification.BOTTOM) { | ||
notificationView.getPlacement().anchorY = 1.0f; | ||
notificationView.getPlacement().parentAnchorY = 0.0f; | ||
notificationView.getPlacement().translationY = -notification.mMargin; | ||
} | ||
|
||
if ((notification.mPositionFlags & Notification.LEFT) == Notification.LEFT) { | ||
notificationView.getPlacement().anchorX = 1.0f; | ||
notificationView.getPlacement().parentAnchorX = 0.0f; | ||
notificationView.getPlacement().translationX = -notification.mMargin; | ||
} | ||
|
||
if ((notification.mPositionFlags & Notification.RIGHT) == Notification.RIGHT) { | ||
notificationView.getPlacement().anchorX = 0.0f; | ||
notificationView.getPlacement().parentAnchorX = 1.0f; | ||
notificationView.getPlacement().translationX = notification.mMargin; | ||
} | ||
|
||
} else { | ||
notificationView.getPlacement().parentAnchorX = 0.0f; | ||
notificationView.getPlacement().parentAnchorY = 1.0f; | ||
notificationView.getPlacement().anchorX = 0.5f; | ||
notificationView.getPlacement().anchorY = 0.5f; | ||
|
||
notificationView.getPlacement().translationX = (offsetViewBounds.left + (width / 2.0f)) * ratio; | ||
notificationView.getPlacement().translationY = -(offsetViewBounds.bottom - (height / 2.0f)) * ratio; | ||
|
||
if ((notification.mPositionFlags & Notification.TOP) == Notification.TOP) { | ||
notificationView.getPlacement().anchorY = 0.0f; | ||
notificationView.getPlacement().translationY = (offsetViewBounds.top + notification.mMargin) * ratio; | ||
} | ||
|
||
if ((notification.mPositionFlags & Notification.BOTTOM) == Notification.BOTTOM) { | ||
notificationView.getPlacement().anchorY = 1.0f; | ||
notificationView.getPlacement().translationY = -(offsetViewBounds.bottom + notification.mMargin) * ratio; | ||
} | ||
|
||
if ((notification.mPositionFlags & Notification.LEFT) == Notification.LEFT) { | ||
notificationView.getPlacement().anchorX = 1.0f; | ||
notificationView.getPlacement().translationX = (offsetViewBounds.left - notification.mMargin) * ratio; | ||
} | ||
|
||
if ((notification.mPositionFlags & Notification.RIGHT) == Notification.RIGHT) { | ||
notificationView.getPlacement().anchorX = 0.0f; | ||
notificationView.getPlacement().translationX = (offsetViewBounds.left + width + notification.mMargin) * ratio; | ||
} | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters