提交 1948bdbf 编写于 作者: B Benjamin Pasero

notifications - add configure dropdown

上级 5196bcb6
......@@ -29,8 +29,4 @@
.dropdown > .dropdown-action, .dropdown > .dropdown-action > .action-label {
display: inline-block;
}
.dropdown > .dropdown-label:not(:empty) {
padding: 0 .5em;
}
\ No newline at end of file
......@@ -9,8 +9,8 @@ import 'vs/css!./dropdown';
import { Builder, $ } from 'vs/base/browser/builder';
import { TPromise } from 'vs/base/common/winjs.base';
import { Gesture, EventType as GestureEventType } from 'vs/base/browser/touch';
import { ActionRunner, IAction } from 'vs/base/common/actions';
import { IActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { ActionRunner, IAction, IActionRunner } from 'vs/base/common/actions';
import { IActionItem, BaseActionItem, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IContextViewProvider } from 'vs/base/browser/ui/contextview/contextview';
import { IMenuOptions } from 'vs/base/browser/ui/menu/menu';
......@@ -242,4 +242,83 @@ export class DropdownMenu extends BaseDropdown {
public hide(): void {
// noop
}
}
export class DropdownMenuActionItem extends BaseActionItem {
private menuActionsOrProvider: any;
private dropdownMenu: DropdownMenu;
private contextMenuProvider: IContextMenuProvider;
private actionItemProvider: IActionItemProvider;
private keybindings: (action: IAction) => ResolvedKeybinding;
private clazz: string;
constructor(action: IAction, menuActions: IAction[], contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, keybindings: (action: IAction) => ResolvedKeybinding, clazz: string);
constructor(action: IAction, actionProvider: IActionProvider, contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, keybindings: (action: IAction) => ResolvedKeybinding, clazz: string);
constructor(action: IAction, menuActionsOrProvider: any, contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, keybindings: (action: IAction) => ResolvedKeybinding, clazz: string) {
super(null, action);
this.menuActionsOrProvider = menuActionsOrProvider;
this.contextMenuProvider = contextMenuProvider;
this.actionItemProvider = actionItemProvider;
this.actionRunner = actionRunner;
this.keybindings = keybindings;
this.clazz = clazz;
}
public render(container: HTMLElement): void {
let labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable => {
this.builder = $('a.action-label').attr({
tabIndex: '0',
role: 'button',
'aria-haspopup': 'true',
title: this._action.label || '',
class: this.clazz
});
this.builder.appendTo(el);
return null;
};
let options: IDropdownMenuOptions = {
contextMenuProvider: this.contextMenuProvider,
labelRenderer: labelRenderer
};
// Render the DropdownMenu around a simple action to toggle it
if (Array.isArray(this.menuActionsOrProvider)) {
options.actions = this.menuActionsOrProvider;
} else {
options.actionProvider = this.menuActionsOrProvider;
}
this.dropdownMenu = new DropdownMenu(container, options);
this.dropdownMenu.menuOptions = {
actionItemProvider: this.actionItemProvider,
actionRunner: this.actionRunner,
getKeyBinding: this.keybindings,
context: this._context
};
}
public setActionContext(newContext: any): void {
super.setActionContext(newContext);
if (this.dropdownMenu) {
this.dropdownMenu.menuOptions.context = newContext;
}
}
public show(): void {
if (this.dropdownMenu) {
this.dropdownMenu.show();
}
}
public dispose(): void {
this.dropdownMenu.dispose();
super.dispose();
}
}
\ No newline at end of file
......@@ -3,10 +3,6 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-toolbar .dropdown > .dropdown-label:not(:empty) {
padding: 0;
}
.monaco-toolbar .toolbar-toggle-more {
display: inline-block;
padding: 0;
......
......@@ -8,12 +8,10 @@
import 'vs/css!./toolbar';
import nls = require('vs/nls');
import { TPromise } from 'vs/base/common/winjs.base';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Builder, $ } from 'vs/base/browser/builder';
import types = require('vs/base/common/types');
import { Action, IActionRunner, IAction } from 'vs/base/common/actions';
import { ActionBar, ActionsOrientation, IActionItemProvider, BaseActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextMenuProvider, DropdownMenu, IActionProvider, ILabelRenderer, IDropdownMenuOptions } from 'vs/base/browser/ui/dropdown/dropdown';
import { ActionBar, ActionsOrientation, IActionItemProvider } from 'vs/base/browser/ui/actionbar/actionbar';
import { IContextMenuProvider, DropdownMenuActionItem } from 'vs/base/browser/ui/dropdown/dropdown';
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
export const CONTEXT = 'context.toolbar';
......@@ -181,83 +179,4 @@ class ToggleMenuAction extends Action {
public set menuActions(actions: IAction[]) {
this._menuActions = actions;
}
}
export class DropdownMenuActionItem extends BaseActionItem {
private menuActionsOrProvider: any;
private dropdownMenu: DropdownMenu;
private contextMenuProvider: IContextMenuProvider;
private actionItemProvider: IActionItemProvider;
private keybindings: (action: IAction) => ResolvedKeybinding;
private clazz: string;
constructor(action: IAction, menuActions: IAction[], contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, keybindings: (action: IAction) => ResolvedKeybinding, clazz: string);
constructor(action: IAction, actionProvider: IActionProvider, contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, keybindings: (action: IAction) => ResolvedKeybinding, clazz: string);
constructor(action: IAction, menuActionsOrProvider: any, contextMenuProvider: IContextMenuProvider, actionItemProvider: IActionItemProvider, actionRunner: IActionRunner, keybindings: (action: IAction) => ResolvedKeybinding, clazz: string) {
super(null, action);
this.menuActionsOrProvider = menuActionsOrProvider;
this.contextMenuProvider = contextMenuProvider;
this.actionItemProvider = actionItemProvider;
this.actionRunner = actionRunner;
this.keybindings = keybindings;
this.clazz = clazz;
}
public render(container: HTMLElement): void {
let labelRenderer: ILabelRenderer = (el: HTMLElement): IDisposable => {
this.builder = $('a.action-label').attr({
tabIndex: '0',
role: 'button',
'aria-haspopup': 'true',
title: this._action.label || '',
class: this.clazz
});
this.builder.appendTo(el);
return null;
};
let options: IDropdownMenuOptions = {
contextMenuProvider: this.contextMenuProvider,
labelRenderer: labelRenderer
};
// Render the DropdownMenu around a simple action to toggle it
if (types.isArray(this.menuActionsOrProvider)) {
options.actions = this.menuActionsOrProvider;
} else {
options.actionProvider = this.menuActionsOrProvider;
}
this.dropdownMenu = new DropdownMenu(container, options);
this.dropdownMenu.menuOptions = {
actionItemProvider: this.actionItemProvider,
actionRunner: this.actionRunner,
getKeyBinding: this.keybindings,
context: this._context
};
}
public setActionContext(newContext: any): void {
super.setActionContext(newContext);
if (this.dropdownMenu) {
this.dropdownMenu.menuOptions.context = newContext;
}
}
public show(): void {
if (this.dropdownMenu) {
this.dropdownMenu.show();
}
}
public dispose(): void {
this.dropdownMenu.dispose();
super.dispose();
}
}
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#C5C5C5"><path d="M12.714 9.603c-.07.207-.15.407-.246.601l1.017 2.139c-.335.424-.718.807-1.142 1.143l-2.14-1.018c-.193.097-.394.176-.601.247l-.795 2.235c-.265.03-.534.05-.807.05-.272 0-.541-.02-.806-.05l-.795-2.235c-.207-.071-.408-.15-.602-.247l-2.14 1.017c-.424-.336-.807-.719-1.143-1.143l1.017-2.139c-.094-.193-.175-.393-.245-.6l-2.236-.796c-.03-.265-.05-.534-.05-.807s.02-.542.05-.807l2.236-.795c.07-.207.15-.407.246-.601l-1.016-2.139c.336-.423.719-.807 1.143-1.142l2.14 1.017c.193-.096.394-.176.602-.247l.793-2.236c.265-.03.534-.05.806-.05.273 0 .542.02.808.05l.795 2.236c.207.07.407.15.601.246l2.14-1.017c.424.335.807.719 1.142 1.142l-1.017 2.139c.096.194.176.394.246.601l2.236.795c.029.266.049.535.049.808s-.02.542-.05.807l-2.236.796zm-4.714-4.603c-1.657 0-3 1.343-3 3s1.343 3 3 3 3-1.343 3-3-1.343-3-3-3z"/><circle cx="8" cy="8" r="1.5"/></g></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><g fill="#424242"><path d="M12.714 9.603c-.07.207-.15.407-.246.601l1.017 2.139c-.335.424-.718.807-1.142 1.143l-2.14-1.018c-.193.097-.394.176-.601.247l-.795 2.235c-.265.03-.534.05-.807.05-.272 0-.541-.02-.806-.05l-.795-2.235c-.207-.071-.408-.15-.602-.247l-2.14 1.017c-.424-.336-.807-.719-1.143-1.143l1.017-2.139c-.094-.193-.175-.393-.245-.6l-2.236-.796c-.03-.265-.05-.534-.05-.807s.02-.542.05-.807l2.236-.795c.07-.207.15-.407.246-.601l-1.016-2.139c.336-.423.719-.807 1.143-1.142l2.14 1.017c.193-.096.394-.176.602-.247l.793-2.236c.265-.03.534-.05.806-.05.273 0 .542.02.808.05l.795 2.236c.207.07.407.15.601.246l2.14-1.017c.424.335.807.719 1.142 1.142l-1.017 2.139c.096.194.176.394.246.601l2.236.795c.029.266.049.535.049.808s-.02.542-.05.807l-2.236.796zm-4.714-4.603c-1.657 0-3 1.343-3 3s1.343 3 3 3 3-1.343 3-3-1.343-3-3-3z"/><circle cx="8" cy="8" r="1.5"/></g></svg>
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action {
background-image: url('close.svg');
}
.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action,
.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action {
background-image: url('close-inverse.svg');
}
.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action {
background-image: url('down.svg');
}
.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action,
.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action {
background-image: url('down-inverse.svg');
}
.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action {
background-image: url('up.svg');
}
.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action,
.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action {
background-image: url('up-inverse.svg');
}
.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action {
background-image: url('configure.svg');
}
.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action,
.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .configure-notification-action {
background-image: url('configure-inverse.svg');
}
\ No newline at end of file
......@@ -109,6 +109,7 @@
.monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .action-label {
flex: 0 0 16px;
display: block;
width: 16px;
height: 22px;
margin-right: 4px;
......@@ -117,33 +118,6 @@
background-repeat: no-repeat;
}
.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action {
background-image: url('close.svg');
}
.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action,
.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .close-notification-action {
background-image: url('close-inverse.svg');
}
.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action {
background-image: url('down.svg');
}
.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action,
.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .expand-notification-action {
background-image: url('down-inverse.svg');
}
.vs .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action {
background-image: url('up.svg');
}
.vs-dark .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action,
.hc-black .monaco-workbench > .notifications-list-container .notification-list-item .notification-list-item-toolbar-container .collapse-notification-action {
background-image: url('up-inverse.svg');
}
/** Notification: Details Row */
.monaco-workbench > .notifications-list-container .notification-list-item > .notification-list-item-details-row {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./media/notificationActions';
import { INotificationViewItem } from 'vs/workbench/services/notification/common/notificationsModel';
import { localize } from 'vs/nls';
import { Action, ActionRunner, IAction } from 'vs/base/common/actions';
import { TPromise } from 'vs/base/common/winjs.base';
export class CloseNotificationAction extends Action {
public static readonly ID = 'workbench.action.closeNotification';
public static readonly LABEL = localize('closeNotification', "Close Notification");
constructor(
id: string,
label: string
) {
super(id, label, 'close-notification-action');
}
public run(context: INotificationViewItem): TPromise<any> {
return TPromise.as(void 0); // TODO@notification
}
}
export class ExpandNotificationAction extends Action {
public static readonly ID = 'workbench.action.expandNotification';
public static readonly LABEL = localize('expandNotification', "Expand Notification");
constructor(
id: string,
label: string
) {
super(id, label, 'expand-notification-action');
}
public run(context: INotificationViewItem): TPromise<any> {
context.expand();
return TPromise.as(void 0); // TODO@notification
}
}
export class CollapseNotificationAction extends Action {
public static readonly ID = 'workbench.action.collapseNotification';
public static readonly LABEL = localize('collapseNotification', "Collapse Notification");
constructor(
id: string,
label: string
) {
super(id, label, 'collapse-notification-action');
}
public run(context: INotificationViewItem): TPromise<any> {
context.collapse();
return TPromise.as(void 0); // TODO@notification
}
}
export class ConfigureNotificationAction extends Action {
public static readonly ID = 'workbench.action.configureNotification';
public static readonly LABEL = localize('configureNotification', "Configure Notification");
constructor(
id: string,
label: string,
private _configurationActions: IAction[]
) {
super(id, label, 'configure-notification-action');
}
public get configurationActions(): IAction[] {
return this._configurationActions;
}
}
export class DoNotShowNotificationAgainAction extends Action {
public static readonly ID = 'workbench.action.doNotShowNotificationAgain';
public static readonly LABEL = localize('dontShowNotificationAgain', "Don't Show Again");
constructor(
id: string,
label: string,
notification: INotificationViewItem
) {
super(id, label);
}
public run(): TPromise<any> {
return TPromise.as(void 0); // TODO@notification
}
}
export class NotificationActionRunner extends ActionRunner {
constructor(private context: INotificationViewItem) {
super();
}
public run(action: IAction, context?: any): TPromise<void> {
return super.run(action, this.context);
}
}
\ No newline at end of file
......@@ -20,10 +20,12 @@ import { attachButtonStyler } from 'vs/platform/theme/common/styler';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IMarkdownString } from 'vs/base/common/htmlContent';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action, ActionRunner, IAction } from 'vs/base/common/actions';
import { TPromise } from 'vs/base/common/winjs.base';
import { IAction } from 'vs/base/common/actions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { CloseNotificationAction, ExpandNotificationAction, ConfigureNotificationAction, CollapseNotificationAction, NotificationActionRunner, DoNotShowNotificationAgainAction } from 'vs/workbench/services/notification/browser/notificationActions';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { DropdownMenuActionItem } from 'vs/base/browser/ui/dropdown/dropdown';
export class NotificationsListDelegate implements IDelegate<INotificationViewItem> {
......@@ -66,8 +68,8 @@ export class NotificationsListDelegate implements IDelegate<INotificationViewIte
expandedHeight += overflow;
}
// Add some padding to separate from actions if any
if (messageOverflows && element.actions.length > 0) {
// Add some padding to separate from details row
if (messageOverflows) {
expandedHeight += NotificationsListDelegate.LINE_HEIGHT;
}
......@@ -87,7 +89,7 @@ export class NotificationsListDelegate implements IDelegate<INotificationViewIte
const messageWidth = Math.max(renderedMessage.scrollWidth, renderedMessage.offsetWidth);
// One row per exceeding the total width of the container
const availableWidth = this.offsetHelper.offsetWidth - (20 /* paddings */ + 22 /* severity */ + 48 /* toolbar */);
const availableWidth = this.offsetHelper.offsetWidth - (20 /* paddings */ + 22 /* severity */ + (24 * 3) /* toolbar */);
const preferredRows = Math.ceil(messageWidth / availableWidth);
// Always clear offset helper after use
......@@ -137,72 +139,6 @@ class NotificationMarkdownRenderer {
}
}
class CloseNotificationAction extends Action {
public static readonly ID = 'workbench.action.closeNotification';
public static readonly LABEL = localize('closeNotification', "Close Notification");
constructor(
id: string,
label: string
) {
super(id, label, 'close-notification-action');
}
public run(context: INotificationViewItem): TPromise<any> {
return TPromise.as(void 0); // TODO@notification
}
}
class ExpandNotificationAction extends Action {
public static readonly ID = 'workbench.action.expandNotification';
public static readonly LABEL = localize('expandNotification', "Expand Notification");
constructor(
id: string,
label: string
) {
super(id, label, 'expand-notification-action');
}
public run(context: INotificationViewItem): TPromise<any> {
context.expand();
return TPromise.as(void 0); // TODO@notification
}
}
class CollapseNotificationAction extends Action {
public static readonly ID = 'workbench.action.collapseNotification';
public static readonly LABEL = localize('collapseNotification', "Collapse Notification");
constructor(
id: string,
label: string
) {
super(id, label, 'collapse-notification-action');
}
public run(context: INotificationViewItem): TPromise<any> {
context.collapse();
return TPromise.as(void 0); // TODO@notification
}
}
class CloseNotificationActionRunner extends ActionRunner {
constructor(private context: INotificationViewItem) {
super();
}
public run(action: IAction, context?: any): TPromise<void> {
return super.run(action, this.context);
}
}
export class NotificationRenderer implements IRenderer<INotificationViewItem, INotificationTemplateData> {
public static readonly TEMPLATE_ID = 'notification';
......@@ -211,12 +147,13 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN
private closeNotificationAction: CloseNotificationAction;
private expandNotificationAction: ExpandNotificationAction;
private collapseNotificationAction: ExpandNotificationAction;
private collapseNotificationAction: CollapseNotificationAction;
constructor(
@IOpenerService private openerService: IOpenerService,
@IThemeService private themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService
@IInstantiationService private instantiationService: IInstantiationService,
@IContextMenuService private contextMenuService: IContextMenuService
) {
this.closeNotificationAction = instantiationService.createInstance(CloseNotificationAction, CloseNotificationAction.ID, CloseNotificationAction.LABEL);
this.expandNotificationAction = instantiationService.createInstance(ExpandNotificationAction, ExpandNotificationAction.ID, ExpandNotificationAction.LABEL);
......@@ -250,8 +187,22 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN
// Toolbar
const toolbarContainer = document.createElement('div');
addClass(toolbarContainer, 'notification-list-item-toolbar-container');
data.toolbar = new ActionBar(toolbarContainer, { ariaLabel: localize('notificationActions', "Notification actions") });
data.toolbar = new ActionBar(
toolbarContainer,
{
ariaLabel: localize('notificationActions', "Notification actions"),
actionItemProvider: action => {
if (action instanceof ConfigureNotificationAction) {
const item = new DropdownMenuActionItem(action, action.configurationActions, this.contextMenuService, null, null, null, action.class);
data.toDispose.push(item);
return item;
}
return null;
}
},
);
// Details Row
data.detailsRow = document.createElement('div');
......@@ -305,18 +256,29 @@ export class NotificationRenderer implements IRenderer<INotificationViewItem, IN
clearNode(data.message);
data.message.appendChild(NotificationMarkdownRenderer.render(element.message, (content: string) => this.openerService.open(URI.parse(content)).then(void 0, onUnexpectedError)));
// Toolbar
data.toolbar.clear();
// Actions
const actions: IAction[] = [];
const doNotShowNotificationAgainAction = this.instantiationService.createInstance(DoNotShowNotificationAgainAction, DoNotShowNotificationAgainAction.ID, DoNotShowNotificationAgainAction.LABEL, element);
data.toDispose.push(doNotShowNotificationAgainAction);
const configureNotificationAction = this.instantiationService.createInstance(ConfigureNotificationAction, ConfigureNotificationAction.ID, ConfigureNotificationAction.LABEL, [doNotShowNotificationAgainAction]);
actions.push(configureNotificationAction);
data.toDispose.push(configureNotificationAction);
if (element.canCollapse) {
actions.push(element.expanded ? this.collapseNotificationAction : this.expandNotificationAction);
}
actions.push(this.closeNotificationAction);
// Toolbar
const notificationActionRunner = new NotificationActionRunner(element);
data.toDispose.push(notificationActionRunner);
data.toolbar.actionRunner = notificationActionRunner;
data.toolbar.clear();
data.toolbar.push(actions, { icon: true, label: false });
data.toolbar.actionRunner = new CloseNotificationActionRunner(element);
data.toDispose.push(data.toolbar.actionRunner);
// Source
if (element.expanded) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册