@@ -108,9 +108,6 @@ define(function (require, exports, module) {
108108 /** @type {string|null } The default/quick-access panel ID */
109109 let _defaultPanelId = null ;
110110
111- /** @type {jQueryObject } The "+" button inside the tab overflow area */
112- let _$addBtn = null ;
113-
114111 // --- Tab helper functions ---
115112
116113 /**
@@ -149,7 +146,7 @@ define(function (require, exports, module) {
149146 */
150147 function _buildTab ( panel , isActive ) {
151148 let title = panel . _tabTitle || _getPanelTitle ( panel . panelID , panel . $panel ) ;
152- // Default panel (Tools ) tab is not draggable — it's a fixed slot , not a user tab
149+ // Default panel (Quick Access ) tab is pinned — not draggable , not closable
153150 const isDefault = panel . panelID === _defaultPanelId ;
154151 let $tab = $ ( '<div class="bottom-panel-tab"></div>' )
155152 . toggleClass ( 'bottom-panel-tab-default' , isDefault )
@@ -163,18 +160,16 @@ define(function (require, exports, module) {
163160 $icon [ 0 ] . style . webkitMaskImage = maskUrl ;
164161 $tab . append ( $icon ) ;
165162 $tab . append ( $ ( '<span class="bottom-panel-tab-title"></span>' ) . text ( title ) ) ;
166- $tab . append ( $ ( '<span class="bottom-panel-tab-close-btn">×</span>' ) . attr ( 'title' , Strings . CLOSE ) ) ;
163+ if ( ! isDefault ) {
164+ $tab . append ( $ ( '<span class="bottom-panel-tab-close-btn">×</span>' ) . attr ( 'title' , Strings . CLOSE ) ) ;
165+ }
167166 return $tab ;
168167 }
169168
170169 function _updateBottomPanelTabBar ( ) {
171170 if ( ! _$tabsOverflow ) {
172171 return ;
173172 }
174- // Detach the add button before emptying to preserve its event handlers
175- if ( _$addBtn ) {
176- _$addBtn . detach ( ) ;
177- }
178173 _$tabsOverflow . empty ( ) ;
179174
180175 _openIds . forEach ( function ( panelId ) {
@@ -185,11 +180,6 @@ define(function (require, exports, module) {
185180 _$tabsOverflow . append ( _buildTab ( panel , panelId === _activeId ) ) ;
186181 } ) ;
187182
188- // Re-append the Tools button at the end
189- if ( _$addBtn ) {
190- _$tabsOverflow . append ( _$addBtn ) ;
191- }
192- _updateAddButtonVisibility ( ) ;
193183 _checkTabOverflow ( ) ;
194184 }
195185
@@ -226,13 +216,7 @@ define(function (require, exports, module) {
226216 return ;
227217 }
228218 let $tab = _buildTab ( panel , panelId === _activeId ) ;
229- // Insert before the Tools button so it stays at the end
230- if ( _$addBtn && _$addBtn . parent ( ) . length ) {
231- _$addBtn . before ( $tab ) ;
232- } else {
233- _$tabsOverflow . append ( $tab ) ;
234- }
235- _updateAddButtonVisibility ( ) ;
219+ _$tabsOverflow . append ( $tab ) ;
236220 _checkTabOverflow ( ) ;
237221 }
238222
@@ -247,7 +231,6 @@ define(function (require, exports, module) {
247231 return ;
248232 }
249233 _$tabsOverflow . find ( '.bottom-panel-tab[data-panel-id="' + panelId + '"]' ) . remove ( ) ;
250- _updateAddButtonVisibility ( ) ;
251234 _checkTabOverflow ( ) ;
252235 }
253236
@@ -311,15 +294,21 @@ define(function (require, exports, module) {
311294 if ( ! draggedTab || this === draggedTab ) {
312295 return ;
313296 }
314- // Don't allow dropping onto the default panel (Tools) tab
297+ // Don't allow dropping onto the pinned Quick Access tab
315298 if ( $ ( this ) . data ( "panel-id" ) === _defaultPanelId ) {
316299 return ;
317300 }
318301 e . preventDefault ( ) ;
319302 e . originalEvent . dataTransfer . dropEffect = "move" ;
320303 _$tabBar . find ( ".bottom-panel-tab" ) . removeClass ( "drag-target" ) ;
321304 $ ( this ) . addClass ( "drag-target" ) ;
322- updateIndicator ( this , getDropPosition ( this , e . originalEvent . clientX ) ) ;
305+ let insertBefore = getDropPosition ( this , e . originalEvent . clientX ) ;
306+ // Can't insert before the first non-default tab (would go ahead of pinned tab)
307+ const targetIdx = _openIds . indexOf ( $ ( this ) . data ( "panel-id" ) ) ;
308+ if ( insertBefore && targetIdx <= 1 ) {
309+ insertBefore = false ;
310+ }
311+ updateIndicator ( this , insertBefore ) ;
323312 } ) ;
324313
325314 _$tabBar . on ( "dragleave" , ".bottom-panel-tab" , function ( e ) {
@@ -350,6 +339,10 @@ define(function (require, exports, module) {
350339 if ( ! insertBefore ) {
351340 newIdx ++ ;
352341 }
342+ // Never place a tab before the pinned Quick Access tab at index 0
343+ if ( newIdx < 1 && _defaultPanelId && _openIds [ 0 ] === _defaultPanelId ) {
344+ newIdx = 1 ;
345+ }
353346 _openIds . splice ( newIdx , 0 , draggedId ) ;
354347 cleanup ( ) ;
355348 _updateBottomPanelTabBar ( ) ;
@@ -503,23 +496,6 @@ define(function (require, exports, module) {
503496 } ) ;
504497 }
505498
506- /**
507- * Show or hide the "+" button based on whether the default panel is active.
508- * The button is hidden when the default panel is the active tab (since
509- * clicking "+" would be a no-op) and shown otherwise.
510- * @private
511- */
512- function _updateAddButtonVisibility ( ) {
513- if ( ! _$addBtn ) {
514- return ;
515- }
516- if ( _defaultPanelId && _activeId === _defaultPanelId ) {
517- _$addBtn . hide ( ) ;
518- } else {
519- _$addBtn . show ( ) ;
520- }
521- }
522-
523499 /**
524500 * Switch the active tab to the given panel. Does not show/hide the container.
525501 * @param {string } panelId
@@ -543,7 +519,6 @@ define(function (require, exports, module) {
543519 newPanel . $panel . addClass ( "active-bottom-panel" ) ;
544520 }
545521 _updateActiveTabHighlight ( ) ;
546- _updateAddButtonVisibility ( ) ;
547522 }
548523
549524
@@ -567,6 +542,12 @@ define(function (require, exports, module) {
567542 this . _tabTitle = _getPanelTitle ( id , $panel , title ) ;
568543 this . _options = options || { } ;
569544 _panelMap [ id ] = this ;
545+
546+ // Quick Access panel is pinned: always at index 0, always in the tab bar
547+ if ( id === _defaultPanelId && _openIds . indexOf ( id ) === - 1 ) {
548+ _openIds . unshift ( id ) ;
549+ _addTabToBar ( id ) ;
550+ }
570551 }
571552
572553 /**
@@ -666,8 +647,13 @@ define(function (require, exports, module) {
666647 exports . trigger ( EVENT_PANEL_SHOWN , panelId ) ;
667648 return ;
668649 }
669- // Not open: add to open set
670- _openIds . push ( panelId ) ;
650+ // Not open: add to open set.
651+ // Quick Access panel is always pinned at index 0.
652+ if ( panelId === _defaultPanelId ) {
653+ _openIds . unshift ( panelId ) ;
654+ } else {
655+ _openIds . push ( panelId ) ;
656+ }
671657
672658 // Show container if it was hidden
673659 if ( ! _$container . is ( ":visible" ) ) {
@@ -684,9 +670,26 @@ define(function (require, exports, module) {
684670 */
685671 Panel . prototype . hide = function ( ) {
686672 let panelId = this . panelID ;
673+
674+ // Quick Access panel is pinned — it stays in _openIds and the tab bar.
675+ // Hiding it collapses the bottom panel container entirely.
676+ if ( panelId === _defaultPanelId ) {
677+ if ( _activeId !== panelId ) {
678+ return ;
679+ }
680+ this . $panel . removeClass ( "active-bottom-panel" ) ;
681+ _activeId = null ;
682+ _updateActiveTabHighlight ( ) ;
683+ if ( _$container ) {
684+ restoreIfMaximized ( ) ;
685+ Resizer . hide ( _$container [ 0 ] ) ;
686+ }
687+ exports . trigger ( EVENT_PANEL_HIDDEN , panelId ) ;
688+ return ;
689+ }
690+
687691 let idx = _openIds . indexOf ( panelId ) ;
688692 if ( idx === - 1 ) {
689- // Not open - no-op
690693 return ;
691694 }
692695
@@ -700,10 +703,9 @@ define(function (require, exports, module) {
700703 if ( wasActive && _openIds . length > 0 ) {
701704 let nextIdx = Math . min ( idx , _openIds . length - 1 ) ;
702705 activatedId = _openIds [ nextIdx ] ;
703- _activeId = null ; // clear so _switchToTab runs
706+ _activeId = null ;
704707 _switchToTab ( activatedId ) ;
705708 } else if ( wasActive ) {
706- // No more tabs - hide the container
707709 _activeId = null ;
708710 if ( _$container ) {
709711 restoreIfMaximized ( ) ;
@@ -713,10 +715,8 @@ define(function (require, exports, module) {
713715
714716 _removeTabFromBar ( panelId ) ;
715717
716- // Always fire HIDDEN for the closed panel first
717718 exports . trigger ( EVENT_PANEL_HIDDEN , panelId ) ;
718719
719- // Then fire SHOWN for the newly activated tab, if any
720720 if ( activatedId ) {
721721 exports . trigger ( EVENT_PANEL_SHOWN , activatedId ) ;
722722 }
@@ -793,18 +793,11 @@ define(function (require, exports, module) {
793793 _recomputeLayout = recomputeLayoutFn ;
794794 _defaultPanelId = defaultPanelId ;
795795
796- // Create the "Tools" button inside the scrollable tabs area.
797- _$addBtn = $ ( '<span class="bottom-panel-add-btn" draggable="false" title="' + Strings . BOTTOM_PANEL_DEFAULT_TITLE + '">'
798- + '<img class="app-drawer-tab-icon" draggable="false" src="styles/images/app-drawer.svg"'
799- + ' style="width:12px;height:12px;vertical-align:middle;margin-right:4px">'
800- + Strings . BOTTOM_PANEL_DEFAULT_TITLE + '</span>' ) ;
801- _$tabsOverflow . append ( _$addBtn ) ;
802-
803796 // Tab bar click handlers
804797 _$tabBar . on ( "click" , ".bottom-panel-tab-close-btn" , function ( e ) {
805798 e . stopPropagation ( ) ;
806799 let panelId = $ ( this ) . closest ( ".bottom-panel-tab" ) . data ( "panel-id" ) ;
807- if ( panelId ) {
800+ if ( panelId && panelId !== _defaultPanelId ) {
808801 let panel = _panelMap [ panelId ] ;
809802 if ( panel ) {
810803 panel . requestClose ( ) ;
@@ -836,14 +829,6 @@ define(function (require, exports, module) {
836829 _showOverflowMenu ( ) ;
837830 } ) ;
838831
839- // "+" button opens the default/quick-access panel
840- _$addBtn . on ( "click" , function ( e ) {
841- e . stopPropagation ( ) ;
842- if ( _defaultPanelId && _panelMap [ _defaultPanelId ] ) {
843- _panelMap [ _defaultPanelId ] . show ( ) ;
844- }
845- } ) ;
846-
847832 // Hide-panel button collapses the container but keeps tabs intact.
848833 // Maximize state is preserved so the panel re-opens maximized.
849834 _$tabBar . on ( "click" , ".bottom-panel-hide-btn" , function ( e ) {
@@ -860,9 +845,8 @@ define(function (require, exports, module) {
860845 } ) ;
861846
862847 // Double-click on empty tab bar area toggles maximize.
863- // Exclude tabs themselves, action buttons, and the add button.
864848 _$tabBar . on ( "dblclick" , function ( e ) {
865- if ( $ ( e . target ) . closest ( ".bottom-panel-tab, .bottom-panel-tab-close-btn, .bottom-panel-hide-btn, .bottom-panel-maximize-btn, .bottom-panel-add-btn " ) . length ) {
849+ if ( $ ( e . target ) . closest ( ".bottom-panel-tab, .bottom-panel-tab-close-btn, .bottom-panel-hide-btn, .bottom-panel-maximize-btn" ) . length ) {
866850 return ;
867851 }
868852 _toggleMaximize ( ) ;
@@ -1088,7 +1072,12 @@ define(function (require, exports, module) {
10881072 // Clear internal state BEFORE hiding the container so the
10891073 // panelCollapsed handler sees an empty _openIds and doesn't
10901074 // redundantly update the stacks.
1091- _openIds = [ ] ;
1075+ // The Quick Access panel stays pinned at index 0.
1076+ if ( _defaultPanelId ) {
1077+ _openIds = [ _defaultPanelId ] ;
1078+ } else {
1079+ _openIds = [ ] ;
1080+ }
10921081 _activeId = null ;
10931082
10941083 if ( _$container && _$container . is ( ":visible" ) ) {
@@ -1098,8 +1087,6 @@ define(function (require, exports, module) {
10981087
10991088 _updateBottomPanelTabBar ( ) ;
11001089
1101- // Fire one EVENT_PANEL_HIDDEN per panel for stack tracking.
1102- // No intermediate EVENT_PANEL_SHOWN events are emitted.
11031090 for ( let i = 0 ; i < closedIds . length ; i ++ ) {
11041091 exports . trigger ( EVENT_PANEL_HIDDEN , closedIds [ i ] ) ;
11051092 }
0 commit comments