Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
39a406da
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,发现更多精彩内容 >>
提交
39a406da
编写于
6月 24, 2020
作者:
A
Alex Ross
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add resolveTreeItem to custom tree
Part of #100741
上级
fe66be12
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
119 addition
and
15 deletion
+119
-15
src/vs/vscode.proposed.d.ts
src/vs/vscode.proposed.d.ts
+5
-0
src/vs/workbench/api/browser/mainThreadTreeViews.ts
src/vs/workbench/api/browser/mainThreadTreeViews.ts
+10
-4
src/vs/workbench/api/common/extHost.protocol.ts
src/vs/workbench/api/common/extHost.protocol.ts
+2
-0
src/vs/workbench/api/common/extHostTreeViews.ts
src/vs/workbench/api/common/extHostTreeViews.ts
+39
-0
src/vs/workbench/common/views.ts
src/vs/workbench/common/views.ts
+50
-0
src/vs/workbench/contrib/views/browser/treeView.ts
src/vs/workbench/contrib/views/browser/treeView.ts
+13
-11
未找到文件。
src/vs/vscode.proposed.d.ts
浏览文件 @
39a406da
...
...
@@ -1146,6 +1146,11 @@ declare module 'vscode' {
}
// https://github.com/microsoft/vscode/issues/100741
export
interface
TreeDataProvider
<
T
>
{
resolveTreeItem
?(
element
:
T
,
item
:
TreeItem2
):
TreeItem2
|
Thenable
<
TreeItem2
>
;
}
export
class
TreeItem2
extends
TreeItem
{
/**
* Label describing this item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri).
...
...
src/vs/workbench/api/browser/mainThreadTreeViews.ts
浏览文件 @
39a406da
...
...
@@ -5,7 +5,7 @@
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
ExtHostContext
,
MainThreadTreeViewsShape
,
ExtHostTreeViewsShape
,
MainContext
,
IExtHostContext
}
from
'
vs/workbench/api/common/extHost.protocol
'
;
import
{
ITreeViewDataProvider
,
ITreeItem
,
IViewsService
,
ITreeView
,
IViewsRegistry
,
ITreeViewDescriptor
,
IRevealOptions
,
Extensions
}
from
'
vs/workbench/common/views
'
;
import
{
ITreeViewDataProvider
,
ITreeItem
,
IViewsService
,
ITreeView
,
IViewsRegistry
,
ITreeViewDescriptor
,
IRevealOptions
,
Extensions
,
ResolvableTreeItem
}
from
'
vs/workbench/common/views
'
;
import
{
extHostNamedCustomer
}
from
'
vs/workbench/api/common/extHostCustomers
'
;
import
{
distinct
}
from
'
vs/base/common/arrays
'
;
import
{
INotificationService
}
from
'
vs/platform/notification/common/notification
'
;
...
...
@@ -163,11 +163,13 @@ type TreeItemHandle = string;
class
TreeViewDataProvider
implements
ITreeViewDataProvider
{
private
readonly
itemsMap
:
Map
<
TreeItemHandle
,
ITreeItem
>
=
new
Map
<
TreeItemHandle
,
ITreeItem
>
();
private
hasResolve
:
Promise
<
boolean
>
;
constructor
(
private
readonly
treeViewId
:
string
,
private
readonly
_proxy
:
ExtHostTreeViewsShape
,
private
readonly
notificationService
:
INotificationService
)
{
this
.
hasResolve
=
this
.
_proxy
.
$hasResolve
(
this
.
treeViewId
);
}
getChildren
(
treeItem
?:
ITreeItem
):
Promise
<
ITreeItem
[]
>
{
...
...
@@ -214,12 +216,16 @@ class TreeViewDataProvider implements ITreeViewDataProvider {
return
this
.
itemsMap
.
size
===
0
;
}
private
postGetChildren
(
elements
:
ITreeItem
[]):
ITreeItem
[]
{
const
result
:
ITreeItem
[]
=
[];
private
async
postGetChildren
(
elements
:
ITreeItem
[]):
Promise
<
ResolvableTreeItem
[]
>
{
const
result
:
ResolvableTreeItem
[]
=
[];
const
hasResolve
=
await
this
.
hasResolve
;
if
(
elements
)
{
for
(
const
element
of
elements
)
{
const
resolvable
=
new
ResolvableTreeItem
(
element
,
hasResolve
?
()
=>
{
return
this
.
_proxy
.
$resolve
(
this
.
treeViewId
,
element
.
handle
);
}
:
undefined
);
this
.
itemsMap
.
set
(
element
.
handle
,
element
);
result
.
push
(
element
);
result
.
push
(
resolvable
);
}
}
return
result
;
...
...
src/vs/workbench/api/common/extHost.protocol.ts
浏览文件 @
39a406da
...
...
@@ -987,6 +987,8 @@ export interface ExtHostTreeViewsShape {
$setExpanded
(
treeViewId
:
string
,
treeItemHandle
:
string
,
expanded
:
boolean
):
void
;
$setSelection
(
treeViewId
:
string
,
treeItemHandles
:
string
[]):
void
;
$setVisible
(
treeViewId
:
string
,
visible
:
boolean
):
void
;
$hasResolve
(
treeViewId
:
string
):
Promise
<
boolean
>
;
$resolve
(
treeViewId
:
string
,
treeItemHandle
:
string
):
Promise
<
ITreeItem
|
undefined
>
;
}
export
interface
ExtHostWorkspaceShape
{
...
...
src/vs/workbench/api/common/extHostTreeViews.ts
浏览文件 @
39a406da
...
...
@@ -119,6 +119,22 @@ export class ExtHostTreeViews implements ExtHostTreeViewsShape {
return
treeView
.
getChildren
(
treeItemHandle
);
}
async
$hasResolve
(
treeViewId
:
string
):
Promise
<
boolean
>
{
const
treeView
=
this
.
treeViews
.
get
(
treeViewId
);
if
(
!
treeView
)
{
throw
new
Error
(
localize
(
'
treeView.notRegistered
'
,
'
No tree view with id
\'
{0}
\'
registered.
'
,
treeViewId
));
}
return
treeView
.
hasResolve
;
}
$resolve
(
treeViewId
:
string
,
treeItemHandle
:
string
):
Promise
<
ITreeItem
|
undefined
>
{
const
treeView
=
this
.
treeViews
.
get
(
treeViewId
);
if
(
!
treeView
)
{
throw
new
Error
(
localize
(
'
treeView.notRegistered
'
,
'
No tree view with id
\'
{0}
\'
registered.
'
,
treeViewId
));
}
return
treeView
.
resolveTreeItem
(
treeItemHandle
);
}
$setExpanded
(
treeViewId
:
string
,
treeItemHandle
:
string
,
expanded
:
boolean
):
void
{
const
treeView
=
this
.
treeViews
.
get
(
treeViewId
);
if
(
!
treeView
)
{
...
...
@@ -160,6 +176,7 @@ type TreeData<T> = { message: boolean, element: T | Root | false };
interface
TreeNode
extends
IDisposable
{
item
:
ITreeItem
;
extensionItem
:
vscode
.
TreeItem2
;
parent
:
TreeNode
|
Root
;
children
?:
TreeNode
[];
}
...
...
@@ -329,6 +346,27 @@ class ExtHostTreeView<T> extends Disposable {
}
}
get
hasResolve
():
boolean
{
return
!!
this
.
dataProvider
.
resolveTreeItem
;
}
async
resolveTreeItem
(
treeItemHandle
:
string
):
Promise
<
ITreeItem
|
undefined
>
{
if
(
!
this
.
dataProvider
.
resolveTreeItem
)
{
return
;
}
const
element
=
this
.
elements
.
get
(
treeItemHandle
);
if
(
element
)
{
const
node
=
this
.
nodes
.
get
(
element
);
if
(
node
)
{
const
resolve
=
await
this
.
dataProvider
.
resolveTreeItem
(
element
,
node
.
extensionItem
);
// Resolvable elements. Currently only tooltip.
node
.
item
.
tooltip
=
resolve
.
tooltip
;
return
node
.
item
;
}
}
return
;
}
private
resolveUnknownParentChain
(
element
:
T
):
Promise
<
TreeNode
[]
>
{
return
this
.
resolveParent
(
element
)
.
then
((
parent
)
=>
{
...
...
@@ -521,6 +559,7 @@ class ExtHostTreeView<T> extends Disposable {
return
{
item
,
extensionItem
:
extensionTreeItem
,
parent
,
children
:
undefined
,
dispose
():
void
{
disposable
.
dispose
();
}
...
...
src/vs/workbench/common/views.ts
浏览文件 @
39a406da
...
...
@@ -648,6 +648,56 @@ export interface ITreeItem {
accessibilityInformation
?:
IAccessibilityInformation
;
}
export
class
ResolvableTreeItem
implements
ITreeItem
{
handle
:
string
;
parentHandle
?:
string
;
collapsibleState
:
TreeItemCollapsibleState
;
label
?:
ITreeItemLabel
;
description
?:
string
|
boolean
;
icon
?:
UriComponents
;
iconDark
?:
UriComponents
;
themeIcon
?:
ThemeIcon
;
resourceUri
?:
UriComponents
;
tooltip
?:
string
|
IMarkdownString
;
contextValue
?:
string
;
command
?:
Command
;
children
?:
ITreeItem
[];
accessibilityInformation
?:
IAccessibilityInformation
;
resolve
:
()
=>
Promise
<
void
>
;
private
resolved
:
boolean
=
false
;
private
_hasResolve
:
boolean
=
false
;
constructor
(
treeItem
:
ITreeItem
,
resolve
?:
(()
=>
Promise
<
ITreeItem
|
undefined
>
))
{
this
.
handle
=
treeItem
.
handle
;
this
.
parentHandle
=
treeItem
.
parentHandle
;
this
.
collapsibleState
=
treeItem
.
collapsibleState
;
this
.
label
=
treeItem
.
label
;
this
.
description
=
treeItem
.
description
;
this
.
icon
=
treeItem
.
icon
;
this
.
iconDark
=
treeItem
.
iconDark
;
this
.
themeIcon
=
treeItem
.
themeIcon
;
this
.
resourceUri
=
treeItem
.
resourceUri
;
this
.
tooltip
=
treeItem
.
tooltip
;
this
.
contextValue
=
treeItem
.
contextValue
;
this
.
command
=
treeItem
.
command
;
this
.
children
=
treeItem
.
children
;
this
.
accessibilityInformation
=
treeItem
.
accessibilityInformation
;
this
.
_hasResolve
=
!!
resolve
;
this
.
resolve
=
async
()
=>
{
if
(
resolve
&&
!
this
.
resolved
)
{
const
resolvedItem
=
await
resolve
();
if
(
resolvedItem
)
{
// Resolvable elements. Currently only tooltip.
this
.
tooltip
=
resolvedItem
.
tooltip
;
}
}
this
.
resolved
=
true
;
};
}
get
hasResolve
():
boolean
{
return
this
.
_hasResolve
;
}
}
export
interface
ITreeViewDataProvider
{
readonly
isTreeEmpty
?:
boolean
;
onDidChangeEmpty
?:
Event
<
void
>
;
...
...
src/vs/workbench/contrib/views/browser/treeView.ts
浏览文件 @
39a406da
...
...
@@ -13,7 +13,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import
{
IMenuService
,
MenuId
,
MenuItemAction
,
registerAction2
,
Action2
}
from
'
vs/platform/actions/common/actions
'
;
import
{
ContextAwareMenuEntryActionViewItem
,
createAndFillInContextMenuActions
}
from
'
vs/platform/actions/browser/menuEntryActionViewItem
'
;
import
{
IContextKeyService
,
ContextKeyExpr
,
ContextKeyEqualsExpr
,
RawContextKey
,
IContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
ITreeView
,
ITreeItem
,
TreeItemCollapsibleState
,
ITreeViewDataProvider
,
TreeViewItemHandleArg
,
ITreeItemLabel
,
IViewDescriptorService
,
ViewContainer
,
ViewContainerLocation
}
from
'
vs/workbench/common/views
'
;
import
{
ITreeView
,
ITreeItem
,
TreeItemCollapsibleState
,
ITreeViewDataProvider
,
TreeViewItemHandleArg
,
ITreeItemLabel
,
IViewDescriptorService
,
ViewContainer
,
ViewContainerLocation
,
ResolvableTreeItem
}
from
'
vs/workbench/common/views
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
INotificationService
}
from
'
vs/platform/notification/common/notification
'
;
import
{
IProgressService
}
from
'
vs/platform/progress/common/progress
'
;
...
...
@@ -38,7 +38,6 @@ import { FuzzyScore, createMatches } from 'vs/base/common/filters';
import
{
CollapseAllAction
}
from
'
vs/base/browser/ui/tree/treeDefaults
'
;
import
{
isFalsyOrWhitespace
}
from
'
vs/base/common/strings
'
;
import
{
SIDE_BAR_BACKGROUND
,
PANEL_BACKGROUND
}
from
'
vs/workbench/common/theme
'
;
import
{
IMarkdownString
}
from
'
vs/base/common/htmlContent
'
;
import
{
IHoverService
}
from
'
vs/workbench/services/hover/browser/hover
'
;
class
Root
implements
ITreeItem
{
...
...
@@ -727,7 +726,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
templateData
.
elementDisposable
.
dispose
();
const
node
=
element
.
element
;
const
resource
=
node
.
resourceUri
?
URI
.
revive
(
node
.
resourceUri
)
:
null
;
const
treeItemLabel
:
ITreeItemLabel
|
undefined
=
node
.
label
?
node
.
label
:
resource
?
{
label
:
basename
(
resource
)
}
:
undefined
;
const
treeItemLabel
:
ITreeItemLabel
|
undefined
=
node
.
label
?
node
.
label
:
(
resource
?
{
label
:
basename
(
resource
)
}
:
undefined
)
;
const
description
=
isString
(
node
.
description
)
?
node
.
description
:
resource
&&
node
.
description
===
true
?
this
.
labelService
.
getUriLabel
(
dirname
(
resource
),
{
relative
:
true
})
:
undefined
;
const
label
=
treeItemLabel
?
treeItemLabel
.
label
:
undefined
;
const
matches
=
(
treeItemLabel
&&
treeItemLabel
.
highlights
&&
label
)
?
treeItemLabel
.
highlights
.
map
(([
start
,
end
])
=>
{
...
...
@@ -749,7 +748,8 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
})
:
undefined
;
const
icon
=
this
.
themeService
.
getColorTheme
().
type
===
LIGHT
?
node
.
icon
:
node
.
iconDark
;
const
iconUrl
=
icon
?
URI
.
revive
(
icon
)
:
null
;
const
title
=
node
.
tooltip
?
isString
(
node
.
tooltip
)
?
node
.
tooltip
:
undefined
:
resource
?
undefined
:
label
;
const
canResolve
=
node
instanceof
ResolvableTreeItem
&&
node
.
hasResolve
;
const
title
=
node
.
tooltip
?
(
isString
(
node
.
tooltip
)
?
node
.
tooltip
:
undefined
)
:
(
resource
?
undefined
:
(
canResolve
?
undefined
:
label
));
// reset
templateData
.
actionBar
.
clear
();
...
...
@@ -785,14 +785,14 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
const
disposableStore
=
new
DisposableStore
();
templateData
.
elementDisposable
=
disposableStore
;
disposableStore
.
add
(
this
.
themeService
.
onDidFileIconThemeChange
(()
=>
this
.
setAlignment
(
templateData
.
container
,
node
)));
this
.
setupHovers
(
node
.
tooltip
,
templateData
.
container
,
disposableStore
);
this
.
setupHovers
(
node
,
templateData
.
container
,
disposableStore
,
label
);
}
private
setupHovers
(
tooltip
:
string
|
IMarkdownString
|
undefined
,
htmlElement
:
HTMLElement
,
disposableStore
:
DisposableStore
):
void
{
if
(
!
tooltip
||
isString
(
tooltip
)
)
{
private
setupHovers
(
node
:
ITreeItem
,
htmlElement
:
HTMLElement
,
disposableStore
:
DisposableStore
,
label
:
string
|
undefined
):
void
{
if
(
(
node
.
tooltip
&&
isString
(
node
.
tooltip
))
||
!
(
node
instanceof
ResolvableTreeItem
)
||
!
node
.
hasResolve
)
{
return
;
}
const
text
:
IMarkdownString
=
tooltip
;
const
resolvableNode
:
ResolvableTreeItem
=
node
;
const
hoverService
=
this
.
hoverService
;
const
hoverDelay
=
this
.
hoverDelay
;
function
mouseOver
(
this
:
HTMLElement
,
e
:
MouseEvent
):
any
{
...
...
@@ -801,9 +801,11 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
isHovering
=
false
;
}
this
.
addEventListener
(
DOM
.
EventType
.
MOUSE_LEAVE
,
mouseLeave
,
{
passive
:
true
});
setTimeout
(()
=>
{
if
(
isHovering
)
{
hoverService
.
showHover
({
text
,
target
:
this
});
setTimeout
(
async
()
=>
{
await
resolvableNode
.
resolve
();
const
tooltip
=
resolvableNode
.
tooltip
??
label
;
if
(
isHovering
&&
tooltip
)
{
hoverService
.
showHover
({
text
:
isString
(
tooltip
)
?
{
value
:
tooltip
}
:
tooltip
,
target
:
this
});
}
this
.
removeEventListener
(
DOM
.
EventType
.
MOUSE_LEAVE
,
mouseLeave
);
},
hoverDelay
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录