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

Added draw of rectangle in 'onEmptyViewClicked' and listener if the same date is clicked twice. (Similar to Google Calendar App). #160

Closed
wants to merge 4 commits into from
Closed
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
166 changes: 160 additions & 6 deletions library/src/main/java/com/alamkanak/weekview/WeekView.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
import android.view.View;
import android.view.WindowManager;
import android.widget.OverScroller;
import android.widget.Scroller;

Expand Down Expand Up @@ -62,16 +64,19 @@ public class WeekView extends View {
private Paint mTodayBackgroundPaint;
private Paint mTodayHeaderTextPaint;
private Paint mEventBackgroundPaint;
private Paint mEmptyEventBackgroundPaint;
private float mHeaderColumnWidth;
private List<EventRect> mEventRects;
private TextPaint mEventTextPaint;
private TextPaint mEmptyEventTextPaint;
private Paint mHeaderColumnBackgroundPaint;
private Scroller mStickyScroller;
private int mFetchedMonths[] = new int[3];
private boolean mRefreshEvents = false;
private float mDistanceY = 0;
private float mDistanceX = 0;
private Direction mCurrentFlingDirection = Direction.NONE;
float mEmptyEventX;

// Attributes and their default values.
private int mHourHeight = 50;
Expand All @@ -90,18 +95,22 @@ public class WeekView extends View {
private int mTodayHeaderTextColor = Color.rgb(39, 137, 228);
private int mEventTextSize = 12;
private int mEventTextColor = Color.BLACK;
private int mEmptyEventTextColor = Color.WHITE;
private int mEventPadding = 8;
private int mHeaderColumnBackgroundColor = Color.WHITE;
private int mDefaultEventColor;
private int mDefaultEmptyEventColor;
private boolean mIsFirstDraw = true;
private boolean mAreDimensionsInvalid = true;
@Deprecated private int mDayNameLength = LENGTH_LONG;
@Deprecated
private int mDayNameLength = LENGTH_LONG;
private int mOverlappingEventGap = 0;
private int mEventMarginVertical = 0;
private float mXScrollingSpeed = 1f;
private Calendar mFirstVisibleDay;
private Calendar mLastVisibleDay;
private Calendar mScrollToDay = null;
private Calendar mCacheEmptyEventDay;
private double mScrollToHour = -1;

// Listeners.
Expand Down Expand Up @@ -177,7 +186,10 @@ public boolean onSingleTapConfirmed(MotionEvent e) {
Calendar selectedTime = getTimeFromPoint(e.getX(), e.getY());
if (selectedTime != null) {
playSoundEffect(SoundEffectConstants.CLICK);
mEmptyViewClickListener.onEmptyViewClicked(selectedTime);
mEmptyEventX = e.getX();
mEmptyViewClickListener.onEmptyViewClicked(selectedTime, mCacheEmptyEventDay, isSameDayAndHour(selectedTime, mCacheEmptyEventDay));
mCacheEmptyEventDay = selectedTime;
invalidate();
}
}

Expand Down Expand Up @@ -248,6 +260,7 @@ public WeekView(Context context, AttributeSet attrs, int defStyleAttr) {
mTodayHeaderTextColor = a.getColor(R.styleable.WeekView_todayHeaderTextColor, mTodayHeaderTextColor);
mEventTextSize = a.getDimensionPixelSize(R.styleable.WeekView_eventTextSize, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, mEventTextSize, context.getResources().getDisplayMetrics()));
mEventTextColor = a.getColor(R.styleable.WeekView_eventTextColor, mEventTextColor);
mEmptyEventTextColor = a.getColor(R.styleable.WeekView_emptyEventTextColor, mEmptyEventTextColor);
mEventPadding = a.getDimensionPixelSize(R.styleable.WeekView_hourSeparatorHeight, mEventPadding);
mHeaderColumnBackgroundColor = a.getColor(R.styleable.WeekView_headerColumnBackground, mHeaderColumnBackgroundColor);
mDayNameLength = a.getInteger(R.styleable.WeekView_dayNameLength, mDayNameLength);
Expand Down Expand Up @@ -321,6 +334,9 @@ private void init() {
// Prepare event background color.
mEventBackgroundPaint = new Paint();
mEventBackgroundPaint.setColor(Color.rgb(174, 208, 238));
// Prepare empty event background color.
mEmptyEventBackgroundPaint = new Paint();
mEmptyEventBackgroundPaint.setColor(Color.rgb(60, 147, 217));

// Prepare header column background color.
mHeaderColumnBackgroundPaint = new Paint();
Expand All @@ -331,22 +347,33 @@ private void init() {
mEventTextPaint.setStyle(Paint.Style.FILL);
mEventTextPaint.setColor(mEventTextColor);
mEventTextPaint.setTextSize(mEventTextSize);
// Prepare empty event text size and color.
mEmptyEventTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);
mEmptyEventTextPaint.setStyle(Paint.Style.FILL);
mEmptyEventTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
mEmptyEventTextPaint.setColor(mEmptyEventTextColor);
mStartDate = (Calendar) mToday.clone();

// Set default event color.
mDefaultEventColor = Color.parseColor("#9fc6e7");
// Set default empty event color.
mDefaultEmptyEventColor = Color.parseColor("#3c93d9");
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

// Draw the header row.
drawHeaderRowAndEvents(canvas);

// Draw the time column and all the axes/separators.
drawTimeColumnAndAxes(canvas);

//Draw empty event
if (mCurrentScrollDirection != Direction.HORIZONTAL) {
if (mCacheEmptyEventDay != null) drawEmptyEvent(mCacheEmptyEventDay, canvas);
} else mCacheEmptyEventDay = null;

// Draw the header row.
drawHeaderRowAndEvents(canvas);
// Hide everything in the first cell (top left corner).
canvas.drawRect(0, 0, mTimeTextWidth + mHeaderColumnPadding * 2, mHeaderTextHeight + mHeaderRowPadding * 2, mHeaderBackgroundPaint);

Expand Down Expand Up @@ -586,6 +613,57 @@ eventRectF.top < getHeight() &&
}
}

/**
* Draw empty event
*
* @param mCacheEmptyEventDay The day.
* @param canvas The canvas to draw upon.
*/
private void drawEmptyEvent(Calendar mCacheEmptyEventDay, Canvas canvas) {
// Prepare to iterate for each day.
Calendar day = (Calendar) mToday.clone();
day.add(Calendar.HOUR, 6);
int leftDaysWithGaps = (int) -(Math.ceil(mCurrentOrigin.x / (mWidthPerDay + mColumnGap)));
//iterate thru days
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(through)
Please correct english 😄 (feature is cool, though)

for (int dayNumber = leftDaysWithGaps + 1;
dayNumber <= leftDaysWithGaps + mNumberOfVisibleDays + 1;
dayNumber++) {
// Check if the day is today.
day = (Calendar) mToday.clone();
day.add(Calendar.DATE, dayNumber - 1);
boolean sameDay = isSameDay(day, mCacheEmptyEventDay);
if (sameDay) {
//calculate bottom and top
float cal_bottom = (mCacheEmptyEventDay.get(Calendar.HOUR_OF_DAY) + 1) * 60;
float bottom = mHourHeight * 24 * cal_bottom / 1440 + mCurrentOrigin.y + mHeaderTextHeight + mHeaderRowPadding * 2 + mHeaderMarginBottom + mTimeTextHeight / 2 - mEventMarginVertical;
float originalBottom = bottom - mTimeTextHeight - mHeaderTextHeight;
float cal_top = mCacheEmptyEventDay.get(Calendar.HOUR_OF_DAY) * 60;
float top = mHourHeight * 24 * cal_top / 1440 + mCurrentOrigin.y + mHeaderTextHeight + mHeaderRowPadding * 2 + mHeaderMarginBottom + mTimeTextHeight / 2 + mEventMarginVertical;
mEmptyEventBackgroundPaint.setColor(mDefaultEmptyEventColor);
// Calculate left and right.
float left = 0;
for (int i = 0; i < mNumberOfVisibleDays + 1; i++) {
int j = i + 1;
float h_wpd = mHeaderColumnWidth + (mWidthPerDay * j);
if (i != 0) h_wpd += (mColumnGap * j);
if (mEmptyEventX <= h_wpd) {
left = mHeaderColumnWidth;
if (i != 0) left += (mWidthPerDay * i) + (mColumnGap * i);
break;
}
}
float right = left + mWidthPerDay;

// Draw the empty event and the text on top of it.
RectF dayRectF = new RectF(left, top, right, bottom);
canvas.drawRect(dayRectF, mEmptyEventBackgroundPaint);
drawEmptyText("+", canvas, (((originalBottom - top) / 2) + top), left, (int) dayRectF.width());
break;

}

}
}

/**
* Draw the name of the event on top of the event rectangle.
Expand Down Expand Up @@ -622,6 +700,48 @@ else if (lineHeight >= availableHeight) {
canvas.restore();
}

/**
* Draw the text on top of the rectangle in the empty event.
*
* @param text The empty text to draw.
* @param canvas The canvas to draw upon.
* @param originalTop The original top position of the rectangle. The rectangle may have some of its portion outside of the visible area.
* @param originalLeft The original left position of the rectangle. The rectangle may have some of its portion outside of the visible area.
*/
private void drawEmptyText(String text, Canvas canvas, float originalTop, float originalLeft, int textWidth) {

// Get text dimensions
DisplayMetrics metrics = new DisplayMetrics();
WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
wm.getDefaultDisplay().getMetrics(metrics);
float textSize = 18f;
switch (metrics.densityDpi) {
case DisplayMetrics.DENSITY_LOW:
textSize = textSize * 0.75f;
break;
case DisplayMetrics.DENSITY_MEDIUM:
textSize = textSize * 1f;
break;
case DisplayMetrics.DENSITY_HIGH:
textSize = textSize * 1.5f;
break;
case DisplayMetrics.DENSITY_XHIGH:
textSize = textSize * 2.0f;
break;
case DisplayMetrics.DENSITY_XXHIGH:
textSize = textSize * 2.5f;
break;
}

mEmptyEventTextPaint.setTextSize(textSize);
mEmptyEventTextPaint.setColor(mEmptyEventTextColor);
StaticLayout textLayout = new StaticLayout(text, mEmptyEventTextPaint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
// Draw text
canvas.save();
canvas.translate(originalLeft, originalTop);
textLayout.draw(canvas);
canvas.restore();
}

/**
* A class to hold reference to the events and their visual representation. An EventRect is
Expand Down Expand Up @@ -1202,6 +1322,15 @@ public void setEventTextColor(int eventTextColor) {
invalidate();
}

public int getEmptyEventTextColor() {
return mEmptyEventTextColor;
}

public void setEmptyEventTextColor(int emptyEventTextColor) {
mEmptyEventTextColor = emptyEventTextColor;
invalidate();
}

public int getEventPadding() {
return mEventPadding;
}
Expand Down Expand Up @@ -1229,6 +1358,15 @@ public void setDefaultEventColor(int defaultEventColor) {
invalidate();
}

public int getDefaultEmptyEventColor() {
return mDefaultEmptyEventColor;
}

public void setDefaultEmptyEventColor(int DefaultEmptyEventColor) {
mDefaultEmptyEventColor = DefaultEmptyEventColor;
invalidate();
}

/**
* <b>Note:</b> Use {@link #setDateTimeInterpreter(DateTimeInterpreter)} and
* {@link #getDateTimeInterpreter()} instead.
Expand Down Expand Up @@ -1376,6 +1514,7 @@ public void computeScroll() {
public void goToToday() {
Calendar today = Calendar.getInstance();
goToDate(today);
mCacheEmptyEventDay = null;
}

/**
Expand Down Expand Up @@ -1469,7 +1608,7 @@ public interface EventLongPressListener {
}

public interface EmptyViewClickListener {
public void onEmptyViewClicked(Calendar time);
public void onEmptyViewClicked(Calendar time, Calendar tempTime, boolean clickedTwice);
}

public interface EmptyViewLongPressListener {
Expand Down Expand Up @@ -1518,4 +1657,19 @@ private boolean isSameDay(Calendar dayOne, Calendar dayTwo) {
return dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR) && dayOne.get(Calendar.DAY_OF_YEAR) == dayTwo.get(Calendar.DAY_OF_YEAR);
}

/**
* Checks if two times are on the same day and hour.
*
* @param dayOne The first day.
* @param dayTwo The second day.
* @return Whether the times are on the same day and hour.
*/
private boolean isSameDayAndHour(Calendar dayOne, Calendar dayTwo) {

if (dayTwo != null) {
return dayOne.get(Calendar.YEAR) == dayTwo.get(Calendar.YEAR) && dayOne.get(Calendar.DAY_OF_YEAR) == dayTwo.get(Calendar.DAY_OF_YEAR) && dayOne.get(Calendar.HOUR_OF_DAY) == dayTwo.get(Calendar.HOUR_OF_DAY);
}
return false;
}

}
1 change: 1 addition & 0 deletions library/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<attr name="todayHeaderTextColor" format="color"/>
<attr name="hourSeparatorHeight" format="dimension"/>
<attr name="eventTextColor" format="color"/>
<attr name="emptyEventTextColor" format="color"/>
<attr name="eventPadding" format="dimension"/>
<attr name="headerColumnBackground" format="color"/>
<attr name="dayNameLength" format="enum">
Expand Down