Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
7b50be29
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
7b50be29
编写于
1月 09, 2019
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
tree: dnd bubble behavior
上级
cd6769c7
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
113 addition
and
34 deletion
+113
-34
src/vs/base/browser/ui/list/list.ts
src/vs/base/browser/ui/list/list.ts
+1
-1
src/vs/base/browser/ui/list/listView.ts
src/vs/base/browser/ui/list/listView.ts
+6
-2
src/vs/base/browser/ui/list/listWidget.ts
src/vs/base/browser/ui/list/listWidget.ts
+35
-10
src/vs/base/browser/ui/tree/abstractTree.ts
src/vs/base/browser/ui/tree/abstractTree.ts
+61
-21
src/vs/base/browser/ui/tree/indexTreeModel.ts
src/vs/base/browser/ui/tree/indexTreeModel.ts
+4
-0
src/vs/base/browser/ui/tree/objectTreeModel.ts
src/vs/base/browser/ui/tree/objectTreeModel.ts
+5
-0
src/vs/base/browser/ui/tree/tree.ts
src/vs/base/browser/ui/tree/tree.ts
+1
-0
未找到文件。
src/vs/base/browser/ui/list/list.ts
浏览文件 @
7b50be29
...
...
@@ -87,7 +87,7 @@ export const ListDragOverReactions = {
export
interface
IListDragAndDrop
<
T
>
{
getDragURI
(
element
:
T
):
string
|
null
;
getDragLabel
?(
elements
:
T
[]):
string
;
getDragLabel
?(
elements
:
T
[]):
string
|
undefined
;
onDragStart
(
data
:
IDragAndDropData
,
originalEvent
:
DragEvent
):
void
;
onDragOver
(
data
:
IDragAndDropData
,
targetElement
:
T
|
undefined
,
targetIndex
:
number
|
undefined
,
originalEvent
:
DragEvent
):
boolean
|
IListDragOverReaction
;
drop
(
data
:
IDragAndDropData
,
targetElement
:
T
|
undefined
,
targetIndex
:
number
|
undefined
,
originalEvent
:
DragEvent
):
void
;
...
...
src/vs/base/browser/ui/list/listView.ts
浏览文件 @
7b50be29
...
...
@@ -611,11 +611,13 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
event
.
dataTransfer
.
setData
(
DataTransfers
.
RESOURCES
,
JSON
.
stringify
([
uri
]));
if
(
event
.
dataTransfer
.
setDragImage
)
{
let
label
:
string
;
let
label
:
string
|
undefined
;
if
(
this
.
dnd
.
getDragLabel
)
{
label
=
this
.
dnd
.
getDragLabel
(
elements
);
}
else
{
}
if
(
typeof
label
===
'
undefined
'
)
{
label
=
String
(
elements
.
length
);
}
...
...
@@ -721,6 +723,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
}
private
onDragLeave
():
void
{
this
.
onDragLeaveTimeout
.
dispose
();
this
.
onDragLeaveTimeout
=
DOM
.
timeout
(()
=>
this
.
clearDragOverFeedback
(),
100
);
}
...
...
@@ -750,6 +753,7 @@ export class ListView<T> implements ISpliceable<T>, IDisposable {
private
clearDragOverFeedback
():
void
{
this
.
currentDragFeedback
=
undefined
;
this
.
currentDragFeedbackDisposable
.
dispose
();
this
.
currentDragFeedbackDisposable
=
Disposable
.
None
;
}
// DND scroll top animation
...
...
src/vs/base/browser/ui/list/listWidget.ts
浏览文件 @
7b50be29
...
...
@@ -16,8 +16,8 @@ import { KeyCode } from 'vs/base/common/keyCodes';
import
{
StandardKeyboardEvent
,
IKeyboardEvent
}
from
'
vs/base/browser/keyboardEvent
'
;
import
{
Event
,
Emitter
,
EventBufferer
}
from
'
vs/base/common/event
'
;
import
{
domEvent
}
from
'
vs/base/browser/event
'
;
import
{
IListVirtualDelegate
,
IListRenderer
,
IListEvent
,
IListContextMenuEvent
,
IListMouseEvent
,
IListTouchEvent
,
IListGestureEvent
,
IIdentityProvider
,
IKeyboardNavigationLabelProvider
,
IListDragAndDrop
}
from
'
./list
'
;
import
{
ListView
,
IListViewOptions
}
from
'
./listView
'
;
import
{
IListVirtualDelegate
,
IListRenderer
,
IListEvent
,
IListContextMenuEvent
,
IListMouseEvent
,
IListTouchEvent
,
IListGestureEvent
,
IIdentityProvider
,
IKeyboardNavigationLabelProvider
,
IListDragAndDrop
,
IListDragOverReaction
}
from
'
./list
'
;
import
{
ListView
,
IListViewOptions
,
IListViewDragAndDrop
}
from
'
./listView
'
;
import
{
Color
}
from
'
vs/base/common/color
'
;
import
{
mixin
}
from
'
vs/base/common/objects
'
;
import
{
ScrollbarVisibility
}
from
'
vs/base/common/scrollable
'
;
...
...
@@ -25,6 +25,7 @@ import { ISpliceable } from 'vs/base/common/sequence';
import
{
CombinedSpliceable
}
from
'
vs/base/browser/ui/list/splice
'
;
import
{
clamp
}
from
'
vs/base/common/numbers
'
;
import
{
matchesPrefix
}
from
'
vs/base/common/filters
'
;
import
{
IDragAndDropData
}
from
'
vs/base/browser/dnd
'
;
interface
ITraitChangeEvent
{
indexes
:
number
[];
...
...
@@ -940,6 +941,37 @@ class AccessibiltyRenderer<T> implements IListRenderer<T, HTMLElement> {
}
}
class
ListViewDragAndDrop
<
T
>
implements
IListViewDragAndDrop
<
T
>
{
constructor
(
private
list
:
List
<
T
>
,
private
dnd
:
IListDragAndDrop
<
T
>
)
{
}
getDragElements
(
element
:
T
):
T
[]
{
const
selection
=
this
.
list
.
getSelectedElements
();
const
elements
=
selection
.
indexOf
(
element
)
>
-
1
?
selection
:
[
element
];
return
elements
;
}
getDragURI
(
element
:
T
):
string
|
null
{
return
this
.
dnd
.
getDragURI
(
element
);
}
getDragLabel
?(
elements
:
T
[]):
string
|
undefined
{
return
this
.
dnd
.
getDragLabel
&&
this
.
dnd
.
getDragLabel
(
elements
);
}
onDragStart
(
data
:
IDragAndDropData
,
originalEvent
:
DragEvent
):
void
{
this
.
dnd
.
onDragStart
(
data
,
originalEvent
);
}
onDragOver
(
data
:
IDragAndDropData
,
targetElement
:
T
,
targetIndex
:
number
,
originalEvent
:
DragEvent
):
boolean
|
IListDragOverReaction
{
return
this
.
dnd
.
onDragOver
(
data
,
targetElement
,
targetIndex
,
originalEvent
);
}
drop
(
data
:
IDragAndDropData
,
targetElement
:
T
,
targetIndex
:
number
,
originalEvent
:
DragEvent
):
void
{
this
.
dnd
.
drop
(
data
,
targetElement
,
targetIndex
,
originalEvent
);
}
}
export
class
List
<
T
>
implements
ISpliceable
<
T
>
,
IDisposable
{
private
static
InstanceCount
=
0
;
...
...
@@ -1051,14 +1083,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
const
viewOptions
:
IListViewOptions
<
T
>
=
{
...
options
,
dnd
:
options
.
dnd
&&
{
...
options
.
dnd
,
getDragElements
:
element
=>
{
const
selection
=
this
.
getSelectedElements
();
const
elements
=
selection
.
indexOf
(
element
)
>
-
1
?
selection
:
[
element
];
return
elements
;
}
}
dnd
:
options
.
dnd
&&
new
ListViewDragAndDrop
(
this
,
options
.
dnd
)
};
this
.
view
=
new
ListView
(
container
,
virtualDelegate
,
renderers
,
viewOptions
);
...
...
src/vs/base/browser/ui/tree/abstractTree.ts
浏览文件 @
7b50be29
...
...
@@ -6,15 +6,71 @@
import
'
vs/css!./media/tree
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
IListOptions
,
List
,
IListStyles
}
from
'
vs/base/browser/ui/list/listWidget
'
;
import
{
IListVirtualDelegate
,
IListRenderer
,
IListMouseEvent
,
IListEvent
,
IListContextMenuEvent
}
from
'
vs/base/browser/ui/list/list
'
;
import
{
IListVirtualDelegate
,
IListRenderer
,
IListMouseEvent
,
IListEvent
,
IListContextMenuEvent
,
IListDragAndDrop
,
IListDragOverReaction
}
from
'
vs/base/browser/ui/list/list
'
;
import
{
append
,
$
,
toggleClass
}
from
'
vs/base/browser/dom
'
;
import
{
Event
,
Relay
}
from
'
vs/base/common/event
'
;
import
{
StandardKeyboardEvent
}
from
'
vs/base/browser/keyboardEvent
'
;
import
{
KeyCode
}
from
'
vs/base/common/keyCodes
'
;
import
{
ITreeModel
,
ITreeNode
,
ITreeRenderer
,
ITreeEvent
,
ITreeMouseEvent
,
ITreeContextMenuEvent
,
ITreeFilter
,
ITreeNavigator
,
ICollapseStateChangeEvent
,
ITreeDragAndDrop
}
from
'
vs/base/browser/ui/tree/tree
'
;
import
{
ITreeModel
,
ITreeNode
,
ITreeRenderer
,
ITreeEvent
,
ITreeMouseEvent
,
ITreeContextMenuEvent
,
ITreeFilter
,
ITreeNavigator
,
ICollapseStateChangeEvent
,
ITreeDragAndDrop
,
TreeDragOverBubble
}
from
'
vs/base/browser/ui/tree/tree
'
;
import
{
ISpliceable
}
from
'
vs/base/common/sequence
'
;
import
{
IDragAndDropData
}
from
'
vs/base/browser/dnd
'
;
import
{
range
}
from
'
vs/base/common/arrays
'
;
function
asListOptions
<
T
,
TFilterData
>
(
options
?:
IAbstractTreeOptions
<
T
,
TFilterData
>
):
IListOptions
<
ITreeNode
<
T
,
TFilterData
>>
|
undefined
{
class
TreeNodeListDragAndDrop
<
T
,
TFilterData
,
TRef
>
implements
IListDragAndDrop
<
ITreeNode
<
T
,
TFilterData
>>
{
constructor
(
private
modelProvider
:
()
=>
ITreeModel
<
T
,
TFilterData
,
TRef
>
,
private
dnd
:
ITreeDragAndDrop
<
T
>
)
{
}
getDragURI
(
node
:
ITreeNode
<
T
,
TFilterData
>
):
string
|
null
{
return
this
.
dnd
.
getDragURI
(
node
.
element
);
}
getDragLabel
(
nodes
:
ITreeNode
<
T
,
TFilterData
>
[]):
string
|
undefined
{
return
this
.
dnd
.
getDragLabel
&&
this
.
dnd
.
getDragLabel
(
nodes
.
map
(
node
=>
node
.
element
));
}
onDragStart
(
data
:
IDragAndDropData
,
originalEvent
:
DragEvent
):
void
{
this
.
dnd
.
onDragStart
(
data
,
originalEvent
);
}
onDragOver
(
data
:
IDragAndDropData
,
targetNode
:
ITreeNode
<
T
,
TFilterData
>
|
undefined
,
targetIndex
:
number
|
undefined
,
originalEvent
:
DragEvent
,
force
=
false
):
boolean
|
IListDragOverReaction
{
const
result
=
this
.
dnd
.
onDragOver
(
data
,
targetNode
&&
targetNode
.
element
,
targetIndex
,
originalEvent
);
if
(
typeof
targetNode
===
'
undefined
'
)
{
return
result
;
}
if
(
typeof
result
===
'
boolean
'
||
!
result
.
accept
||
typeof
result
.
bubble
===
'
undefined
'
)
{
if
(
force
)
{
const
accept
=
typeof
result
===
'
boolean
'
?
result
:
result
.
accept
;
const
effect
=
typeof
result
===
'
boolean
'
?
undefined
:
result
.
effect
;
return
{
accept
,
effect
,
feedback
:
[
targetIndex
!
]
};
}
return
result
;
}
if
(
result
.
bubble
===
TreeDragOverBubble
.
Up
)
{
const
parentNode
=
targetNode
.
parent
;
const
model
=
this
.
modelProvider
();
const
parentIndex
=
parentNode
&&
model
.
getListIndex
(
model
.
getNodeLocation
(
parentNode
));
return
this
.
onDragOver
(
data
,
parentNode
,
parentIndex
,
originalEvent
,
true
);
}
const
model
=
this
.
modelProvider
();
const
ref
=
model
.
getNodeLocation
(
targetNode
);
const
start
=
model
.
getListIndex
(
ref
);
const
length
=
model
.
getListRenderCount
(
ref
);
return
{
...
result
,
feedback
:
range
(
start
,
start
+
length
)
};
}
drop
(
data
:
IDragAndDropData
,
targetNode
:
ITreeNode
<
T
,
TFilterData
>
|
undefined
,
targetIndex
:
number
|
undefined
,
originalEvent
:
DragEvent
):
void
{
this
.
dnd
.
drop
(
data
,
targetNode
&&
targetNode
.
element
,
targetIndex
,
originalEvent
);
}
}
function
asListOptions
<
T
,
TFilterData
,
TRef
>
(
modelProvider
:
()
=>
ITreeModel
<
T
,
TFilterData
,
TRef
>
,
options
?:
IAbstractTreeOptions
<
T
,
TFilterData
>
):
IListOptions
<
ITreeNode
<
T
,
TFilterData
>>
|
undefined
{
return
options
&&
{
...
options
,
identityProvider
:
options
.
identityProvider
&&
{
...
...
@@ -22,23 +78,7 @@ function asListOptions<T, TFilterData>(options?: IAbstractTreeOptions<T, TFilter
return
options
.
identityProvider
!
.
getId
(
el
.
element
);
}
},
dnd
:
options
.
dnd
&&
{
getDragURI
(
node
)
{
return
options
.
dnd
!
.
getDragURI
(
node
.
element
);
},
getDragLabel
:
options
.
dnd
!
.
getDragLabel
&&
((
nodes
)
=>
{
return
options
.
dnd
!
.
getDragLabel
!
(
nodes
.
map
(
node
=>
node
.
element
));
}),
onDragStart
(
data
,
originalEvent
)
{
return
options
.
dnd
!
.
onDragStart
(
data
,
originalEvent
);
},
onDragOver
(
data
,
targetNode
,
targetIndex
,
originalEvent
)
{
return
options
.
dnd
!
.
onDragOver
(
data
,
targetNode
&&
targetNode
.
element
,
targetIndex
,
originalEvent
);
},
drop
(
data
,
targetNode
,
targetIndex
,
originalEvent
)
{
return
options
.
dnd
!
.
drop
(
data
,
targetNode
&&
targetNode
.
element
,
targetIndex
,
originalEvent
);
}
},
dnd
:
options
.
dnd
&&
new
TreeNodeListDragAndDrop
(
modelProvider
,
options
.
dnd
),
multipleSelectionController
:
options
.
multipleSelectionController
&&
{
isSelectionSingleChangeEvent
(
e
)
{
return
options
.
multipleSelectionController
!
.
isSelectionSingleChangeEvent
({
...
e
,
element
:
e
.
element
}
as
any
);
...
...
@@ -239,7 +279,7 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
const
treeRenderers
=
renderers
.
map
(
r
=>
new
TreeRenderer
<
T
,
TFilterData
,
any
>
(
r
,
onDidChangeCollapseStateRelay
.
event
));
this
.
disposables
.
push
(...
treeRenderers
);
this
.
view
=
new
List
(
container
,
treeDelegate
,
treeRenderers
,
asListOptions
(
options
));
this
.
view
=
new
List
(
container
,
treeDelegate
,
treeRenderers
,
asListOptions
(
()
=>
this
.
model
,
options
));
this
.
model
=
this
.
createModel
(
this
.
view
,
options
);
onDidChangeCollapseStateRelay
.
input
=
this
.
model
.
onDidChangeCollapseState
;
...
...
src/vs/base/browser/ui/tree/indexTreeModel.ts
浏览文件 @
7b50be29
...
...
@@ -127,6 +127,10 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
return
this
.
getTreeNodeWithListIndex
(
location
).
listIndex
;
}
getListRenderCount
(
location
:
number
[]):
number
{
return
this
.
getTreeNode
(
location
).
renderNodeCount
;
}
isCollapsible
(
location
:
number
[]):
boolean
{
return
this
.
getTreeNode
(
location
).
collapsible
;
}
...
...
src/vs/base/browser/ui/tree/objectTreeModel.ts
浏览文件 @
7b50be29
...
...
@@ -123,6 +123,11 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
return
this
.
model
.
getListIndex
(
location
);
}
getListRenderCount
(
element
:
T
):
number
{
const
location
=
this
.
getElementLocation
(
element
);
return
this
.
model
.
getListRenderCount
(
location
);
}
isCollapsible
(
element
:
T
):
boolean
{
const
location
=
this
.
getElementLocation
(
element
);
return
this
.
model
.
isCollapsible
(
location
);
...
...
src/vs/base/browser/ui/tree/tree.ts
浏览文件 @
7b50be29
...
...
@@ -101,6 +101,7 @@ export interface ITreeModel<T, TFilterData, TRef> {
readonly
onDidChangeRenderNodeCount
:
Event
<
ITreeNode
<
T
,
TFilterData
>>
;
getListIndex
(
location
:
TRef
):
number
;
getListRenderCount
(
location
:
TRef
):
number
;
getNode
(
location
?:
TRef
):
ITreeNode
<
T
,
any
>
;
getNodeLocation
(
node
:
ITreeNode
<
T
,
any
>
):
TRef
;
getParentNodeLocation
(
location
:
TRef
):
TRef
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录