Skip to content

Redesign timeline annotations: track-bound notes with inline editing and floating windows#896

Open
dhingora-amd wants to merge 10 commits into
mainfrom
dhingora/annotations-redesign
Open

Redesign timeline annotations: track-bound notes with inline editing and floating windows#896
dhingora-amd wants to merge 10 commits into
mainfrom
dhingora/annotations-redesign

Conversation

@dhingora-amd

Copy link
Copy Markdown
Contributor

Motivation

Timeline annotations (sticky notes) were clunky to use. Creating and editing
a note required separate "Add" and "Edit" modal popups, notes floated free in
content space rather than belonging to any track, and the timeline anchor was
hard to place — it couldn't be moved while a note was expanded and couldn't be
dragged past the visible range. This PR reworks annotations end-to-end into a
direct, inline experience and ties each note to the track it describes.

Technical Details

  • Track-bound notes: Annotations are now anchored to a specific track,
    with their Y position stored relative to that track's top. The bound
    track_id is persisted (JSON_KEY_ANNOTATION_TRACK_ID) and NavigationEvent
    carries it so "go to note" lands on the right track. The annotation list
    gains a Track column showing the bound track's name, or "Unbound" for legacy
    notes saved before this change.
  • Inline create/edit: Removed the Add/Edit modal dialogs (and the
    kStickyNoteEdited round-trip). A new note opens expanded and focused,
    commits on the first keystroke, and auto-discards if left empty. The
    expanded note's title is click-to-edit and the body is inline-editable, with
    trash/close buttons in the window.
  • Floating expanded window: The expanded note is now a movable floating
    window that stays where the user drags it (position tracked live, not
    persisted).
  • Draggable anchor + edge auto-scroll: The timeline anchor can be dragged
    whether the note is minimized or expanded. It is clamped to the visible
    track viewport, and the timeline pans/scrolls when the anchor nears a
    viewport edge so it can be placed beyond the currently visible range
    (rendering stays continuous during the drag for smooth motion).
  • Time guide line: A hovered/dragged note draws a time indicator line
    spanning the full visible track area.
  • Restyle: Reworked the sticky-note color palette (dark and light themes)
    to a warmer amber look with better contrast.
  • Cleanup: Removed dead annotation code (modal/edit paths, unused members,
    empty destructor, stale includes), added an INVALID_STICKY_ID sentinel,
    and updated the agent docs in .agents/AGENTS.md.

dhingora-amd and others added 8 commits June 18, 2026 13:42
Annotations were anchored to an absolute vertical position, so they
stayed put when tracks were reordered, collapsed, or resized. Bind each
sticky note to a track and store its offset relative to the track top so
it follows the track, while keeping it freely draggable.

- StickyNote stores a track id and a track-relative y offset; a per-frame
  TrackLayout resolver maps track ids to/from absolute Y.
- Notes re-anchor to whichever track they are dragged over; legacy notes
  with no binding re-anchor on first render (backward compatible).
- During a track reorder, the bound note rides the floating preview via a
  foreground drag ghost instead of being left behind until drop.
- Add a Track column to the annotations list and carry the track id
  through navigation so "jump to note" resolves the correct position.
- Persist the track id in the project file (legacy files load unbound).

Co-authored-by: Cursor <cursoragent@cursor.com>
Annotations are pinned to a timestamp, but there was no visual cue for
which point on the timeline a note refers to. Draw a vertical guide at
the note's time, spanning the graph height down to the ruler, so the
latched time is easy to read against the axis ticks.

- The guide appears while a note is hovered (minimized marker or expanded
  panel) or being dragged, and is hidden otherwise to avoid clutter.
- Tinted with the sticky-note accent color and drawn behind the marker.

Co-authored-by: Cursor <cursoragent@cursor.com>
Render the expanded sticky note as its own floating ImGui window so it
can be moved anywhere in the app instead of being clipped to the
timeline. ImGui now owns the window's move/resize, so the manual
HandleResize path and the resize/drag-within-timeline state are removed;
HandleDrag now only handles the minimized marker.

Also recolor the sticky-note palette to a cohesive yellow, fixing the
dark-mode brown-background / blue-border clash and the light-mode blue
border, and keep button hover/active states within the palette.

Co-authored-by: Cursor <cursoragent@cursor.com>
The minimized anchor marker now stays on the timeline while a note is
expanded, so its location is always visible. Hovering either the marker
or the floating window lights both with a soft accent halo, making it
easy to tell which marker belongs to which window. Clicking the marker
expands a minimized note or raises the window to the front when it is
already open.

Split the sticky-note render into focused marker/window/glow helpers and
replace the position sentinel and remaining literals with named helpers
and constants.

Co-authored-by: Cursor <cursoragent@cursor.com>
Draw the marker's hover glow on the timeline draw list instead of the
foreground one so the expanded window occludes it when the anchor sits
behind it, rather than the halo painting over the note.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the Add/Edit annotation modal popups with inline editing on the
note itself, and make the timeline anchor easier to place.

- Create notes inline: a new note opens expanded and focused, commits on
  the first keystroke, and auto-discards if left empty, removing the
  separate Add/Edit modal dialogs and the kStickyNoteEdited round-trip.
- Make the expanded note's title (click-to-edit) and body inline-editable,
  with trash/close buttons in the window.
- Allow dragging the timeline anchor while the note is expanded; clamp the
  anchor to the visible track viewport and pan/scroll the timeline when it
  nears a viewport edge, keeping render continuous during the drag.
- Draw the hovered/dragged note's time guide across the full visible track
  area instead of only near the top.
- Remove dead annotation code (modal/edit paths, unused members, empty
  destructor, stale includes), introduce INVALID_STICKY_ID, and refresh
  the agent docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
When an expanded note's header overlapped its timeline anchor icon,
dragging the header to move the window also satisfied the anchor's
hit test, so the note's timeline position moved along with the window.

Suppress starting an anchor drag when the click lands inside the
expanded note window's rect, so only the window moves.

Co-authored-by: Cursor <cursoragent@cursor.com>
@tomk-amd

Copy link
Copy Markdown
Collaborator

When the track that the note is attached to is hidden the note lands on a different track. And it still shows the old (hidden) track name as its "parent", ex:

image

Once it is clicked it updates to lock onto the new track. I am not sure if this is correct? When the track is hidden, I think the annotation should hide along with the track? Thoughts?

A note stayed on the timeline when its track was hidden, landing on
another track and showing the stale track as its parent. Skip a note's
rendering and interaction when its bound track's display flag is off.

Co-authored-by: Cursor <cursoragent@cursor.com>
sticky_json[JSON_KEY_ANNOTATION_TITLE] = notes[i].GetTitle();
sticky_json[JSON_KEY_ANNOTATION_ID] = notes[i].GetID();
sticky_json[JSON_KEY_ANNOTATION_TRACK_ID] =
static_cast<double>(notes[i].GetTrackId());

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double for track id?

else
{
ImGui::PushID("note_track");
ElidedText(track_name.c_str(), ImGui::GetContentRegionAvail().x);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This column has different vertical alignment vs others.

Image

ImGui::SetCursorPos(ImVec2(
win_size.x - action_btn_size * 2.0f - kHeaderButtonGap - kNoteMargin,
action_btn_y));
if(ImGui::Button(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These buttons become off center from frame the larger the font. Can we center or just go frameless?

Image

@drchen-amd drchen-amd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove StickyNoteEvent in rocprofvis_events.cpp. This is no longer used in current implementation.

@drchen-amd

Copy link
Copy Markdown
Member

When the track that the note is attached to is hidden the note lands on a different track. And it still shows the old (hidden) track name as its "parent", ex:

image Once it is clicked it updates to lock onto the new track. I am not sure if this is correct? When the track is hidden, I think the annotation should hide along with the track? Thoughts?

Maybe when a track with a note is hidden, the square indicator hides with it, and in the annotation table, the visible checkbox is greyed out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants