Skip to content

Commit

Permalink
Move Bookmarks and Downloads to the tray
Browse files Browse the repository at this point in the history
For convenience, replace the Library button with separate buttons for
the Bookmarks and Downloads. This is the first step in reorganizing
the Library and Tray.

Simplify the code to animate the buttons' padding when selected.
  • Loading branch information
felipeerias committed Dec 4, 2024
1 parent a467cf1 commit 32af1ff
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1291,7 +1291,16 @@ public void onPrivateBrowsingClicked() {
}

@Override
public void onLibraryClicked() {
public void onBookmarksClicked() {
onLibraryClicked();
}

@Override
public void onDownloadsClicked() {
onLibraryClicked();
}

private void onLibraryClicked() {
if (mAttachedWindow.isResizing()) {
exitResizeMode(ResizeAction.RESTORE_SIZE);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ public interface TrayListener {
default void onPrivateBrowsingClicked() {}
default void onAddWindowClicked() {}
default void onTabsClicked() {}
default void onLibraryClicked() {}
default void onBookmarksClicked() {}
default void onDownloadsClicked() {}
}
132 changes: 64 additions & 68 deletions app/src/common/shared/com/igalia/wolvic/ui/widgets/TrayWidget.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

package com.igalia.wolvic.ui.widgets;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
Expand All @@ -27,7 +25,6 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;

import androidx.annotation.NonNull;
import androidx.databinding.DataBindingUtil;
Expand Down Expand Up @@ -217,13 +214,23 @@ public void updateUI() {
notifyAddWindowClicked();
});

mBinding.libraryButton.setOnHoverListener(mButtonScaleHoverListener);
mBinding.libraryButton.setOnClickListener(view -> {
mBinding.bookmarksButton.setOnHoverListener(mButtonScaleHoverListener);
mBinding.bookmarksButton.setOnClickListener(view -> {
if (mAudio != null) {
mAudio.playSound(AudioEngine.Sound.CLICK);
}

notifyLibraryClicked();
notifyBookmarksClicked();
view.requestFocusFromTouch();
});

mBinding.downloadsButton.setOnHoverListener(mButtonScaleHoverListener);
mBinding.downloadsButton.setOnClickListener(view -> {
if (mAudio != null) {
mAudio.playSound(AudioEngine.Sound.CLICK);
}

notifyDownloadsClicked();
view.requestFocusFromTouch();
});

Expand Down Expand Up @@ -399,72 +406,54 @@ public void onConfigurationChanged(Configuration newConfig) {
}

private OnHoverListener mButtonScaleHoverListener = (view, motionEvent) -> {
UIButton button = (UIButton)view;
UIButton button = (UIButton) view;
if (button.isActive() || button.isPrivate()) {
return false;
}

int ev = motionEvent.getActionMasked();
switch (ev) {
case MotionEvent.ACTION_HOVER_ENTER:
if (!view.isPressed() && ViewUtils.isInsideView(view, (int)motionEvent.getRawX(), (int)motionEvent.getRawY())) {
animateViewPadding(view, mMaxPadding, mMinPadding, ICON_ANIMATION_DURATION);
if (!button.isPressed() && ViewUtils.isInsideView(button, (int) motionEvent.getRawX(), (int) motionEvent.getRawY())) {
animateButtonPadding(button, mMinPadding, ICON_ANIMATION_DURATION);
}
return false;

case MotionEvent.ACTION_HOVER_EXIT:
if (!ViewUtils.isInsideView(view, (int)motionEvent.getRawX(), (int)motionEvent.getRawY())) {
animateViewPadding(view, mMinPadding, mMaxPadding, ICON_ANIMATION_DURATION);
if (!ViewUtils.isInsideView(button, (int) motionEvent.getRawX(), (int) motionEvent.getRawY())) {
animateButtonPadding(button, mMaxPadding, ICON_ANIMATION_DURATION);
}
return false;
}

return false;
};

private void animateViewPadding(View view, int paddingStart, int paddingEnd, int duration) {
if (view.isPressed() || !mIsWindowAttached) {
view.setPadding(paddingEnd, paddingEnd, paddingEnd, paddingEnd);
// This animation assumes that the padding is always symmetrical.
private void animateButtonPadding(UIButton button, int paddingEnd, int duration) {
if (button.getPaddingLeft() == paddingEnd) {
return;
}

ValueAnimator animation = ValueAnimator.ofInt(paddingStart, paddingEnd);
animation.setDuration(duration);
animation.setInterpolator(new AccelerateDecelerateInterpolator());
animation.addUpdateListener(valueAnimator -> {
try {
int newPadding = Integer.parseInt(valueAnimator.getAnimatedValue().toString());
view.setPadding(newPadding, newPadding, newPadding, newPadding);
}
catch (NumberFormatException ex) {
Log.e(LOGTAG, "Error parsing tray animation value: " + valueAnimator.getAnimatedValue().toString());
}
});
animation.addListener(new Animator.AnimatorListener() {

@Override
public void onAnimationStart(Animator animator) {
}

@Override
public void onAnimationEnd(Animator animator) {
UIButton button = (UIButton)view;
if(button.isActive() || button.isPrivate()) {
view.setPadding(mMinPadding, mMinPadding, mMinPadding, mMinPadding);
}
}

@Override
public void onAnimationCancel(Animator animator) {

}

@Override
public void onAnimationRepeat(Animator animator) {
if (button.isPressed() || !mIsWindowAttached) {
button.setPadding(paddingEnd, paddingEnd, paddingEnd, paddingEnd);
return;
}

}
});
animation.start();
int paddingStart = button.getPaddingLeft();
button.animate()
.setDuration(duration)
.setUpdateListener(animation -> {
float progress = animation.getAnimatedFraction();
int interpolatedPadding = (int) (paddingStart + progress * (paddingEnd - paddingStart));
button.setPadding(interpolatedPadding, interpolatedPadding, interpolatedPadding, interpolatedPadding);
})
.withEndAction(() -> {
if (button.isActive() || button.isPrivate()) {
button.setPadding(mMinPadding, mMinPadding, mMinPadding, mMinPadding);
}
})
.start();
}

public void addListeners(TrayListener... listeners) {
Expand All @@ -490,9 +479,14 @@ private void notifyAddWindowClicked() {
mTrayListeners.forEach(TrayListener::onAddWindowClicked);
}

private void notifyLibraryClicked() {
private void notifyBookmarksClicked() {
hideNotifications();
mTrayListeners.forEach(TrayListener::onBookmarksClicked);
}

private void notifyDownloadsClicked() {
hideNotifications();
mTrayListeners.forEach(TrayListener::onLibraryClicked);
mTrayListeners.forEach(TrayListener::onDownloadsClicked);
}

@Override
Expand Down Expand Up @@ -577,7 +571,7 @@ public void detachFromWindow() {
mWidgetPlacement.parentHandle = -1;

if (mViewModel != null) {
mViewModel.getIsNativeContentVisible().removeObserver(mIsNativeContentVisible);
mViewModel.getCurrentContentType().removeObserver(mCurrentContentTypeObserver);
mViewModel.getIsPrivateSession().removeObserver(mIsPrivateSession);
mViewModel = null;
}
Expand All @@ -600,7 +594,7 @@ public void attachToWindow(@NonNull WindowWidget aWindow) {
(VRBrowserActivity)getContext(),
ViewModelProvider.AndroidViewModelFactory.getInstance(((VRBrowserActivity) getContext()).getApplication()))
.get(String.valueOf(mAttachedWindow.hashCode()), WindowViewModel.class);
mViewModel.getIsNativeContentVisible().observe((VRBrowserActivity)getContext(), mIsNativeContentVisible);
mViewModel.getCurrentContentType().observe((VRBrowserActivity) getContext(), mCurrentContentTypeObserver);
mViewModel.getIsPrivateSession().observe((VRBrowserActivity)getContext(), mIsPrivateSession);

mBinding.setViewmodel(mViewModel);
Expand All @@ -610,14 +604,16 @@ public void attachToWindow(@NonNull WindowWidget aWindow) {
mIsWindowAttached = true;
}

private Observer<ObservableBoolean> mIsNativeContentVisible = aBoolean -> {
if (mBinding.libraryButton.isHovered()) {
return;
}
if (aBoolean.get()) {
animateViewPadding(mBinding.libraryButton, mMaxPadding, mMinPadding, ICON_ANIMATION_DURATION);
private Observer<Windows.ContentType> mCurrentContentTypeObserver = contentType -> {
if (contentType == Windows.ContentType.WEB_CONTENT) {
animateButtonPadding(mBinding.bookmarksButton, mMaxPadding, ICON_ANIMATION_DURATION);
animateButtonPadding(mBinding.downloadsButton, mMaxPadding, ICON_ANIMATION_DURATION);
} else if (contentType == Windows.ContentType.DOWNLOADS) {
animateButtonPadding(mBinding.bookmarksButton, mMaxPadding, ICON_ANIMATION_DURATION);
animateButtonPadding(mBinding.downloadsButton, mMinPadding, ICON_ANIMATION_DURATION);
} else {
animateViewPadding(mBinding.libraryButton, mMinPadding, mMaxPadding, ICON_ANIMATION_DURATION);
animateButtonPadding(mBinding.bookmarksButton, mMinPadding, ICON_ANIMATION_DURATION);
animateButtonPadding(mBinding.downloadsButton, mMaxPadding, ICON_ANIMATION_DURATION);
}
};

Expand All @@ -626,9 +622,9 @@ public void attachToWindow(@NonNull WindowWidget aWindow) {
return;
}
if (aBoolean.get()) {
animateViewPadding(mBinding.privateButton, mMaxPadding, mMinPadding, ICON_ANIMATION_DURATION);
animateButtonPadding(mBinding.privateButton, mMinPadding, ICON_ANIMATION_DURATION);
} else {
animateViewPadding(mBinding.privateButton, mMinPadding, mMaxPadding, ICON_ANIMATION_DURATION);
animateButtonPadding(mBinding.privateButton, mMaxPadding, ICON_ANIMATION_DURATION);
}
};

Expand Down Expand Up @@ -683,16 +679,16 @@ public void showTabSentNotification() {
}

public void showBookmarkAddedNotification() {
showNotification(BOOKMARK_ADDED_NOTIFICATION_ID, mBinding.libraryButton, R.string.bookmarks_saved_notification);
showNotification(BOOKMARK_ADDED_NOTIFICATION_ID, mBinding.bookmarksButton, R.string.bookmarks_saved_notification);
}

public void showWebAppAddedNotification() {
showNotification(WEB_APP_ADDED_NOTIFICATION_ID, mBinding.libraryButton, R.string.web_apps_saved_notification);
showNotification(WEB_APP_ADDED_NOTIFICATION_ID, mBinding.bookmarksButton, R.string.web_apps_saved_notification);
}

public void showDownloadCompletedNotification(String filename) {
showNotification(DOWNLOAD_COMPLETED_NOTIFICATION_ID,
mBinding.libraryButton,
mBinding.downloadsButton,
getContext().getString(R.string.download_completed_notification, filename));
}

Expand Down Expand Up @@ -747,7 +743,7 @@ public void onDownloadsUpdate(@NonNull List<Download> downloads) {
long inProgressNum = downloads.stream().filter(item -> item.inProgress()).count();
mTrayViewModel.setDownloadsNumber((int)inProgressNum);
if (inProgressNum == 0) {
mBinding.libraryButton.setLevel(0);
mBinding.downloadsButton.setLevel(0);

} else {
long size = downloads.stream()
Expand All @@ -759,7 +755,7 @@ public void onDownloadsUpdate(@NonNull List<Download> downloads) {
.sum();
if (size > 0) {
long percent = downloaded*100/size;
mBinding.libraryButton.setLevel((int)percent*100);
mBinding.downloadsButton.setLevel((int) percent * 100);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,10 @@ public boolean isNativeContentVisible() {
return mViewModel.getIsNativeContentVisible().getValue().get();
}

public Windows.ContentType getCurrentContentType() {
return mViewModel.getCurrentContentType().getValue();
}

public int getWindowWidth() {
return mWidgetPlacement.width;
}
Expand Down
17 changes: 11 additions & 6 deletions app/src/common/shared/com/igalia/wolvic/ui/widgets/Windows.java
Original file line number Diff line number Diff line change
Expand Up @@ -1201,18 +1201,23 @@ public void onAddWindowClicked() {
}

@Override
public void onLibraryClicked() {
if (mFocusedWindow.isNativeContentVisible()) {
public void onBookmarksClicked() {
if (mFocusedWindow.getCurrentContentType() == ContentType.BOOKMARKS) {
mFocusedWindow.hidePanel();

} else if (mDownloadsManager.isDownloading()) {
mFocusedWindow.showPanel(ContentType.DOWNLOADS);

} else {
mFocusedWindow.showPanel(ContentType.BOOKMARKS);
}
}

@Override
public void onDownloadsClicked() {
if (mFocusedWindow.getCurrentContentType() == ContentType.DOWNLOADS) {
mFocusedWindow.hidePanel();
} else {
mFocusedWindow.showPanel(ContentType.DOWNLOADS);
}
}

@Override
public void onTabsClicked() {
if (mTabsWidget == null) {
Expand Down
22 changes: 17 additions & 5 deletions app/src/main/res/layout/tray.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tool="http://schemas.android.com/tools">
<data>
<import type="com.igalia.wolvic.ui.widgets.Windows.ContentType"/>
<variable
name="viewmodel"
type="com.igalia.wolvic.ui.viewmodel.WindowViewModel" />
Expand All @@ -14,7 +15,7 @@
<RelativeLayout
android:layout_width="@dimen/tray_width"
android:layout_height="@dimen/tray_height"
android:gravity="top|center_horizontal">
android:gravity="center">

<RelativeLayout
android:id="@+id/status_bar"
Expand Down Expand Up @@ -183,19 +184,30 @@
android:src="@{viewmodel.isPrivateSession ? @drawable/ic_icon_tray_private_browsing_on_v2 : @drawable/ic_icon_tray_private_browsing_v2}"
app:privateMode="@{viewmodel.isPrivateSession}"/>

<com.igalia.wolvic.ui.views.UIButton
android:id="@+id/bookmarksButton"
style="@style/trayButtonMiddleTheme"
android:src="@drawable/ic_icon_bookmark"
android:tooltipText="@{viewmodel.currentContentType == ContentType.BOOKMARKS ? @string/close_library_tooltip : @string/open_library_tooltip}"
app:activeMode="@{viewmodel.currentContentType == ContentType.BOOKMARKS}"
app:clipDrawable="@drawable/ic_icon_library_clip"
app:tooltipDensity="@dimen/tray_tooltip_density"
app:tooltipLayout="@layout/tooltip_tray"
app:tooltipPosition="bottom" />

<RelativeLayout
android:layout_width="40dp"
android:layout_height="40dp">
<com.igalia.wolvic.ui.views.UIButton
android:id="@+id/libraryButton"
android:id="@+id/downloadsButton"
style="@style/trayButtonMiddleTheme"
android:tooltipText="@{viewmodel.isNativeContentVisible ? @string/close_library_tooltip : @string/open_library_tooltip}"
android:tooltipText="@{viewmodel.currentContentType == ContentType.DOWNLOADS ? @string/close_library_tooltip : @string/open_library_tooltip}"
app:tooltipDensity="@dimen/tray_tooltip_density"
app:tooltipPosition="bottom"
app:tooltipLayout="@layout/tooltip_tray"
android:src="@drawable/ic_icon_library"
android:src="@drawable/ic_icon_downloads"
app:clipDrawable="@drawable/ic_icon_library_clip"
app:activeMode="@{viewmodel.isNativeContentVisible}"/>
app:activeMode="@{viewmodel.currentContentType == ContentType.DOWNLOADS}"/>
<com.google.android.material.textview.MaterialTextView
android:layout_width="12dp"
android:layout_height="12dp"
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/values/dimen.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@
<!-- Tray -->
<item name="tray_world_y" format="float" type="dimen">0.25</item>
<item name="tray_world_z" format="float" type="dimen">-2.5</item>
<item name="tray_world_width" format="float" type="dimen">1.2</item>
<dimen name="tray_width">204dp</dimen>
<item name="tray_world_width" format="float" type="dimen">1.4</item>
<dimen name="tray_width">244dp</dimen>
<dimen name="tray_height">66dp</dimen>
<!-- The density of the tray tooltips is the default one. -->
<item name="tray_tooltip_density" format="float" type="dimen">1.0</item>
Expand Down

0 comments on commit 32af1ff

Please sign in to comment.