Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
var ROUTES_INDEX = { name: '<root>', kind: 'module', children: [] };
Comment thread
GaneshPatil7517 marked this conversation as resolved.
Outdated
Comment thread
GaneshPatil7517 marked this conversation as resolved.
Outdated
171 changes: 171 additions & 0 deletions packages/phoenix-event-display/src/event-display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ export class EventDisplay {
private onEventsChange: ((events: any) => void)[] = [];
/** Array containing callbacks to be called when the displayed event changes. */
private onDisplayedEventChange: ((nowDisplayingEvent: any) => void)[] = [];
/** Array containing callbacks to be called when an object is selected. */
private onObjectSelectedCallbacks: ((object: any, data: any) => void)[] = [];
/** Array containing callbacks to be called when an object is deselected. */
private onObjectDeselectedCallbacks: ((object: any) => void)[] = [];
/** Array containing callbacks to be called when an object is hovered. */
private onObjectHoveredCallbacks: ((object: any, data: any) => void)[] = [];
/** Array containing callbacks to be called when object hover ends. */
private onObjectHoverEndCallbacks: ((object: any) => void)[] = [];
/** Array containing callbacks to be called when selection state changes. */
private onSelectionChangedCallbacks: ((
selectedObjects: any[],
selectionData: any,
Comment thread
GaneshPatil7517 marked this conversation as resolved.
) => void)[] = [];
/** Three manager for three.js operations. */
private graphicsLibrary: ThreeManager;
/** Info logger for storing event display logs. */
Expand Down Expand Up @@ -83,6 +96,10 @@ export class EventDisplay {
this.graphicsLibrary.init(configuration);
// Initialize the UI with configuration
this.ui.init(configuration);

// Set up selection callbacks for external integrations
this.setupSelectionCallbacks();

// Apply JiveXML track extension configuration and surface UI controls when available
const loaderWithTrackExtension = this.configuration.eventDataLoader as any;
if (loaderWithTrackExtension?.setTrackExtensionConfig) {
Expand Down Expand Up @@ -127,6 +144,11 @@ export class EventDisplay {
// Clear accumulated callbacks
this.onEventsChange = [];
this.onDisplayedEventChange = [];
this.onObjectSelectedCallbacks = [];
this.onObjectDeselectedCallbacks = [];
this.onObjectHoveredCallbacks = [];
this.onObjectHoverEndCallbacks = [];
this.onSelectionChangedCallbacks = [];
// Reset singletons for clean view transition
this.loadingManager?.reset();
this.stateManager?.resetForViewTransition();
Expand Down Expand Up @@ -620,6 +642,155 @@ export class EventDisplay {
};
}

/**
* Add a callback to be invoked when an object is selected.
* @param callback Callback receiving the selected object and associated data.
* @returns Unsubscribe function to remove the callback.
*/
public onObjectSelected(
callback: (object: any, data: any) => void,
): () => void {
this.onObjectSelectedCallbacks.push(callback);
return () => {
const index = this.onObjectSelectedCallbacks.indexOf(callback);
if (index > -1) {
this.onObjectSelectedCallbacks.splice(index, 1);
}
};
}

/**
* Add a callback to be invoked when an object is deselected.
* @param callback Callback receiving the deselected object.
* @returns Unsubscribe function to remove the callback.
*/
public onObjectDeselected(callback: (object: any) => void): () => void {
this.onObjectDeselectedCallbacks.push(callback);
return () => {
const index = this.onObjectDeselectedCallbacks.indexOf(callback);
if (index > -1) {
this.onObjectDeselectedCallbacks.splice(index, 1);
}
};
}

/**
* Add a callback to be invoked when an object is hovered.
* @param callback Callback receiving the hovered object and associated data.
* @returns Unsubscribe function to remove the callback.
*/
public onObjectHovered(
callback: (object: any, data: any) => void,
): () => void {
this.onObjectHoveredCallbacks.push(callback);
return () => {
const index = this.onObjectHoveredCallbacks.indexOf(callback);
if (index > -1) {
this.onObjectHoveredCallbacks.splice(index, 1);
}
};
}

/**
* Add a callback to be invoked when object hover ends.
* @param callback Callback receiving the object that was hovered.
* @returns Unsubscribe function to remove the callback.
*/
public onObjectHoverEnd(callback: (object: any) => void): () => void {
this.onObjectHoverEndCallbacks.push(callback);
return () => {
const index = this.onObjectHoverEndCallbacks.indexOf(callback);
if (index > -1) {
this.onObjectHoverEndCallbacks.splice(index, 1);
}
};
}

/**
* Add a callback to be invoked when the selection state changes.
* @param callback Callback receiving the list of selected objects and selection data.
* @returns Unsubscribe function to remove the callback.
*/
public onSelectionChanged(
callback: (selectedObjects: any[], selectionData: any) => void,
): () => void {
this.onSelectionChangedCallbacks.push(callback);
return () => {
const index = this.onSelectionChangedCallbacks.indexOf(callback);
if (index > -1) {
this.onSelectionChangedCallbacks.splice(index, 1);
}
};
}

Comment thread
GaneshPatil7517 marked this conversation as resolved.
/**
* Internal method to fire object selected callbacks.
* Called by the SelectionManager when an object is selected.
* @internal
*/
public fireObjectSelectedCallback(object: any, data?: any) {
this.onObjectSelectedCallbacks.forEach((callback) =>
callback(object, data),
);
}

/**
* Internal method to fire object deselected callbacks.
* Called by the SelectionManager when an object is deselected.
* @internal
*/
public fireObjectDeselectedCallback(object: any) {
this.onObjectDeselectedCallbacks.forEach((callback) => callback(object));
}

/**
* Internal method to fire object hovered callbacks.
* Called by the SelectionManager when an object is hovered.
* @internal
*/
public fireObjectHoveredCallback(object: any, data?: any) {
this.onObjectHoveredCallbacks.forEach((callback) => callback(object, data));
}

/**
* Internal method to fire object hover end callbacks.
* Called by the SelectionManager when hover ends.
* @internal
*/
public fireObjectHoverEndCallback(object: any) {
this.onObjectHoverEndCallbacks.forEach((callback) => callback(object));
}

/**
* Internal method to fire selection changed callbacks.
* Called by the SelectionManager when selection state changes.
* @internal
*/
public fireSelectionChangedCallback(
selectedObjects: any[],
selectionData?: any,
) {
this.onSelectionChangedCallbacks.forEach((callback) =>
callback(selectedObjects, selectionData),
);
}
Comment thread
GaneshPatil7517 marked this conversation as resolved.
Outdated

/**
* Set up selection callbacks on ThreeManager's SelectionManager.
* This connects the internal fire*Callback methods to the SelectionManager.
* @private
*/
private setupSelectionCallbacks(): void {
this.graphicsLibrary.setSelectionCallbacks(
(object: any) => this.fireObjectSelectedCallback(object),
(object: any) => this.fireObjectDeselectedCallback(object),
(object: any) => this.fireObjectHoveredCallback(object),
(object: any) => this.fireObjectHoverEndCallback(object),
(selectedObjects: any[]) =>
this.fireSelectionChangedCallback(selectedObjects),
Comment thread
GaneshPatil7517 marked this conversation as resolved.
Outdated
);
}

/**
* Get metadata associated to the displayed event (experiment info, time, run, event...).
* @returns Metadata of the displayed event.
Expand Down
43 changes: 43 additions & 0 deletions packages/phoenix-event-display/src/managers/three-manager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,49 @@ export class ThreeManager {
return this.selectionManager;
}

/**
* Set selection callbacks on the SelectionManager for EventDisplay integration.
* @param onObjectSelectedCallback Called when an object is selected
* @param onObjectDeselectedCallback Called when an object is deselected
* @param onObjectHoveredCallback Called when an object is hovered
* @param onObjectHoverEndCallback Called when hover ends
* @param onSelectionChangedCallback Called when selection changes
* @internal Used by EventDisplay to integrate selection callbacks
*/
public setSelectionCallbacks(
onObjectSelectedCallback?: ((object: any, data?: any) => void) | null,
onObjectDeselectedCallback?: ((object: any) => void) | null,
onObjectHoveredCallback?: ((object: any, data?: any) => void) | null,
onObjectHoverEndCallback?: ((object: any) => void) | null,
onSelectionChangedCallback?:
| ((selectedObjects: any[], selectionData?: any) => void)
| null,
): void {
const selectionManager = this.getSelectionManager();

if (onObjectSelectedCallback !== undefined) {
selectionManager.setOnObjectSelectedCallback(onObjectSelectedCallback);
}
if (onObjectDeselectedCallback !== undefined) {
selectionManager.setOnObjectDeselectedCallback(
onObjectDeselectedCallback,
);
}
if (onObjectHoveredCallback !== undefined) {
selectionManager.setOnObjectHoveredCallback(onObjectHoveredCallback);
}
if (onObjectHoverEndCallback !== undefined) {
selectionManager.setOnObjectHoverEndCallback(onObjectHoverEndCallback);
}
if (onSelectionChangedCallback !== undefined) {
selectionManager.setOnSelectionChangedCallback(
onSelectionChangedCallback
? (set, arr) => onSelectionChangedCallback(arr)
Comment thread
GaneshPatil7517 marked this conversation as resolved.
Outdated
: null,
);
Comment thread
GaneshPatil7517 marked this conversation as resolved.
}
}

/**
* Animates camera position.
* @param cameraPosition End position.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,24 @@ export class SelectionManager {
TO_LOW_SKIP: 45, // FPS above 45 → skip 3 frames
TO_MINIMAL_SKIP: 90, // FPS above 55 → skip 1 frame
};

// External callbacks for integration with EventDisplay and external applications
/** Callback function called when an object is selected */
private onObjectSelectedCallback:
| ((object: Mesh, data?: any) => void)
| null = null;
/** Callback function called when an object is deselected */
private onObjectDeselectedCallback: ((object: Mesh) => void) | null = null;
/** Callback function called when an object is hovered */
private onObjectHoveredCallback: ((object: Mesh, data?: any) => void) | null =
null;
/** Callback function called when hover ends */
private onObjectHoverEndCallback: ((object: Mesh) => void) | null = null;
/** Callback function called when selection changes */
private onSelectionChangedCallback:
| ((selectedObjects: Set<Mesh>, selectedObjectsArray: Mesh[]) => void)
| null = null;

/**
* Constructor for the selection manager.
*/
Expand Down Expand Up @@ -1045,6 +1063,18 @@ export class SelectionManager {
this.effectsManager.selectObject(object);
this.selectedObjects.add(object);
this.logSelectionAction(object, true);

// Fire callbacks
if (this.onObjectSelectedCallback) {
this.onObjectSelectedCallback(object);
}
if (this.onSelectionChangedCallback) {
this.onSelectionChangedCallback(
this.selectedObjects,
Array.from(this.selectedObjects),
);
}
Comment thread
GaneshPatil7517 marked this conversation as resolved.
Comment thread
GaneshPatil7517 marked this conversation as resolved.

return true;
}

Expand All @@ -1061,6 +1091,18 @@ export class SelectionManager {
this.effectsManager.deselectObject(object);
this.selectedObjects.delete(object);
this.logSelectionAction(object, false);

// Fire callbacks
if (this.onObjectDeselectedCallback) {
this.onObjectDeselectedCallback(object);
}
if (this.onSelectionChangedCallback) {
this.onSelectionChangedCallback(
this.selectedObjects,
Array.from(this.selectedObjects),
);
}

return true;
}

Expand Down Expand Up @@ -1145,6 +1187,67 @@ export class SelectionManager {
this.setupOverlayListeners();
}

/**
* Set callback for when an object is selected.
* @param callback Function to call when object is selected, or null to remove.
* @internal Used by EventDisplay to integrate selection callbacks
*/
public setOnObjectSelectedCallback(
callback: ((object: Mesh, data?: any) => void) | null,
): void {
this.onObjectSelectedCallback = callback;
}

/**
* Set callback for when an object is deselected.
* @param callback Function to call when object is deselected, or null to remove.
* @internal Used by EventDisplay to integrate selection callbacks
*/
public setOnObjectDeselectedCallback(
callback: ((object: Mesh) => void) | null,
): void {
this.onObjectDeselectedCallback = callback;
}

/**
* Set callback for when an object is hovered.
* @param callback Function to call when object is hovered, or null to remove.
* @internal Used by EventDisplay to integrate hover callbacks
*/
public setOnObjectHoveredCallback(
callback: ((object: Mesh, data?: any) => void) | null,
): void {
this.onObjectHoveredCallback = callback;
}

/**
* Set callback for when hover ends.
* @param callback Function to call when hover ends, or null to remove.
* @internal Used by EventDisplay to integrate hover callbacks
*/
public setOnObjectHoverEndCallback(
callback: ((object: Mesh) => void) | null,
): void {
this.onObjectHoverEndCallback = callback;
}
Comment thread
GaneshPatil7517 marked this conversation as resolved.

/**
* Set callback for when selection changes.
* @param callback Function to call when selection changes, or null to remove.
* @internal Used by EventDisplay to integrate selection change callbacks
*/
public setOnSelectionChangedCallback(
callback:
| ((selectedObjects: Set<Mesh>, selectedObjectsArray: Mesh[]) => void)
| null,
): void {
this.onSelectionChangedCallback = callback;
}
Comment thread
GaneshPatil7517 marked this conversation as resolved.

// =====================================
// Private methods and event handlers
// =====================================

/**
* Determine if a mouse event came from the overlay canvas.
* @param event The mouse event to check
Expand Down
Loading