mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 (#7206)
* Merge from vscode 64980ea1f3f532c82bb6c28d27bba9ef2c5b4463 * fix config changes * fix strictnull checks
This commit is contained in:
10
extensions/image-preview/.vscodeignore
Normal file
10
extensions/image-preview/.vscodeignore
Normal file
@@ -0,0 +1,10 @@
|
||||
test/**
|
||||
src/**
|
||||
tsconfig.json
|
||||
out/test/**
|
||||
out/**
|
||||
extension.webpack.config.js
|
||||
cgmanifest.json
|
||||
yarn.lock
|
||||
preview-src/**
|
||||
webpack.config.js
|
||||
3
extensions/image-preview/README.md
Normal file
3
extensions/image-preview/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Image Preview
|
||||
|
||||
**Notice:** This extension is bundled with Visual Studio Code. It can be disabled but not uninstalled.
|
||||
20
extensions/image-preview/extension.webpack.config.js
Normal file
20
extensions/image-preview/extension.webpack.config.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
//@ts-check
|
||||
|
||||
'use strict';
|
||||
|
||||
const withDefaults = require('../shared.webpack.config');
|
||||
|
||||
module.exports = withDefaults({
|
||||
context: __dirname,
|
||||
resolve: {
|
||||
mainFields: ['module', 'main']
|
||||
},
|
||||
entry: {
|
||||
extension: './src/extension.ts',
|
||||
}
|
||||
});
|
||||
78
extensions/image-preview/media/main.css
Normal file
78
extensions/image-preview/media/main.css
Normal file
@@ -0,0 +1,78 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
|
||||
body img {
|
||||
max-width: none;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.container:focus {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 5px 0 0 10px;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.container.image {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.container.image img {
|
||||
padding: 0;
|
||||
background-position: 0 0, 8px 8px;
|
||||
background-size: 16px 16px;
|
||||
}
|
||||
|
||||
.container.image img {
|
||||
background-image:
|
||||
linear-gradient(45deg, rgb(230, 230, 230) 25%, transparent 25%, transparent 75%, rgb(230, 230, 230) 75%, rgb(230, 230, 230)),
|
||||
linear-gradient(45deg, rgb(230, 230, 230) 25%, transparent 25%, transparent 75%, rgb(230, 230, 230) 75%, rgb(230, 230, 230));
|
||||
}
|
||||
|
||||
.vscode-dark.container.image img {
|
||||
background-image:
|
||||
linear-gradient(45deg, rgb(20, 20, 20) 25%, transparent 25%, transparent 75%, rgb(20, 20, 20) 75%, rgb(20, 20, 20)),
|
||||
linear-gradient(45deg, rgb(20, 20, 20) 25%, transparent 25%, transparent 75%, rgb(20, 20, 20) 75%, rgb(20, 20, 20));
|
||||
}
|
||||
|
||||
.container img.pixelated {
|
||||
image-rendering: pixelated;
|
||||
}
|
||||
|
||||
.container img.scale-to-fit {
|
||||
max-width: calc(100% - 20px);
|
||||
max-height: calc(100% - 20px);
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.container img {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.container.zoom-in {
|
||||
cursor: zoom-in;
|
||||
}
|
||||
|
||||
.container.zoom-out {
|
||||
cursor: zoom-out;
|
||||
}
|
||||
|
||||
.container .embedded-link,
|
||||
.container .embedded-link:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
margin-left: 5px;
|
||||
}
|
||||
258
extensions/image-preview/media/main.js
Normal file
258
extensions/image-preview/media/main.js
Normal file
@@ -0,0 +1,258 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
// @ts-check
|
||||
"use strict";
|
||||
|
||||
(function () {
|
||||
/**
|
||||
* @param {number} value
|
||||
* @param {number} min
|
||||
* @param {number} max
|
||||
* @return {number}
|
||||
*/
|
||||
function clamp(value, min, max) {
|
||||
return Math.min(Math.max(value, min), max);
|
||||
}
|
||||
|
||||
function getSettings() {
|
||||
const element = document.getElementById('image-preview-settings');
|
||||
if (element) {
|
||||
const data = element.getAttribute('data-settings');
|
||||
if (data) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error(`Could not load settings`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable image-rendering: pixelated for images scaled by more than this.
|
||||
*/
|
||||
const PIXELATION_THRESHOLD = 3;
|
||||
|
||||
const SCALE_PINCH_FACTOR = 0.075;
|
||||
const MAX_SCALE = 20;
|
||||
const MIN_SCALE = 0.1;
|
||||
|
||||
const zoomLevels = [
|
||||
0.1,
|
||||
0.2,
|
||||
0.3,
|
||||
0.4,
|
||||
0.5,
|
||||
0.6,
|
||||
0.7,
|
||||
0.8,
|
||||
0.9,
|
||||
1,
|
||||
1.5,
|
||||
2,
|
||||
3,
|
||||
5,
|
||||
7,
|
||||
10,
|
||||
15,
|
||||
20
|
||||
];
|
||||
|
||||
const isMac = getSettings().isMac;
|
||||
|
||||
const vscode = acquireVsCodeApi();
|
||||
|
||||
const initialState = vscode.getState() || { scale: 'fit', offsetX: 0, offsetY: 0 };
|
||||
|
||||
// State
|
||||
let scale = initialState.scale;
|
||||
let ctrlPressed = false;
|
||||
let altPressed = false;
|
||||
|
||||
// Elements
|
||||
const container = /** @type {HTMLElement} */(document.querySelector('body'));
|
||||
const image = document.querySelector('img');
|
||||
|
||||
function updateScale(newScale) {
|
||||
if (!image || !image.parentElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (newScale === 'fit') {
|
||||
scale = 'fit';
|
||||
image.classList.add('scale-to-fit');
|
||||
image.classList.remove('pixelated');
|
||||
image.style.minWidth = 'auto';
|
||||
image.style.width = 'auto';
|
||||
vscode.setState(undefined);
|
||||
} else {
|
||||
const oldWidth = image.width;
|
||||
const oldHeight = image.height;
|
||||
|
||||
scale = clamp(newScale, MIN_SCALE, MAX_SCALE);
|
||||
if (scale >= PIXELATION_THRESHOLD) {
|
||||
image.classList.add('pixelated');
|
||||
} else {
|
||||
image.classList.remove('pixelated');
|
||||
}
|
||||
|
||||
const { scrollTop, scrollLeft } = image.parentElement;
|
||||
const dx = (scrollLeft + image.parentElement.clientWidth / 2) / image.parentElement.scrollWidth;
|
||||
const dy = (scrollTop + image.parentElement.clientHeight / 2) / image.parentElement.scrollHeight;
|
||||
|
||||
image.classList.remove('scale-to-fit');
|
||||
image.style.minWidth = `${(image.naturalWidth * scale)}px`;
|
||||
image.style.width = `${(image.naturalWidth * scale)}px`;
|
||||
|
||||
const newWidth = image.width;
|
||||
const scaleFactor = (newWidth - oldWidth) / oldWidth;
|
||||
|
||||
const newScrollLeft = ((oldWidth * scaleFactor * dx) + scrollLeft);
|
||||
const newScrollTop = ((oldHeight * scaleFactor * dy) + scrollTop);
|
||||
// scrollbar.setScrollPosition({
|
||||
// scrollLeft: newScrollLeft,
|
||||
// scrollTop: newScrollTop,
|
||||
// });
|
||||
|
||||
vscode.setState({ scale: scale, offsetX: newScrollLeft, offsetY: newScrollTop });
|
||||
}
|
||||
|
||||
vscode.postMessage({
|
||||
type: 'zoom',
|
||||
value: scale
|
||||
});
|
||||
}
|
||||
|
||||
function firstZoom() {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
scale = image.clientWidth / image.naturalWidth;
|
||||
updateScale(scale);
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', (/** @type {KeyboardEvent} */ e) => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
ctrlPressed = e.ctrlKey;
|
||||
altPressed = e.altKey;
|
||||
|
||||
if (isMac ? altPressed : ctrlPressed) {
|
||||
container.classList.remove('zoom-in');
|
||||
container.classList.add('zoom-out');
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('keyup', (/** @type {KeyboardEvent} */ e) => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctrlPressed = e.ctrlKey;
|
||||
altPressed = e.altKey;
|
||||
|
||||
if (!(isMac ? altPressed : ctrlPressed)) {
|
||||
container.classList.remove('zoom-out');
|
||||
container.classList.add('zoom-in');
|
||||
}
|
||||
});
|
||||
|
||||
container.addEventListener('click', (/** @type {MouseEvent} */ e) => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// left click
|
||||
if (scale === 'fit') {
|
||||
firstZoom();
|
||||
}
|
||||
|
||||
if (!(isMac ? altPressed : ctrlPressed)) { // zoom in
|
||||
let i = 0;
|
||||
for (; i < zoomLevels.length; ++i) {
|
||||
if (zoomLevels[i] > scale) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateScale(zoomLevels[i] || MAX_SCALE);
|
||||
} else {
|
||||
let i = zoomLevels.length - 1;
|
||||
for (; i >= 0; --i) {
|
||||
if (zoomLevels[i] < scale) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateScale(zoomLevels[i] || MIN_SCALE);
|
||||
}
|
||||
});
|
||||
|
||||
container.addEventListener('wheel', (/** @type {WheelEvent} */ e) => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
const isScrollWheelKeyPressed = isMac ? altPressed : ctrlPressed;
|
||||
if (!isScrollWheelKeyPressed && !e.ctrlKey) { // pinching is reported as scroll wheel + ctrl
|
||||
return;
|
||||
}
|
||||
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (scale === 'fit') {
|
||||
firstZoom();
|
||||
}
|
||||
|
||||
let delta = e.deltaY > 0 ? 1 : -1;
|
||||
updateScale(scale * (1 - delta * SCALE_PINCH_FACTOR));
|
||||
});
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
if (!image || !image.parentElement || scale === 'fit') {
|
||||
return;
|
||||
}
|
||||
|
||||
const entry = vscode.getState();
|
||||
if (entry) {
|
||||
vscode.setState({ scale: entry.scale, offsetX: window.scrollX, offsetY: window.scrollY });
|
||||
}
|
||||
});
|
||||
|
||||
container.classList.add('image');
|
||||
container.classList.add('zoom-in');
|
||||
|
||||
image.classList.add('scale-to-fit');
|
||||
image.style.visibility = 'hidden';
|
||||
|
||||
image.addEventListener('load', () => {
|
||||
if (!image) {
|
||||
return;
|
||||
}
|
||||
|
||||
vscode.postMessage({
|
||||
type: 'size',
|
||||
value: `${image.naturalWidth}x${image.naturalHeight}`,
|
||||
});
|
||||
|
||||
image.style.visibility = 'visible';
|
||||
updateScale(scale);
|
||||
|
||||
if (initialState.scale !== 'fit') {
|
||||
window.scrollTo(initialState.offsetX, initialState.offsetY);
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('message', e => {
|
||||
switch (e.data.type) {
|
||||
case 'setScale':
|
||||
updateScale(e.data.scale);
|
||||
break;
|
||||
}
|
||||
});
|
||||
}());
|
||||
43
extensions/image-preview/package.json
Normal file
43
extensions/image-preview/package.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "image-preview",
|
||||
"displayName": "%displayName%",
|
||||
"description": "%description%",
|
||||
"version": "1.0.0",
|
||||
"publisher": "vscode",
|
||||
"enableProposedApi": true,
|
||||
"license": "MIT",
|
||||
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
|
||||
"engines": {
|
||||
"vscode": "^1.39.0"
|
||||
},
|
||||
"main": "./out/extension",
|
||||
"categories": [
|
||||
"Other"
|
||||
],
|
||||
"activationEvents": [
|
||||
"onWebviewEditor:imagePreview.previewEditor"
|
||||
],
|
||||
"contributes": {
|
||||
"webviewEditors": [
|
||||
{
|
||||
"viewType": "imagePreview.previewEditor",
|
||||
"displayName": "%webviewEditors.displayName%",
|
||||
"selector": [
|
||||
{
|
||||
"filenamePattern": "*.{jpg,jpe,jpeg,png,bmp,gif,ico,tga,tif,tiff,webp}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "gulp compile-extension:image-preview",
|
||||
"watch": "npm run build-preview && gulp watch-extension:image-preview",
|
||||
"vscode:prepublish": "npm run build-ext",
|
||||
"build-ext": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:image-preview ./tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-nls": "^4.0.0"
|
||||
}
|
||||
}
|
||||
5
extensions/image-preview/package.nls.json
Normal file
5
extensions/image-preview/package.nls.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"displayName": "Image Preview",
|
||||
"description": "Previews images.",
|
||||
"webviewEditors.displayName": "Image Preview"
|
||||
}
|
||||
42
extensions/image-preview/src/dispose.ts
Normal file
42
extensions/image-preview/src/dispose.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
export function disposeAll(disposables: vscode.Disposable[]) {
|
||||
while (disposables.length) {
|
||||
const item = disposables.pop();
|
||||
if (item) {
|
||||
item.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Disposable {
|
||||
private _isDisposed = false;
|
||||
|
||||
protected _disposables: vscode.Disposable[] = [];
|
||||
|
||||
public dispose(): any {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
this._isDisposed = true;
|
||||
disposeAll(this._disposables);
|
||||
}
|
||||
|
||||
protected _register<T extends vscode.Disposable>(value: T): T {
|
||||
if (this._isDisposed) {
|
||||
value.dispose();
|
||||
} else {
|
||||
this._disposables.push(value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
protected get isDisposed() {
|
||||
return this._isDisposed;
|
||||
}
|
||||
}
|
||||
28
extensions/image-preview/src/extension.ts
Normal file
28
extensions/image-preview/src/extension.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { Preview } from './preview';
|
||||
import { SizeStatusBarEntry } from './sizeStatusBarEntry';
|
||||
import { ZoomStatusBarEntry } from './zoomStatusBarEntry';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
const extensionRoot = vscode.Uri.file(context.extensionPath);
|
||||
|
||||
const sizeStatusBarEntry = new SizeStatusBarEntry();
|
||||
context.subscriptions.push(sizeStatusBarEntry);
|
||||
|
||||
const zoomStatusBarEntry = new ZoomStatusBarEntry();
|
||||
context.subscriptions.push(zoomStatusBarEntry);
|
||||
|
||||
context.subscriptions.push(vscode.window.registerWebviewEditorProvider(
|
||||
Preview.viewType,
|
||||
{
|
||||
async resolveWebviewEditor(resource: vscode.Uri, editor: vscode.WebviewEditor): Promise<void> {
|
||||
// tslint:disable-next-line: no-unused-expression
|
||||
new Preview(extensionRoot, resource, editor, sizeStatusBarEntry, zoomStatusBarEntry);
|
||||
}
|
||||
}));
|
||||
}
|
||||
113
extensions/image-preview/src/preview.ts
Normal file
113
extensions/image-preview/src/preview.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { SizeStatusBarEntry } from './sizeStatusBarEntry';
|
||||
import { ZoomStatusBarEntry } from './zoomStatusBarEntry';
|
||||
import { Disposable } from './dispose';
|
||||
|
||||
export class Preview extends Disposable {
|
||||
|
||||
public static readonly viewType = 'imagePreview.previewEditor';
|
||||
|
||||
private _active = true;
|
||||
|
||||
constructor(
|
||||
private readonly extensionRoot: vscode.Uri,
|
||||
resource: vscode.Uri,
|
||||
private readonly webviewEditor: vscode.WebviewEditor,
|
||||
private readonly sizeStatusBarEntry: SizeStatusBarEntry,
|
||||
private readonly zoomStatusBarEntry: ZoomStatusBarEntry,
|
||||
) {
|
||||
super();
|
||||
const resourceRoot = resource.with({
|
||||
path: resource.path.replace(/\/[^\/]+?\.\w+$/, '/'),
|
||||
});
|
||||
|
||||
webviewEditor.webview.options = {
|
||||
enableScripts: true,
|
||||
localResourceRoots: [
|
||||
resourceRoot,
|
||||
extensionRoot,
|
||||
]
|
||||
};
|
||||
|
||||
webviewEditor.webview.html = this.getWebiewContents(webviewEditor, resource);
|
||||
|
||||
this._register(webviewEditor.webview.onDidReceiveMessage(message => {
|
||||
switch (message.type) {
|
||||
case 'size':
|
||||
{
|
||||
this.sizeStatusBarEntry.update(message.value);
|
||||
break;
|
||||
}
|
||||
case 'zoom':
|
||||
{
|
||||
this.zoomStatusBarEntry.update(message.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(zoomStatusBarEntry.onDidChangeScale(e => {
|
||||
this.webviewEditor.webview.postMessage({ type: 'setScale', scale: e.scale });
|
||||
}));
|
||||
|
||||
this._register(webviewEditor.onDidChangeViewState(() => {
|
||||
this.update();
|
||||
}));
|
||||
this._register(webviewEditor.onDidDispose(() => {
|
||||
if (this._active) {
|
||||
this.sizeStatusBarEntry.hide();
|
||||
this.zoomStatusBarEntry.hide();
|
||||
}
|
||||
}));
|
||||
this.update();
|
||||
}
|
||||
|
||||
private update() {
|
||||
this._active = this.webviewEditor.active;
|
||||
if (this._active) {
|
||||
this.sizeStatusBarEntry.show();
|
||||
this.zoomStatusBarEntry.show();
|
||||
} else {
|
||||
this.sizeStatusBarEntry.hide();
|
||||
this.zoomStatusBarEntry.hide();
|
||||
}
|
||||
}
|
||||
|
||||
private getWebiewContents(webviewEditor: vscode.WebviewEditor, resource: vscode.Uri): string {
|
||||
const settings = {
|
||||
isMac: process.platform === 'darwin'
|
||||
};
|
||||
|
||||
return /* html */`<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Image Preview</title>
|
||||
<link rel="stylesheet" class="code-user-style" href="${escapeAttribute(this.extensionResource('/media/main.css'))}" type="text/css" media="screen">
|
||||
|
||||
<meta id="image-preview-settings" data-settings="${escapeAttribute(JSON.stringify(settings))}">
|
||||
</head>
|
||||
<body class="container image scale-to-fit">
|
||||
<img src="${escapeAttribute(webviewEditor.webview.asWebviewUri(resource))}">
|
||||
<script src="${escapeAttribute(this.extensionResource('/media/main.js'))}"></script>
|
||||
</body>
|
||||
</html>`;
|
||||
}
|
||||
|
||||
private extensionResource(path: string) {
|
||||
return this.webviewEditor.webview.asWebviewUri(this.extensionRoot.with({
|
||||
path: this.extensionRoot.path + path
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
function escapeAttribute(value: string | vscode.Uri): string {
|
||||
return value.toString().replace(/"/g, '"');
|
||||
}
|
||||
33
extensions/image-preview/src/sizeStatusBarEntry.ts
Normal file
33
extensions/image-preview/src/sizeStatusBarEntry.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { Disposable } from './dispose';
|
||||
|
||||
export class SizeStatusBarEntry extends Disposable {
|
||||
private readonly _entry: vscode.StatusBarItem;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._entry = this._register(vscode.window.createStatusBarItem({
|
||||
id: 'imagePreview.size',
|
||||
name: 'Image Size',
|
||||
alignment: vscode.StatusBarAlignment.Right,
|
||||
priority: 101 /* to the left of editor status (100) */,
|
||||
}));
|
||||
}
|
||||
|
||||
public show() {
|
||||
this._entry.show();
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this._entry.hide();
|
||||
}
|
||||
|
||||
public update(text: string) {
|
||||
this._entry.text = text;
|
||||
}
|
||||
}
|
||||
8
extensions/image-preview/src/typings/ref.d.ts
vendored
Normal file
8
extensions/image-preview/src/typings/ref.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/// <reference path='../../../../src/vs/vscode.d.ts'/>
|
||||
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
|
||||
/// <reference types='@types/node'/>
|
||||
68
extensions/image-preview/src/zoomStatusBarEntry.ts
Normal file
68
extensions/image-preview/src/zoomStatusBarEntry.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { Disposable } from './dispose';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
const selectZoomLevelCommandId = '_imagePreview.selectZoomLevel';
|
||||
|
||||
type Scale = number | 'fit';
|
||||
|
||||
export class ZoomStatusBarEntry extends Disposable {
|
||||
private readonly _entry: vscode.StatusBarItem;
|
||||
|
||||
private readonly _onDidChangeScale = this._register(new vscode.EventEmitter<{ scale: Scale }>());
|
||||
public readonly onDidChangeScale = this._onDidChangeScale.event;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._entry = this._register(vscode.window.createStatusBarItem({
|
||||
id: 'imagePreview.zoom',
|
||||
name: 'Image Zoom',
|
||||
alignment: vscode.StatusBarAlignment.Right,
|
||||
priority: 102 /* to the left of editor size entry (101) */,
|
||||
}));
|
||||
|
||||
this._register(vscode.commands.registerCommand(selectZoomLevelCommandId, async () => {
|
||||
type MyPickItem = vscode.QuickPickItem & { scale: Scale };
|
||||
|
||||
const scales: Scale[] = [10, 5, 2, 1, 0.5, 0.2, 'fit'];
|
||||
const options = scales.map((scale): MyPickItem => ({
|
||||
label: this.zoomLabel(scale),
|
||||
scale
|
||||
}));
|
||||
|
||||
const pick = await vscode.window.showQuickPick(options, {
|
||||
placeHolder: localize('zoomStatusBar.placeholder', "Select zoom level")
|
||||
});
|
||||
if (pick) {
|
||||
this._onDidChangeScale.fire({ scale: pick.scale });
|
||||
}
|
||||
}));
|
||||
|
||||
this._entry.command = selectZoomLevelCommandId;
|
||||
}
|
||||
|
||||
public show() {
|
||||
this._entry.show();
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this._entry.hide();
|
||||
}
|
||||
|
||||
public update(scale: Scale) {
|
||||
this._entry.text = this.zoomLabel(scale);
|
||||
}
|
||||
|
||||
private zoomLabel(scale: Scale): string {
|
||||
return scale === 'fit'
|
||||
? localize('zoomStatusBar.wholeImageLabel', "Whole Image")
|
||||
: `${Math.round(scale * 100)}%`;
|
||||
}
|
||||
}
|
||||
10
extensions/image-preview/tsconfig.json
Normal file
10
extensions/image-preview/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "../shared.tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./out",
|
||||
"experimentalDecorators": true
|
||||
},
|
||||
"include": [
|
||||
"src/**/*"
|
||||
]
|
||||
}
|
||||
46
extensions/image-preview/yarn.lock
Normal file
46
extensions/image-preview/yarn.lock
Normal file
@@ -0,0 +1,46 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
applicationinsights@1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.0.8.tgz#db6e3d983cf9f9405fe1ee5ba30ac6e1914537b5"
|
||||
integrity sha512-KzOOGdphOS/lXWMFZe5440LUdFbrLpMvh2SaRxn7BmiI550KAoSb2gIhiq6kJZ9Ir3AxRRztjhzif+e5P5IXIg==
|
||||
dependencies:
|
||||
diagnostic-channel "0.2.0"
|
||||
diagnostic-channel-publishers "0.2.1"
|
||||
zone.js "0.7.6"
|
||||
|
||||
diagnostic-channel-publishers@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.2.1.tgz#8e2d607a8b6d79fe880b548bc58cc6beb288c4f3"
|
||||
integrity sha1-ji1geottef6IC1SLxYzGvrKIxPM=
|
||||
|
||||
diagnostic-channel@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-0.2.0.tgz#cc99af9612c23fb1fff13612c72f2cbfaa8d5a17"
|
||||
integrity sha1-zJmvlhLCP7H/8TYSxy8sv6qNWhc=
|
||||
dependencies:
|
||||
semver "^5.3.0"
|
||||
|
||||
semver@^5.3.0:
|
||||
version "5.5.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
|
||||
integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==
|
||||
|
||||
vscode-extension-telemetry@0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.1.tgz#91387e06b33400c57abd48979b0e790415ae110b"
|
||||
integrity sha512-TkKKG/B/J94DP5qf6xWB4YaqlhWDg6zbbqVx7Bz//stLQNnfE9XS1xm3f6fl24c5+bnEK0/wHgMgZYKIKxPeUA==
|
||||
dependencies:
|
||||
applicationinsights "1.0.8"
|
||||
|
||||
vscode-nls@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.0.0.tgz#4001c8a6caba5cedb23a9c5ce1090395c0e44002"
|
||||
integrity sha512-qCfdzcH+0LgQnBpZA53bA32kzp9rpq/f66Som577ObeuDlFIrtbEJ+A/+CCxjIh4G8dpJYNCKIsxpRAHIfsbNw==
|
||||
|
||||
zone.js@0.7.6:
|
||||
version "0.7.6"
|
||||
resolved "https://registry.yarnpkg.com/zone.js/-/zone.js-0.7.6.tgz#fbbc39d3e0261d0986f1ba06306eb3aeb0d22009"
|
||||
integrity sha1-+7w50+AmHQmG8boGMG6zrrDSIAk=
|
||||
Reference in New Issue
Block a user