+ if( !player_replay.editor_mode ) return;
+ ui_capture_mouse(1);
+
+ ui_rect panel = { 0, timeline[3] + 20, 200, 400 };
+ ui_fill( panel, ui_opacity( ui_colour(k_ui_bg), 0.5f ) );
+ ui_rect_pad( panel, (ui_px[2]){4,4} );
+
+ if( ui_button( panel,
+ (player_replay.replay_control == k_replay_control_play)?
+ "Pause (space)": "Play (space)" ) == k_ui_button_click )
+ {
+ player_replay.replay_control ^= k_replay_control_play;
+ }
+
+ /* script bar */
+ ui_rect script = { 0, height + 2, vg.window_x, 16 };
+ ui_fill( script, ui_colour( k_ui_bg ) );
+
+ f64 mouse_t = start + ((f64)g_ui_ctx->mouse[0] / (f64)vg.window_x)*len;
+
+ /* keyframe draw and select */
+ bool absorb_by_keyframe = 0;
+ ui_px lx = 0;
+ for( u32 i=0; i<player_replay.keyframe_count; i ++ )
+ {
+ replay_keyframe *kf = &player_replay.keyframes[i];
+ f64 t = (kf->time-start)/len;
+
+ ui_px x = t*(f64)vg.window_x-8;
+
+ /* draw connections between keyframes */
+ if( i )
+ {
+ ui_rect con = { lx, script[1]+7, x-lx, 1 };
+ ui_fill( con, ui_colour(k_ui_blue) );
+ vg_line( kf->cam.pos, player_replay.keyframes[i-1].cam.pos, VG__BLUE );
+ }
+
+ /* keyframe selection */
+ ui_rect tag = { x, script[1], 16, 16 };
+
+ if( ui_inside_rect( tag, g_ui_ctx->mouse ) )
+ {
+ absorb_by_keyframe = 1;
+
+ if( ui_click_down( UI_MOUSE_LEFT ) )
+ {
+ if( player_replay.active_keyframe != i )
+ {
+ player_replay.active_keyframe = i;
+ replay_seek( &player_replay.local, kf->time );
+ }
+ }
+ else
+ {
+ ui_outline( tag, 1, ui_colour(k_ui_fg), 0 );
+ }
+ }
+
+ /* edit controls */
+ u32 drag_colour = ui_opacity( ui_colour(k_ui_bg+2), 0.5f );
+ if( i == player_replay.active_keyframe )
+ {
+ ui_outline( tag, 2, ui_colour(k_ui_fg), 0 );
+
+ ui_rect tray = { tag[0]+8-32, tag[1]+16+2, 64, 16 };
+ ui_rect dragbar = { tray[0]+16, tray[1], 32, 16 };
+
+ bool pos_correct = 0;
+
+ if( ui_inside_rect( dragbar, g_ui_ctx->mouse_click ) )
+ {
+ if( ui_clicking( UI_MOUSE_LEFT ) )
+ {
+ drag_colour = ui_opacity( ui_colour(k_ui_fg), 0.5f );
+ pos_correct = 1;
+ replay_seek( &player_replay.local, mouse_t );
+ }
+ else if( ui_click_up( UI_MOUSE_LEFT ) )
+ {
+ pos_correct = 1;
+ kf->time = mouse_t;
+ replay_keyframe_sort();
+
+ for( u32 j=0; j<player_replay.keyframe_count; j ++ )
+ {
+ if( player_replay.keyframes[j].time == mouse_t )
+ {
+ player_replay.active_keyframe = j;
+ break;
+ }
+ }
+ }
+
+ if( pos_correct )
+ {
+ tag[0] = g_ui_ctx->mouse[0]-8;
+ tray[0] = tag[0]+8-32;
+ dragbar[0] = tray[0]+16;
+ }
+ }
+
+ if( ui_inside_rect( dragbar, g_ui_ctx->mouse ) )
+ {
+ g_ui_ctx->cursor = k_ui_cursor_hand;
+ }
+
+ if( !pos_correct )
+ ui_fill( tray, ui_opacity( ui_colour(k_ui_bg+2), 0.5f ) );
+
+ ui_fill( dragbar, drag_colour );
+ ui_text( dragbar, ":::", 1, k_ui_align_middle_center, 0 );
+
+ if( !pos_correct )
+ {
+ ui_rect btn = { tray[0], tray[1], 16, 16 };
+ if( ui_button_text( btn, "X", 1 ) == k_ui_button_click )
+ {
+ for( u32 j=i; j<player_replay.keyframe_count-1; j ++ )
+ player_replay.keyframes[j] = player_replay.keyframes[j+1];
+
+ player_replay.keyframe_count --;
+ player_replay.active_keyframe = -1;
+ }
+
+ ui_rect btn1 = { tray[0]+48, tray[1], 16, 16 };