Explorar o código

Inspector: Use fixed mini-panel (#33070)

sunag hai 1 mes
pai
achega
f274d6ad5e

+ 0 - 6
examples/jsm/inspector/Inspector.js

@@ -224,12 +224,6 @@ class Inspector extends RendererInspector {
 
 			this.parameters.show();
 
-			if ( this.parameters.isDetached === false ) {
-
-				this.profiler.setActiveTab( this.parameters.id );
-
-			}
-
 		}
 
 		return this.parameters.createGroup( name );

+ 64 - 146
examples/jsm/inspector/ui/Profiler.js

@@ -256,6 +256,13 @@ export class Profiler {
 		// Set initial position class
 		this.panel.classList.add( `position-${this.position}` );
 
+		if ( this.position === 'right' ) {
+
+			this.toggleButton.classList.add( 'position-right' );
+			this.miniPanel.classList.add( 'position-right' );
+
+		}
+
 	}
 
 	setupResizing() {
@@ -416,7 +423,12 @@ export class Profiler {
 
 		this.setupTabDragAndDrop( tab );
 
-		this.tabsContainer.appendChild( tab.button );
+		if ( ! tab.builtin ) {
+
+			this.tabsContainer.appendChild( tab.button );
+
+		}
+
 		this.contentWrapper.appendChild( tab.content );
 
 		// Apply the current visibility state to the DOM elements
@@ -473,89 +485,51 @@ export class Profiler {
 
 			e.stopPropagation(); // Prevent toggle panel from triggering
 
-			const isPanelVisible = this.panel.classList.contains( 'visible' );
-
-			if ( isPanelVisible ) {
+			// Toggle mini-panel for this tab
+			const isCurrentlyActive = miniContent.style.display !== 'none' && miniContent.children.length > 0;
 
-				// Panel is visible - navigate to tab
-				if ( ! tab.isVisible ) {
-
-					tab.show();
-
-				}
+			// Hide all other mini-panel contents
+			this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
 
-				if ( tab.isDetached ) {
+				content.style.display = 'none';
 
-					// If tab is detached, just bring its window to front
-					if ( tab.detachedWindow ) {
+			} );
 
-						this.bringWindowToFront( tab.detachedWindow.panel );
+			// Remove active state from all builtin buttons
+			this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
 
-					}
+				btn.classList.remove( 'active' );
 
-				} else {
+			} );
 
-					// Activate the tab
-					this.setActiveTab( tab.id );
+			if ( isCurrentlyActive ) {
 
-				}
+				// Toggle off - hide mini-panel
+				this.miniPanel.classList.remove( 'visible' );
+				miniContent.style.display = 'none';
 
 			} else {
 
-				// Panel is hidden - toggle mini-panel for this tab
-				const isCurrentlyActive = miniContent.style.display !== 'none' && miniContent.children.length > 0;
+				// Toggle on - show mini-panel with this tab's content
+				builtinButton.classList.add( 'active' );
 
-				// Hide all other mini-panel contents
-				this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
-
-					content.style.display = 'none';
-
-				} );
+				// Move actual content to mini-panel (not clone) if not already there
+				if ( ! miniContent.firstChild ) {
 
-				// Remove active state from all builtin buttons
-				this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
+					const actualContent = tab.content.querySelector( '.list-scroll-wrapper' ) || tab.content.firstElementChild;
 
-					btn.classList.remove( 'active' );
-
-				} );
-
-				if ( isCurrentlyActive ) {
-
-					// Toggle off - hide mini-panel and move content back
-					this.miniPanel.classList.remove( 'visible' );
-					miniContent.style.display = 'none';
-
-					// Move content back to main panel
-					if ( miniContent.firstChild ) {
-
-						tab.content.appendChild( miniContent.firstChild );
-
-					}
-
-				} else {
-
-					// Toggle on - show mini-panel with this tab's content
-					builtinButton.classList.add( 'active' );
-
-					// Move actual content to mini-panel (not clone) if not already there
-					if ( ! miniContent.firstChild ) {
-
-						const actualContent = tab.content.querySelector( '.list-scroll-wrapper' ) || tab.content.firstElementChild;
-
-						if ( actualContent ) {
-
-							miniContent.appendChild( actualContent );
+					if ( actualContent ) {
 
-						}
+						miniContent.appendChild( actualContent );
 
 					}
 
-					// Show after content is moved
-					miniContent.style.display = 'block';
-					this.miniPanel.classList.add( 'visible' );
-
 				}
 
+				// Show after content is moved
+				miniContent.style.display = 'block';
+				this.miniPanel.classList.add( 'visible' );
+
 			}
 
 		};
@@ -1471,87 +1445,11 @@ export class Profiler {
 	togglePanel() {
 
 		this.panel.classList.toggle( 'visible' );
-		this.toggleButton.classList.toggle( 'hidden' );
+		this.toggleButton.classList.toggle( 'panel-open' );
+		this.miniPanel.classList.toggle( 'panel-open' );
 
 		const isVisible = this.panel.classList.contains( 'visible' );
 
-		if ( isVisible ) {
-
-			// Save mini-panel state before hiding
-			this.savedMiniPanelState = {
-				isVisible: this.miniPanel.classList.contains( 'visible' ),
-				activeTabId: null,
-				contentMap: {}
-			};
-
-			// Find which tab was active in mini-panel
-			this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
-
-				if ( content.style.display !== 'none' && content.firstChild ) {
-
-					// Find the tab that owns this content
-					Object.values( this.tabs ).forEach( tab => {
-
-						if ( tab.miniContent === content ) {
-
-							this.savedMiniPanelState.activeTabId = tab.id;
-							// Move content back to main panel
-							tab.content.appendChild( content.firstChild );
-
-						}
-
-					} );
-
-				}
-
-			} );
-
-			// Hide mini-panel temporarily
-			this.miniPanel.classList.remove( 'visible' );
-
-			// Hide all mini-panel contents
-			this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
-
-				content.style.display = 'none';
-
-			} );
-
-			// Remove active state from builtin buttons
-			this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
-
-				btn.classList.remove( 'active' );
-
-			} );
-
-		} else {
-
-			// Restore mini-panel state when minimizing
-			if ( this.savedMiniPanelState && this.savedMiniPanelState.isVisible && this.savedMiniPanelState.activeTabId ) {
-
-				const tab = this.tabs[ this.savedMiniPanelState.activeTabId ];
-
-				if ( tab && tab.miniContent && tab.builtinButton ) {
-
-					// Restore mini-panel visibility
-					this.miniPanel.classList.add( 'visible' );
-					tab.miniContent.style.display = 'block';
-					tab.builtinButton.classList.add( 'active' );
-
-					// Move content back to mini-panel
-					const actualContent = tab.content.querySelector( '.list-scroll-wrapper, .profiler-content > *' );
-
-					if ( actualContent ) {
-
-						tab.miniContent.appendChild( actualContent );
-
-					}
-
-				}
-
-			}
-
-		}
-
 		this.detachedWindows.forEach( detachedWindow => {
 
 			if ( isVisible ) {
@@ -1598,6 +1496,8 @@ export class Profiler {
 			// Apply right position styles
 			this.panel.classList.remove( 'position-bottom' );
 			this.panel.classList.add( 'position-right' );
+			this.toggleButton.classList.add( 'position-right' );
+			this.miniPanel.classList.add( 'position-right' );
 			this.panel.style.bottom = '';
 			this.panel.style.top = '0';
 			this.panel.style.right = '0';
@@ -1626,6 +1526,8 @@ export class Profiler {
 			// Apply bottom position styles
 			this.panel.classList.remove( 'position-right' );
 			this.panel.classList.add( 'position-bottom' );
+			this.toggleButton.classList.remove( 'position-right' );
+			this.miniPanel.classList.remove( 'position-right' );
 			this.panel.style.top = '';
 			this.panel.style.right = '';
 			this.panel.style.bottom = '0';
@@ -1696,7 +1598,11 @@ export class Profiler {
 
 		try {
 
-			localStorage.setItem( 'profiler-layout', JSON.stringify( layout ) );
+			const savedData = localStorage.getItem( 'threejs-inspector' );
+			const data = JSON.parse( savedData || '{}' );
+
+			data.layout = layout;
+			localStorage.setItem( 'threejs-inspector', JSON.stringify( data ) );
 
 		} catch ( e ) {
 
@@ -1710,11 +1616,14 @@ export class Profiler {
 
 		try {
 
-			const savedLayout = localStorage.getItem( 'profiler-layout' );
+			const savedData = localStorage.getItem( 'threejs-inspector' );
+
+			if ( ! savedData ) return;
 
-			if ( ! savedLayout ) return;
+			const parsedData = JSON.parse( savedData );
+			const layout = parsedData.layout;
 
-			const layout = JSON.parse( savedLayout );
+			if ( ! layout ) return;
 
 			// Constrain detached tabs positions to current screen bounds
 			if ( layout.detachedTabs && layout.detachedTabs.length > 0 ) {
@@ -1827,6 +1736,8 @@ export class Profiler {
 
 				this.panel.classList.remove( 'position-bottom' );
 				this.panel.classList.add( 'position-right' );
+				this.toggleButton.classList.add( 'position-right' );
+				this.miniPanel.classList.add( 'position-right' );
 				this.panel.style.bottom = '';
 				this.panel.style.top = '0';
 				this.panel.style.right = '0';
@@ -1863,6 +1774,13 @@ export class Profiler {
 			// Update panel size after loading layout
 			this.updatePanelSize();
 
+			// Ensure initial open state applies to mini panel as well
+			if ( this.panel.classList.contains( 'visible' ) ) {
+
+				this.miniPanel.classList.add( 'panel-open' );
+
+			}
+
 		} catch ( e ) {
 
 			console.warn( 'Failed to load profiler layout:', e );

+ 24 - 3
examples/jsm/inspector/ui/Style.js

@@ -52,13 +52,25 @@ export class Style {
 	font-family: var(--font-family);
 }
 
+#profiler-toggle.position-right.panel-open {
+	right: auto;
+	left: 15px;
+	border-radius: 6px 12px 12px 6px;
+	flex-direction: row-reverse;
+}
+
+#profiler-toggle.position-right.panel-open #builtin-tabs-container {
+	border-right: none;
+	border-left: 1px solid #262636;
+}
+
 #profiler-toggle:hover {
 	border-color: var(--accent-color);
 }
 
-#profiler-toggle.hidden {
-	opacity: 0;
-	pointer-events: none;
+#profiler-toggle.panel-open #toggle-icon {
+	background-color: rgba(0, 170, 255, 0.2);
+	color: var(--accent-color);
 }
 
 #toggle-icon {
@@ -74,6 +86,10 @@ export class Style {
 	background-color: rgba(255, 255, 255, 0.05);
 }
 
+#profiler-toggle.panel-open:hover #toggle-icon {
+	background-color: rgba(0, 170, 255, 0.3);
+}
+
 .toggle-separator {
 	width: 1px;
 	background-color: var(--profiler-border);
@@ -166,6 +182,11 @@ export class Style {
 	            transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
 }
 
+#profiler-mini-panel.position-right.panel-open {
+	right: auto;
+	left: 15px;
+}
+
 #profiler-mini-panel.visible {
 	display: block;
 	opacity: 1;

粤ICP备19079148号