mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 739407: Perform animation while showing/hiding tabs. [r=mfinkle]
This commit is contained in:
parent
acc455e350
commit
873878486e
@ -64,7 +64,8 @@ import dalvik.system.*;
|
||||
abstract public class GeckoApp
|
||||
extends GeckoActivity
|
||||
implements GeckoEventListener, SensorEventListener, LocationListener,
|
||||
GeckoApplication.ApplicationLifecycleCallbacks {
|
||||
GeckoApplication.ApplicationLifecycleCallbacks,
|
||||
TabsPanel.TabsLayoutChangeListener {
|
||||
private static final String LOGTAG = "GeckoApp";
|
||||
|
||||
public static enum StartupMode {
|
||||
@ -112,6 +113,8 @@ abstract public class GeckoApp
|
||||
private static AbsoluteLayout mPluginContainer;
|
||||
private static FindInPageBar mFindInPageBar;
|
||||
|
||||
private PropertyAnimator mMainLayoutAnimator;
|
||||
|
||||
private FullScreenHolder mFullScreenPluginContainer;
|
||||
private View mFullScreenPluginView;
|
||||
|
||||
@ -1020,6 +1023,28 @@ abstract public class GeckoApp
|
||||
return mTabsPanel.isShown();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTabsLayoutChange(int width, int height) {
|
||||
if (mMainLayoutAnimator != null)
|
||||
mMainLayoutAnimator.stop();
|
||||
|
||||
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mMainLayout.getLayoutParams();
|
||||
|
||||
if (isTablet())
|
||||
mMainLayoutAnimator = new PropertyAnimator(mMainLayout,
|
||||
PropertyAnimator.Property.MARGIN_LEFT,
|
||||
params.leftMargin,
|
||||
width,
|
||||
200);
|
||||
else
|
||||
mMainLayoutAnimator = new PropertyAnimator(mMainLayout,
|
||||
PropertyAnimator.Property.MARGIN_TOP,
|
||||
params.topMargin,
|
||||
height,
|
||||
200);
|
||||
mMainLayoutAnimator.start();
|
||||
}
|
||||
|
||||
public void handleMessage(String event, JSONObject message) {
|
||||
Log.i(LOGTAG, "Got message: " + event);
|
||||
try {
|
||||
@ -1889,6 +1914,7 @@ abstract public class GeckoApp
|
||||
|
||||
// setup tabs panel
|
||||
mTabsPanel = (TabsPanel) findViewById(R.id.tabs_panel);
|
||||
mTabsPanel.setTabsLayoutChangeListener(this);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
mBrowserToolbar.setTitle(savedInstanceState.getString(SAVED_STATE_TITLE));
|
||||
|
@ -88,6 +88,7 @@ FENNEC_JAVA_FILES = \
|
||||
MenuItemActionBar.java \
|
||||
MenuItemDefault.java \
|
||||
NSSBridge.java \
|
||||
PropertyAnimator.java \
|
||||
ProfileMigrator.java \
|
||||
PromptService.java \
|
||||
sqlite/ByteBufferInputStream.java \
|
||||
|
113
mobile/android/base/PropertyAnimator.java
Normal file
113
mobile/android/base/PropertyAnimator.java
Normal file
@ -0,0 +1,113 @@
|
||||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.view.animation.Interpolator;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.view.View;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
public class PropertyAnimator extends TimerTask {
|
||||
private static final String LOGTAG = "GeckoPropertyAnimator";
|
||||
|
||||
private Timer mTimer;
|
||||
private TimerTask mShowTask;
|
||||
private Interpolator mInterpolator;
|
||||
|
||||
public static enum Property {
|
||||
MARGIN_LEFT,
|
||||
MARGIN_RIGHT,
|
||||
MARGIN_TOP,
|
||||
MARGIN_BOTTOM
|
||||
}
|
||||
|
||||
private View mView;
|
||||
private Property mProperty;
|
||||
private int mDuration;
|
||||
private int mFrom;
|
||||
private int mTo;
|
||||
|
||||
private int mCount;
|
||||
|
||||
// Default refresh rate in ms.
|
||||
private static final int sInterval = 10;
|
||||
|
||||
public PropertyAnimator(View view, Property property, int from, int to, int duration) {
|
||||
mView = view;
|
||||
mProperty = property;
|
||||
mDuration = duration;
|
||||
mFrom = from;
|
||||
mTo = to;
|
||||
|
||||
mTimer = new Timer();
|
||||
mInterpolator = new DecelerateInterpolator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
float interpolation = mInterpolator.getInterpolation((float) (mCount * sInterval) / (float) mDuration);
|
||||
int delta;
|
||||
if (mFrom < mTo)
|
||||
delta = mFrom + (int) ((mTo - mFrom) * interpolation);
|
||||
else
|
||||
delta = mFrom - (int) ((mFrom - mTo) * interpolation);
|
||||
|
||||
invalidate(delta);
|
||||
|
||||
mCount++;
|
||||
|
||||
if (mCount * sInterval >= mDuration)
|
||||
stop();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mCount = 0;
|
||||
mTimer.scheduleAtFixedRate(this, 0, sInterval);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
cancel();
|
||||
mTimer.cancel();
|
||||
mTimer.purge();
|
||||
|
||||
// Make sure to snap to the end position.
|
||||
invalidate(mTo);
|
||||
}
|
||||
|
||||
private void invalidate(final int delta) {
|
||||
// Post the layout changes on the view's UI thread.
|
||||
mView.getHandler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mView.getLayoutParams());
|
||||
switch(mProperty) {
|
||||
case MARGIN_TOP:
|
||||
params.setMargins(0, delta, 0, 0);
|
||||
break;
|
||||
|
||||
case MARGIN_BOTTOM:
|
||||
params.setMargins(0, 0, 0, delta);
|
||||
break;
|
||||
|
||||
case MARGIN_LEFT:
|
||||
params.setMargins(delta, 0, 0, 0);
|
||||
break;
|
||||
|
||||
case MARGIN_RIGHT:
|
||||
params.setMargins(0, 0, delta, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
mView.setLayoutParams(params);
|
||||
mView.requestLayout();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -34,8 +34,13 @@ public class TabsPanel extends LinearLayout {
|
||||
public void hide();
|
||||
}
|
||||
|
||||
public static interface TabsLayoutChangeListener {
|
||||
public void onTabsLayoutChange(int width, int height);
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private PanelView mPanel;
|
||||
private TabsLayoutChangeListener mLayoutChangeListener;
|
||||
|
||||
private static ImageButton mRemoteTabs;
|
||||
private TextView mTitle;
|
||||
@ -80,6 +85,7 @@ public class TabsPanel extends LinearLayout {
|
||||
|
||||
public void show(Panel panel) {
|
||||
if (mPanel != null) {
|
||||
// Remove the old panel.
|
||||
mPanel.hide();
|
||||
if (getChildCount() == 2)
|
||||
removeViewAt(1);
|
||||
@ -102,7 +108,10 @@ public class TabsPanel extends LinearLayout {
|
||||
mPanel.setHeightRestriction(mHeightRestricted);
|
||||
mPanel.show();
|
||||
addView(mPanel.getLayout(), 1);
|
||||
setVisibility(View.VISIBLE);
|
||||
|
||||
// Tablet has fixed sized panel, hence we need to inform when we show.
|
||||
// Phones can be informed too. But the list wouldn't have been inflated by now.
|
||||
dispatchLayoutChange(getWidth(), getHeight());
|
||||
|
||||
// If Sync is set up, query the database for remote clients.
|
||||
final Context context = mContext;
|
||||
@ -124,11 +133,16 @@ public class TabsPanel extends LinearLayout {
|
||||
}
|
||||
|
||||
public void hide() {
|
||||
setVisibility(View.GONE);
|
||||
mPanel.hide();
|
||||
if (getChildCount() == 2)
|
||||
removeViewAt(1);
|
||||
mVisible = false;
|
||||
dispatchLayoutChange(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
|
||||
// This is used only for sliding action on phones.
|
||||
// Tablets have a fixed size pane, hence this should be done while showing.
|
||||
if (mVisible)
|
||||
dispatchLayoutChange(width, height);
|
||||
}
|
||||
|
||||
public void refresh() {
|
||||
@ -140,4 +154,13 @@ public class TabsPanel extends LinearLayout {
|
||||
public boolean isShown() {
|
||||
return mVisible;
|
||||
}
|
||||
|
||||
public void setTabsLayoutChangeListener(TabsLayoutChangeListener listener) {
|
||||
mLayoutChangeListener = listener;
|
||||
}
|
||||
|
||||
private void dispatchLayoutChange(int width, int height) {
|
||||
if (mLayoutChangeListener != null)
|
||||
mLayoutChangeListener.onTabsLayoutChange(width, height);
|
||||
}
|
||||
}
|
||||
|
@ -10,12 +10,10 @@
|
||||
<org.mozilla.gecko.TabsPanel android:id="@+id/tabs_panel"
|
||||
android:layout_width="200dip"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@drawable/tabs_tray_bg_repeat"
|
||||
android:visibility="gone"/>
|
||||
android:background="@drawable/tabs_tray_bg_repeat"/>
|
||||
|
||||
<LinearLayout android:id="@+id/main_layout"
|
||||
style="@style/Screen"
|
||||
android:layout_toRightOf="@id/tabs_panel">
|
||||
style="@style/Screen">
|
||||
|
||||
<include layout="@layout/browser_toolbar"/>
|
||||
|
||||
|
@ -10,12 +10,10 @@
|
||||
<org.mozilla.gecko.TabsPanel android:id="@+id/tabs_panel"
|
||||
android:layout_width="200dip"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@drawable/tabs_tray_bg_repeat"
|
||||
android:visibility="gone"/>
|
||||
android:background="@drawable/tabs_tray_bg_repeat"/>
|
||||
|
||||
<LinearLayout android:id="@+id/main_layout"
|
||||
style="@style/Screen"
|
||||
android:layout_toRightOf="@id/tabs_panel">
|
||||
style="@style/Screen">
|
||||
|
||||
<include layout="@layout/browser_toolbar"/>
|
||||
|
||||
|
@ -10,12 +10,10 @@
|
||||
<org.mozilla.gecko.TabsPanel android:id="@+id/tabs_panel"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/tabs_tray_bg_repeat"
|
||||
android:visibility="gone"/>
|
||||
android:background="@drawable/tabs_tray_bg_repeat"/>
|
||||
|
||||
<LinearLayout android:id="@+id/main_layout"
|
||||
style="@style/Screen"
|
||||
android:layout_below="@id/tabs_panel">
|
||||
style="@style/Screen">
|
||||
|
||||
<include layout="@layout/browser_toolbar"/>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user