@@ -26,7 +26,7 @@ import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElemen
26
26
import { ScrollbarVisibility } from 'vs/base/common/scrollable' ;
27
27
import { getOrSet } from 'vs/base/common/map' ;
28
28
import { IThemeService , registerThemingParticipant } from 'vs/platform/theme/common/themeService' ;
29
- import { TAB_INACTIVE_BACKGROUND , TAB_ACTIVE_BACKGROUND , TAB_ACTIVE_FOREGROUND , TAB_INACTIVE_FOREGROUND , TAB_BORDER , EDITOR_DRAG_AND_DROP_BACKGROUND , TAB_UNFOCUSED_ACTIVE_FOREGROUND , TAB_UNFOCUSED_INACTIVE_FOREGROUND , TAB_UNFOCUSED_ACTIVE_BACKGROUND , TAB_UNFOCUSED_ACTIVE_BORDER , TAB_ACTIVE_BORDER , TAB_HOVER_BACKGROUND , TAB_HOVER_BORDER , TAB_UNFOCUSED_HOVER_BACKGROUND , TAB_UNFOCUSED_HOVER_BORDER , EDITOR_GROUP_HEADER_TABS_BACKGROUND , WORKBENCH_BACKGROUND , TAB_ACTIVE_BORDER_TOP , TAB_UNFOCUSED_ACTIVE_BORDER_TOP , TAB_ACTIVE_MODIFIED_BORDER , TAB_INACTIVE_MODIFIED_BORDER , TAB_UNFOCUSED_ACTIVE_MODIFIED_BORDER , TAB_UNFOCUSED_INACTIVE_MODIFIED_BORDER , TAB_UNFOCUSED_INACTIVE_BACKGROUND , TAB_HOVER_FOREGROUND , TAB_UNFOCUSED_HOVER_FOREGROUND , EDITOR_GROUP_HEADER_TABS_BORDER , TAB_LAST_PINNED_BORDER , TAB_DRAG_AND_DROP_BETWEEEN_INDICATOR } from 'vs/workbench/common/theme' ;
29
+ import { TAB_INACTIVE_BACKGROUND , TAB_ACTIVE_BACKGROUND , TAB_ACTIVE_FOREGROUND , TAB_INACTIVE_FOREGROUND , TAB_BORDER , EDITOR_DRAG_AND_DROP_BACKGROUND , TAB_UNFOCUSED_ACTIVE_FOREGROUND , TAB_UNFOCUSED_INACTIVE_FOREGROUND , TAB_UNFOCUSED_ACTIVE_BACKGROUND , TAB_UNFOCUSED_ACTIVE_BORDER , TAB_ACTIVE_BORDER , TAB_HOVER_BACKGROUND , TAB_HOVER_BORDER , TAB_UNFOCUSED_HOVER_BACKGROUND , TAB_UNFOCUSED_HOVER_BORDER , EDITOR_GROUP_HEADER_TABS_BACKGROUND , WORKBENCH_BACKGROUND , TAB_ACTIVE_BORDER_TOP , TAB_UNFOCUSED_ACTIVE_BORDER_TOP , TAB_ACTIVE_MODIFIED_BORDER , TAB_INACTIVE_MODIFIED_BORDER , TAB_UNFOCUSED_ACTIVE_MODIFIED_BORDER , TAB_UNFOCUSED_INACTIVE_MODIFIED_BORDER , TAB_UNFOCUSED_INACTIVE_BACKGROUND , TAB_HOVER_FOREGROUND , TAB_UNFOCUSED_HOVER_FOREGROUND , EDITOR_GROUP_HEADER_TABS_BORDER , TAB_LAST_PINNED_BORDER } from 'vs/workbench/common/theme' ;
30
30
import { activeContrastBorder , contrastBorder , editorBackground } from 'vs/platform/theme/common/colorRegistry' ;
31
31
import { ResourcesDropHandler , DraggedEditorIdentifier , DraggedEditorGroupIdentifier , extractTreeDropData , isWindowDraggedOver } from 'vs/workbench/browser/dnd' ;
32
32
import { Color } from 'vs/base/common/color' ;
@@ -131,30 +131,6 @@ export class MultiEditorTabsControl extends EditorTabsControl {
131
131
132
132
private lastMouseWheelEventTime = 0 ;
133
133
private isMouseOverTabs = false ;
134
-
135
- private _dndDropTarget : { leftElement : HTMLElement | undefined ; rightElement : HTMLElement | undefined } | undefined ;
136
- private set dndDropTarget ( target : { leftElement : HTMLElement | undefined ; rightElement : HTMLElement | undefined } | undefined ) {
137
- const oldTargets = this . _dndDropTarget ;
138
- if ( oldTargets === target || oldTargets && target && oldTargets . leftElement === target . leftElement && oldTargets . rightElement === target . rightElement ) {
139
- return ;
140
- }
141
-
142
- const dropClassLeft = 'drop-target-left' ;
143
- const dropClassRight = 'drop-target-right' ;
144
-
145
- if ( oldTargets ) {
146
- oldTargets . leftElement ?. classList . remove ( dropClassLeft ) ;
147
- oldTargets . rightElement ?. classList . remove ( dropClassRight ) ;
148
- }
149
-
150
- if ( target ) {
151
- target . leftElement ?. classList . add ( dropClassLeft ) ;
152
- target . rightElement ?. classList . add ( dropClassRight ) ;
153
- }
154
-
155
- this . _dndDropTarget = target ;
156
- }
157
-
158
134
constructor (
159
135
parent : HTMLElement ,
160
136
editorPartsView : IEditorPartsView ,
@@ -370,15 +346,9 @@ export class MultiEditorTabsControl extends EditorTabsControl {
370
346
return ;
371
347
}
372
348
373
- // Return if dragged editor is last tab because then this is a no-op
374
- let isLocalDragAndDrop = false ;
375
- if ( this . editorTransfer . hasData ( DraggedEditorIdentifier . prototype ) ) {
376
- isLocalDragAndDrop = true ;
377
- }
378
-
379
349
// Update the dropEffect to "copy" if there is no local data to be dragged because
380
350
// in that case we can only copy the data into and not move it from its source
381
- if ( ! isLocalDragAndDrop ) {
351
+ if ( ! this . editorTransfer . hasData ( DraggedEditorIdentifier . prototype ) ) {
382
352
if ( e . dataTransfer ) {
383
353
e . dataTransfer . dropEffect = 'copy' ;
384
354
}
@@ -1055,7 +1025,7 @@ export class MultiEditorTabsControl extends EditorTabsControl {
1055
1025
this . doFillResourceDataTransfers ( [ editor ] , e , isNewWindowOperation ) ;
1056
1026
1057
1027
// Fixes https://github.com/microsoft/vscode/issues/18733
1058
- this . updateDropFeedback ( tab . cloneNode ( true ) as HTMLElement , true , e , tabIndex ) ;
1028
+ this . updateDropFeedback ( tab , true , e , tabIndex ) ;
1059
1029
scheduleAtNextAnimationFrame ( getWindow ( this . parent ) , ( ) => this . updateDropFeedback ( tab , false , e , tabIndex ) ) ;
1060
1030
} ,
1061
1031
@@ -1136,10 +1106,13 @@ export class MultiEditorTabsControl extends EditorTabsControl {
1136
1106
1137
1107
// compute the target index
1138
1108
let targetIndex = tabIndex ;
1139
- if ( ! this . isHeadOfTab ( e , tab ) ) {
1109
+ if ( this . getTabDragOverLocation ( e , tab ) === 'right' ) {
1140
1110
targetIndex ++ ;
1141
1111
}
1142
1112
1113
+ // If we are moving an editor inside the same group and it is located before the target index
1114
+ // wee need to reduce the index by one to account for the fact that the move will cause all subsequent
1115
+ // tabs to move one to the left.
1143
1116
const editorIdentifiers = this . editorTransfer . getData ( DraggedEditorIdentifier . prototype ) ;
1144
1117
if ( editorIdentifiers !== undefined ) {
1145
1118
@@ -1188,15 +1161,17 @@ export class MultiEditorTabsControl extends EditorTabsControl {
1188
1161
private updateDropFeedback ( element : HTMLElement , isDND : boolean , e : DragEvent , tabIndex ?: number ) : void {
1189
1162
const isTab = ( typeof tabIndex === 'number' ) ;
1190
1163
1164
+ let dropTarget ;
1191
1165
if ( isDND ) {
1192
1166
if ( isTab ) {
1193
- this . dndDropTarget = this . computeDropTarget ( e , tabIndex , element ) ;
1167
+ dropTarget = this . computeDropTarget ( e , tabIndex , element ) ;
1194
1168
} else {
1195
- this . dndDropTarget = { leftElement : element . lastElementChild as HTMLElement , rightElement : undefined } ;
1169
+ dropTarget = { leftElement : element . lastElementChild as HTMLElement , rightElement : undefined } ;
1196
1170
}
1197
1171
} else {
1198
- this . dndDropTarget = undefined ;
1172
+ dropTarget = undefined ;
1199
1173
}
1174
+ this . updateDropTarget ( dropTarget ) ;
1200
1175
1201
1176
// Outline
1202
1177
const activeContrastBorderColor = this . getColor ( activeContrastBorder ) ;
@@ -1213,30 +1188,53 @@ export class MultiEditorTabsControl extends EditorTabsControl {
1213
1188
}
1214
1189
}
1215
1190
1216
- private isHeadOfTab ( e : DragEvent , tab : HTMLElement ) : boolean {
1191
+ private dropTarget : { leftElement : HTMLElement | undefined ; rightElement : HTMLElement | undefined } | undefined ;
1192
+ private updateDropTarget ( target : { leftElement : HTMLElement | undefined ; rightElement : HTMLElement | undefined } | undefined ) : void {
1193
+ const oldTargets = this . dropTarget ;
1194
+ if ( oldTargets === target || oldTargets && target && oldTargets . leftElement === target . leftElement && oldTargets . rightElement === target . rightElement ) {
1195
+ return ;
1196
+ }
1197
+
1198
+ const dropClassLeft = 'drop-target-left' ;
1199
+ const dropClassRight = 'drop-target-right' ;
1200
+
1201
+ if ( oldTargets ) {
1202
+ oldTargets . leftElement ?. classList . remove ( dropClassLeft ) ;
1203
+ oldTargets . rightElement ?. classList . remove ( dropClassRight ) ;
1204
+ }
1205
+
1206
+ if ( target ) {
1207
+ target . leftElement ?. classList . add ( dropClassLeft ) ;
1208
+ target . rightElement ?. classList . add ( dropClassRight ) ;
1209
+ }
1210
+
1211
+ this . dropTarget = target ;
1212
+ }
1213
+
1214
+ private getTabDragOverLocation ( e : DragEvent , tab : HTMLElement ) : 'left' | 'right' {
1217
1215
const rect = tab . getBoundingClientRect ( ) ;
1218
1216
const offsetXRelativeToParent = e . clientX - rect . left ;
1219
- return offsetXRelativeToParent <= rect . width / 2 ;
1217
+ return offsetXRelativeToParent <= rect . width / 2 ? 'left' : 'right' ;
1220
1218
}
1221
1219
1222
1220
private computeDropTarget ( e : DragEvent , tabIndex : number , targetTab : HTMLElement ) : { leftElement : HTMLElement | undefined ; rightElement : HTMLElement | undefined } | undefined {
1223
- const isHeadOfTab = this . isHeadOfTab ( e , targetTab ) ;
1221
+ const isLeftSideOfTab = this . getTabDragOverLocation ( e , targetTab ) === 'left' ;
1224
1222
const isLastTab = tabIndex === this . tabsModel . count - 1 ;
1225
1223
const isFirstTab = tabIndex === 0 ;
1226
1224
1227
1225
// Before first tab
1228
- if ( isHeadOfTab && isFirstTab ) {
1226
+ if ( isLeftSideOfTab && isFirstTab ) {
1229
1227
return { leftElement : undefined , rightElement : targetTab } ;
1230
1228
}
1231
1229
1232
1230
// After last tab
1233
- if ( ! isHeadOfTab && isLastTab ) {
1231
+ if ( ! isLeftSideOfTab && isLastTab ) {
1234
1232
return { leftElement : targetTab , rightElement : undefined } ;
1235
1233
}
1236
1234
1237
1235
// Between two tabs
1238
- const tabBefore = isHeadOfTab ? targetTab . previousElementSibling : targetTab ;
1239
- const tabAfter = isHeadOfTab ? targetTab : targetTab . nextElementSibling ;
1236
+ const tabBefore = isLeftSideOfTab ? targetTab . previousElementSibling : targetTab ;
1237
+ const tabAfter = isLeftSideOfTab ? targetTab : targetTab . nextElementSibling ;
1240
1238
1241
1239
return { leftElement : tabBefore as HTMLElement , rightElement : tabAfter as HTMLElement } ;
1242
1240
}
@@ -2410,16 +2408,4 @@ registerThemingParticipant((theme, collector) => {
2410
2408
collector . addRule ( makeTabBackgroundRule ( adjustedColor , adjustedColorDrag , false , false ) ) ;
2411
2409
}
2412
2410
}
2413
-
2414
- const tabDndIndicatorColor = theme . getColor ( TAB_DRAG_AND_DROP_BETWEEEN_INDICATOR ) ;
2415
- if ( tabDndIndicatorColor ) {
2416
- // DnD Feedback
2417
-
2418
- collector . addRule ( `
2419
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.drop-target-left::after,
2420
- .monaco-workbench .part.editor > .content .editor-group-container > .title .tabs-container > .tab.drop-target-right::before {
2421
- background-color: ${ tabDndIndicatorColor } ;
2422
- }
2423
- ` ) ;
2424
- }
2425
2411
} ) ;
0 commit comments