Skip to content

Commit

Permalink
fixed various issues with all-day events.
Browse files Browse the repository at this point in the history
added CTOR for all-day event that takes a single day.
  • Loading branch information
AndroidDeveloperLB committed May 29, 2018
1 parent 9d6f070 commit 0be8d77
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 158 deletions.
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ There is also a [sample app](https://github.com/quivr/Android-Week-View/tree/mas
License
----------

Copyright 2014 Raquib-ul-Alam

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ package com.alamkanak.weekview

import java.util.*

/**
* Created by Raquib on 1/6/2015.
*/
interface DateTimeInterpreter {
fun interpretDate(date: Calendar): String

Expand Down
33 changes: 15 additions & 18 deletions library/src/main/java/com/alamkanak/weekview/WeekView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ import com.alamkanak.weekview.WeekViewUtil.today
import java.text.SimpleDateFormat
import java.util.*

/**
* Created by Raquib-ul-Alam Kanak on 7/21/2014.
* Website: http://alamkanak.github.io/
*/
class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : View(context, attrs, defStyleAttr) {
//region fields and properties
private var mHomeDate: Calendar? = null
Expand Down Expand Up @@ -366,7 +362,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
val reversedEventRects = mEventRects
reversedEventRects!!.reverse()
for (eventRect in reversedEventRects) {
if (newEventIdentifier != eventRect.event.identifier && eventRect.rectF != null && e.x > eventRect.rectF!!.left && e.x < eventRect.rectF!!.right && e.y > eventRect.rectF!!.top && e.y < eventRect.rectF!!.bottom) {
if (newEventIdentifier != eventRect.event.id && eventRect.rectF != null && e.x > eventRect.rectF!!.left && e.x < eventRect.rectF!!.right && e.y > eventRect.rectF!!.top && e.y < eventRect.rectF!!.bottom) {
eventClickListener!!.onEventClick(eventRect.originalEvent, eventRect.rectF!!)
playSoundEffect(SoundEffectConstants.CLICK)
return super.onSingleTapConfirmed(e)
Expand Down Expand Up @@ -433,11 +429,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
val right = left + mWidthPerDay

// Add the new event if its bounds are valid
if (left < right &&
left < width &&
top < height &&
right > mHeaderColumnWidth &&
bottom > 0) {
if (left < right && left < width && top < height && right > mHeaderColumnWidth && bottom > 0) {
val dayRectF = RectF(left, top, right, bottom - mCurrentOrigin.y)
newEvent.color = newEventColor
mNewEventRect = EventRect(newEvent, newEvent, dayRectF)
Expand Down Expand Up @@ -1672,7 +1664,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
if (mEventRects!![i].event.startTime!!.get(Calendar.HOUR_OF_DAY) < mMinTime)
topToUse = hourHeight * getPassedMinutesInDay(mMinTime, 0) / 60 + eventsTop

if (newEventIdentifier != mEventRects!![i].event.identifier)
if (newEventIdentifier != mEventRects!![i].event.id)
drawEventTitle(mEventRects!![i].event, mEventRects!![i].rectF!!, canvas, topToUse, left)
else
drawEmptyImage(mEventRects!![i].event, mEventRects!![i].rectF!!, canvas, topToUse, left)
Expand Down Expand Up @@ -1774,7 +1766,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
var availableLineCount = availableHeight / lineHeight
do {
// Ellipsize text to fit into event rect.
if (newEventIdentifier != event.identifier)
if (newEventIdentifier != event.id)
textLayout = StaticLayout(TextUtils.ellipsize(bob, mEventTextPaint, (availableLineCount * availableWidth).toFloat(), TextUtils.TruncateAt.END), mEventTextPaint, (rect.right - originalLeft - (eventPadding * 2).toFloat()).toInt(), Layout.Alignment.ALIGN_NORMAL, 1.0f, 0f, false)

// Reduce line count.
Expand Down Expand Up @@ -1812,7 +1804,6 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
* stored in "originalEvent". But the event that corresponds to rectangle the rectangle
* instance will be stored in "event".
*/
private inner class EventRect
/**
* Create a new instance of event rect. An EventRect is actually the rectangle that is drawn
* on the calendar for a given event. There may be more than one rectangle for a single
Expand All @@ -1825,11 +1816,15 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
* @param originalEvent The original event that was passed by the user.
* @param rectF The rectangle.
*/
(var event: WeekViewEvent, var originalEvent: WeekViewEvent, var rectF: RectF?) {
private inner class EventRect(var event: WeekViewEvent, var originalEvent: WeekViewEvent, var rectF: RectF?) {
var left: Float = 0f
var width: Float = 0f
var top: Float = 0f
var bottom: Float = 0f
override fun toString(): String {
return "EventRect(left=$left, width=$width, top=$top, bottom=$bottom, rectF=$rectF, event=$event, originalEvent=$originalEvent)"
}

}


Expand Down Expand Up @@ -1960,7 +1955,7 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?

outerLoop@ for (collisionGroup in collisionGroups) {
for (groupEvent in collisionGroup) {
if (isEventsCollide(groupEvent.event, eventRect.event) && groupEvent.event.isAllDay == eventRect.event.isAllDay) {
if (isEventsCollide(groupEvent.event, eventRect.event)) { //&& groupEvent.event.isAllDay == eventRect.event.isAllDay) {
collisionGroup.add(eventRect)
isPlaced = true
break@outerLoop
Expand Down Expand Up @@ -2045,13 +2040,15 @@ class WeekView @JvmOverloads constructor(context: Context, attrs: AttributeSet?
* @return true if the events overlap.
*/
private fun isEventsCollide(event1: WeekViewEvent, event2: WeekViewEvent): Boolean {
if (event1.isAllDay != event2.isAllDay)
return false
val start1 = event1.startTime!!.timeInMillis
val end1 = event1.endTime!!.timeInMillis
val start2 = event2.startTime!!.timeInMillis
val end1 = event1.endTime!!.timeInMillis
val end2 = event2.endTime!!.timeInMillis

if (event1.isAllDay)
return !(start1 > end2 || end1 < start2)
val minOverlappingMillis = (minOverlappingMinutes * 60 * 1000).toLong()

return !(start1 + minOverlappingMillis >= end2 || end1 <= start2 + minOverlappingMillis)
}

Expand Down
181 changes: 86 additions & 95 deletions library/src/main/java/com/alamkanak/weekview/WeekViewEvent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,68 +5,57 @@ import android.support.annotation.ColorInt
import com.alamkanak.weekview.WeekViewUtil.isSameDay
import java.util.*

/**
* Created by Raquib-ul-Alam Kanak on 7/21/2014.
* Website: http://april-shower.com
*/
class WeekViewEvent {
var identifier: String? = null
var id: String? = null
var startTime: Calendar? = null
set(value) {
field = value
resetDatesForAllDayIfNeeded()
}
var endTime: Calendar? = null
set(value) {
field = value
resetDatesForAllDayIfNeeded()
}
var name: String? = null
var location: String? = null
@ColorInt
@get:ColorInt
var color: Int = 0
var isAllDay: Boolean = false
var shader: Shader? = null

var id: Long
@Deprecated("")
get() = java.lang.Long.parseLong(identifier)
@Deprecated("")
set(id) {
this.identifier = id.toString()
set(value) {
field = value
resetDatesForAllDayIfNeeded()
}
var shader: Shader? = null

constructor()

/**
* Initializes the event for week view.
*
* @param id The id of the event as String.
* @param name Name of the event.
* @param startYear Year when the event starts.
* @param startMonth Month when the event starts.
* @param startDay Day when the event starts.
* @param startHour Hour (in 24-hour format) when the event starts.
* @param startMinute Minute when the event starts.
* @param endYear Year when the event ends.
* @param endMonth Month when the event ends.
* @param endDay Day when the event ends.
* @param endHour Hour (in 24-hour format) when the event ends.
* @param endMinute Minute when the event ends.
*/
constructor(id: String, name: String, startYear: Int, startMonth: Int, startDay: Int, startHour: Int, startMinute: Int, endYear: Int, endMonth: Int, endDay: Int, endHour: Int, endMinute: Int) {
this.identifier = id

startTime = Calendar.getInstance().apply {
set(Calendar.YEAR, startYear)
set(Calendar.MONTH, startMonth - 1)
set(Calendar.DAY_OF_MONTH, startDay)
set(Calendar.HOUR_OF_DAY, startHour)
set(Calendar.MINUTE, startMinute)
}
endTime = Calendar.getInstance().apply {
set(Calendar.YEAR, endYear)
set(Calendar.MONTH, endMonth - 1)
set(Calendar.DAY_OF_MONTH, endDay)
set(Calendar.HOUR_OF_DAY, endHour)
set(Calendar.MINUTE, endMinute)
private fun resetDatesForAllDayIfNeeded() {
if (!isAllDay)
return
when {
startTime == null && endTime != null -> {
WeekViewUtil.resetTime(endTime!!)
startTime = endTime
}
startTime != null && endTime == null -> {
WeekViewUtil.resetTime(startTime!!)
endTime = startTime
}
startTime != null && endTime != null -> {
WeekViewUtil.resetTime(startTime!!)
if (!WeekViewUtil.isSameDay(startTime!!, endTime!!))
WeekViewUtil.resetTime(endTime!!)
else if (endTime !== startTime)
endTime = startTime
}
}
this.name = name
}

/**CTOR for a single, all day event*/
constructor(id: String?, name: String?, location: String? = null, allDayTime: Calendar, shader: Shader? = null) : this(id, name, location, allDayTime, allDayTime, true, shader)

/**
* Initializes the event for week view.
*
Expand All @@ -79,11 +68,13 @@ class WeekViewEvent {
* @param shader the Shader of the event rectangle
*/
@JvmOverloads constructor(id: String?, name: String?, location: String?, startTime: Calendar, endTime: Calendar, allDay: Boolean = false, shader: Shader? = null) {
this.identifier = id
this.id = id
this.name = name
this.location = location
this.isAllDay = allDay
this.startTime = startTime
this.endTime = endTime
this.startTime = startTime
this.isAllDay = allDay
this.shader = shader
}
Expand All @@ -101,73 +92,73 @@ class WeekViewEvent {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || javaClass != other.javaClass) return false

val that = other as WeekViewEvent?

return identifier == that!!.identifier
return id == that!!.id
}

override fun hashCode(): Int {
return identifier!!.hashCode()
return id!!.hashCode()
}


fun splitWeekViewEvents(): MutableList<WeekViewEvent> {
//This function splits the WeekViewEvent in WeekViewEvents by day
if (this.endTime == null || isSameDay(this.startTime!!, this.endTime!!)) {
val events = ArrayList<WeekViewEvent>(1)
events.add(this)
return events
}
val events = ArrayList<WeekViewEvent>()
// The first millisecond of the next day is still the same day. (no need to split events for this).
var endTime = this.endTime!!.clone() as Calendar
endTime.add(Calendar.MILLISECOND, -1)
if (!isSameDay(this.startTime!!, endTime)) {
endTime = this.startTime!!.clone() as Calendar
endTime.set(Calendar.HOUR_OF_DAY, 23)
endTime.set(Calendar.MINUTE, 59)
val event1 = WeekViewEvent(this.identifier!!, this.name, this.location, this.startTime!!, endTime, this.isAllDay)
event1.color = this.color
events.add(event1)

// Add other days.
if (!isSameDay(this.startTime!!, this.endTime!!)) {
val otherDay = this.startTime!!.clone() as Calendar
endTime = this.startTime!!.clone() as Calendar
endTime.set(Calendar.HOUR_OF_DAY, 23)
endTime.set(Calendar.MINUTE, 59)
val event1 = WeekViewEvent(this.id!!, this.name, this.location, this.startTime!!, endTime, this.isAllDay)
event1.color = this.color
events.add(event1)

// Add other days.
if (!isSameDay(this.startTime!!, this.endTime!!)) {
val otherDay = this.startTime!!.clone() as Calendar
otherDay.add(Calendar.DATE, 1)
while (!isSameDay(otherDay, this.endTime!!)) {
val overDay = otherDay.clone() as Calendar
overDay.set(Calendar.HOUR_OF_DAY, 0)
overDay.set(Calendar.MINUTE, 0)
val endOfOverDay = overDay.clone() as Calendar
endOfOverDay.set(Calendar.HOUR_OF_DAY, 23)
endOfOverDay.set(Calendar.MINUTE, 59)
val eventMore = WeekViewEvent(this.id!!, this.name, null, overDay, endOfOverDay, this.isAllDay)
eventMore.color = this.color
events.add(eventMore)

// Add next day.
otherDay.add(Calendar.DATE, 1)
while (!isSameDay(otherDay, this.endTime!!)) {
val overDay = otherDay.clone() as Calendar
overDay.set(Calendar.HOUR_OF_DAY, 0)
overDay.set(Calendar.MINUTE, 0)
val endOfOverDay = overDay.clone() as Calendar
endOfOverDay.set(Calendar.HOUR_OF_DAY, 23)
endOfOverDay.set(Calendar.MINUTE, 59)
val eventMore = WeekViewEvent(this.identifier!!, this.name, null, overDay, endOfOverDay, this.isAllDay)
eventMore.color = this.color
events.add(eventMore)

// Add next day.
otherDay.add(Calendar.DATE, 1)
}
// Add last day.
val startTime = this.endTime!!.clone() as Calendar
startTime.set(Calendar.HOUR_OF_DAY, 0)
startTime.set(Calendar.MINUTE, 0)
val event2 = WeekViewEvent(this.identifier!!, this.name, this.location, startTime, this.endTime!!, this.isAllDay)
event2.color = this.color
events.add(event2)
}
} else {
events.add(this)
// Add last day.
val startTime = this.endTime!!.clone() as Calendar
startTime.set(Calendar.HOUR_OF_DAY, 0)
startTime.set(Calendar.MINUTE, 0)
val event2 = WeekViewEvent(this.id!!, this.name, this.location, startTime, this.endTime!!, this.isAllDay)
event2.color = this.color
events.add(event2)
}

return events
}

override fun toString(): String {
if (isAllDay)
return "WeekViewEvent(identifier=$identifier, time=${WeekViewUtil.calendarToString(startTime, false)}, name=$name, location=$location, color=$color, isAllDay=$isAllDay, shader=$shader)"
val startTimeText = if (startTime == null) null
else startTime!!.get(Calendar.YEAR).toString() + "-" + (startTime!!.get(Calendar.MONTH) + 1).toString() + "-" + startTime!!.get(Calendar.DAY_OF_MONTH).toString() + " " +
startTime!!.get(Calendar.HOUR_OF_DAY).toString() + ":" + startTime!!.get(Calendar.MINUTE) + ":" + startTime!!.get(Calendar.SECOND) + "." + startTime!!.get(Calendar.MILLISECOND)
val endTimeText = if (endTime == null) null
else endTime!!.get(Calendar.YEAR).toString() + "-" + (endTime!!.get(Calendar.MONTH) + 1).toString() + "-" + endTime!!.get(Calendar.DAY_OF_MONTH).toString() + " " +
endTime!!.get(Calendar.HOUR_OF_DAY).toString() + ":" + endTime!!.get(Calendar.MINUTE) + ":" + endTime!!.get(Calendar.SECOND) + "." + endTime!!.get(Calendar.MILLISECOND)
return "WeekViewEvent(identifier=$identifier, startTime=$startTimeText, endTime=$endTimeText, name=$name, location=$location, color=$color, isAllDay=$isAllDay, shader=$shader)"
val colorStr = "#${Integer.toHexString(color)}"
val startTimeStr = WeekViewUtil.calendarToString(startTime, !isAllDay)
if (isAllDay) {
if (endTime != null || WeekViewUtil.isSameDay(startTime!!, endTime!!))
return "allDayEvent(id=$id, time=$startTimeStr..${WeekViewUtil.calendarToString(startTime, false)}, name=$name, location=$location, color=$colorStr ,shader=$shader)"
return "allDayEvent(id=$id, time=$startTimeStr, name=$name, location=$location, color=$colorStr ,shader=$shader)"
}
if (endTime != null)
return "normalEvent(id=$id, startTime=$startTimeStr, name=$name, location=$location, color=$colorStr , shader=$shader)"
val endTimeStr = WeekViewUtil.calendarToString(endTime, true)
return "normalEvent(id=$id, startTime=$colorStr, endTime=$endTimeStr, name=$name, location=$location, color=$colorStr , shader=$shader)"
}
}
16 changes: 12 additions & 4 deletions library/src/main/java/com/alamkanak/weekview/WeekViewUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ import android.text.format.DateFormat
import java.text.SimpleDateFormat
import java.util.*

/**
* Created by jesse on 6/02/2016.
*/
object WeekViewUtil {


Expand Down Expand Up @@ -142,9 +139,20 @@ object WeekViewUtil {
sb.append(get(Calendar.YEAR).toString()).append('-').append((get(Calendar.MONTH) + 1).toString())
.append('-').append(get(Calendar.DAY_OF_MONTH).toString())
if (includeTime)
sb.append(get(Calendar.HOUR_OF_DAY).toString()).append(':').append(get(Calendar.MINUTE).toString()).append(':')
sb.append(" ").append(get(Calendar.HOUR_OF_DAY).toString()).append(':').append(get(Calendar.MINUTE).toString()).append(':')
.append(get(Calendar.SECOND).toString()).append('.').append(get(Calendar.MILLISECOND).toString())
}
return sb.toString()
}

@JvmStatic
fun resetTime(cal: Calendar) {
with(cal)
{
set(java.util.Calendar.HOUR_OF_DAY, 0)
set(java.util.Calendar.SECOND, 0)
set(java.util.Calendar.MINUTE, 0)
set(java.util.Calendar.MILLISECOND, 0)
}
}
}
Loading

0 comments on commit 0be8d77

Please sign in to comment.