Bugfixes calendar auto scroll
This commit is contained in:
parent
5cf089dd72
commit
73c4190231
|
@ -3,15 +3,16 @@ package de.kif.frontend.views.calendar
|
||||||
import de.kif.frontend.launch
|
import de.kif.frontend.launch
|
||||||
import de.kif.frontend.repository.RoomRepository
|
import de.kif.frontend.repository.RoomRepository
|
||||||
import de.kif.frontend.repository.ScheduleRepository
|
import de.kif.frontend.repository.ScheduleRepository
|
||||||
import de.westermann.kwebview.View
|
import de.westermann.kwebview.*
|
||||||
import de.westermann.kwebview.createHtmlView
|
import de.westermann.robots.website.toolkit.view.TouchEvent
|
||||||
import de.westermann.kwebview.iterator
|
|
||||||
import org.w3c.dom.*
|
import org.w3c.dom.*
|
||||||
|
import org.w3c.dom.events.Event
|
||||||
import org.w3c.dom.events.EventListener
|
import org.w3c.dom.events.EventListener
|
||||||
|
import org.w3c.dom.events.MouseEvent
|
||||||
|
import org.w3c.dom.events.WheelEvent
|
||||||
import kotlin.browser.document
|
import kotlin.browser.document
|
||||||
import kotlin.browser.window
|
import kotlin.browser.window
|
||||||
import kotlin.js.Date
|
import kotlin.js.Date
|
||||||
import kotlin.math.abs
|
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
|
@ -80,6 +81,41 @@ class Calendar(calendar: HTMLElement) : View(calendar) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun scroll(horizontal: Double, vertical: Double, event: Event? = null) {
|
||||||
|
var horizontalScroll = horizontal
|
||||||
|
var verticalScroll = vertical
|
||||||
|
|
||||||
|
if (verticalScroll > 0) {
|
||||||
|
val x = html.offsetTop - htmlBody.scrollTop
|
||||||
|
if (x > 0) {
|
||||||
|
val bodyScroll = min(x, verticalScroll)
|
||||||
|
verticalScroll -= bodyScroll
|
||||||
|
htmlBody.scrollBy(ScrollToOptions(0.0, bodyScroll, ScrollBehavior.INSTANT))
|
||||||
|
} else {
|
||||||
|
if (calendarTable.scrollTop + calendarTable.clientHeight + 5 >= calendarTable.scrollHeight) {
|
||||||
|
htmlBody.scrollBy(ScrollToOptions(0.0, verticalScroll, ScrollBehavior.INSTANT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (verticalScroll < 0) {
|
||||||
|
val x = html.offsetTop - htmlBody.scrollTop
|
||||||
|
if (x < 0) {
|
||||||
|
val bodyScroll = max(x, verticalScroll)
|
||||||
|
verticalScroll -= bodyScroll
|
||||||
|
htmlBody.scrollBy(ScrollToOptions(0.0, bodyScroll, ScrollBehavior.INSTANT))
|
||||||
|
} else {
|
||||||
|
if (calendarTable.scrollTop == 0.0) {
|
||||||
|
htmlBody.scrollBy(ScrollToOptions(0.0, verticalScroll, ScrollBehavior.INSTANT))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollHorizontalBy(horizontalScroll, ScrollBehavior.INSTANT)
|
||||||
|
scrollVerticalBy(verticalScroll, ScrollBehavior.INSTANT)
|
||||||
|
|
||||||
|
event?.preventDefault()
|
||||||
|
event?.stopPropagation()
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
scroll += calendarTable
|
scroll += calendarTable
|
||||||
|
|
||||||
|
@ -113,52 +149,61 @@ class Calendar(calendar: HTMLElement) : View(calendar) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onWheel {
|
document.addEventListener("wheel", EventListener {
|
||||||
|
val event = it as? WheelEvent ?: return@EventListener
|
||||||
|
|
||||||
autoScroll = false
|
autoScroll = false
|
||||||
|
|
||||||
val multiplier = when (it.deltaMode) {
|
val multiplier = when (event.deltaMode) {
|
||||||
1 -> 16.0
|
1 -> 16.0
|
||||||
2 -> window.innerHeight.toDouble()
|
2 -> window.innerHeight.toDouble()
|
||||||
else -> 1.0
|
else -> 1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
var verticalScroll = it.deltaY * multiplier
|
scroll(event.deltaX * multiplier, event.deltaY * multiplier, event)
|
||||||
|
})
|
||||||
|
|
||||||
if (verticalScroll > 0) {
|
var mousePoint: Point? = null
|
||||||
val x = html.offsetTop - htmlBody.scrollTop
|
|
||||||
if (x > 0) {
|
|
||||||
val bodyScroll = min(x, verticalScroll)
|
|
||||||
verticalScroll -= bodyScroll
|
|
||||||
htmlBody.scrollBy(ScrollToOptions(0.0, bodyScroll, ScrollBehavior.INSTANT))
|
|
||||||
} else {
|
|
||||||
if (calendarTable.scrollTop + calendarTable.clientHeight + 5 >= calendarTable.scrollHeight) {
|
|
||||||
htmlBody.scrollBy(ScrollToOptions(0.0, verticalScroll, ScrollBehavior.INSTANT))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (verticalScroll < 0) {
|
|
||||||
val x = html.offsetTop - htmlBody.scrollTop
|
|
||||||
if (x < 0) {
|
|
||||||
val bodyScroll = max(x, verticalScroll)
|
|
||||||
verticalScroll -= bodyScroll
|
|
||||||
htmlBody.scrollBy(ScrollToOptions(0.0, bodyScroll, ScrollBehavior.INSTANT))
|
|
||||||
} else {
|
|
||||||
if (calendarTable.scrollTop == 0.0) {
|
|
||||||
htmlBody.scrollBy(ScrollToOptions(0.0, verticalScroll, ScrollBehavior.INSTANT))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
scrollHorizontalBy(it.deltaX * multiplier, ScrollBehavior.INSTANT)
|
document.addEventListener("mousedown", EventListener {
|
||||||
scrollVerticalBy(verticalScroll, ScrollBehavior.INSTANT)
|
val event = it as? MouseEvent ?: return@EventListener
|
||||||
|
mousePoint = event.toPoint()
|
||||||
it.preventDefault()
|
})
|
||||||
}
|
document.addEventListener("mouseup", EventListener {
|
||||||
|
mousePoint = null
|
||||||
onMouseDown {
|
})
|
||||||
|
document.addEventListener("mousemove", EventListener {
|
||||||
|
val event = it as? MouseEvent ?: return@EventListener
|
||||||
autoScroll = false
|
autoScroll = false
|
||||||
}
|
|
||||||
|
|
||||||
html.addEventListener("touchstart", EventListener {
|
val mp = mousePoint ?: return@EventListener
|
||||||
|
val p = event.toPoint()
|
||||||
|
|
||||||
|
scroll(mp.x - p.x, mp.y - p.y, event)
|
||||||
|
|
||||||
|
mousePoint = p
|
||||||
|
})
|
||||||
|
|
||||||
|
document.addEventListener("touchstart", EventListener {
|
||||||
|
val event = it as? TouchEvent ?: return@EventListener
|
||||||
|
mousePoint = event.toPoint()
|
||||||
|
})
|
||||||
|
document.addEventListener("touchend", EventListener {
|
||||||
|
mousePoint = null
|
||||||
|
})
|
||||||
|
document.addEventListener("touchmove", EventListener {
|
||||||
|
val event = it as? TouchEvent ?: return@EventListener
|
||||||
|
autoScroll = false
|
||||||
|
|
||||||
|
val mp = mousePoint ?: return@EventListener
|
||||||
|
val p = event.toPoint() ?: return@EventListener
|
||||||
|
|
||||||
|
scroll(mp.x - p.x, mp.y - p.y, event)
|
||||||
|
|
||||||
|
mousePoint = p
|
||||||
|
})
|
||||||
|
|
||||||
|
document.addEventListener("scroll", EventListener {
|
||||||
autoScroll = false
|
autoScroll = false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
39
src/jsMain/kotlin/de/westermann/kwebview/TouchPolyfill.kt
Normal file
39
src/jsMain/kotlin/de/westermann/kwebview/TouchPolyfill.kt
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
package de.westermann.robots.website.toolkit.view
|
||||||
|
|
||||||
|
import org.w3c.dom.events.EventTarget
|
||||||
|
import org.w3c.dom.events.UIEvent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lars
|
||||||
|
*/
|
||||||
|
|
||||||
|
open external class TouchEvent(type: String) : UIEvent {
|
||||||
|
open val changedTouches: TouchList
|
||||||
|
open val targetTouches: TouchList
|
||||||
|
open val touches: TouchList
|
||||||
|
open val ctrlKey: Boolean
|
||||||
|
open val shiftKey: Boolean
|
||||||
|
open val altKey: Boolean
|
||||||
|
open val metaKey: Boolean
|
||||||
|
fun getModifierState(keyArg: String): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
open external class TouchList() {
|
||||||
|
open val length: Int
|
||||||
|
open fun item(index: Int): Touch?
|
||||||
|
}
|
||||||
|
|
||||||
|
open external class Touch() {
|
||||||
|
open val identifier: Int
|
||||||
|
open val target: EventTarget
|
||||||
|
open val screenX: Int
|
||||||
|
open val screenY: Int
|
||||||
|
open val clientX: Int
|
||||||
|
open val clientY: Int
|
||||||
|
open val pageX: Int
|
||||||
|
open val pageY: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun TouchList.get(index: Int) = item(index)
|
||||||
|
fun TouchList.all(): List<Touch> = (0..length).map { item(it) }.filterNotNull()
|
||||||
|
fun TouchList.find(identifier: Int): Touch? = all().find { it.identifier == identifier }
|
|
@ -1,6 +1,8 @@
|
||||||
package de.westermann.kwebview
|
package de.westermann.kwebview
|
||||||
|
|
||||||
import de.westermann.kobserve.event.EventHandler
|
import de.westermann.kobserve.event.EventHandler
|
||||||
|
import de.westermann.robots.website.toolkit.view.TouchEvent
|
||||||
|
import de.westermann.robots.website.toolkit.view.get
|
||||||
import org.w3c.dom.*
|
import org.w3c.dom.*
|
||||||
import org.w3c.dom.events.Event
|
import org.w3c.dom.events.Event
|
||||||
import org.w3c.dom.events.EventListener
|
import org.w3c.dom.events.EventListener
|
||||||
|
@ -72,6 +74,7 @@ inline fun <reified T> EventHandler<T>.bind(element: HTMLElement, event: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MouseEvent.toPoint(): Point = Point(clientX, clientY)
|
fun MouseEvent.toPoint(): Point = Point(clientX, clientY)
|
||||||
|
fun TouchEvent.toPoint(): Point? = touches[0]?.let { Point(it.clientX, it.clientY) }
|
||||||
fun DOMRect.toDimension(): Dimension = Dimension(x, y, width, height)
|
fun DOMRect.toDimension(): Dimension = Dimension(x, y, width, height)
|
||||||
|
|
||||||
fun Number.format(digits: Int): String = this.asDynamic().toFixed(digits)
|
fun Number.format(digits: Int): String = this.asDynamic().toFixed(digits)
|
||||||
|
|
Loading…
Reference in a new issue