| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 |
- import { EventDispatcher } from 'three';
- /**
- * Tab class
- * @param {string} title - The title of the tab
- * @param {Object} options - Options for the tab
- * @param {boolean} [options.allowDetach=true] - Whether the tab can be detached into a separate window
- * @param {boolean} [options.builtin=false] - Whether the tab should appear in the profiler-toggle button
- * @param {string} [options.icon] - SVG icon HTML for the builtin button
- *
- * @example
- * // Create a tab that can be detached (default behavior)
- * const tab1 = new Tab('My Tab');
- *
- * // Create a tab that cannot be detached
- * const tab2 = new Tab('Fixed Tab', { allowDetach: false });
- *
- * // Create a builtin tab that appears in the profiler-toggle
- * const tab3 = new Tab('Builtin Tab', { builtin: true });
- *
- * // Create a builtin tab with custom icon
- * const tab4 = new Tab('Settings', { builtin: true, icon: '<svg>...</svg>' });
- *
- * // Control builtin tab visibility
- * tab3.showBuiltin(); // Show the builtin button and mini-content
- * tab3.hideBuiltin(); // Hide the builtin button and mini-content
- */
- export class Tab extends EventDispatcher {
- constructor( title, options = {} ) {
- super();
- this.id = title.toLowerCase();
- this.button = document.createElement( 'button' );
- this.button.className = 'tab-btn';
- this.button.textContent = title;
- this.content = document.createElement( 'div' );
- this.content.id = `${this.id}-content`;
- this.content.className = 'profiler-content';
- this._isActive = false;
- this.isVisible = true;
- this.isDetached = false;
- this.detachedWindow = null;
- this.allowDetach = options.allowDetach !== undefined ? options.allowDetach : true;
- this.builtin = options.builtin !== undefined ? options.builtin : false;
- this.icon = options.icon || null;
- this.builtinButton = null; // Reference to the builtin button in profiler-toggle
- this.miniContent = null; // Reference to the mini-panel content container
- this.profiler = null; // Reference to the profiler instance
- this.onVisibilityChange = null; // Callback for visibility changes
- }
- get inspector() {
- return this.profiler.inspector;
- }
- get isActive() {
- const isProfilerVisible = this.profiler && this.profiler.panel.classList.contains( 'visible' );
- if ( ! isProfilerVisible ) return false;
- return this.isDetached || this._isActive;
- }
- set isActive( value ) {
- this._isActive = value;
- }
- init( /*inspector*/ ) { }
- update( /*inspector*/ ) { }
- setActive( isActive ) {
- this.button.classList.toggle( 'active', isActive );
- this.content.classList.toggle( 'active', isActive );
- this.isActive = isActive;
- }
- show() {
- this.content.style.display = '';
- this.button.style.display = '';
- this.isVisible = true;
- // Show detached window if tab is detached
- if ( this.isDetached && this.detachedWindow ) {
- this.detachedWindow.panel.style.display = '';
- }
- // Notify profiler of visibility change
- if ( this.onVisibilityChange ) {
- this.onVisibilityChange();
- }
- this.showBuiltin();
- }
- hide() {
- this.content.style.display = 'none';
- this.button.style.display = 'none';
- this.isVisible = false;
- // Hide detached window if tab is detached
- if ( this.isDetached && this.detachedWindow ) {
- this.detachedWindow.panel.style.display = 'none';
- }
- // Notify profiler of visibility change
- if ( this.onVisibilityChange ) {
- this.onVisibilityChange();
- }
- this.hideBuiltin();
- }
- showBuiltin() {
- if ( ! this.builtin ) return;
- // Show the builtin-tabs-container
- if ( this.profiler && this.profiler.builtinTabsContainer ) {
- this.profiler.builtinTabsContainer.style.display = '';
- }
- // Show the button
- if ( this.builtinButton ) {
- this.builtinButton.style.display = '';
- }
- // Show and activate the mini-panel with content
- if ( this.miniContent && this.profiler ) {
- // Hide all other mini-panel contents
- this.profiler.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
- content.style.display = 'none';
- } );
- // Remove active state from all builtin buttons
- this.profiler.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
- btn.classList.remove( 'active' );
- } );
- // Activate this tab's button
- if ( this.builtinButton ) {
- this.builtinButton.classList.add( 'active' );
- }
- // Move content to mini-panel if not already there
- if ( ! this.miniContent.firstChild ) {
- while ( this.content.firstChild ) {
- this.miniContent.appendChild( this.content.firstChild );
- }
- }
- // Show the mini-panel and content
- this.miniContent.style.display = 'block';
- this.profiler.miniPanel.classList.add( 'visible' );
- }
- }
- hideBuiltin() {
- if ( ! this.builtin ) return;
- // Hide the button
- if ( this.builtinButton ) {
- this.builtinButton.style.display = 'none';
- }
- // Hide the mini-panel content
- if ( this.miniContent ) {
- this.miniContent.style.display = 'none';
- // Move content back to main panel
- if ( this.miniContent.firstChild ) {
- while ( this.miniContent.firstChild ) {
- this.content.appendChild( this.miniContent.firstChild );
- }
- }
- }
- // Deactivate button
- if ( this.builtinButton ) {
- this.builtinButton.classList.remove( 'active' );
- }
- // Hide mini-panel if no content is visible
- if ( this.profiler ) {
- const hasVisibleContent = Array.from( this.profiler.miniPanel.querySelectorAll( '.mini-panel-content' ) )
- .some( content => content.style.display !== 'none' );
- if ( ! hasVisibleContent ) {
- this.profiler.miniPanel.classList.remove( 'visible' );
- }
- // Hide the builtin-tabs-container if all builtin buttons are hidden
- const hasVisibleBuiltinButtons = Array.from( this.profiler.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ) )
- .some( btn => btn.style.display !== 'none' );
- if ( ! hasVisibleBuiltinButtons ) {
- this.profiler.builtinTabsContainer.style.display = 'none';
- }
- }
- }
- }
|