Kaynağa Gözat

move it responsibility away from DayGrid/TimeGrid

Adam Shaw 7 yıl önce
ebeveyn
işleme
2287c71eaf

+ 46 - 3
src/agenda/SimpleTimeGrid.ts

@@ -1,5 +1,5 @@
 import TimeGrid, { TimeGridSeg } from './TimeGrid'
-import Component from '../component/Component'
+import DateComponent from '../component/DateComponent'
 import { DateProfile } from '../DateProfileGenerator'
 import { EventStore } from '../structs/event-store'
 import { EventUiHash } from '../component/event-rendering'
@@ -11,6 +11,8 @@ import DayTable from '../common/DayTable'
 import { DateEnv } from '../datelib/env'
 import { DateMarker, addMs } from '../datelib/marker'
 import { Slicer } from '../common/slicing-utils'
+import OffsetTracker from '../common/OffsetTracker'
+import { Hit } from '../interactions/HitDragging'
 
 export interface SimpleTimeGridProps {
   dateProfile: DateProfile | null
@@ -24,16 +26,17 @@ export interface SimpleTimeGridProps {
   eventResize: EventInteractionUiState | null
 }
 
-export default class SimpleTimeGrid extends Component<SimpleTimeGridProps> {
+export default class SimpleTimeGrid extends DateComponent<SimpleTimeGridProps> {
 
   timeGrid: TimeGrid
   dayRanges: DateRange[]
+  offsetTracker: OffsetTracker
 
   private buildDayRanges = reselector(buildDayRanges)
   private slicer = new Slicer(sliceSegs)
 
   constructor(context, timeGrid: TimeGrid) {
-    super(context)
+    super(context, timeGrid.el)
 
     this.timeGrid = timeGrid
     this.slicer.component = timeGrid
@@ -69,8 +72,48 @@ export default class SimpleTimeGrid extends Component<SimpleTimeGridProps> {
     )
   }
 
+  prepareHits() {
+    this.offsetTracker = new OffsetTracker(this.timeGrid.el)
+  }
+
+  releaseHits() {
+    this.offsetTracker.destroy()
+  }
+
+  queryHit(leftOffset, topOffset): Hit {
+    let { offsetTracker } = this
+
+    if (offsetTracker.isWithinClipping(leftOffset, topOffset)) {
+      let originLeft = offsetTracker.computeLeft()
+      let originTop = offsetTracker.computeTop()
+
+      let rawHit = this.timeGrid.positionToHit(
+        leftOffset - originLeft,
+        topOffset - originTop
+      )
+
+      if (rawHit) {
+        return {
+          component: this.timeGrid,
+          dateSpan: rawHit.dateSpan,
+          dayEl: rawHit.dayEl,
+          rect: {
+            left: rawHit.relativeRect.left + originLeft,
+            right: rawHit.relativeRect.right + originLeft,
+            top: rawHit.relativeRect.top + originTop,
+            bottom: rawHit.relativeRect.bottom + originTop
+          },
+          layer: 0
+        }
+      }
+    }
+  }
+
 }
 
+SimpleTimeGrid.prototype.isInteractable = true
+
+
 export function buildDayRanges(dayTable: DayTable, dateProfile: DateProfile, dateEnv: DateEnv): DateRange[] {
   let ranges: DateRange[] = []
 

+ 30 - 50
src/agenda/TimeGrid.ts

@@ -9,8 +9,6 @@ import { startOfDay, DateMarker } from '../datelib/marker'
 import { DateFormatter, createFormatter, formatIsoTimeString } from '../datelib/formatting'
 import { ComponentContext } from '../component/Component'
 import DateComponent, { Seg, EventSegUiInteractionState } from '../component/DateComponent'
-import OffsetTracker from '../common/OffsetTracker'
-import { Hit } from '../interactions/HitDragging'
 import DayBgRow from '../basic/DayBgRow'
 import { DateProfile } from '../DateProfileGenerator'
 
@@ -73,7 +71,6 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
 
   colPositions: PositionCache
   slatPositions: PositionCache
-  offsetTracker: OffsetTracker
 
   rootBgContainerEl: HTMLElement
   bottomRuleEl: HTMLElement // hidden by default
@@ -592,56 +589,40 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
   /* Hit System
   ------------------------------------------------------------------------------------------------------------------*/
 
+  positionToHit(positionLeft, positionTop) {
+    let { dateEnv, snapsPerSlot, slatPositions, colPositions } = this
 
-  prepareHits() {
-    this.offsetTracker = new OffsetTracker(this.el)
-  }
-
+    let colIndex = colPositions.leftToIndex(positionLeft)
+    let slatIndex = slatPositions.topToIndex(positionTop)
 
-  releaseHits() {
-    this.offsetTracker.destroy()
-  }
+    if (colIndex != null && slatIndex != null) {
+      let slatTop = slatPositions.tops[slatIndex]
+      let slatHeight = slatPositions.getHeight(slatIndex)
+      let partial = (positionTop - slatTop) / slatHeight // floating point number between 0 and 1
+      let localSnapIndex = Math.floor(partial * snapsPerSlot) // the snap # relative to start of slat
+      let snapIndex = slatIndex * snapsPerSlot + localSnapIndex
 
+      let dayDate = this.props.cells[colIndex].date
+      let time = addDurations(
+        this.props.dateProfile.minTime,
+        multiplyDuration(this.snapDuration, snapIndex)
+      )
 
-  queryHit(leftOffset, topOffset): Hit {
-    let { dateEnv, snapsPerSlot, slatPositions, colPositions, offsetTracker } = this
-
-    if (offsetTracker.isWithinClipping(leftOffset, topOffset)) {
-      let leftOrigin = offsetTracker.computeLeft()
-      let topOrigin = offsetTracker.computeTop()
-      let colIndex = colPositions.leftToIndex(leftOffset - leftOrigin)
-      let slatIndex = slatPositions.topToIndex(topOffset - topOrigin)
-
-      if (colIndex != null && slatIndex != null) {
-        let slatTop = slatPositions.tops[slatIndex] + topOrigin
-        let slatHeight = slatPositions.getHeight(slatIndex)
-        let partial = (topOffset - slatTop) / slatHeight // floating point number between 0 and 1
-        let localSnapIndex = Math.floor(partial * snapsPerSlot) // the snap # relative to start of slat
-        let snapIndex = slatIndex * snapsPerSlot + localSnapIndex
-
-        let dayDate = this.props.cells[colIndex].date
-        let time = addDurations(
-          this.props.dateProfile.minTime,
-          multiplyDuration(this.snapDuration, snapIndex)
-        )
-
-        let start = dateEnv.add(dayDate, time)
-        let end = dateEnv.add(start, this.snapDuration)
-
-        return {
-          component: this,
-          dateSpan: {
-            range: { start, end },
-            allDay: false
-          },
-          dayEl: this.colEls[colIndex],
-          rect: {
-            left: colPositions.lefts[colIndex] + leftOrigin,
-            right: colPositions.rights[colIndex] + leftOrigin,
-            top: slatTop,
-            bottom: slatTop + slatHeight
-          },
-          layer: 0
+      let start = dateEnv.add(dayDate, time)
+      let end = dateEnv.add(start, this.snapDuration)
+
+      return {
+        col: colIndex,
+        dateSpan: {
+          range: { start, end },
+          allDay: false
+        },
+        dayEl: this.colEls[colIndex],
+        relativeRect: {
+          left: colPositions.lefts[colIndex],
+          right: colPositions.rights[colIndex],
+          top: slatTop,
+          bottom: slatTop + slatHeight
         }
       }
     }
@@ -678,6 +659,5 @@ export default class TimeGrid extends DateComponent<TimeGridProps> {
 
 }
 
-TimeGrid.prototype.isInteractable = true
 TimeGrid.prototype.doesDragMirror = true
 TimeGrid.prototype.doesDragHighlight = false

+ 20 - 39
src/basic/DayGrid.ts

@@ -17,9 +17,7 @@ import { createFormatter } from '../datelib/formatting'
 import DateComponentProps, { EventSegUiInteractionState } from '../component/DateComponent'
 import { Seg } from '../component/DateComponent'
 import DayTile from './DayTile'
-import { Hit } from '../interactions/HitDragging'
 import { rangeContainsMarker, intersectRanges } from '../datelib/date-range'
-import OffsetTracker from '../common/OffsetTracker'
 import { EventRenderRange } from '../component/event-rendering'
 import { buildGotoAnchorHtml, getDayClasses } from '../component/date-rendering'
 import DayBgRow from './DayBgRow'
@@ -81,7 +79,6 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
 
   rowPositions: PositionCache
   colPositions: PositionCache
-  offsetTracker: OffsetTracker
 
   segPopover: Popover // the Popover that holds events that can't fit in a cell. null when not visible
   segPopoverTile: DayTile
@@ -396,41 +393,26 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
   /* Hit System
   ------------------------------------------------------------------------------------------------------------------*/
 
-
-  prepareHits() {
-    this.offsetTracker = new OffsetTracker(this.el)
-  }
-
-
-  releaseHits() {
-    this.offsetTracker.destroy()
-  }
-
-
-  queryHit(leftOffset, topOffset): Hit {
-    let { colPositions, rowPositions, offsetTracker } = this
-
-    if (offsetTracker.isWithinClipping(leftOffset, topOffset)) {
-      let leftOrigin = offsetTracker.computeLeft()
-      let topOrigin = offsetTracker.computeTop()
-      let col = colPositions.leftToIndex(leftOffset - leftOrigin)
-      let row = rowPositions.topToIndex(topOffset - topOrigin)
-
-      if (row != null && col != null) {
-        return {
-          component: this,
-          dateSpan: {
-            range: this.getCellRange(row, col),
-            allDay: true
-          },
-          dayEl: this.getCellEl(row, col),
-          rect: {
-            left: colPositions.lefts[col] + leftOrigin,
-            right: colPositions.rights[col] + leftOrigin,
-            top: rowPositions.tops[row] + topOrigin,
-            bottom: rowPositions.bottoms[row] + topOrigin
-          },
-          layer: 0
+  positionToHit(leftPosition, topPosition) {
+    let { colPositions, rowPositions } = this
+
+    let col = colPositions.leftToIndex(leftPosition)
+    let row = rowPositions.topToIndex(topPosition)
+
+    if (row != null && col != null) {
+      return {
+        row,
+        col,
+        dateSpan: {
+          range: this.getCellRange(row, col),
+          allDay: true
+        },
+        dayEl: this.getCellEl(row, col),
+        relativeRect: {
+          left: colPositions.lefts[col],
+          right: colPositions.rights[col],
+          top: rowPositions.tops[row],
+          bottom: rowPositions.bottoms[row]
         }
       }
     }
@@ -816,6 +798,5 @@ export default class DayGrid extends DateComponentProps<DayGridProps> {
 
 }
 
-DayGrid.prototype.isInteractable = true
 DayGrid.prototype.doesDragMirror = false
 DayGrid.prototype.doesDragHighlight = true

+ 46 - 3
src/basic/SimpleDayGrid.ts

@@ -6,9 +6,11 @@ import { DateSpan } from '../structs/date-span'
 import { EventInteractionUiState } from '../interactions/event-interaction-state'
 import DayTable from '../common/DayTable'
 import { Duration } from '../datelib/duration'
-import Component from '../component/Component'
+import DateComponent from '../component/DateComponent'
 import { DateRange } from '../datelib/date-range'
 import { Slicer } from '../common/slicing-utils'
+import OffsetTracker from '../common/OffsetTracker'
+import { Hit } from '../interactions/HitDragging'
 
 export interface SimpleDayGridProps {
   dateProfile: DateProfile | null
@@ -24,14 +26,15 @@ export interface SimpleDayGridProps {
   isRigid: boolean
 }
 
-export default class SimpleDayGrid extends Component<SimpleDayGridProps> {
+export default class SimpleDayGrid extends DateComponent<SimpleDayGridProps> {
 
   dayGrid: DayGrid
+  offsetTracker: OffsetTracker
 
   private slicer = new Slicer(sliceSegs)
 
   constructor(context, dayGrid: DayGrid) {
-    super(context)
+    super(context, dayGrid.el)
 
     this.dayGrid = dayGrid
     this.slicer.component = dayGrid
@@ -54,8 +57,48 @@ export default class SimpleDayGrid extends Component<SimpleDayGridProps> {
     })
   }
 
+  prepareHits() {
+    this.offsetTracker = new OffsetTracker(this.dayGrid.el)
+  }
+
+  releaseHits() {
+    this.offsetTracker.destroy()
+  }
+
+  queryHit(leftOffset, topOffset): Hit {
+    let { offsetTracker } = this
+
+    if (offsetTracker.isWithinClipping(leftOffset, topOffset)) {
+      let originLeft = offsetTracker.computeLeft()
+      let originTop = offsetTracker.computeTop()
+
+      let rawHit = this.dayGrid.positionToHit(
+        leftOffset - originLeft,
+        topOffset - originTop
+      )
+
+      if (rawHit) {
+        return {
+          component: this.dayGrid,
+          dateSpan: rawHit.dateSpan,
+          dayEl: rawHit.dayEl,
+          rect: {
+            left: rawHit.relativeRect.left + originLeft,
+            right: rawHit.relativeRect.right + originLeft,
+            top: rawHit.relativeRect.top + originTop,
+            bottom: rawHit.relativeRect.bottom + originTop
+          },
+          layer: 0
+        }
+      }
+    }
+  }
+
 }
 
+SimpleDayGrid.prototype.isInteractable = true
+
+
 export function sliceSegs(range: DateRange, dayTable: DayTable, isRtl: boolean): DayGridSeg[] {
   return dayTable.sliceRange(range).map(function(seg) {
     return {