@@ -19,13 +19,16 @@ import {
1919 onEventAdd ,
2020 useCursor ,
2121 Layer ,
22- TimelineEvent
22+ TimelineEvent ,
23+ useMarkers ,
24+ TimelineMarker
2325} from ' ./composable'
2426import { useApps } from ' @front/features/apps'
2527import { onKeyUp } from ' @front/util/keyboard'
2628import SharedData from ' @utils/shared-data'
2729import { useDarkMode } from ' @front/util/theme'
2830import { dimColor , boostColor } from ' @front/util/color'
31+ import { formatTime } from ' @front/util/format'
2932
3033const LAYER_SIZE = 16
3134const GROUP_SIZE = 6
@@ -41,6 +44,10 @@ export default defineComponent({
4144 const { startTime, endTime, minTime, maxTime } = useTime ()
4245 const { darkMode } = useDarkMode ()
4346
47+ function getTimePosition (time : number ) {
48+ return (time - minTime .value ) / (endTime .value - startTime .value ) * app .view .width
49+ }
50+
4451 // Reset
4552
4653 type ResetCb = () => void
@@ -106,6 +113,53 @@ export default defineComponent({
106113 updateBackground ()
107114 })
108115
116+ // Markers
117+
118+ const { currentAppMarkers } = useMarkers ()
119+
120+ let markerContainer: PIXI .Graphics
121+
122+ onMounted (() => {
123+ markerContainer = new PIXI .Graphics ()
124+ app .stage .addChild (markerContainer )
125+ drawMarkers ()
126+ })
127+
128+ function drawMarkers () {
129+ console .log (' markers' , currentAppMarkers .value )
130+ markerContainer .clear ()
131+ for (const marker of currentAppMarkers .value ) {
132+ markerContainer .lineStyle (1 , marker .color , 0.5 , 0 , true )
133+ const x = getTimePosition (marker .time )
134+ marker .x = x
135+ markerContainer .moveTo (x , 0 )
136+ markerContainer .lineTo (x , app .view .height )
137+ }
138+ markerContainer .x = horizontalScrollingContainer .x
139+ }
140+
141+ watch (currentAppMarkers , () => {
142+ if (markerContainer ) {
143+ drawMarkers ()
144+ }
145+ })
146+
147+ function getMarkerAtPosition (targetX : number ): TimelineMarker | null {
148+ let choice: TimelineMarker = null
149+ let dist: number
150+
151+ for (const marker of currentAppMarkers .value ) {
152+ const globalX = marker .x + markerContainer .x
153+ const currentDist = Math .abs (targetX - globalX )
154+ if (currentDist <= 50 && (currentDist < dist || ! choice )) {
155+ dist = currentDist
156+ choice = marker
157+ }
158+ }
159+
160+ return choice
161+ }
162+
109163 // Layers
110164
111165 const {
@@ -247,10 +301,6 @@ export default defineComponent({
247301
248302 let events: TimelineEvent [] = []
249303
250- function getEventPosition (event : TimelineEvent ) {
251- return (event .time - minTime .value ) / (endTime .value - startTime .value ) * app .view .width
252- }
253-
254304 const updateEventPositionQueue = new Set <TimelineEvent >()
255305 let currentEventPositionUpdate: TimelineEvent = null
256306 let updateEventPositionQueued = false
@@ -262,7 +312,7 @@ export default defineComponent({
262312 e .container .visible = ! ignored
263313 if (ignored ) continue
264314 // Update horizontal position immediately
265- e .container .x = getEventPosition ( e )
315+ e .container .x = getTimePosition ( e . time )
266316 // Queue vertical position compute
267317 updateEventPositionQueue .add (e )
268318 }
@@ -316,13 +366,13 @@ export default defineComponent({
316366 (
317367 // Horizontal intersection (first event)
318368 (
319- getEventPosition (firstEvent ) >= getEventPosition (otherGroup .firstEvent ) - offset &&
320- getEventPosition (firstEvent ) <= getEventPosition (otherGroup .lastEvent ) + offset + lastOffset
369+ getTimePosition (firstEvent . time ) >= getTimePosition (otherGroup .firstEvent . time ) - offset &&
370+ getTimePosition (firstEvent . time ) <= getTimePosition (otherGroup .lastEvent . time ) + offset + lastOffset
321371 ) ||
322372 // Horizontal intersection (last event)
323373 (
324- getEventPosition (lastEvent ) >= getEventPosition (otherGroup .firstEvent ) - offset - lastOffset &&
325- getEventPosition (lastEvent ) <= getEventPosition (otherGroup .lastEvent ) + offset
374+ getTimePosition (lastEvent . time ) >= getTimePosition (otherGroup .firstEvent . time ) - offset - lastOffset &&
375+ getTimePosition (lastEvent . time ) <= getTimePosition (otherGroup .lastEvent . time ) + offset
326376 )
327377 )
328378 ) {
@@ -657,10 +707,11 @@ export default defineComponent({
657707 eventTooltip .addChild (eventTooltipText )
658708
659709 app .stage .addListener (' mousemove' , mouseEvent => {
710+ const text: string [] = []
711+
712+ // Event tooltip
660713 const event = getEventAtPosition (mouseEvent .data .global .x , mouseEvent .data .global .y )
661714 if (event ) {
662- const text = []
663-
664715 text .push (event .title ?? ' Event' )
665716 if (event .subtitle ) {
666717 text .push (event .subtitle )
@@ -670,34 +721,41 @@ export default defineComponent({
670721 text .push (` Group: ${event .group .duration }ms (${event .group .events .length } event${event .group .events .length > 1 ? ' s' : ' ' }) ` )
671722 }
672723
673- if (! text .length ) {
674- eventTooltip .visible = false
675- } else {
676- eventTooltipText .text = text .join (' \n ' )
677-
678- eventTooltipGraphics .clear ()
679- eventTooltipGraphics .beginFill (0xffffff )
680- eventTooltipGraphics .lineStyle (1 , 0x000000 , 0.2 , 1 )
681- eventTooltipGraphics .drawRoundedRect (0 , 0 , eventTooltipText .width + 8 , eventTooltipText .height + 8 , 4 )
682-
683- eventTooltip .x = mouseEvent .data .global .x + 12
684- if (eventTooltip .x + eventTooltip .width > app .renderer .width ) {
685- eventTooltip .x = mouseEvent .data .global .x - eventTooltip .width - 12
686- }
687- eventTooltip .y = mouseEvent .data .global .y + 12
688- if (eventTooltip .y + eventTooltip .height > app .renderer .height ) {
689- eventTooltip .y = mouseEvent .data .global .y - eventTooltip .height - 12
690- }
691- eventTooltip .visible = true
692- }
693-
694724 if (hoverEvent ?.container && hoverEvent !== event ) {
695725 hoverEvent .container .alpha = 1
696726 }
697727 hoverEvent = event
698728 if (hoverEvent ?.container ) {
699729 hoverEvent .container .alpha = 0.5
700730 }
731+ } else {
732+ // Marker tooltip
733+ const marker = getMarkerAtPosition (mouseEvent .data .global .x )
734+ if (marker ) {
735+ text .push (marker .label )
736+ text .push (formatTime (marker .time , ' ms' ))
737+ text .push (' (marker)' )
738+ }
739+ }
740+
741+ if (text .length ) {
742+ // Draw tooltip
743+ eventTooltipText .text = text .join (' \n ' )
744+
745+ eventTooltipGraphics .clear ()
746+ eventTooltipGraphics .beginFill (0xffffff )
747+ eventTooltipGraphics .lineStyle (1 , 0x000000 , 0.2 , 1 )
748+ eventTooltipGraphics .drawRoundedRect (0 , 0 , eventTooltipText .width + 8 , eventTooltipText .height + 8 , 4 )
749+
750+ eventTooltip .x = mouseEvent .data .global .x + 12
751+ if (eventTooltip .x + eventTooltip .width > app .renderer .width ) {
752+ eventTooltip .x = mouseEvent .data .global .x - eventTooltip .width - 12
753+ }
754+ eventTooltip .y = mouseEvent .data .global .y + 12
755+ if (eventTooltip .y + eventTooltip .height > app .renderer .height ) {
756+ eventTooltip .y = mouseEvent .data .global .y - eventTooltip .height - 12
757+ }
758+ eventTooltip .visible = true
701759 } else {
702760 if (hoverEvent ?.container ) {
703761 hoverEvent .container .alpha = 1
@@ -716,7 +774,7 @@ export default defineComponent({
716774 /** @type {PIXI.Graphics} */
717775 const g = event .groupG
718776 g .clear ()
719- const size = getEventPosition (event .group .lastEvent ) - getEventPosition (event .group .firstEvent )
777+ const size = getTimePosition (event .group .lastEvent . time ) - getTimePosition (event .group .firstEvent . time )
720778 if (event .layer .groupsOnly ) {
721779 if (drawAsSelected ) {
722780 g .lineStyle (2 , boostColor (event .layer .color , darkMode .value ))
@@ -861,6 +919,7 @@ export default defineComponent({
861919 horizontalScrollingContainer .x = - (startTime .value - minTime .value ) / (endTime .value - startTime .value ) * app .view .width
862920 drawLayerBackgroundEffects ()
863921 drawTimeGrid ()
922+ drawMarkers ()
864923 }
865924
866925 watch (startTime , () => queueCameraUpdate ())
0 commit comments