Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit a7bcd2b

Browse files
authored
Refine example explorer view. (#387)
1 parent 19971ea commit a7bcd2b

14 files changed

+182
-4
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ node_modules
44
.vscode-test
55
.idea
66
src/views/app/sprites-generated
7+
**/package-lock.json
8+
test/**/c_cpp_properties.json

images/examples/FolderOpen_16x.svg

Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading

images/examples/Folder_16x.svg

Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading

images/examples/ino_16x.svg

Lines changed: 39 additions & 0 deletions
Loading

package.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"aiKey": "83dd2c27-6594-41d3-85a9-bdb22070eb42",
88
"preview": true,
99
"engines": {
10-
"vscode": "^1.7.0"
10+
"vscode": "^1.13.0"
1111
},
1212
"icon": "images/arduino.png",
1313
"license": "SEE LICENSE IN LICENSE.txt",
@@ -116,6 +116,15 @@
116116
"title": "Arduino: Examples"
117117
}
118118
],
119+
"views": {
120+
"explorer": [
121+
{
122+
"id": "arduinoExampleExplorer",
123+
"name": "Arduino Examples",
124+
"when": "vscode-arduino:showExampleExplorer"
125+
}
126+
]
127+
},
119128
"debuggers": [
120129
{
121130
"type": "arduino",

src/arduino/boardManager.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export class BoardManager {
3030

3131
private _currentBoard: IBoard;
3232

33+
private _onBoardTypeChanged = new vscode.EventEmitter<void>();
34+
3335
constructor(private _settings: IArduinoSettings, private _arduinoApp: ArduinoApp) {
3436
this._boardConfigStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, constants.statusBarPriority.BOARD);
3537
this._boardConfigStatusBar.command = "arduino.showBoardConfig";
@@ -111,13 +113,19 @@ export class BoardManager {
111113
return true;
112114
}
113115

116+
public get onBoardTypeChanged(): vscode.Event<void> {
117+
return this._onBoardTypeChanged.event;
118+
}
119+
114120
public doChangeBoardType(targetBoard: IBoard) {
115121
const dc = DeviceContext.getInstance();
116122
dc.board = targetBoard.key;
117123
this._currentBoard = targetBoard;
118124
dc.configuration = this._currentBoard.customConfig;
119125
this._boardConfigStatusBar.text = targetBoard.name;
120126
this._arduinoApp.addLibPath(null);
127+
128+
this._onBoardTypeChanged.fire();
121129
}
122130

123131
public get packages(): IPackage[] {

src/arduino/exampleProvider.ts

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT license.
3+
4+
import * as path from "path";
5+
import * as vscode from "vscode";
6+
7+
import { DeviceContext } from "../deviceContext";
8+
import { BoardManager } from "./boardManager";
9+
import { ExampleManager, IExampleNode } from "./exampleManager";
10+
11+
export class ExampleProvider implements vscode.TreeDataProvider<ExampleItem> {
12+
13+
private _onDidChangeTreeData: vscode.EventEmitter<null> = new vscode.EventEmitter<null>();
14+
15+
// tslint:disable-next-line:member-ordering
16+
public readonly onDidChangeTreeData: vscode.Event<null> = this._onDidChangeTreeData.event;
17+
18+
private _exmaples: IExampleNode[] = null;
19+
20+
constructor(private _exampleManager: ExampleManager, private _boardManager: BoardManager) {
21+
this._boardManager.onBoardTypeChanged(() => {
22+
this.loadData();
23+
});
24+
}
25+
26+
public getTreeItem(element: ExampleItem): vscode.TreeItem | Thenable<vscode.TreeItem> {
27+
return element;
28+
}
29+
30+
public getChildren(element?: ExampleItem): ExampleItem[] {
31+
if (!this._exmaples) {
32+
this.loadData();
33+
return null;
34+
}
35+
if (!element) {
36+
return this.createExampleItemList(this._exmaples);
37+
} else {
38+
return this.createExampleItemList(element.getChildren());
39+
}
40+
}
41+
42+
private loadData() {
43+
this._exmaples = null;
44+
this._exampleManager.loadExamples().then((examples) => {
45+
this._exmaples = examples;
46+
this._onDidChangeTreeData.fire();
47+
});
48+
}
49+
50+
private createExampleItemList(examples: IExampleNode[]): ExampleItem[] {
51+
const result = [];
52+
if (examples && examples.length) {
53+
examples.forEach((example) => {
54+
result.push(new ExampleItem(example));
55+
});
56+
}
57+
return result;
58+
}
59+
}
60+
61+
class ExampleItem extends vscode.TreeItem {
62+
/**
63+
* These static fields/methods provide delay loading and a single copy of icons.
64+
*/
65+
private static _folderIcon;
66+
private static _inoIcon;
67+
68+
private static getFolderIcon() {
69+
if (!ExampleItem._folderIcon) {
70+
ExampleItem._folderIcon = {
71+
light: ExampleItem.getIconUri("Folder_16x.svg"),
72+
dark: ExampleItem.getIconUri("Folder_16x_inverse.svg"),
73+
};
74+
}
75+
return ExampleItem._folderIcon;
76+
}
77+
78+
private static getInoIcon() {
79+
if (!ExampleItem._inoIcon) {
80+
ExampleItem._inoIcon = ExampleItem.getIconUri("ino_16x.svg");
81+
}
82+
return ExampleItem._inoIcon;
83+
}
84+
85+
private static getIconUri(uriPath: string) {
86+
const dc = DeviceContext.getInstance();
87+
return vscode.Uri.file(path.join(dc.extensionPath, "images/examples", uriPath));
88+
}
89+
90+
constructor(private _example: IExampleNode) {
91+
super(_example.name, _example.isLeaf ? vscode.TreeItemCollapsibleState.None : vscode.TreeItemCollapsibleState.Collapsed);
92+
if (_example.isLeaf) {
93+
this.command = {
94+
title: "Open Example",
95+
command: "arduino.openExample",
96+
arguments: [_example.path],
97+
};
98+
this.iconPath = ExampleItem.getInoIcon();
99+
} else {
100+
this.iconPath = ExampleItem.getFolderIcon();
101+
}
102+
}
103+
104+
public getChildren(): IExampleNode[] {
105+
return this._example.children;
106+
}
107+
}

src/arduinoActivator.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4+
import * as vscode from "vscode";
5+
46
import { ArduinoApp } from "./arduino/arduino";
57
import { ArduinoSettings } from "./arduino/arduinoSettings";
68
import { BoardManager } from "./arduino/boardManager";
79
import { ExampleManager } from "./arduino/exampleManager";
10+
import { ExampleProvider } from "./arduino/exampleProvider";
811
import { LibraryManager } from "./arduino/libraryManager";
912
import ArduinoContext from "./arduinoContext";
1013
import { DeviceContext } from "./deviceContext";
@@ -33,6 +36,9 @@ class ArduinoActivator {
3336
arduinoApp.libraryManager = new LibraryManager(arduinoSettings, arduinoApp);
3437
arduinoApp.exampleManager = new ExampleManager(arduinoSettings, arduinoApp);
3538
ArduinoContext.arduinoApp = arduinoApp;
39+
40+
const exampleProvider = new ExampleProvider(arduinoApp.exampleManager, arduinoApp.boardManager);
41+
vscode.window.registerTreeDataProvider("arduinoExampleExplorer", exampleProvider);
3642
})();
3743
await this._initializePromise;
3844
}

src/extension.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ export async function activate(context: vscode.ExtensionContext) {
157157
});
158158

159159
registerArduinoCommand("arduino.addLibPath", (path) => ArduinoContext.arduinoApp.addLibPath(path));
160+
registerArduinoCommand("arduino.openExample", (path) => ArduinoContext.arduinoApp.openExample(path));
160161

161162
// Arduino debugger
162163
registerArduinoCommand("arduino.debug.startSession", async (config) => {
@@ -198,6 +199,7 @@ export async function activate(context: vscode.ExtensionContext) {
198199
SerialMonitor.getInstance().initialize();
199200
}
200201
ArduinoContext.boardManager.updateStatusBar(true);
202+
vscode.commands.executeCommand("setContext", "vscode-arduino:showExampleExplorer", true);
201203
})();
202204
}
203205
vscode.window.onDidChangeActiveTextEditor(async () => {
@@ -213,6 +215,7 @@ export async function activate(context: vscode.ExtensionContext) {
213215
SerialMonitor.getInstance().initialize();
214216
}
215217
ArduinoContext.boardManager.updateStatusBar(true);
218+
vscode.commands.executeCommand("setContext", "vscode-arduino:showExampleExplorer", true);
216219
}
217220
});
218221
Logger.traceUserData("end-activate-extension", {correlationId: activeGuid});

src/serialmonitor/usbDetector.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,8 @@ export class UsbDetector {
150150
const readme = path.join(ArduinoContext.boardManager.currentBoard.platform.rootBoardPath, "README.md");
151151
if (util.fileExistsSync(readme)) {
152152
vscode.commands.executeCommand("markdown.showPreview", vscode.Uri.file(readme));
153+
vscode.commands.executeCommand("setContext", "vscode-arduino:showExampleExplorer", true);
153154
}
154-
vscode.commands.executeCommand("arduino.reloadExample");
155-
vscode.commands.executeCommand("arduino.showExamples");
156155
}
157156
}
158157

src/views/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"file-loader": "^0.10.0",
2020
"html-webpack-plugin": "^2.28.0",
2121
"node-sass": "^4.5.0",
22-
"rc-tree": "^1.4.5",
22+
"rc-tree": "~1.4.5",
2323
"react": "^15.4.2",
2424
"react-bootstrap": "^0.30.7",
2525
"react-dom": "^15.4.2",

test/extension.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ suite("Arduino: Extension Tests", () => {
4848
"arduino.closeSerialMonitor",
4949
"arduino.reloadExample",
5050
"arduino.debug.startSession",
51+
"arduino.showExampleExplorer",
5152
];
5253

5354
const foundArduinoCommands = commands.filter((value) => {

0 commit comments

Comments
 (0)