diff --git a/.reuse/dep5 b/.reuse/dep5 index d0ce366a47a..4121b85fb1e 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -59,10 +59,22 @@ Files: tools/slintpad/*.html tools/slintpad/styles/*.css tools/slintpad/*.json Copyright: Copyright © SixtyFPS GmbH License: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial -Files: editors/vscode/*.json editors/vscode/README.md editors/vscode/css/*.css editors/tree-sitter-slint/corpus/*.txt +Files: editors/vscode/*.json editors/vscode/README.md editors/vscode/css/*.css editors/tree-sitter-slint/corpus/*.txt editors/vscode/static/**/*.html editors/vscode/static/assets/img/bg-dark.svg editors/vscode/static/assets/img/slint-*.svg Copyright: Copyright © SixtyFPS GmbH License: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial +Files: editors/vscode/static/assets/img/cpp_logo.svg +Copyright: Copyright © 2017 Jeremy Kratz +License: CC0-1.0 + +Files: editors/vscode/static/assets/img/rust-logo.svg +Copyright: ® Rust Foundation +License: CC-BY-4.0 + +Files: editors/vscode/static/assets/img/nodejs_logo.svg +Copyright: node.js authors +License: CC0-1.0 + Files: tests/screenshots/references/software/*/*.png Copyright: Copyright © SixtyFPS GmbH License: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial diff --git a/LICENSES/CC0-1.0.txt b/LICENSES/CC0-1.0.txt new file mode 100644 index 00000000000..0e259d42c99 --- /dev/null +++ b/LICENSES/CC0-1.0.txt @@ -0,0 +1,121 @@ +Creative Commons Legal Code + +CC0 1.0 Universal + + CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE + LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN + ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS + INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES + REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS + PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM + THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED + HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work of +authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without fear +of later claims of infringement build upon, modify, incorporate in other +works, reuse and redistribute as freely as possible in any form whatsoever +and for any purposes, including without limitation commercial purposes. +These owners may contribute to the Commons to promote the ideal of a free +culture and the further production of creative, cultural and scientific +works, or to gain reputation or greater distribution for their Work in +part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or she +is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under its +terms, with knowledge of his or her Copyright and Related Rights in the +Work and the meaning and intended legal effect of CC0 on those rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + + i. the right to reproduce, adapt, distribute, perform, display, + communicate, and translate a Work; + ii. moral rights retained by the original author(s) and/or performer(s); +iii. publicity and privacy rights pertaining to a person's image or + likeness depicted in a Work; + iv. rights protecting against unfair competition in regards to a Work, + subject to the limitations in paragraph 4(a), below; + v. rights protecting the extraction, dissemination, use and reuse of data + in a Work; + vi. database rights (such as those arising under Directive 96/9/EC of the + European Parliament and of the Council of 11 March 1996 on the legal + protection of databases, and under any national implementation + thereof, including any amended or successor version of such + directive); and +vii. other similar, equivalent or corresponding rights throughout the + world based on applicable law or treaty, and any national + implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or future +medium and for any number of copies, and (iv) for any purpose whatsoever, +including without limitation commercial, advertising or promotional +purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each +member of the public at large and to the detriment of Affirmer's heirs and +successors, fully intending that such Waiver shall not be subject to +revocation, rescission, cancellation, termination, or any other legal or +equitable action to disrupt the quiet enjoyment of the Work by the public +as contemplated by Affirmer's express Statement of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non exclusive, +irrevocable and unconditional license to exercise Affirmer's Copyright and +Related Rights in the Work (i) in all territories worldwide, (ii) for the +maximum duration provided by applicable law or treaty (including future +time extensions), (iii) in any current or future medium and for any number +of copies, and (iv) for any purpose whatsoever, including without +limitation commercial, advertising or promotional purposes (the +"License"). The License shall be deemed effective as of the date CC0 was +applied by Affirmer to the Work. Should any part of the License for any +reason be judged legally invalid or ineffective under applicable law, such +partial invalidity or ineffectiveness shall not invalidate the remainder +of the License, and in such case Affirmer hereby affirms that he or she +will not (i) exercise any of his or her remaining Copyright and Related +Rights in the Work or (ii) assert any associated claims and causes of +action with respect to the Work, in either case contrary to Affirmer's +express Statement of Purpose. + +4. Limitations and Disclaimers. + + a. No trademark or patent rights held by Affirmer are waived, abandoned, + surrendered, licensed or otherwise affected by this document. + b. Affirmer offers the Work as-is and makes no representations or + warranties of any kind concerning the Work, express, implied, + statutory or otherwise, including without limitation warranties of + title, merchantability, fitness for a particular purpose, non + infringement, or the absence of latent or other defects, accuracy, or + the present or absence of errors, whether or not discoverable, all to + the greatest extent permissible under applicable law. + c. Affirmer disclaims responsibility for clearing rights of other persons + that may apply to the Work or any use thereof, including without + limitation any person's Copyright and Related Rights in the Work. + Further, Affirmer disclaims responsibility for obtaining any necessary + consents, permissions or other rights required for any use of the + Work. + d. Affirmer understands and acknowledges that Creative Commons is not a + party to this document and has no duty or obligation with respect to + this CC0 or use of the Work. diff --git a/editors/vscode/package.json b/editors/vscode/package.json index 5e6ff4853a8..eb978cc5ebb 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -17,10 +17,14 @@ "Programming Languages" ], "activationEvents": [ + "onCommand:slint.showPreview", + "onCommand:slint.showWelcome", + "onCommand:slint.reload", "onLanguage:slint", "onLanguage:rust", "onWebviewPanel:slint-preview", - "onView:slint.propertiesView" + "onView:slint.propertiesView", + "workspaceContains:{**/CMakeLists.txt,**/Cargo.toml,**/*.slint}" ], "main": "./out/extension.js", "browser": "./out/browser.js", @@ -61,6 +65,11 @@ "title": "Show Preview", "category": "Slint" }, + { + "command": "slint.showWelcome", + "title": "Show Welcome Page", + "category": "Slint" + }, { "command": "slint.toggleDesignMode", "title": "Toggle Design Mode in Slint Preview (experimental)", @@ -108,6 +117,11 @@ "type": "string" }, "description": "List of paths in which the `import` statement and `@image-url` are looked up" + }, + "slint.showWelcomeOnActivation": { + "type": "string", + "default": "", + "description": "Open the Slint Welcome page when the Plugin gets activated (\"always\", \"never\")" } } }, diff --git a/editors/vscode/src/common.ts b/editors/vscode/src/common.ts index 9e04f7f41ad..0ac2e481394 100644 --- a/editors/vscode/src/common.ts +++ b/editors/vscode/src/common.ts @@ -8,6 +8,7 @@ import * as vscode from "vscode"; import { PropertiesViewProvider } from "./properties_webview"; import * as wasm_preview from "./wasm_preview"; import * as lsp_commands from "../../../tools/slintpad/src/shared/lsp_commands"; +import * as welcome from "./welcome/welcomepanel"; import { BaseLanguageClient, @@ -51,7 +52,9 @@ export class ClientHandle { async stop() { if (this.#client) { // mark as stopped so that we don't detect it as a crash - Object.defineProperty(this.#client, "slint_stopped", { value: true }); + Object.defineProperty(this.#client, "slint_stopped", { + value: true, + }); await this.#client.stop(); } } @@ -145,6 +148,11 @@ export function activate( lsp_commands.showPreview(ae.document.uri.toString(), ""); }), ); + context.subscriptions.push( + vscode.commands.registerCommand("slint.showWelcome", function () { + welcome.WelcomePanel.createOrShow(context.extensionPath); + }), + ); context.subscriptions.push( vscode.commands.registerCommand("slint.toggleDesignMode", function () { lsp_commands.toggleDesignMode(); @@ -181,6 +189,7 @@ export function activate( }, ); wasm_preview.refreshPreview(); + welcome.WelcomePanel.updateShowConfig(); } }); @@ -200,6 +209,8 @@ export function activate( }, 1); }); + setTimeout(() => welcome.WelcomePanel.maybeShow(context.extensionPath), 1); + return [statusBar, properties_provider]; } diff --git a/editors/vscode/src/welcome/welcomepanel.ts b/editors/vscode/src/welcome/welcomepanel.ts new file mode 100644 index 00000000000..758cdc3dd6b --- /dev/null +++ b/editors/vscode/src/welcome/welcomepanel.ts @@ -0,0 +1,140 @@ +// Copyright © SixtyFPS GmbH +// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial + +import * as vscode from "vscode"; + +const pkg = require("../../package.json"); + +// This file is the Welcome Panel/Page +export class WelcomePanel { + static #currentPanel: WelcomePanel | undefined; + #webview: vscode.WebviewPanel; + #disposables: vscode.Disposable[] = []; + + constructor(extensionPath: string, column: vscode.ViewColumn) { + const url = vscode.Uri.file(extensionPath); + this.#webview = vscode.window.createWebviewPanel( + "slint.WelcomePage", + "Slint Welcome Page", + column, + { + enableScripts: true, + retainContextWhenHidden: true, + localResourceRoots: [vscode.Uri.joinPath(url, "static")], + }, + ); + this.getHtml(url).then( + (contents) => (this.#webview.webview.html = contents), + ); + this.#webview.webview.onDidReceiveMessage(async (message: any) => { + switch (message.command) { + case "ChangeShowWelcomeConfig": { + WelcomePanel.showWelcomeOnActivation = + WelcomePanel.filterShowWelcomeOnActivation( + message.value, + ); + return; + } + } + }); + + this.#webview.onDidDispose( + () => this.dispose(), + null, + this.#disposables, + ); + } + + public dispose() { + WelcomePanel.#currentPanel = undefined; + this.#webview.dispose(); + } + + public static createOrShow(extensionPath: string) { + const column = vscode.window.activeTextEditor?.viewColumn; + if (WelcomePanel.#currentPanel) { + WelcomePanel.#currentPanel.#webview.reveal(column); + } else { + WelcomePanel.#currentPanel = new WelcomePanel( + extensionPath, + column ?? vscode.ViewColumn.One, + ); + } + WelcomePanel.updateShowConfig(); + } + + public static maybeShow(extensionPath: string) { + if (WelcomePanel.openPanelOnActivation()) { + WelcomePanel.createOrShow(extensionPath); + } + } + + public static postMessage(message: any) { + if (WelcomePanel.#currentPanel) { + WelcomePanel.#currentPanel.#webview.webview.postMessage(message); + } + } + + private static set showWelcomeOnActivation(value: string) { + vscode.workspace + .getConfiguration("slint") + .update("showWelcomeOnActivation", value, true); + } + + private static get showWelcomeOnActivation(): string { + return ( + vscode.workspace + .getConfiguration("slint") + .get("showWelcomeOnActivation") ?? "" + ); + } + + private static filterShowWelcomeOnActivation(value: string): string { + if (value === "always" || value === "never") { + return value; + } + return "never"; + } + + private static openPanelOnActivation(): boolean { + const result = WelcomePanel.showWelcomeOnActivation; + const filtered = this.filterShowWelcomeOnActivation(result); + if (result !== filtered) { + WelcomePanel.showWelcomeOnActivation = filtered; + } + + return result !== "never"; // Use the result here, not filtered! + } + + static updateShowConfig() { + const value = WelcomePanel.showWelcomeOnActivation; + WelcomePanel.postMessage({ + command: "ChangeShowWelcomeConfig", + value: this.filterShowWelcomeOnActivation(value), + }); + } + + private async getHtml(extensionUri: vscode.Uri): Promise { + let data = await vscode.workspace.fs.readFile( + vscode.Uri.joinPath( + extensionUri, + "static", + "welcome", + "index.html", + ), + ); + let result = Buffer.from(data).toString("utf-8"); + + result = result.replaceAll("", pkg.version); + result = result.replaceAll( + "", + this.#webview.webview + .asWebviewUri( + vscode.Uri.joinPath(extensionUri, "static", "assets"), + ) + .toString(), + ); + + return result; + } +} diff --git a/editors/vscode/static/assets/img/bg-dark.svg b/editors/vscode/static/assets/img/bg-dark.svg new file mode 100644 index 00000000000..b74099102a3 --- /dev/null +++ b/editors/vscode/static/assets/img/bg-dark.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/editors/vscode/static/assets/img/cpp_logo.svg b/editors/vscode/static/assets/img/cpp_logo.svg new file mode 100644 index 00000000000..a2f5adb0e3b --- /dev/null +++ b/editors/vscode/static/assets/img/cpp_logo.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + diff --git a/editors/vscode/static/assets/img/nodejs_logo.svg b/editors/vscode/static/assets/img/nodejs_logo.svg new file mode 100644 index 00000000000..15d83f159f7 --- /dev/null +++ b/editors/vscode/static/assets/img/nodejs_logo.svg @@ -0,0 +1 @@ + diff --git a/editors/vscode/static/assets/img/rust-logo.svg b/editors/vscode/static/assets/img/rust-logo.svg new file mode 100644 index 00000000000..e44f14a5dc8 --- /dev/null +++ b/editors/vscode/static/assets/img/rust-logo.svg @@ -0,0 +1,18 @@ + + diff --git a/editors/vscode/static/assets/img/slint-favicon.svg b/editors/vscode/static/assets/img/slint-favicon.svg new file mode 100644 index 00000000000..6351d013ce3 --- /dev/null +++ b/editors/vscode/static/assets/img/slint-favicon.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/editors/vscode/static/assets/img/slint-logo-dark.svg b/editors/vscode/static/assets/img/slint-logo-dark.svg new file mode 100644 index 00000000000..cfd6e651ff8 --- /dev/null +++ b/editors/vscode/static/assets/img/slint-logo-dark.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/editors/vscode/static/assets/img/slint-logo.svg b/editors/vscode/static/assets/img/slint-logo.svg new file mode 100644 index 00000000000..9c80286419d --- /dev/null +++ b/editors/vscode/static/assets/img/slint-logo.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/editors/vscode/static/welcome/index.html b/editors/vscode/static/welcome/index.html new file mode 100644 index 00000000000..81403726fc3 --- /dev/null +++ b/editors/vscode/static/welcome/index.html @@ -0,0 +1,605 @@ + + + + + + +
+
+ +
+ +
+ + + +
+ + +

Documentation

+ +

+ Whether you’re developing the UI or the backend, Slint's + documentation will guide you. +

+
+
+
+
+
DSL
+

Slint Language

+

+ +

+

+ Language Documentation +

+
+ +
+ +
+
+
+
APIs
+

Using Rust

+

+ +

+

+ API Documentation +

+

+ Tutorial +

+

+ Tutorial Video +

+

+ Project Template +

+
+ +
+
APIs
+

Using C++

+

+ +

+

+ API Documentation +

+

+ Tutorial +

+

+ Project Template +

+
+ +
+
APIs
+

Using NodeJS (beta)

+

+ +

+

+ API Documentation +

+

+ Tutorial +

+

+ Project Template +

+
+ +
+ +
+ +
+ +
+ +

+ Show this page: + +

+
+ + + + diff --git a/editors/vscode/tsconfig.json b/editors/vscode/tsconfig.json index 2a4de3bbeeb..a6e8c80d154 100644 --- a/editors/vscode/tsconfig.json +++ b/editors/vscode/tsconfig.json @@ -3,7 +3,7 @@ "module": "commonjs", "target": "es2020", "outDir": "out", - "lib": ["es2020", "WebWorker", "dom"], + "lib": ["es2021", "WebWorker", "dom"], "sourceMap": true, "rootDir": ".", "strict": true /* enable all strict type-checking options */