Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
1090fc63
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1090fc63
编写于
9月 18, 2017
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
wip: more panelview work, PanelViewlet
上级
a2964093
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
294 addition
and
206 deletion
+294
-206
src/vs/base/browser/ui/splitview/panelview.css
src/vs/base/browser/ui/splitview/panelview.css
+67
-0
src/vs/base/browser/ui/splitview/panelview.ts
src/vs/base/browser/ui/splitview/panelview.ts
+51
-32
src/vs/base/browser/ui/splitview/splitview2.css
src/vs/base/browser/ui/splitview/splitview2.css
+23
-0
src/vs/base/browser/ui/splitview/splitview2.ts
src/vs/base/browser/ui/splitview/splitview2.ts
+2
-3
src/vs/platform/theme/common/styler.ts
src/vs/platform/theme/common/styler.ts
+6
-2
src/vs/workbench/browser/parts/views/views2.ts
src/vs/workbench/browser/parts/views/views2.ts
+36
-25
src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts
src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts
+109
-144
未找到文件。
src/vs/base/browser/ui/splitview/panelview.css
0 → 100644
浏览文件 @
1090fc63
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-panel-view
{
width
:
100%
;
height
:
100%
;
}
.monaco-panel-view
.panel
{
overflow
:
hidden
;
width
:
100%
;
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
}
.monaco-panel-view
.panel
>
.panel-header
{
font-size
:
11px
;
font-weight
:
bold
;
text-transform
:
uppercase
;
padding-left
:
20px
;
overflow
:
hidden
;
}
/* Bold font style does not go well with CJK fonts */
.monaco-panel-view
:lang
(
zh-Hans
)
.panel
>
.panel-header
,
.monaco-panel-view
:lang
(
zh-Hant
)
.panel
>
.panel-header
,
.monaco-panel-view
:lang
(
ja
)
.panel
>
.panel-header
,
.monaco-panel-view
:lang
(
ko
)
.panel
>
.panel-header
{
font-weight
:
normal
;
}
.monaco-panel-view
.panel
>
.panel-header.hidden
{
display
:
none
;
}
.monaco-panel-view
.panel
>
.panel-body
{
overflow
:
hidden
;
flex
:
1
;
}
.monaco-panel-view
.panel
>
.panel-header
{
cursor
:
pointer
;
/* background: rgba(128, 128, 128, 0.2); */
}
.monaco-panel-view
.panel
>
.panel-header
{
background-image
:
url('arrow-collapse.svg')
;
background-position
:
2px
center
;
background-repeat
:
no-repeat
;
}
.monaco-panel-view
.panel
>
.panel-header.expanded
{
background-image
:
url('arrow-expand.svg')
;
background-position
:
2px
center
;
background-repeat
:
no-repeat
;
}
.vs-dark
.monaco-panel-view
.panel
>
.panel-header
{
background-image
:
url('arrow-collapse-dark.svg')
;
}
.vs-dark
.monaco-panel-view
.panel
>
.panel-header.expanded
{
background-image
:
url('arrow-expand-dark.svg')
;
}
\ No newline at end of file
src/vs/base/browser/ui/splitview/panelview.ts
浏览文件 @
1090fc63
...
...
@@ -5,7 +5,7 @@
'
use strict
'
;
import
'
vs/css!./
split
view
'
;
import
'
vs/css!./
panel
view
'
;
import
{
IDisposable
,
dispose
,
combinedDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
Event
,
{
Emitter
,
chain
}
from
'
vs/base/common/event
'
;
import
{
domEvent
}
from
'
vs/base/browser/event
'
;
...
...
@@ -25,6 +25,9 @@ export interface IPanelOptions {
export
interface
IPanelStyles
{
dropBackground
?:
Color
;
headerForeground
?:
Color
;
headerBackground
?:
Color
;
headerHighContrastBorder
?:
Color
;
}
export
abstract
class
Panel
implements
IView
{
...
...
@@ -38,9 +41,18 @@ export abstract class Panel implements IView {
private
_maximumBodySize
:
number
;
private
ariaHeaderLabel
:
string
;
readonly
header
:
HTMLElement
;
private
header
:
HTMLElement
;
protected
disposables
:
IDisposable
[]
=
[];
get
draggable
():
HTMLElement
{
return
this
.
header
;
}
private
_dropBackground
:
Color
|
undefined
;
get
dropBackground
():
Color
|
undefined
{
return
this
.
_dropBackground
;
}
get
minimumBodySize
():
number
{
return
this
.
_minimumBodySize
;
}
...
...
@@ -59,8 +71,12 @@ export abstract class Panel implements IView {
this
.
_onDidChange
.
fire
();
}
private
get
headerSize
():
number
{
return
this
.
headerVisible
?
Panel
.
HEADER_SIZE
:
0
;
}
get
minimumSize
():
number
{
const
headerSize
=
this
.
header
Visible
?
Panel
.
HEADER_SIZE
:
0
;
const
headerSize
=
this
.
header
Size
;
const
expanded
=
!
this
.
headerVisible
||
this
.
expanded
;
const
minimumBodySize
=
expanded
?
this
.
_minimumBodySize
:
0
;
...
...
@@ -68,7 +84,7 @@ export abstract class Panel implements IView {
}
get
maximumSize
():
number
{
const
headerSize
=
this
.
header
Visible
?
Panel
.
HEADER_SIZE
:
0
;
const
headerSize
=
this
.
header
Size
;
const
expanded
=
!
this
.
headerVisible
||
this
.
expanded
;
const
maximumBodySize
=
expanded
?
this
.
_maximumBodySize
:
0
;
...
...
@@ -82,6 +98,7 @@ export abstract class Panel implements IView {
this
.
ariaHeaderLabel
=
options
.
ariaHeaderLabel
||
''
;
this
.
_minimumBodySize
=
typeof
options
.
minimumBodySize
===
'
number
'
?
options
.
minimumBodySize
:
44
;
this
.
_maximumBodySize
=
typeof
options
.
maximumBodySize
===
'
number
'
?
options
.
maximumBodySize
:
Number
.
POSITIVE_INFINITY
;
this
.
header
=
$
(
'
.panel-header
'
);
}
get
expanded
():
boolean
{
...
...
@@ -94,7 +111,7 @@ export abstract class Panel implements IView {
}
this
.
_expanded
=
!!
expanded
;
this
.
render
Header
();
this
.
update
Header
();
this
.
_onDidChange
.
fire
();
}
...
...
@@ -108,20 +125,21 @@ export abstract class Panel implements IView {
}
this
.
_headerVisible
=
!!
visible
;
this
.
render
Header
();
this
.
update
Header
();
this
.
_onDidChange
.
fire
();
}
render
(
container
:
HTMLElement
):
void
{
const
panel
=
append
(
container
,
$
(
'
.panel
'
));
const
header
=
append
(
panel
,
$
(
'
.panel-header
'
));
header
.
setAttribute
(
'
tabindex
'
,
'
0
'
);
header
.
setAttribute
(
'
role
'
,
'
toolbar
'
);
header
.
setAttribute
(
'
aria-label
'
,
this
.
ariaHeaderLabel
);
this
.
renderHeader
();
append
(
panel
,
this
.
header
);
this
.
header
.
setAttribute
(
'
tabindex
'
,
'
0
'
);
this
.
header
.
setAttribute
(
'
role
'
,
'
toolbar
'
);
this
.
header
.
setAttribute
(
'
aria-label
'
,
this
.
ariaHeaderLabel
);
this
.
renderHeader
(
this
.
header
);
this
.
updateHeader
();
const
onHeaderKeyDown
=
chain
(
domEvent
(
header
,
'
keydown
'
))
const
onHeaderKeyDown
=
chain
(
domEvent
(
this
.
header
,
'
keydown
'
))
.
map
(
e
=>
new
StandardKeyboardEvent
(
e
));
onHeaderKeyDown
.
filter
(
e
=>
e
.
keyCode
===
KeyCode
.
Enter
||
e
.
keyCode
===
KeyCode
.
Space
)
...
...
@@ -133,7 +151,7 @@ export abstract class Panel implements IView {
onHeaderKeyDown
.
filter
(
e
=>
e
.
keyCode
===
KeyCode
.
RightArrow
)
.
event
(()
=>
this
.
expanded
=
true
,
null
,
this
.
disposables
);
domEvent
(
header
,
'
click
'
)
domEvent
(
this
.
header
,
'
click
'
)
(()
=>
this
.
expanded
=
!
this
.
expanded
,
null
,
this
.
disposables
);
// TODO@Joao move this down to panelview
...
...
@@ -152,18 +170,24 @@ export abstract class Panel implements IView {
this
.
layoutBody
(
size
-
headerSize
);
}
focus
():
void
{
// TODO@joao what to do
style
(
styles
:
IPanelStyles
):
void
{
this
.
header
.
style
.
color
=
styles
.
headerForeground
?
styles
.
headerForeground
.
toString
()
:
null
;
this
.
header
.
style
.
backgroundColor
=
styles
.
headerBackground
?
styles
.
headerBackground
.
toString
()
:
null
;
this
.
header
.
style
.
borderTop
=
styles
.
headerHighContrastBorder
?
`1px solid
${
styles
.
headerHighContrastBorder
}
`
:
null
;
this
.
_dropBackground
=
styles
.
dropBackground
;
}
private
render
Header
():
void
{
private
update
Header
():
void
{
const
expanded
=
!
this
.
headerVisible
||
this
.
expanded
;
this
.
header
.
style
.
height
=
`
${
this
.
headerSize
}
px`
;
this
.
header
.
style
.
lineHeight
=
`
${
this
.
headerSize
}
px`
;
toggleClass
(
this
.
header
,
'
hidden
'
,
!
this
.
headerVisible
);
toggleClass
(
this
.
header
,
'
expanded
'
,
expanded
);
this
.
header
.
setAttribute
(
'
aria-expanded
'
,
String
(
expanded
));
}
protected
abstract
renderHeader
(
container
:
HTMLElement
):
void
;
protected
abstract
renderBody
(
container
:
HTMLElement
):
void
;
protected
abstract
layoutBody
(
size
:
number
):
void
;
...
...
@@ -173,7 +197,6 @@ export abstract class Panel implements IView {
}
interface
IDndContext
{
dropBackground
:
Color
|
undefined
;
draggable
:
PanelDraggable
|
null
;
}
...
...
@@ -189,17 +212,17 @@ class PanelDraggable implements IDisposable {
readonly
onDidDrop
=
this
.
_onDidDrop
.
event
;
constructor
(
private
panel
:
Panel
,
private
context
:
IDndContext
)
{
domEvent
(
panel
.
header
,
'
dragstart
'
)(
this
.
onDragStart
,
this
,
this
.
disposables
);
domEvent
(
panel
.
header
,
'
dragenter
'
)(
this
.
onDragEnter
,
this
,
this
.
disposables
);
domEvent
(
panel
.
header
,
'
dragleave
'
)(
this
.
onDragLeave
,
this
,
this
.
disposables
);
domEvent
(
panel
.
header
,
'
dragend
'
)(
this
.
onDragEnd
,
this
,
this
.
disposables
);
domEvent
(
panel
.
header
,
'
drop
'
)(
this
.
onDrop
,
this
,
this
.
disposables
);
domEvent
(
panel
.
draggable
,
'
dragstart
'
)(
this
.
onDragStart
,
this
,
this
.
disposables
);
domEvent
(
panel
.
draggable
,
'
dragenter
'
)(
this
.
onDragEnter
,
this
,
this
.
disposables
);
domEvent
(
panel
.
draggable
,
'
dragleave
'
)(
this
.
onDragLeave
,
this
,
this
.
disposables
);
domEvent
(
panel
.
draggable
,
'
dragend
'
)(
this
.
onDragEnd
,
this
,
this
.
disposables
);
domEvent
(
panel
.
draggable
,
'
drop
'
)(
this
.
onDrop
,
this
,
this
.
disposables
);
}
private
onDragStart
(
e
:
DragEvent
):
void
{
e
.
dataTransfer
.
effectAllowed
=
'
move
'
;
const
dragImage
=
append
(
document
.
body
,
$
(
'
.monaco-panel-drag-image
'
,
{},
this
.
panel
.
header
.
textContent
));
const
dragImage
=
append
(
document
.
body
,
$
(
'
.monaco-panel-drag-image
'
,
{},
this
.
panel
.
draggable
.
textContent
));
e
.
dataTransfer
.
setDragImage
(
dragImage
,
-
10
,
-
10
);
setTimeout
(()
=>
document
.
body
.
removeChild
(
dragImage
),
0
);
...
...
@@ -256,10 +279,10 @@ class PanelDraggable implements IDisposable {
let
backgroundColor
:
string
=
null
;
if
(
this
.
dragOverCounter
>
0
)
{
backgroundColor
=
(
this
.
context
.
dropBackground
||
PanelDraggable
.
DefaultDragOverBackgroundColor
).
toString
();
backgroundColor
=
(
this
.
panel
.
dropBackground
||
PanelDraggable
.
DefaultDragOverBackgroundColor
).
toString
();
}
this
.
panel
.
header
.
style
.
backgroundColor
=
backgroundColor
;
this
.
panel
.
draggable
.
style
.
backgroundColor
=
backgroundColor
;
}
dispose
():
void
{
...
...
@@ -279,7 +302,7 @@ interface IPanelItem {
export
class
PanelView
implements
IDisposable
{
private
dnd
:
boolean
;
private
dndContext
:
IDndContext
=
{
dr
opBackground
:
undefined
,
dr
aggable
:
null
};
private
dndContext
:
IDndContext
=
{
draggable
:
null
};
private
el
:
HTMLElement
;
private
panelItems
:
IPanelItem
[]
=
[];
private
splitview
:
SplitView
;
...
...
@@ -288,10 +311,10 @@ export class PanelView implements IDisposable {
private
_onDidDrop
=
new
Emitter
<
{
from
:
Panel
,
to
:
Panel
}
>
();
readonly
onDidDrop
:
Event
<
{
from
:
Panel
,
to
:
Panel
}
>
=
this
.
_onDidDrop
.
event
;
constructor
(
private
container
:
HTMLElement
,
options
?:
IPanelViewOptions
)
{
constructor
(
private
container
:
HTMLElement
,
options
:
IPanelViewOptions
=
{}
)
{
this
.
dnd
=
!!
options
.
dnd
;
this
.
el
=
append
(
container
,
$
(
'
.monaco-panel-view
'
));
this
.
splitview
=
new
SplitView
(
container
);
this
.
splitview
=
new
SplitView
(
this
.
el
);
}
addPanel
(
panel
:
Panel
,
size
:
number
,
index
=
this
.
splitview
.
length
):
void
{
...
...
@@ -337,10 +360,6 @@ export class PanelView implements IDisposable {
this
.
splitview
.
layout
(
size
);
}
style
(
styles
:
IPanelStyles
):
void
{
this
.
dndContext
.
dropBackground
=
styles
.
dropBackground
;
}
private
setupAnimation
():
void
{
if
(
typeof
this
.
animationTimer
===
'
number
'
)
{
window
.
clearTimeout
(
this
.
animationTimer
);
...
...
src/vs/base/browser/ui/splitview/splitview2.css
0 → 100644
浏览文件 @
1090fc63
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-split-view2
{
position
:
relative
;
overflow
:
hidden
;
width
:
100%
;
height
:
100%
;
}
.monaco-split-view2
>
.split-view-view
{
overflow
:
hidden
;
}
.monaco-split-view2.vertical
>
.split-view-view
{
width
:
100%
;
}
.monaco-split-view2.horizontal
>
.split-view-view
{
height
:
100%
;
}
src/vs/base/browser/ui/splitview/splitview2.ts
浏览文件 @
1090fc63
...
...
@@ -5,7 +5,7 @@
'
use strict
'
;
import
'
vs/css!./splitview
'
;
import
'
vs/css!./splitview
2
'
;
import
{
IDisposable
,
combinedDisposable
,
toDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
Event
,
{
fromEventEmitter
,
mapEvent
}
from
'
vs/base/common/event
'
;
import
types
=
require
(
'
vs/base/common/types
'
);
...
...
@@ -25,7 +25,6 @@ export interface IView {
readonly
onDidChange
:
Event
<
void
>
;
render
(
container
:
HTMLElement
,
orientation
:
Orientation
):
void
;
layout
(
size
:
number
,
orientation
:
Orientation
):
void
;
focus
():
void
;
}
interface
ISashEvent
{
...
...
@@ -80,7 +79,7 @@ export class SplitView implements IDisposable {
this
.
orientation
=
types
.
isUndefined
(
options
.
orientation
)
?
Orientation
.
VERTICAL
:
options
.
orientation
;
this
.
el
=
document
.
createElement
(
'
div
'
);
dom
.
addClass
(
this
.
el
,
'
monaco-split-view
'
);
dom
.
addClass
(
this
.
el
,
'
monaco-split-view
2
'
);
dom
.
addClass
(
this
.
el
,
this
.
orientation
===
Orientation
.
VERTICAL
?
'
vertical
'
:
'
horizontal
'
);
container
.
appendChild
(
this
.
el
);
}
...
...
src/vs/platform/theme/common/styler.ts
浏览文件 @
1090fc63
...
...
@@ -15,11 +15,15 @@ export interface IThemable {
style
:
styleFn
;
}
export
function
attachStyler
(
themeService
:
IThemeService
,
optionsMapping
:
{
[
optionsKey
:
string
]:
ColorIdentifier
|
ColorFunction
},
widgetOrCallback
:
IThemable
|
styleFn
):
IDisposable
{
export
interface
IColorMapping
{
[
optionsKey
:
string
]:
ColorIdentifier
|
ColorFunction
|
undefined
;
}
export
function
attachStyler
<
T
extends
IColorMapping
>
(
themeService
:
IThemeService
,
optionsMapping
:
T
,
widgetOrCallback
:
IThemable
|
styleFn
):
IDisposable
{
function
applyStyles
(
theme
:
ITheme
):
void
{
const
styles
=
Object
.
create
(
null
);
for
(
let
key
in
optionsMapping
)
{
const
value
=
optionsMapping
[
key
];
const
value
=
optionsMapping
[
key
as
string
];
if
(
typeof
value
===
'
string
'
)
{
styles
[
key
]
=
theme
.
getColor
(
value
);
}
else
if
(
typeof
value
===
'
function
'
)
{
...
...
src/vs/workbench/browser/parts/views/views2.ts
浏览文件 @
1090fc63
...
...
@@ -6,7 +6,9 @@
import
*
as
nls
from
'
vs/nls
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
attachStyler
}
from
'
vs/platform/theme/common/styler
'
;
import
{
ColorIdentifier
,
contrastBorder
}
from
'
vs/platform/theme/common/colorRegistry
'
;
import
{
attachStyler
,
IColorMapping
,
IThemable
}
from
'
vs/platform/theme/common/styler
'
;
import
{
SIDE_BAR_DRAG_AND_DROP_BACKGROUND
,
SIDE_BAR_SECTION_HEADER_FOREGROUND
,
SIDE_BAR_SECTION_HEADER_BACKGROUND
}
from
'
vs/workbench/common/theme
'
;
import
{
Dimension
,
Builder
}
from
'
vs/base/browser/builder
'
;
import
{
append
,
$
}
from
'
vs/base/browser/dom
'
;
import
{
IDisposable
,
combinedDisposable
}
from
'
vs/base/common/lifecycle
'
;
...
...
@@ -21,9 +23,24 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import
{
IContextMenuService
}
from
'
vs/platform/contextview/browser/contextView
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
IThemeService
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
SIDE_BAR_DRAG_AND_DROP_BACKGROUND
}
from
'
vs/workbench/common/theme
'
;
import
{
PanelView
,
IPanelOptions
,
Panel
}
from
'
vs/base/browser/ui/splitview/panelview
'
;
export
interface
IPanelColors
extends
IColorMapping
{
dropBackground
?:
ColorIdentifier
;
headerForeground
?:
ColorIdentifier
;
headerBackground
?:
ColorIdentifier
;
headerHighContrastBorder
?:
ColorIdentifier
;
}
export
function
attachPanelStyler
(
widget
:
IThemable
,
themeService
:
IThemeService
)
{
return
attachStyler
<
IPanelColors
>
(
themeService
,
{
headerForeground
:
SIDE_BAR_SECTION_HEADER_FOREGROUND
,
headerBackground
:
SIDE_BAR_SECTION_HEADER_BACKGROUND
,
headerHighContrastBorder
:
contrastBorder
,
dropBackground
:
SIDE_BAR_DRAG_AND_DROP_BACKGROUND
},
widget
);
}
export
interface
IViewletPanelOptions
extends
IPanelOptions
{
actionRunner
?:
IActionRunner
;
}
...
...
@@ -37,28 +54,24 @@ export abstract class ViewletPanel extends Panel {
private
toolbar
:
ToolBar
;
constructor
(
readonly
name
:
string
,
initialSize
:
number
,
readonly
title
:
string
,
options
:
IViewletPanelOptions
,
protected
keybindingService
:
IKeybindingService
,
protected
contextMenuService
:
IContextMenuService
@
IKeybindingService
protected
keybindingService
:
IKeybindingService
,
@
IContextMenuService
protected
contextMenuService
:
IContextMenuService
)
{
super
(
options
);
this
.
actionRunner
=
options
.
actionRunner
;
}
render
(
container
:
HTMLElement
):
void
{
super
.
render
(
container
);
const
title
=
append
(
this
.
header
,
$
(
'
div.title
'
));
title
.
textContent
=
this
.
name
;
protected
renderHeader
(
container
:
HTMLElement
):
void
{
this
.
renderHeaderTitle
(
container
);
const
actions
=
append
(
this
.
header
,
$
(
'
div
.actions
'
));
const
actions
=
append
(
container
,
$
(
'
.actions
'
));
this
.
toolbar
=
new
ToolBar
(
actions
,
this
.
contextMenuService
,
{
orientation
:
ActionsOrientation
.
HORIZONTAL
,
actionItemProvider
:
action
=>
this
.
getActionItem
(
action
),
ariaLabel
:
nls
.
localize
(
'
viewToolbarAriaLabel
'
,
"
{0} actions
"
,
this
.
nam
e
),
ariaLabel
:
nls
.
localize
(
'
viewToolbarAriaLabel
'
,
"
{0} actions
"
,
this
.
titl
e
),
getKeyBinding
:
action
=>
this
.
keybindingService
.
lookupKeybinding
(
action
.
id
),
actionRunner
:
this
.
actionRunner
});
...
...
@@ -67,8 +80,11 @@ export abstract class ViewletPanel extends Panel {
this
.
updateActions
();
}
protected
renderHeaderTitle
(
container
:
HTMLElement
):
void
{
append
(
container
,
$
(
'
.title
'
,
null
,
this
.
title
));
}
focus
():
void
{
super
.
focus
();
this
.
_onDidFocus
.
fire
();
}
...
...
@@ -102,10 +118,6 @@ export interface IViewsViewletOptions {
showHeaderInTitleWhenSingleView
:
boolean
;
}
const
SplitViewThemeMapping
=
{
dropBackground
:
SIDE_BAR_DRAG_AND_DROP_BACKGROUND
};
interface
IViewletPanelItem
{
panel
:
ViewletPanel
;
disposable
:
IDisposable
;
...
...
@@ -139,15 +151,13 @@ export class PanelViewlet extends Viewlet {
const
container
=
parent
.
getHTMLElement
();
this
.
panelview
=
this
.
_register
(
new
PanelView
(
container
));
this
.
_register
(
attachStyler
(
this
.
themeService
,
SplitViewThemeMapping
,
this
.
panelview
));
// this._register(this.panelview.onFocus(view => this.lastFocusedView = view));
}
getTitle
():
string
{
let
title
=
Registry
.
as
<
ViewletRegistry
>
(
Extensions
.
Viewlets
).
getViewlet
(
this
.
getId
()).
name
;
if
(
this
.
isSingleView
)
{
title
+=
'
:
'
+
this
.
panelItems
[
0
].
panel
.
nam
e
;
title
+=
'
:
'
+
this
.
panelItems
[
0
].
panel
.
titl
e
;
}
return
title
;
...
...
@@ -190,20 +200,21 @@ export class PanelViewlet extends Viewlet {
return
Math
.
max
(...
sizes
);
}
add
View
(
panel
:
ViewletPanel
,
index
=
this
.
panelItems
.
length
-
1
):
void
{
add
Panel
(
panel
:
ViewletPanel
,
size
:
number
,
index
=
this
.
panelItems
.
length
-
1
):
void
{
const
disposables
:
IDisposable
[]
=
[];
const
onDidFocus
=
panel
.
onDidFocus
(()
=>
this
.
lastFocusedPanel
=
panel
,
null
,
disposables
);
const
disposable
=
combinedDisposable
([
onDidFocus
]);
const
styler
=
attachPanelStyler
(
panel
,
this
.
themeService
);
const
disposable
=
combinedDisposable
([
onDidFocus
,
styler
]);
const
panelItem
:
IViewletPanelItem
=
{
panel
,
disposable
};
this
.
panelItems
.
splice
(
index
,
0
,
panelItem
);
this
.
panelview
.
addPanel
(
panel
,
200
,
index
);
this
.
panelview
.
addPanel
(
panel
,
size
,
index
);
this
.
updateViewHeaders
();
this
.
updateTitleArea
();
}
remove
View
(
panel
:
ViewletPanel
):
void
{
remove
Panel
(
panel
:
ViewletPanel
):
void
{
const
index
=
firstIndex
(
this
.
panelItems
,
i
=>
i
.
panel
===
panel
);
if
(
index
===
-
1
)
{
...
...
src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts
浏览文件 @
1090fc63
...
...
@@ -13,7 +13,7 @@ import { basename } from 'vs/base/common/paths';
import
{
onUnexpectedError
}
from
'
vs/base/common/errors
'
;
import
{
IDisposable
,
dispose
,
combinedDisposable
,
empty
as
EmptyDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
Builder
}
from
'
vs/base/browser/builder
'
;
import
{
P
ersistentViewsViewlet
,
CollapsibleView
,
IViewletViewOptions
,
IViewletView
,
IViewOptions
}
from
'
vs/workbench/browser/parts/views/views
'
;
import
{
P
anelViewlet
,
ViewletPanel
}
from
'
vs/workbench/browser/parts/views/views2
'
;
import
{
append
,
$
,
toggleClass
,
trackFocus
}
from
'
vs/base/browser/dom
'
;
import
{
ITelemetryService
}
from
'
vs/platform/telemetry/common/telemetry
'
;
import
{
List
}
from
'
vs/base/browser/ui/list/listWidget
'
;
...
...
@@ -43,9 +43,7 @@ import Severity from 'vs/base/common/severity';
import
{
IExtensionService
}
from
'
vs/platform/extensions/common/extensions
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IStorageService
}
from
'
vs/platform/storage/common/storage
'
;
import
{
ViewLocation
,
ViewsRegistry
,
IViewDescriptor
}
from
'
vs/workbench/browser/parts/views/viewsRegistry
'
;
import
{
IViewletService
}
from
'
vs/workbench/services/viewlet/browser/viewlet
'
;
import
{
ViewSizing
}
from
'
vs/base/browser/ui/splitview/splitview
'
;
import
{
IExtensionsViewlet
,
VIEWLET_ID
as
EXTENSIONS_VIEWLET_ID
}
from
'
vs/workbench/parts/extensions/common/extensions
'
;
import
{
InputBox
}
from
'
vs/base/browser/ui/inputbox/inputBox
'
;
import
*
as
platform
from
'
vs/base/common/platform
'
;
...
...
@@ -86,13 +84,6 @@ interface IViewModel {
toggleRepositoryVisibility
(
repository
:
ISCMRepository
,
visible
:
boolean
);
}
class
ProvidersViewDescriptor
implements
IViewDescriptor
{
readonly
id
=
'
providers
'
;
readonly
name
=
''
;
readonly
location
=
ViewLocation
.
SCM
;
readonly
ctor
=
null
;
}
class
ProvidersListDelegate
implements
IDelegate
<
ISCMRepository
>
{
getHeight
(
element
:
ISCMRepository
):
number
{
...
...
@@ -211,31 +202,19 @@ class ProviderRenderer implements IRenderer<ISCMRepository, RepositoryTemplateDa
}
}
class
Providers
View
extends
CollapsibleView
{
class
Providers
Panel
extends
ViewletPanel
{
private
list
:
List
<
ISCMRepository
>
;
constructor
(
initialSize
:
number
,
protected
viewModel
:
IViewModel
,
options
:
IViewletViewOptions
,
@
IKeybindingService
protected
keybindingService
:
IKeybindingService
,
@
IContextMenuService
protected
contextMenuService
:
IContextMenuService
,
@
ISCMService
protected
scmService
:
ISCMService
,
@
IInstantiationService
private
instantiationService
:
IInstantiationService
)
{
super
(
initialSize
,
{
...(
options
as
IViewOptions
),
sizing
:
ViewSizing
.
Fixed
,
name
:
localize
(
'
scm providers
'
,
"
Source Control Providers
"
),
},
keybindingService
,
contextMenuService
);
}
renderHeader
(
container
:
HTMLElement
):
void
{
const
title
=
append
(
container
,
$
(
'
div.title
'
));
title
.
textContent
=
this
.
name
;
super
.
renderHeader
(
container
);
super
(
localize
(
'
scm providers
'
,
"
Source Control Providers
"
),
{},
keybindingService
,
contextMenuService
);
this
.
updateBodySize
();
}
protected
renderBody
(
container
:
HTMLElement
):
void
{
...
...
@@ -243,35 +222,32 @@ class ProvidersView extends CollapsibleView {
const
renderer
=
this
.
instantiationService
.
createInstance
(
ProviderRenderer
,
this
.
viewModel
);
this
.
list
=
new
List
<
ISCMRepository
>
(
container
,
delegate
,
[
renderer
]);
this
.
scmService
.
onDidAddRepository
(
this
.
onDidAddRepository
,
this
,
this
.
toDispose
);
this
.
scmService
.
onDidRemoveRepository
(
this
.
onDidRemoveRepository
,
this
,
this
.
toDispose
);
this
.
update
List
();
this
.
scmService
.
onDidAddRepository
(
this
.
onDidAddRepository
,
this
,
this
.
disposables
);
this
.
scmService
.
onDidRemoveRepository
(
this
.
onDidRemoveRepository
,
this
,
this
.
disposables
);
this
.
update
();
}
layoutBody
(
size
:
number
):
void
{
if
(
!
this
.
list
)
{
return
;
}
protected
layoutBody
(
size
:
number
):
void
{
this
.
list
.
layout
(
size
);
}
private
updateList
():
void
{
this
.
list
.
splice
(
0
,
this
.
list
.
length
,
this
.
scmService
.
repositories
);
}
private
onDidAddRepository
(
repository
:
ISCMRepository
):
void
{
this
.
updateList
();
this
.
setBodySize
(
this
.
getExpandedBodySize
());
this
.
update
();
}
private
onDidRemoveRepository
(
repository
:
ISCMRepository
):
void
{
this
.
updateList
();
this
.
setBodySize
(
this
.
getExpandedBodySize
());
this
.
update
();
}
private
getExpandedBodySize
():
number
{
return
Math
.
min
(
5
,
this
.
scmService
.
repositories
.
length
)
*
22
;
private
update
():
void
{
this
.
list
.
splice
(
0
,
this
.
list
.
length
,
this
.
scmService
.
repositories
);
this
.
updateBodySize
();
}
private
updateBodySize
():
void
{
const
size
=
Math
.
min
(
5
,
this
.
scmService
.
repositories
.
length
)
*
22
;
this
.
minimumBodySize
=
size
;
this
.
maximumBodySize
=
size
;
}
}
...
...
@@ -420,38 +396,38 @@ class ProviderListDelegate implements IDelegate<ISCMResourceGroup | ISCMResource
}
}
class
ProviderViewDescriptor
implements
IViewDescriptor
{
//
class ProviderViewDescriptor implements IViewDescriptor {
// This ID magic needs to happen in order to preserve
// good splitview state when reloading the workbench
static
idCount
=
0
;
static
freeIds
:
string
[]
=
[];
//
// This ID magic needs to happen in order to preserve
//
// good splitview state when reloading the workbench
//
static idCount = 0;
//
static freeIds: string[] = [];
readonly
id
:
string
;
//
readonly id: string;
get
repository
():
ISCMRepository
{
return
this
.
_repository
;
}
get
name
():
string
{
return
this
.
_repository
.
provider
.
rootUri
?
`
${
basename
(
this
.
_repository
.
provider
.
rootUri
.
fsPath
)}
(
${
this
.
_repository
.
provider
.
label
}
)`
:
this
.
_repository
.
provider
.
label
;
}
get
ctor
():
any
{
return
null
;
}
get
location
():
ViewLocation
{
return
ViewLocation
.
SCM
;
}
//
get repository(): ISCMRepository { return this._repository; }
//
get name(): string {
//
return this._repository.provider.rootUri
//
? `${basename(this._repository.provider.rootUri.fsPath)} (${this._repository.provider.label})`
//
: this._repository.provider.label;
//
}
//
get ctor(): any { return null; }
//
get location(): ViewLocation { return ViewLocation.SCM; }
constructor
(
private
_repository
:
ISCMRepository
)
{
if
(
ProviderViewDescriptor
.
freeIds
.
length
>
0
)
{
this
.
id
=
ProviderViewDescriptor
.
freeIds
.
shift
();
}
else
{
this
.
id
=
`scm
${
ProviderViewDescriptor
.
idCount
++
}
`
;
}
}
//
constructor(private _repository: ISCMRepository) {
//
if (ProviderViewDescriptor.freeIds.length > 0) {
//
this.id = ProviderViewDescriptor.freeIds.shift();
//
} else {
//
this.id = `scm${ProviderViewDescriptor.idCount++}`;
//
}
//
}
dispose
():
void
{
ProviderViewDescriptor
.
freeIds
.
push
(
this
.
id
);
}
}
//
dispose(): void {
//
ProviderViewDescriptor.freeIds.push(this.id);
//
}
//
}
class
Provider
View
extends
CollapsibleView
{
class
Provider
Panel
extends
ViewletPanel
{
private
cachedHeight
:
number
|
undefined
;
private
inputBoxContainer
:
HTMLElement
;
...
...
@@ -459,12 +435,9 @@ class ProviderView extends CollapsibleView {
private
listContainer
:
HTMLElement
;
private
list
:
List
<
ISCMResourceGroup
|
ISCMResource
>
;
private
menus
:
SCMMenus
;
private
disposables
:
IDisposable
[]
=
[];
constructor
(
initialSize
:
number
,
private
repository
:
ISCMRepository
,
options
:
IViewletViewOptions
,
@
IKeybindingService
protected
keybindingService
:
IKeybindingService
,
@
IThemeService
protected
themeService
:
IThemeService
,
@
IContextMenuService
protected
contextMenuService
:
IContextMenuService
,
...
...
@@ -476,13 +449,13 @@ class ProviderView extends CollapsibleView {
@
IEditorGroupService
protected
editorGroupService
:
IEditorGroupService
,
@
IInstantiationService
protected
instantiationService
:
IInstantiationService
)
{
super
(
initialSize
,
{
...(
options
as
IViewOptions
),
sizing
:
ViewSizing
.
Flexible
},
keybindingService
,
contextMenuService
);
super
(
repository
.
provider
.
label
,
{
},
keybindingService
,
contextMenuService
);
this
.
menus
=
instantiationService
.
createInstance
(
SCMMenus
,
repository
.
provider
);
this
.
menus
.
onDidChangeTitle
(
this
.
updateActions
,
this
,
this
.
disposables
);
}
renderHeader
(
container
:
HTMLElement
):
void
{
protected
renderHeaderTitle
(
container
:
HTMLElement
):
void
{
const
header
=
append
(
container
,
$
(
'
.title.scm-provider
'
));
const
name
=
append
(
header
,
$
(
'
.name
'
));
const
title
=
append
(
name
,
$
(
'
span.title
'
));
...
...
@@ -495,11 +468,9 @@ class ProviderView extends CollapsibleView {
title
.
textContent
=
this
.
repository
.
provider
.
label
;
type
.
textContent
=
''
;
}
super
.
renderHeader
(
container
);
}
renderBody
(
container
:
HTMLElement
):
void
{
protected
renderBody
(
container
:
HTMLElement
):
void
{
const
focusTracker
=
trackFocus
(
container
);
this
.
disposables
.
push
(
focusTracker
.
addFocusListener
(()
=>
this
.
repository
.
focus
()));
this
.
disposables
.
push
(
focusTracker
);
...
...
@@ -585,7 +556,9 @@ class ProviderView extends CollapsibleView {
}
focus
():
void
{
if
(
this
.
isExpanded
())
{
super
.
focus
();
if
(
this
.
expanded
)
{
this
.
inputBox
.
focus
();
}
}
...
...
@@ -697,16 +670,19 @@ class InstallAdditionalSCMProvidersAction extends Action {
}
}
export
class
SCMViewlet
extends
P
ersistentViews
Viewlet
{
export
class
SCMViewlet
extends
P
anel
Viewlet
{
private
menus
:
SCMMenus
;
private
repositoryToViewDescriptor
=
new
Map
<
string
,
ProviderViewDescriptor
>
();
private
providersPanel
:
ProvidersPanel
;
// private repositoryToViewDescriptor = new Map<string, ProviderViewDescriptor>();
private
disposables
:
IDisposable
[]
=
[];
constructor
(
@
ITelemetryService
telemetryService
:
ITelemetryService
,
@
ISCMService
protected
scmService
:
ISCMService
,
@
IInstantiationService
instantiationService
:
IInstantiationService
,
@
IInstantiationService
protected
instantiationService
:
IInstantiationService
,
@
IContextViewService
protected
contextViewService
:
IContextViewService
,
@
IContextKeyService
contextKeyService
:
IContextKeyService
,
@
IKeybindingService
protected
keybindingService
:
IKeybindingService
,
...
...
@@ -721,67 +697,56 @@ export class SCMViewlet extends PersistentViewsViewlet {
@
IStorageService
storageService
:
IStorageService
,
@
IExtensionService
extensionService
:
IExtensionService
)
{
super
(
VIEWLET_ID
,
ViewLocation
.
SCM
,
'
scm
'
,
false
,
telemetryService
,
storageService
,
instantiationService
,
themeService
,
contextService
,
contextKeyService
,
contextMenuService
,
extensionService
);
super
(
VIEWLET_ID
,
{
showHeaderInTitleWhenSingleView
:
false
},
telemetryService
,
themeService
);
this
.
menus
=
instantiationService
.
createInstance
(
SCMMenus
,
undefined
);
this
.
menus
.
onDidChangeTitle
(
this
.
updateTitleArea
,
this
,
this
.
disposables
);
}
private
onDidAddRepository
(
repository
:
ISCMRepository
):
void
{
const
viewDescriptor
=
new
ProviderViewDescriptor
(
repository
);
this
.
repositoryToViewDescriptor
.
set
(
repository
.
provider
.
id
,
viewDescriptor
);
async
create
(
parent
:
Builder
):
TPromise
<
void
>
{
await
super
.
create
(
parent
);
ViewsRegistry
.
registerViews
([
viewDescriptor
]);
toggleClass
(
this
.
getContainer
().
getHTMLElement
(),
'
empty
'
,
this
.
views
.
length
===
0
);
this
.
updateTitleArea
();
}
parent
.
addClass
(
'
scm-viewlet
'
/* , 'empty' */
);
// append(parent.getHTMLElement(), $('div.empty-message', null, localize('no open repo', "There are no source control providers active.")));
private
onDidRemoveRepository
(
repository
:
ISCMRepository
):
void
{
const
viewDescriptor
=
this
.
repositoryToViewDescriptor
.
get
(
repository
.
provider
.
id
);
this
.
repositoryToViewDescriptor
.
delete
(
repository
.
provider
.
id
);
viewDescriptor
.
dispose
();
this
.
providersPanel
=
this
.
instantiationService
.
createInstance
(
ProvidersPanel
,
this
);
this
.
addPanel
(
this
.
providersPanel
,
this
.
providersPanel
.
minimumSize
);
// this.scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables);
// this.scmService.onDidRemoveRepository(this.onDidRemoveRepository, this, this.disposables);
// this.scmService.repositories.forEach(p => this.onDidAddRepository(p));
ViewsRegistry
.
deregisterViews
([
viewDescriptor
.
id
],
ViewLocation
.
SCM
);
toggleClass
(
this
.
getContainer
().
getHTMLElement
(),
'
empty
'
,
this
.
views
.
length
===
0
);
this
.
updateTitleArea
();
// ViewsRegistry.registerViews([new ProvidersViewDescriptor()]);
}
async
create
(
parent
:
Builder
):
TPromise
<
void
>
{
await
super
.
create
(
parent
);
// private onDidAddRepository(repository: ISCMRepository): void {
// const viewDescriptor = new ProviderViewDescriptor(repository);
// this.repositoryToViewDescriptor.set(repository.provider.id, viewDescriptor);
parent
.
addClass
(
'
scm-viewlet
'
,
'
empty
'
);
append
(
parent
.
getHTMLElement
(),
$
(
'
div.empty-message
'
,
null
,
localize
(
'
no open repo
'
,
"
There are no source control providers active.
"
)));
// ViewsRegistry.registerViews([viewDescriptor]);
// toggleClass(this.getContainer().getHTMLElement(), 'empty', this.views.length === 0);
// this.updateTitleArea();
// }
this
.
scmService
.
onDidAddRepository
(
this
.
onDidAddRepository
,
this
,
this
.
disposables
);
this
.
scmService
.
onDidRemoveRepository
(
this
.
onDidRemoveRepository
,
this
,
this
.
disposables
);
this
.
scmService
.
repositories
.
forEach
(
p
=>
this
.
onDidAddRepository
(
p
));
// private onDidRemoveRepository(repository: ISCMRepository): void {
// const viewDescriptor = this.repositoryToViewDescriptor.get(repository.provider.id);
// this.repositoryToViewDescriptor.delete(repository.provider.id);
// viewDescriptor.dispose();
ViewsRegistry
.
registerViews
([
new
ProvidersViewDescriptor
()]);
}
// ViewsRegistry.deregisterViews([viewDescriptor.id], ViewLocation.SCM);
// toggleClass(this.getContainer().getHTMLElement(), 'empty', this.views.length === 0);
// this.updateTitleArea();
// }
isRepositoryVisible
(
repository
:
ISCMRepository
):
boolean
{
const
view
=
this
.
repositoryToViewDescriptor
.
get
(
repository
.
provider
.
id
);
return
!!
this
.
getView
(
view
.
id
);
// const view = this.repositoryToViewDescriptor.get(repository.provider.id);
// return !!this.getView(view.id);
return
true
;
}
toggleRepositoryVisibility
(
repository
:
ISCMRepository
,
visible
:
boolean
):
void
{
const
view
=
this
.
repositoryToViewDescriptor
.
get
(
repository
.
provider
.
id
);
this
.
toggleViewVisibility
(
view
.
id
,
visible
);
}
protected
createView
(
viewDescriptor
:
IViewDescriptor
,
initialSize
:
number
,
options
:
IViewletViewOptions
):
IViewletView
{
if
(
viewDescriptor
instanceof
ProviderViewDescriptor
)
{
return
this
.
instantiationService
.
createInstance
(
ProviderView
,
initialSize
,
viewDescriptor
.
repository
,
options
);
}
else
if
(
viewDescriptor
instanceof
ProvidersViewDescriptor
)
{
return
this
.
instantiationService
.
createInstance
(
ProvidersView
,
initialSize
,
this
,
options
);
}
return
this
.
instantiationService
.
createInstance
(
viewDescriptor
.
ctor
,
initialSize
,
options
);
}
protected
getDefaultViewSize
():
number
|
undefined
{
return
this
.
dimension
&&
this
.
dimension
.
height
/
Math
.
max
(
this
.
views
.
length
,
1
);
// const view = this.repositoryToViewDescriptor.get(repository.provider.id);
// this.toggleViewVisibility(view.id, visible);
}
getOptimalWidth
():
number
{
...
...
@@ -790,20 +755,20 @@ export class SCMViewlet extends PersistentViewsViewlet {
getTitle
():
string
{
const
title
=
localize
(
'
source control
'
,
"
Source Control
"
);
const
views
=
ViewsRegistry
.
getViews
(
ViewLocation
.
SCM
);
//
const views = ViewsRegistry.getViews(ViewLocation.SCM);
if
(
views
.
length
===
1
)
{
const
view
=
views
[
0
];
return
localize
(
'
viewletTitle
'
,
"
{0}: {1}
"
,
title
,
view
.
name
);
}
else
{
return
title
;
}
//
if (views.length === 1) {
//
const view = views[0];
//
return localize('viewletTitle', "{0}: {1}", title, view.name);
//
} else {
return
title
;
//
}
}
getActions
():
IAction
[]
{
if
(
this
.
showHeaderInTitleArea
()
&&
this
.
views
.
length
===
1
)
{
return
this
.
views
[
0
].
getActions
();
}
// if (this.isSingleView
) {
//
return this.views[0].getActions();
//
}
return
this
.
menus
.
getTitleActions
();
}
...
...
@@ -811,18 +776,18 @@ export class SCMViewlet extends PersistentViewsViewlet {
getSecondaryActions
():
IAction
[]
{
let
result
:
IAction
[];
if
(
this
.
showHeaderInTitleArea
()
&&
this
.
views
.
length
===
1
)
{
result
=
[
...
this
.
views
[
0
].
getSecondaryActions
(),
new
Separator
()
];
}
else
{
result
=
this
.
menus
.
getTitleSecondaryActions
();
// if (this.isSingleView
) {
//
result = [
//
...this.views[0].getSecondaryActions(),
//
new Separator()
//
];
//
} else {
result
=
this
.
menus
.
getTitleSecondaryActions
();
if
(
result
.
length
>
0
)
{
result
.
push
(
new
Separator
());
}
if
(
result
.
length
>
0
)
{
result
.
push
(
new
Separator
());
}
// }
result
.
push
(
this
.
instantiationService
.
createInstance
(
InstallAdditionalSCMProvidersAction
));
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录