mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 13:29:44 +00:00
scm viewlet inline actions
This commit is contained in:
parent
7f8d9c9bed
commit
ceafebde3e
|
@ -38,22 +38,38 @@
|
|||
{
|
||||
"command": "git.stage",
|
||||
"title": "Stage",
|
||||
"category": "Git"
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/stage.svg",
|
||||
"dark": "resources/icons/dark/stage.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.stage-all",
|
||||
"title": "Stage All",
|
||||
"category": "Git"
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/stage.svg",
|
||||
"dark": "resources/icons/dark/stage.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.unstage",
|
||||
"title": "Unstage",
|
||||
"category": "Git"
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/unstage.svg",
|
||||
"dark": "resources/icons/dark/unstage.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "git.unstage-all",
|
||||
"title": "Unstage All",
|
||||
"category": "Git"
|
||||
"category": "Git",
|
||||
"icon": {
|
||||
"light": "resources/icons/light/unstage.svg",
|
||||
"dark": "resources/icons/dark/unstage.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
|
@ -63,24 +79,48 @@
|
|||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"scm/git/index/group": [
|
||||
{
|
||||
"command": "git.unstage-all",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"scm/git/index/group/context": [
|
||||
{
|
||||
"command": "git.unstage-all",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"scm/git/index/resource": [
|
||||
{
|
||||
"command": "git.unstage",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"scm/git/index/resource/context": [
|
||||
{
|
||||
"command": "git.unstage",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"scm/git/workingTree/group": [
|
||||
{
|
||||
"command": "git.stage-all",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"scm/git/workingTree/group/context": [
|
||||
{
|
||||
"command": "git.stage-all",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"scm/git/workingTree/resource": [
|
||||
{
|
||||
"command": "git.stage",
|
||||
"group": "navigation"
|
||||
}
|
||||
],
|
||||
"scm/git/workingTree/resource/context": [
|
||||
{
|
||||
"command": "git.stage",
|
||||
|
|
1
extensions/git/resources/icons/dark/stage.svg
Normal file
1
extensions/git/resources/icons/dark/stage.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#C5C5C5"/><rect height="3" width="11" y="7" x="3" fill="#C5C5C5"/></svg>
|
After Width: | Height: | Size: 203 B |
1
extensions/git/resources/icons/dark/unstage.svg
Normal file
1
extensions/git/resources/icons/dark/unstage.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="3" width="11" y="7" x="3" fill="#C5C5C5"/></svg>
|
After Width: | Height: | Size: 147 B |
1
extensions/git/resources/icons/light/stage.svg
Normal file
1
extensions/git/resources/icons/light/stage.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="11" width="3" y="3" x="7" fill="#424242"/><rect height="3" width="11" y="7" x="3" fill="#424242"/></svg>
|
After Width: | Height: | Size: 203 B |
1
extensions/git/resources/icons/light/unstage.svg
Normal file
1
extensions/git/resources/icons/light/unstage.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><title>Layer 1</title><rect height="3" width="11" y="7" x="3" fill="#424242"/></svg>
|
After Width: | Height: | Size: 147 B |
|
@ -5,7 +5,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import { commands, Disposable } from 'vscode';
|
||||
import { commands, Disposable, SCMResourceGroup, SCMResource } from 'vscode';
|
||||
import { Model } from './model';
|
||||
import { log } from './util';
|
||||
|
||||
|
@ -20,9 +20,29 @@ function openChange(...args: any[]): void {
|
|||
console.log('openChange', args);
|
||||
}
|
||||
|
||||
function stage(resource: SCMResource): void {
|
||||
log('stage', resource);
|
||||
}
|
||||
|
||||
function stageAll(resourceGroup: SCMResourceGroup): void {
|
||||
log('stage-all', resourceGroup);
|
||||
}
|
||||
|
||||
function unstage(resource: SCMResource): void {
|
||||
log('unstage', resource);
|
||||
}
|
||||
|
||||
function unstageAll(resourceGroup: SCMResourceGroup): void {
|
||||
log('unstage-all', resourceGroup);
|
||||
}
|
||||
|
||||
export function registerCommands(model: Model): Disposable {
|
||||
const disposables = [
|
||||
commands.registerCommand('git.refresh', refresh(model)),
|
||||
commands.registerCommand('git.stage', stage),
|
||||
commands.registerCommand('git.stage-all', stageAll),
|
||||
commands.registerCommand('git.unstage', unstage),
|
||||
commands.registerCommand('git.unstage-all', unstageAll),
|
||||
commands.registerCommand('git.open-change', openChange)
|
||||
];
|
||||
|
||||
|
|
|
@ -29,12 +29,41 @@
|
|||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.scm-viewlet .monaco-list-row > .resource-group > .count-badge {
|
||||
.scm-viewlet .monaco-list-row > .resource-group:hover > .count {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scm-viewlet .monaco-list-row > .resource-group:not(:hover) > .actions {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.scm-viewlet .monaco-list-row > .resource {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.scm-viewlet .monaco-list-row > .resource > .name {
|
||||
flex: 1;
|
||||
font-size: 11px;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
cursor: default;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scm-viewlet .monaco-list-row > .resource > .name > .monaco-icon-label {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.scm-viewlet .monaco-list-row > .resource > .actions .action-label,
|
||||
.scm-viewlet .monaco-list-row > .resource-group > .actions .action-label {
|
||||
width: 16px;
|
||||
height: 100%;
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.scm-viewlet .monaco-list-row > .resource:not(:hover) > .actions {
|
||||
display: none;
|
||||
}
|
|
@ -63,23 +63,39 @@ export class SCMMenus implements IDisposable {
|
|||
return this.titleSecondaryActions;
|
||||
}
|
||||
|
||||
getResourceGroupActions(providerId: string, resourceGroupId: string): IAction[] {
|
||||
const menuId = new SCMMenuId(providerId, resourceGroupId, SCMMenuType.ResourceGroup, false);
|
||||
getResourceGroupActions(resourceGroupId: string): IAction[] {
|
||||
if (!this.scmService.activeProvider) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const menuId = new SCMMenuId(this.scmService.activeProvider.id, resourceGroupId, SCMMenuType.ResourceGroup, false);
|
||||
return this.getActions(menuId);
|
||||
}
|
||||
|
||||
getResourceGroupContextActions(providerId: string, resourceGroupId: string): IAction[] {
|
||||
const menuId = new SCMMenuId(providerId, resourceGroupId, SCMMenuType.ResourceGroup, true);
|
||||
getResourceGroupContextActions(resourceGroupId: string): IAction[] {
|
||||
if (!this.scmService.activeProvider) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const menuId = new SCMMenuId(this.scmService.activeProvider.id, resourceGroupId, SCMMenuType.ResourceGroup, true);
|
||||
return this.getActions(menuId);
|
||||
}
|
||||
|
||||
getResourceActions(providerId: string, resourceGroupId: string): IAction[] {
|
||||
const menuId = new SCMMenuId(providerId, resourceGroupId, SCMMenuType.Resource, false);
|
||||
getResourceActions(resourceGroupId: string): IAction[] {
|
||||
if (!this.scmService.activeProvider) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const menuId = new SCMMenuId(this.scmService.activeProvider.id, resourceGroupId, SCMMenuType.Resource, false);
|
||||
return this.getActions(menuId);
|
||||
}
|
||||
|
||||
getResourceContextActions(providerId: string, resourceGroupId: string): IAction[] {
|
||||
const menuId = new SCMMenuId(providerId, resourceGroupId, SCMMenuType.Resource, true);
|
||||
getResourceContextActions(resourceGroupId: string): IAction[] {
|
||||
if (!this.scmService.activeProvider) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const menuId = new SCMMenuId(this.scmService.activeProvider.id, resourceGroupId, SCMMenuType.Resource, true);
|
||||
return this.getActions(menuId);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ import { IMenuService } from 'vs/platform/actions/common/actions';
|
|||
import { IAction, IActionItem } from 'vs/base/common/actions';
|
||||
import { createActionItem } from 'vs/platform/actions/browser/menuItemActionItem';
|
||||
import { SCMMenus } from './scmMenus';
|
||||
import { ActionBar, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
|
||||
interface SearchInputEvent extends Event {
|
||||
target: HTMLInputElement;
|
||||
|
@ -43,6 +44,7 @@ interface SearchInputEvent extends Event {
|
|||
interface ResourceGroupTemplate {
|
||||
name: HTMLElement;
|
||||
count: CountBadge;
|
||||
actionBar: ActionBar;
|
||||
}
|
||||
|
||||
class ResourceGroupRenderer implements IRenderer<ISCMResourceGroup, ResourceGroupTemplate> {
|
||||
|
@ -50,18 +52,27 @@ class ResourceGroupRenderer implements IRenderer<ISCMResourceGroup, ResourceGrou
|
|||
static TEMPLATE_ID = 'resource group';
|
||||
get templateId(): string { return ResourceGroupRenderer.TEMPLATE_ID; }
|
||||
|
||||
constructor(
|
||||
private scmMenus: SCMMenus,
|
||||
private actionItemProvider: IActionItemProvider
|
||||
) { }
|
||||
|
||||
renderTemplate(container: HTMLElement): ResourceGroupTemplate {
|
||||
const element = append(container, $('.resource-group'));
|
||||
const name = append(element, $('.name'));
|
||||
const countContainer = append(element, $('div'));
|
||||
const countContainer = append(element, $('.count'));
|
||||
const count = new CountBadge(countContainer);
|
||||
const actionsContainer = append(element, $('.actions'));
|
||||
const actionBar = new ActionBar(actionsContainer, { actionItemProvider: this.actionItemProvider });
|
||||
|
||||
return { name, count };
|
||||
return { name, count, actionBar };
|
||||
}
|
||||
|
||||
renderElement(group: ISCMResourceGroup, index: number, template: ResourceGroupTemplate): void {
|
||||
template.name.textContent = group.label;
|
||||
template.count.setCount(group.resources.length);
|
||||
template.actionBar.clear();
|
||||
template.actionBar.push(this.scmMenus.getResourceGroupActions(group.id));
|
||||
}
|
||||
|
||||
disposeTemplate(template: ResourceGroupTemplate): void {
|
||||
|
@ -71,6 +82,7 @@ class ResourceGroupRenderer implements IRenderer<ISCMResourceGroup, ResourceGrou
|
|||
|
||||
interface ResourceTemplate {
|
||||
fileLabel: FileLabel;
|
||||
actionBar: ActionBar;
|
||||
}
|
||||
|
||||
class ResourceRenderer implements IRenderer<ISCMResource, ResourceTemplate> {
|
||||
|
@ -79,19 +91,27 @@ class ResourceRenderer implements IRenderer<ISCMResource, ResourceTemplate> {
|
|||
get templateId(): string { return ResourceRenderer.TEMPLATE_ID; }
|
||||
|
||||
constructor(
|
||||
private scmMenus: SCMMenus,
|
||||
private actionItemProvider: IActionItemProvider,
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
renderTemplate(container: HTMLElement): ResourceTemplate {
|
||||
const fileLabel = this.instantiationService.createInstance(FileLabel, container, void 0);
|
||||
const element = append(container, $('.resource'));
|
||||
const name = append(element, $('.name'));
|
||||
const fileLabel = this.instantiationService.createInstance(FileLabel, name, void 0);
|
||||
const actionsContainer = append(element, $('.actions'));
|
||||
const actionBar = new ActionBar(actionsContainer, { actionItemProvider: this.actionItemProvider });
|
||||
|
||||
return { fileLabel };
|
||||
return { fileLabel, actionBar };
|
||||
}
|
||||
|
||||
renderElement(resource: ISCMResource, index: number, template: ResourceTemplate): void {
|
||||
template.fileLabel.setFile(resource.uri);
|
||||
template.actionBar.clear();
|
||||
template.actionBar.push(this.scmMenus.getResourceActions(resource.resourceGroupId));
|
||||
}
|
||||
|
||||
disposeTemplate(template: ResourceTemplate): void {
|
||||
|
@ -176,9 +196,11 @@ export class SCMViewlet extends Viewlet {
|
|||
this.listContainer = append(root, $('.scm-status.show-file-icons'));
|
||||
const delegate = new Delegate();
|
||||
|
||||
const actionItemProvider = action => this.getActionItem(action);
|
||||
|
||||
this.list = new List(this.listContainer, delegate, [
|
||||
new ResourceGroupRenderer(),
|
||||
this.instantiationService.createInstance(ResourceRenderer)
|
||||
new ResourceGroupRenderer(this.menus, actionItemProvider),
|
||||
this.instantiationService.createInstance(ResourceRenderer, this.menus, actionItemProvider)
|
||||
]);
|
||||
|
||||
chain(this.list.onSelectionChange)
|
||||
|
@ -254,21 +276,15 @@ export class SCMViewlet extends Viewlet {
|
|||
}
|
||||
|
||||
private onListContextMenu(e: IListMouseEvent<ISCMResourceGroup | ISCMResource>): void {
|
||||
const provider = this.scmService.activeProvider;
|
||||
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
const element = e.element;
|
||||
let actions: IAction[];
|
||||
|
||||
if ((element as ISCMResource).uri) {
|
||||
const resource = element as ISCMResource;
|
||||
actions = this.menus.getResourceContextActions(provider.id, resource.resourceGroupId);
|
||||
actions = this.menus.getResourceContextActions(resource.resourceGroupId);
|
||||
} else {
|
||||
const resourceGroup = element as ISCMResourceGroup;
|
||||
actions = this.menus.getResourceGroupContextActions(provider.id, resourceGroup.id);
|
||||
actions = this.menus.getResourceGroupContextActions(resourceGroup.id);
|
||||
}
|
||||
|
||||
this.contextMenuService.showContextMenu({
|
||||
|
|
Loading…
Reference in a new issue