提交 60dd5edd 编写于 作者: J Johannes Rieken

create css styles for icons, used them instead of the icon paths

上级 dbb8c3f3
......@@ -11,12 +11,10 @@ import Event, {Emitter} from 'vs/base/common/event';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {IExtensionService} from 'vs/platform/extensions/common/extensions';
import {Menus, MenuItem, IMenuService} from 'vs/platform/actions/common/actions';
import {MenuId, MenuItem, IMenuService} from 'vs/platform/actions/common/actions';
import {ResourceContextKey} from 'vs/platform/actions/common/resourceContextKey';
import {Action, IAction} from 'vs/base/common/actions';
import {BaseActionItem, ActionItem} from 'vs/base/browser/ui/actionbar/actionbar';
import {IThemeService} from 'vs/workbench/services/themes/common/themeService';
import {isLightTheme} from 'vs/platform/theme/common/themes';
import {domEvent} from 'vs/base/browser/event';
export class ActionBarContributor {
......@@ -28,11 +26,10 @@ export class ActionBarContributor {
constructor(
scope: HTMLElement,
location: Menus,
location: MenuId,
@IMenuService private _menuService: IMenuService,
@IKeybindingService private _keybindingService: IKeybindingService,
@IExtensionService private _extensionService: IExtensionService,
@IThemeService private _themeService: IThemeService
@IExtensionService private _extensionService: IExtensionService
) {
this._scope = scope;
this._extensionService.onReady().then(() => {
......@@ -82,7 +79,7 @@ export class ActionBarContributor {
getActionItem(action: IAction): BaseActionItem {
if (action instanceof MenuItemAction) {
return new MenuItemActionItem(action, this._themeService, this._keybindingService);
return new MenuItemActionItem(action, this._keybindingService);
}
}
}
......@@ -129,12 +126,9 @@ class MenuItemActionItem extends ActionItem {
constructor(
action: MenuItemAction,
@IThemeService private _themeService: IThemeService,
@IKeybindingService private _keybindingService: IKeybindingService
) {
super(undefined, action, { icon: true, label: false });
this._callOnDispose.push(this._themeService.onDidThemeChange(_ => this._updateClass()));
}
private get command() {
......@@ -182,10 +176,8 @@ class MenuItemActionItem extends ActionItem {
_updateClass(): void {
if (this.options.icon) {
const element = this.$e.getHTMLElement();
const {darkThemeIcon, lightThemeIcon} = this.command;
const themeId = this._themeService.getTheme();
element.classList.add('icon');
element.style.backgroundImage = `url("${isLightTheme(themeId) ? lightThemeIcon : darkThemeIcon}")`;
const {iconClass} = this.command;
element.classList.add('icon', iconClass);
}
}
}
......@@ -4,18 +4,31 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import {createCSSRule} from 'vs/base/browser/dom';
import {localize} from 'vs/nls';
import {join} from 'vs/base/common/paths';
import {IdGenerator} from 'vs/base/common/idGenerator';
import {IJSONSchema} from 'vs/base/common/jsonSchema';
import {forEach} from 'vs/base/common/collections';
import {IExtensionPointUser, IExtensionMessageCollector, ExtensionsRegistry} from 'vs/platform/extensions/common/extensionsRegistry';
import {IUserFriendlyCommand, IUserFriendlyMenuItem, IUserFriendlyMenuLocation, MenuRegistry} from './menusService';
import {IDeclaredMenuItem, MenuRegistry} from './menusService';
import {MenuId} from 'vs/platform/actions/common/actions';
namespace schema {
// --- menus contribution point
export function isValidMenuItems(menu: IUserFriendlyMenuItem[], collector: IExtensionMessageCollector): boolean {
export function parseMenus(value: string): MenuId {
switch (value) {
case 'editor/title': return MenuId.EditorTitle;
case 'explorer/context': return MenuId.ExplorerContext;
}
}
export function isValidMenuItems(menu: IDeclaredMenuItem[], collector: IExtensionMessageCollector): boolean {
if (!Array.isArray(menu)) {
collector.error(localize('requirearry', "menu items must be an arry"));
return false;
......@@ -74,6 +87,15 @@ namespace schema {
// --- commands contribution point
export interface IUserFriendlyCommand {
command: string;
title: string;
category?: string;
icon?: IUserFriendlyIcon;
}
export type IUserFriendlyIcon = string | { light: string; dark: string; };
export function isValidCommand(command: IUserFriendlyCommand, collector: IExtensionMessageCollector): boolean {
if (!command) {
collector.error(localize('nonempty', "expected non-empty value."));
......@@ -97,7 +119,7 @@ namespace schema {
return true;
}
function isValidIcon(icon: string | { light: string; dark: string;}, collector: IExtensionMessageCollector): boolean {
function isValidIcon(icon: IUserFriendlyIcon, collector: IExtensionMessageCollector): boolean {
if (typeof icon === 'undefined') {
return true;
}
......@@ -159,7 +181,7 @@ namespace schema {
};
}
ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: IUserFriendlyMenuItem[] }>('menus', schema.menusContribtion).setHandler(extensions => {
ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: IDeclaredMenuItem[] }>('menus', schema.menusContribtion).setHandler(extensions => {
for (let extension of extensions) {
const {value, collector} = extension;
......@@ -168,40 +190,50 @@ ExtensionsRegistry.registerExtensionPoint<{ [loc: string]: IUserFriendlyMenuItem
return;
}
if (!MenuRegistry.registerMenuItems(<IUserFriendlyMenuLocation>entry.key, entry.value)) {
// ignored
const menu = schema.parseMenus(entry.key);
if (!menu) {
collector.warn(localize('menuId.invalid', "`{0}` is not a valid menu identifier", entry.key));
return;
}
MenuRegistry.registerMenuItems(menu, entry.value);
});
}
});
ExtensionsRegistry.registerExtensionPoint<IUserFriendlyCommand | IUserFriendlyCommand[]>('commands', schema.commandsContribution).setHandler(extensions => {
ExtensionsRegistry.registerExtensionPoint<schema.IUserFriendlyCommand | schema.IUserFriendlyCommand[]>('commands', schema.commandsContribution).setHandler(extensions => {
function handleCommand(command: IUserFriendlyCommand, extension: IExtensionPointUser<any>) {
const ids = new IdGenerator('contrib-cmd-icon-');
if (!schema.isValidCommand(command, extension.collector)) {
function handleCommand(userFriendlyCommand: schema.IUserFriendlyCommand , extension: IExtensionPointUser<any>) {
if (!schema.isValidCommand(userFriendlyCommand, extension.collector)) {
return;
}
let {icon} = command;
if (!icon) {
// ignore
} else if (typeof icon === 'string') {
command.icon = join(extension.description.extensionFolderPath, icon);
} else {
const light = join(extension.description.extensionFolderPath, icon.light);
const dark = join(extension.description.extensionFolderPath, icon.dark);
command.icon = { light, dark };
let {icon, category, title, command} = userFriendlyCommand;
let iconClass: string;
if (icon) {
iconClass = ids.nextId();
if (typeof icon === 'string') {
const path = join(extension.description.extensionFolderPath, icon);
createCSSRule(`icon.${iconClass}`, `background-image: url("${path}")`);
} else {
const light = join(extension.description.extensionFolderPath, icon.light);
const dark = join(extension.description.extensionFolderPath, icon.dark);
createCSSRule(`.icon.${iconClass}`, `background-image: url("${light}")`);
createCSSRule(`.vs-dark .icon.${iconClass}, hc-black .icon.${iconClass}`, `background-image: url("${dark}")`);
}
}
if (MenuRegistry.registerCommand(command)) {
extension.collector.info(localize('dup', "Command `{0}` appears multiple times in the `commands` section.", command.command));
if (MenuRegistry.registerCommand({ id: command, title, category, iconClass })) {
extension.collector.info(localize('dup', "Command `{0}` appears multiple times in the `commands` section.", userFriendlyCommand.command));
}
}
for (let extension of extensions) {
const {value} = extension;
if (Array.isArray<IUserFriendlyCommand>(value)) {
if (Array.isArray<schema.IUserFriendlyCommand>(value)) {
for (let command of value) {
handleCommand(command, extension);
}
......
......@@ -7,65 +7,41 @@
import {values} from 'vs/base/common/collections';
import {KbExpr} from 'vs/platform/keybinding/common/keybindingService';
import {Menus, CommandAction, MenuItem, IMenuService} from './actions';
import {MenuId, CommandAction, MenuItem, IMenuService} from 'vs/platform/actions/common/actions';
export type IUserFriendlyMenuLocation = 'editor/title';
export interface IUserFriendlyMenuItem {
export interface IDeclaredMenuItem {
command: string;
alt?: string;
when?: string;
}
export interface IUserFriendlyCommand {
command: string;
title: string;
category?: string;
icon?: string | { light: string; dark: string; };
}
export interface IMenuRegistry {
registerCommand(userCommand: IUserFriendlyCommand): boolean;
registerMenuItems(location: IUserFriendlyMenuLocation, items: IUserFriendlyMenuItem[]): boolean;
registerCommand(userCommand: CommandAction): boolean;
registerMenuItems(location: MenuId, items: IDeclaredMenuItem[]): void;
}
const _registry = new class {
private _commands: { [id: string]: CommandAction } = Object.create(null);
private _menuItems: { [loc: number]: IUserFriendlyMenuItem[] } = Object.create(null);
registerCommand(userCommand: IUserFriendlyCommand): boolean {
let {command, category, icon, title} = userCommand;
if (!icon) {
icon = '';
}
const old = this._commands[command];
this._commands[command] = {
id: command,
title,
category,
lightThemeIcon: typeof icon === 'string' ? icon : icon.light,
darkThemeIcon: typeof icon === 'string' ? icon : icon.dark
};
private _menuItems: { [loc: number]: IDeclaredMenuItem[] } = Object.create(null);
registerCommand(command: CommandAction): boolean {
const old = this._commands[command.id];
this._commands[command.id] = command;
return old !== void 0;
}
registerMenuItems(location: IUserFriendlyMenuLocation, items: IUserFriendlyMenuItem[]): boolean {
const loc = Menus.parse(location);
if (loc) {
let array = this._menuItems[loc];
if (!array) {
this._menuItems[loc] = items;
} else {
array.push(...items);
}
return true;
registerMenuItems(loc: MenuId, items: IDeclaredMenuItem[]): void {
let array = this._menuItems[loc];
if (!array) {
this._menuItems[loc] = items;
} else {
array.push(...items);
}
}
getMenuItems(loc: Menus): MenuItem[] {
getMenuItems(loc: MenuId): MenuItem[] {
const menuItems = this._menuItems[loc];
if (menuItems) {
return menuItems.map(item => {
......@@ -88,7 +64,7 @@ export class MenuService implements IMenuService {
serviceId;
getMenuItems(loc: Menus): MenuItem[] {
getMenuItems(loc: MenuId): MenuItem[] {
return _registry.getMenuItems(loc);
}
......
......@@ -13,13 +13,11 @@ import {KbExpr, IKeybindings, IKeybindingService} from 'vs/platform/keybinding/c
import {IDisposable} from 'vs/base/common/lifecycle';
import {createDecorator} from 'vs/platform/instantiation/common/instantiation';
export interface CommandAction {
id: string;
title: string;
category: string;
lightThemeIcon: string;
darkThemeIcon: string;
category?: string;
iconClass?: string;
}
export interface MenuItem {
......@@ -28,27 +26,18 @@ export interface MenuItem {
when?: KbExpr;
}
export enum Menus {
export enum MenuId {
EditorTitle = 1,
ExplorerContext = 2
}
export namespace Menus {
export function parse(value: string): Menus {
switch (value) {
case 'editor/title': return Menus.EditorTitle;
case 'explorer/context': return Menus.ExplorerContext;
}
}
}
export const IMenuService = createDecorator<IMenuService>('menuService');
export interface IMenuService {
serviceId: any;
getMenuItems(loc: Menus): MenuItem[];
getMenuItems(loc: MenuId): MenuItem[];
getCommandActions(): CommandAction[];
}
......
......@@ -31,8 +31,8 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat
import {IKeybindingService} from 'vs/platform/keybinding/common/keybindingService';
import {CloseEditorsInGroupAction, MoveGroupLeftAction, MoveGroupRightAction, SplitEditorAction, CloseEditorAction, KeepEditorAction, CloseOtherEditorsInGroupAction, CloseRightEditorsInGroupAction, ShowEditorsInGroupAction} from 'vs/workbench/browser/parts/editor/editorActions';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import {ActionBarContributor} from 'vs/platform/actions/workbench/actionBarContributor';
import {Menus} from 'vs/platform/actions/common/actions';
import {ActionBarContributor} from 'vs/platform/actions/browser/actionBarContributor';
import {MenuId} from 'vs/platform/actions/common/actions';
import {ResourceContextKey} from 'vs/platform/actions/common/resourceContextKey';
export interface IToolbarActions {
......@@ -177,7 +177,7 @@ export abstract class TitleControl implements ITitleAreaControl {
}
public create(parent: HTMLElement): void {
this.titleActionBarContributor = this.instantiationService.createInstance(ActionBarContributor, parent, Menus.EditorTitle);
this.titleActionBarContributor = this.instantiationService.createInstance(ActionBarContributor, parent, MenuId.EditorTitle);
this.toDispose.push(this.titleActionBarContributor.onDidUpdate(e => this.refresh()));
this.toDispose.push(this.titleActionBarContributor);
}
......
......@@ -65,7 +65,7 @@ import {IThreadService} from 'vs/platform/thread/common/thread';
import {MainThreadService} from 'vs/platform/thread/common/mainThreadService';
import {IStatusbarService} from 'vs/platform/statusbar/common/statusbar';
import {IMenuService} from 'vs/platform/actions/common/actions';
import {MenuService} from 'vs/platform/actions/common/menusService';
import {MenuService} from 'vs/platform/actions/browser/menusService';
import {IContextMenuService} from 'vs/platform/contextview/browser/contextView';
interface WorkbenchParams {
......
......@@ -46,8 +46,8 @@ import {IProgressService} from 'vs/platform/progress/common/progress';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {Keybinding, CommonKeybindings} from 'vs/base/common/keyCodes';
import {IKeyboardEvent} from 'vs/base/browser/keyboardEvent';
import {ActionBarContributor} from 'vs/platform/actions/workbench/actionBarContributor';
import {Menus} from 'vs/platform/actions/common/actions';
import {ActionBarContributor} from 'vs/platform/actions/browser/actionBarContributor';
import {MenuId} from 'vs/platform/actions/common/actions';
export class FileDataSource implements IDataSource {
private workspace: IWorkspace;
......@@ -468,7 +468,7 @@ export class FileController extends DefaultController {
if (!this.contextMenuActions) {
this.contextMenuActions = this.instantiationService.createInstance(ActionBarContributor,
tree.getHTMLElement(), Menus.ExplorerContext);
tree.getHTMLElement(), MenuId.ExplorerContext);
}
event.preventDefault();
......
......@@ -17,7 +17,7 @@ import 'vs/editor/browser/editor.all';
import 'vs/languages/languages.main';
// Menus/Actions
import 'vs/platform/actions/common/menusExtensionPoint';
import 'vs/platform/actions/browser/menusExtensionPoint';
// Workbench
import 'vs/workbench/browser/actions/toggleStatusbarVisibility';
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册