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

center zoom around focused point... #277

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ You can customize the look of the `WeekView` in xml. Use the following attribute
- `eventTextColor`
- `eventTextSize`
- `firstDayOfWeek`
- `zoomFocusPoint` The focused point (percentage of the view height) where the week view is zoomed around. This point will not move while zooming. You can declare it as a fraction `app:focusPoint="30%"` and if is not declared the top of the view is used.
- `zoomFocusPointEnabled` If you set this to ``false`` the zoomFocusPoint won't take effect any more while zooming. The zoom will always be focused at the center of your gesture.
- `headerColumnBackground`
- `headerColumnPadding`
- `headerColumnTextColor`
Expand Down
115 changes: 93 additions & 22 deletions library/src/main/java/com/alamkanak/weekview/WeekView.java
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,9 @@ private enum Direction {
private boolean mShowDistinctPastFutureColor = false;
private boolean mHorizontalFlingEnabled = true;
private boolean mVerticalFlingEnabled = true;
private int mAllDayEventHeight = 100;
private int mAllDayEventHeight= 100;
private float mZoomFocusPoint = 0;
private boolean mZoomFocusPointEnabled = true;
private int mScrollDuration = 250;

// Listeners.
Expand Down Expand Up @@ -352,6 +354,8 @@ public WeekView(Context context, AttributeSet attrs, int defStyleAttr) {
mHorizontalFlingEnabled = a.getBoolean(R.styleable.WeekView_horizontalFlingEnabled, mHorizontalFlingEnabled);
mVerticalFlingEnabled = a.getBoolean(R.styleable.WeekView_verticalFlingEnabled, mVerticalFlingEnabled);
mAllDayEventHeight = a.getDimensionPixelSize(R.styleable.WeekView_allDayEventHeight, mAllDayEventHeight);
mZoomFocusPoint = a.getFraction(R.styleable.WeekView_zoomFocusPoint, 1, 1, mZoomFocusPoint);
mZoomFocusPointEnabled = a.getBoolean(R.styleable.WeekView_zoomFocusPointEnabled, mZoomFocusPointEnabled);
mScrollDuration = a.getInt(R.styleable.WeekView_scrollDuration, mScrollDuration);
} finally {
a.recycle();
Expand Down Expand Up @@ -443,26 +447,7 @@ private void init() {
// Set default event color.
mDefaultEventColor = Color.parseColor("#9fc6e7");

mScaleDetector = new ScaleGestureDetector(mContext, new ScaleGestureDetector.OnScaleGestureListener() {
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
mIsZooming = false;
}

@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mIsZooming = true;
goToNearestOrigin();
return true;
}

@Override
public boolean onScale(ScaleGestureDetector detector) {
mNewHourHeight = Math.round(mHourHeight * detector.getScaleFactor());
invalidate();
return true;
}
});
mScaleDetector = new ScaleGestureDetector(mContext, new WeekViewGestureListener());
}

// fix rotation changes
Expand Down Expand Up @@ -586,7 +571,6 @@ private void drawHeaderRowAndEvents(Canvas canvas) {
else if (mNewHourHeight > mMaxHourHeight)
mNewHourHeight = mMaxHourHeight;

mCurrentOrigin.y = (mCurrentOrigin.y/mHourHeight)*mNewHourHeight;
mHourHeight = mNewHourHeight;
mNewHourHeight = -1;
}
Expand Down Expand Up @@ -1798,6 +1782,45 @@ public void setAllDayEventHeight(int height) {
mAllDayEventHeight = height;
}

/**
* Enable zoom focus point
* If you set this to false the `zoomFocusPoint` won't take effect any more while zooming.
* The zoom will always be focused at the center of your gesture.
*/
public void setZoomFocusPointEnabled(boolean zoomFocusPointEnabled) {
mZoomFocusPointEnabled = zoomFocusPointEnabled;
}

/*
* Is focus point enabled
* @return fixed focus point enabled?
*/
public boolean isZoomFocusPointEnabled() {
return mZoomFocusPointEnabled;
}

/*
* Get focus point
* 0 = top of view, 1 = bottom of view
* The focused point (multiplier of the view height) where the week view is zoomed around.
* This point will not move while zooming.
* @return focus point
*/
public float getZoomFocusPoint() {
return mZoomFocusPoint;
}

/**
* Set focus point
* 0 = top of view, 1 = bottom of view
* The focused point (multiplier of the view height) where the week view is zoomed around.
* This point will not move while zooming.
*/
public void setZoomFocusPoint(int zoomFocusPoint) {
mZoomFocusPoint = zoomFocusPoint;
}


/**
* Get scroll duration
* @return scroll duration
Expand Down Expand Up @@ -2039,4 +2062,52 @@ public interface ScrollListener {
*/
void onFirstVisibleDayChanged(Calendar newFirstVisibleDay, Calendar oldFirstVisibleDay);
}

/**
* A simple GestureListener that holds the focused hour while scaling.
*/
private class WeekViewGestureListener implements ScaleGestureDetector.OnScaleGestureListener {

float mFocusedPointY;

@Override
public void onScaleEnd(ScaleGestureDetector detector) {
mIsZooming = false;
}

@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
mIsZooming = true;
goToNearestOrigin();

// Calculate focused point for scale action
if (mZoomFocusPointEnabled) {
// Use fractional focus, percentage of height
mFocusedPointY = (getHeight() - mHeaderHeight - mHeaderRowPadding * 2 - mHeaderMarginBottom) * mZoomFocusPoint;
} else {
// Grab focus
mFocusedPointY = detector.getFocusY();
}

return true;
}

@Override
public boolean onScale(ScaleGestureDetector detector) {
final float scale = detector.getScaleFactor();

mNewHourHeight = Math.round(mHourHeight * scale);

// Calculating difference
float diffY = mFocusedPointY - mCurrentOrigin.y;
// Scaling difference
diffY = diffY * scale - diffY;
// Updating week view origin
mCurrentOrigin.y -= diffY;

invalidate();
return true;
}

}
}
2 changes: 2 additions & 0 deletions library/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
<attr name="horizontalFlingEnabled" format="boolean"/>
<attr name="verticalFlingEnabled" format="boolean"/>
<attr name="allDayEventHeight" format="dimension"/>
<attr name="zoomFocusPoint" format="fraction"/>
<attr name="zoomFocusPointEnabled" format="boolean"/>
<attr name="scrollDuration" format="integer"/>
</declare-styleable>
</resources>