Function trigger for trace offset?

Does anyone know a hook or other method to use for triggering a function upon offsetting a trace? I'd like to be able to drag a trace in a graph window to a new location (ie, for offsetting a threshold trace), and then when released have igor execute a function to take into account the new offset location, etc.

Any ideas?
Here is something that might be of use.

Caveat: The hook is not called if the trace offsets are set by a command, only if set by dragging.

Function GetTraceOffset(graphNameStr, traceIndex, xOffset, yOffset)
    String graphNameStr
    Variable traceIndex     // 0 for first trace, 1 for second, . . .
    Variable& xOffset       // Output
    Variable& yOffset       // Output
   
    xOffset = NaN
    yOffset = NaN
   
    String info = TraceInfo(graphNameStr, "", traceIndex)
    if (strlen(info) == 0)
        return -1
    endif
   
    // Strip out everything before "offset(x)" - (would not be necessary if I knew what I was doing with regular expressions)
    Variable pos = strsearch(info, "offset(x)", 0)
    Variable len = strlen(info)
    info = info[pos,len]
   
    // Strip out everything after next semicolon - (would not be necessary if I knew what I was doing with regular expressions)
    pos = strsearch(info, ";", 0)
    info = info[0, pos]

    // Extract x and y offsets as strings
    String regExp = ".*offset\\(x\\)={([^,]*),([^\\}]*)"
    String xOffsetStr, yOffsetStr
    SplitString /E=regExp info, xOffsetStr, yOffsetStr

    // Convert to numbers and return via pass-by-reference parameters
    xOffset = str2num(xOffsetStr)
    yOffset = str2num(yOffsetStr)
   
    return 0
End

Function MyWinHook(s)
    STRUCT WMWinHookStruct &s

    Variable xOffset, yOffset

    Variable rval= 0
    switch(s.eventCode)
        case 4:         // Mouse down
            GetTraceOffset(s.winName, 0, xOffset, yOffset)      // 0 means first trace
            // Printf "xOffset=%g, yOffset=%g\r", xOffset, yOffset
            Variable /G root:gLastXOffset = xOffset
            Variable /G root:gLastYOffset = yOffset
            break
        case 5:         // Mouse up
            GetTraceOffset(s.winName, 0, xOffset, yOffset)      // 0 means first trace
            // Printf "xOffset=%g, yOffset=%g\r", xOffset, yOffset
            NVAR lastXOffset = root:gLastXOffset
            if (xOffset != lastXOffset)
                Printf "New X offset = %d\r", xOffset
            endif
            NVAR lastYOffset = root:gLastYOffset
            if (yOffset != lastYOffset)
                Printf "New Y offset = %d\r", yOffset
            endif
            break
    endswitch

    return rval
End

Function DemoSetCursorHook()
    Make/O jack=x
    Display jack
    SetWindow kwTopWin,hook(testhook)= MyWinHook
End


For details on window hooks:
DisplayHelpTopic "Window Hook Functions"


Another approach would be to use a background task to look at the trace offsets periodically.

DisplayHelpTopic "Background Tasks"


Another possibility is to run your function when the "modified" event for the graph is sent:

eventCode=8
eventName="modified"

A modification to the window has been made. This is sent to graph and notebook windows only. It is an error to try to kill a notebook window from the window hook during the modified event.

NOTE: If your function modifies the graph, add recursion protection to prevent responding to the resulting "modified" event again.

--Jim Prouty
Software Engineer, WaveMetrics, Inc.
Great! I've used various Igor hook functions before, but missed the method for applying one to windows. I've got it set up and am exploring the various event triggers in the structure that might be beneficial. Thanks!