mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-30 13:51:13 +00:00
node: api review adjustements part I (#3766)
* Update api/node/src/types/brush.rs Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update tests/cases/callbacks/handler_with_arg.slint Co-authored-by: Olivier Goffart <olivier.goffart@slint.dev> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Olivier Goffart <olivier.goffart@slint.dev>
This commit is contained in:
parent
081e7fe456
commit
0045787e1c
18 changed files with 340 additions and 142 deletions
|
@ -128,7 +128,7 @@ export component MyComponent inherits Window {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The callbacks in JavaScript are exposed as property that has a setHandler function, and that can be called as a function.
|
The callbacks in JavaScript are exposed as property and that can be called as a function.
|
||||||
|
|
||||||
**`main.js`**
|
**`main.js`**
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@ let ui = slint.loadFile("ui/my-component.slint");
|
||||||
let component = new ui.MyComponent();
|
let component = new ui.MyComponent();
|
||||||
|
|
||||||
// connect to a callback
|
// connect to a callback
|
||||||
component.clicked.setHandler(function() { console.log("hello"); })
|
component.clicked = function() { console.log("hello"); };
|
||||||
// emit a callback
|
// emit a callback
|
||||||
component.clicked();
|
component.clicked();
|
||||||
```
|
```
|
||||||
|
|
|
@ -22,25 +22,25 @@ test('loadFile', (t) => {
|
||||||
t.is(error?.message, "Could not compile " + errorPath);
|
t.is(error?.message, "Could not compile " + errorPath);
|
||||||
t.deepEqual(error?.diagnostics, [
|
t.deepEqual(error?.diagnostics, [
|
||||||
{
|
{
|
||||||
column: 18,
|
columnNumber: 18,
|
||||||
level: 0,
|
level: 0,
|
||||||
lineNumber: 7,
|
lineNumber: 7,
|
||||||
message: 'Missing type. The syntax to declare a property is `property <type> name;`. Only two way bindings can omit the type',
|
message: 'Missing type. The syntax to declare a property is `property <type> name;`. Only two way bindings can omit the type',
|
||||||
sourceFile: errorPath
|
fileName: errorPath
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
column: 22,
|
columnNumber: 22,
|
||||||
level: 0,
|
level: 0,
|
||||||
lineNumber: 7,
|
lineNumber: 7,
|
||||||
message: 'Syntax error: expected \';\'',
|
message: 'Syntax error: expected \';\'',
|
||||||
sourceFile: errorPath
|
fileName: errorPath
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
column: 22,
|
columnNumber: 22,
|
||||||
level: 0,
|
level: 0,
|
||||||
lineNumber: 7,
|
lineNumber: 7,
|
||||||
message: 'Parse error',
|
message: 'Parse error',
|
||||||
sourceFile: errorPath
|
fileName: errorPath
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
})
|
})
|
||||||
|
@ -50,7 +50,6 @@ test('constructor parameters', (t) => {
|
||||||
let hello = "";
|
let hello = "";
|
||||||
let test = new demo.Test({ say_hello: function() { hello = "hello"; }, check: "test"});
|
let test = new demo.Test({ say_hello: function() { hello = "hello"; }, check: "test"});
|
||||||
|
|
||||||
// test.say_hello.setHandler(function () { blub = "hello"; });
|
|
||||||
test.say_hello();
|
test.say_hello();
|
||||||
|
|
||||||
t.is(test.check, "test");
|
t.is(test.check, "test");
|
||||||
|
|
|
@ -15,6 +15,20 @@ test('get/set include paths', (t) => {
|
||||||
t.deepEqual(compiler.includePaths, ["path/one/", "path/two/", "path/three/"]);
|
t.deepEqual(compiler.includePaths, ["path/one/", "path/two/", "path/three/"]);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('get/set library paths', (t) => {
|
||||||
|
let compiler = new private_api.ComponentCompiler;
|
||||||
|
|
||||||
|
compiler.libraryPaths = {
|
||||||
|
"libfile.slint" : "third_party/libfoo/ui/lib.slint",
|
||||||
|
"libdir" : "third_party/libbar/ui/",
|
||||||
|
};
|
||||||
|
|
||||||
|
t.deepEqual(compiler.libraryPaths, {
|
||||||
|
"libfile.slint" : "third_party/libfoo/ui/lib.slint",
|
||||||
|
"libdir" : "third_party/libbar/ui/",
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
test('get/set style', (t) => {
|
test('get/set style', (t) => {
|
||||||
let compiler = new private_api.ComponentCompiler;
|
let compiler = new private_api.ComponentCompiler;
|
||||||
|
|
||||||
|
@ -209,8 +223,8 @@ test('compiler diagnostics', (t) => {
|
||||||
level: 0,
|
level: 0,
|
||||||
message: 'Parse error',
|
message: 'Parse error',
|
||||||
lineNumber: 2,
|
lineNumber: 2,
|
||||||
column: 12,
|
columnNumber: 12,
|
||||||
sourceFile: 'testsource.slint'
|
fileName: 'testsource.slint'
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -190,9 +190,9 @@ test('get/set image properties', async (t) => {
|
||||||
t.not(instance, null);
|
t.not(instance, null);
|
||||||
|
|
||||||
let slintImage = instance!.getProperty("image");
|
let slintImage = instance!.getProperty("image");
|
||||||
if (t.true((slintImage instanceof ImageData))) {
|
if (t.true((slintImage instanceof private_api.ImageData))) {
|
||||||
t.deepEqual((slintImage as ImageData).width, 64);
|
t.deepEqual((slintImage as private_api.ImageData).width, 64);
|
||||||
t.deepEqual((slintImage as ImageData).height, 64);
|
t.deepEqual((slintImage as private_api.ImageData).height, 64);
|
||||||
|
|
||||||
let image = await Jimp.read(path.join(__dirname, "resources/rgb.png"));
|
let image = await Jimp.read(path.join(__dirname, "resources/rgb.png"));
|
||||||
|
|
||||||
|
@ -237,6 +237,8 @@ test('get/set brush properties', (t) => {
|
||||||
in-out property <brush> black: #000000;
|
in-out property <brush> black: #000000;
|
||||||
in-out property <brush> trans: transparent;
|
in-out property <brush> trans: transparent;
|
||||||
in-out property <brush> ref: transparent;
|
in-out property <brush> ref: transparent;
|
||||||
|
in-out property <brush> linear-gradient: @linear-gradient(90deg, #3f87a6 0%, #ebf8e1 50%, #f69d3c 100%);
|
||||||
|
in-out property <brush> radial-gradient: @radial-gradient(circle, #f00 0%, #0f0 50%, #00f 100%);
|
||||||
}
|
}
|
||||||
`, "");
|
`, "");
|
||||||
t.not(definition, null);
|
t.not(definition, null);
|
||||||
|
@ -271,7 +273,7 @@ test('get/set brush properties', (t) => {
|
||||||
t.assert((transparent as Brush).isTransparent);
|
t.assert((transparent as Brush).isTransparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
let ref = Brush.fromColor(Color.fromRgb(100, 110, 120));
|
let ref = new Brush({ red: 100, green: 110, blue: 120, alpha: 255 });
|
||||||
instance!.setProperty("ref", ref);
|
instance!.setProperty("ref", ref);
|
||||||
|
|
||||||
let instance_ref = instance!.getProperty("ref");
|
let instance_ref = instance!.getProperty("ref");
|
||||||
|
@ -281,6 +283,21 @@ test('get/set brush properties', (t) => {
|
||||||
t.deepEqual(ref_color.red, 100);
|
t.deepEqual(ref_color.red, 100);
|
||||||
t.deepEqual(ref_color.green, 110);
|
t.deepEqual(ref_color.green, 110);
|
||||||
t.deepEqual(ref_color.blue, 120);
|
t.deepEqual(ref_color.blue, 120);
|
||||||
|
t.deepEqual(ref_color.alpha, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
let radialGradient = instance!.getProperty("radial-gradient");
|
||||||
|
|
||||||
|
if (t.true((radialGradient instanceof Brush))) {
|
||||||
|
t.is((radialGradient as Brush).toString(),
|
||||||
|
"radial-gradient(circle, rgba(255, 0, 0, 255) 0%, rgba(0, 255, 0, 255) 50%, rgba(0, 0, 255, 255) 100%)");
|
||||||
|
}
|
||||||
|
|
||||||
|
let linearGradient = instance!.getProperty("linear-gradient");
|
||||||
|
|
||||||
|
if (t.true((linearGradient instanceof Brush))) {
|
||||||
|
t.is((linearGradient as Brush).toString(),
|
||||||
|
"linear-gradient(90deg, rgba(63, 135, 166, 255) 0%, rgba(235, 248, 225, 255) 50%, rgba(246, 157, 60, 255) 100%)");
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
import test from 'ava';
|
import test from 'ava';
|
||||||
|
|
||||||
import { Brush, Color, ArrayModel, Timer } from '../index'
|
import { Brush, ArrayModel, Timer, private_api } from '../index'
|
||||||
|
|
||||||
test('Color from fromRgb', (t) => {
|
test('Color from fromRgb', (t) => {
|
||||||
let color = Color.fromRgb(100, 110, 120);
|
let color = private_api.SlintColor.fromRgb(100, 110, 120);
|
||||||
|
|
||||||
t.deepEqual(color.red, 100);
|
t.deepEqual(color.red, 100);
|
||||||
t.deepEqual(color.green, 110);
|
t.deepEqual(color.green, 110);
|
||||||
|
@ -14,7 +14,7 @@ test('Color from fromRgb', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Color from fromArgb', (t) => {
|
test('Color from fromArgb', (t) => {
|
||||||
let color = Color.fromArgb(120, 100, 110, 120);
|
let color = private_api.SlintColor.fromArgb(120, 100, 110, 120);
|
||||||
|
|
||||||
t.deepEqual(color.red, 100);
|
t.deepEqual(color.red, 100);
|
||||||
t.deepEqual(color.green, 110);
|
t.deepEqual(color.green, 110);
|
||||||
|
@ -23,7 +23,7 @@ test('Color from fromArgb', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Color from fromArgbEncoded', (t) => {
|
test('Color from fromArgbEncoded', (t) => {
|
||||||
let color = Color.fromArgbEncoded(2019847800);
|
let color = private_api.SlintColor.fromArgbEncoded(2019847800);
|
||||||
|
|
||||||
t.deepEqual(color.red, 100);
|
t.deepEqual(color.red, 100);
|
||||||
t.deepEqual(color.green, 110);
|
t.deepEqual(color.green, 110);
|
||||||
|
@ -31,7 +31,7 @@ test('Color from fromArgbEncoded', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Color brighter', (t) => {
|
test('Color brighter', (t) => {
|
||||||
let color = Color.fromRgb(100, 110, 120).brighter(0.1);
|
let color = private_api.SlintColor.fromRgb(100, 110, 120).brighter(0.1);
|
||||||
|
|
||||||
t.deepEqual(color.red, 110);
|
t.deepEqual(color.red, 110);
|
||||||
t.deepEqual(color.green, 121);
|
t.deepEqual(color.green, 121);
|
||||||
|
@ -39,7 +39,7 @@ test('Color brighter', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Color darker', (t) => {
|
test('Color darker', (t) => {
|
||||||
let color = Color.fromRgb(100, 110, 120).darker(0.1);
|
let color = private_api.SlintColor.fromRgb(100, 110, 120).darker(0.1);
|
||||||
|
|
||||||
t.deepEqual(color.red, 91);
|
t.deepEqual(color.red, 91);
|
||||||
t.deepEqual(color.green, 100);
|
t.deepEqual(color.green, 100);
|
||||||
|
@ -47,11 +47,20 @@ test('Color darker', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Brush from Color', (t) => {
|
test('Brush from Color', (t) => {
|
||||||
let brush = Brush.fromColor(Color.fromRgb(100, 110, 120));
|
let brush = new Brush({ red: 100, green: 110, blue: 120, alpha: 255 });
|
||||||
|
|
||||||
t.deepEqual(brush.color.red, 100);
|
t.deepEqual(brush.color.red, 100);
|
||||||
t.deepEqual(brush.color.green, 110);
|
t.deepEqual(brush.color.green, 110);
|
||||||
t.deepEqual(brush.color.blue, 120);
|
t.deepEqual(brush.color.blue, 120);
|
||||||
|
|
||||||
|
t.throws(() => {
|
||||||
|
new Brush({ red: -100, green: 110, blue: 120, alpha: 255 })
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "GenericFailure",
|
||||||
|
message: "A channel of Color cannot be negative"
|
||||||
|
}
|
||||||
|
);
|
||||||
})
|
})
|
||||||
|
|
||||||
test('ArrayModel push', (t) => {
|
test('ArrayModel push', (t) => {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { private_api, Window } from '../index'
|
||||||
|
|
||||||
test('Window constructor', (t) => {
|
test('Window constructor', (t) => {
|
||||||
t.throws(() => {
|
t.throws(() => {
|
||||||
new Window()
|
new private_api.Window()
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
code: "GenericFailure",
|
code: "GenericFailure",
|
||||||
|
@ -30,9 +30,9 @@ test('Window show / hide', (t) => {
|
||||||
t.not(instance, null);
|
t.not(instance, null);
|
||||||
|
|
||||||
let window = instance!.window();
|
let window = instance!.window();
|
||||||
t.is(window.is_visible, false);
|
t.is(window.isVisible, false);
|
||||||
window.show();
|
window.show();
|
||||||
t.is(window.is_visible, true);
|
t.is(window.isVisible, true);
|
||||||
window.hide();
|
window.hide();
|
||||||
t.is(window.is_visible, false);
|
t.is(window.isVisible, false);
|
||||||
})
|
})
|
|
@ -127,7 +127,7 @@ export component MyComponent inherits Window {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The callbacks in JavaScript are exposed as property that has a setHandler function, and that can be called as a function.
|
The callbacks in JavaScript are exposed as property and that can be called as a function.
|
||||||
|
|
||||||
**`main.js`**
|
**`main.js`**
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ let ui = slint.loadFile("ui/my-component.slint");
|
||||||
let component = new ui.MyComponent();
|
let component = new ui.MyComponent();
|
||||||
|
|
||||||
// connect to a callback
|
// connect to a callback
|
||||||
component.clicked.setHandler(function() { console.log("hello"); })
|
component.clicked = function() { console.log("hello"); };
|
||||||
// emit a callback
|
// emit a callback
|
||||||
component.clicked();
|
component.clicked();
|
||||||
```
|
```
|
||||||
|
|
|
@ -4,40 +4,78 @@
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
import * as napi from "./rust-module";
|
import * as napi from "./rust-module";
|
||||||
export { Diagnostic, DiagnosticLevel, Window, Brush, Color, ImageData, Point, Size, SlintModelNotify } from "./rust-module";
|
export { Diagnostic, DiagnosticLevel, Brush, Color, SlintModelNotify } from "./rust-module";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ModelPeer is the interface that the run-time implements. An instance is
|
* Represents a two-dimensional point.
|
||||||
* set on dynamic {@link Model} instances and can be used to notify the run-time
|
|
||||||
* of changes in the structure or data of the model.
|
|
||||||
*/
|
*/
|
||||||
export interface ModelPeer {
|
export interface Point {
|
||||||
|
x: number,
|
||||||
|
y: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a two-dimensional size.
|
||||||
|
*/
|
||||||
|
export interface Size {
|
||||||
|
width: number,
|
||||||
|
height: number
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type represents a window towards the windowing system, that's used to render the
|
||||||
|
* scene of a component. It provides API to control windowing system specific aspects such
|
||||||
|
* as the position on the screen.
|
||||||
|
*/
|
||||||
|
export interface Window {
|
||||||
/**
|
/**
|
||||||
* Call this function from our own model to notify that fields of data
|
* Shows the window on the screen. An additional strong reference on the
|
||||||
* in the specified row have changed.
|
* associated component is maintained while the window is visible.
|
||||||
* @argument row
|
|
||||||
*/
|
*/
|
||||||
rowDataChanged(row: number): void;
|
show(): void;
|
||||||
/**
|
|
||||||
* Call this function from your own model to notify that one or multiple
|
/** Hides the window, so that it is not visible anymore. */
|
||||||
* rows were added to the model, starting at the specified row.
|
hide(): void;
|
||||||
* @param row
|
|
||||||
* @param count
|
|
||||||
*/
|
|
||||||
rowAdded(row: number, count: number): void;
|
|
||||||
/**
|
|
||||||
* Call this function from your own model to notify that one or multiple
|
|
||||||
* rows were removed from the model, starting at the specified row.
|
|
||||||
* @param row
|
|
||||||
* @param count
|
|
||||||
*/
|
|
||||||
rowRemoved(row: number, count: number): void;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call this function from your own model to notify that the model has been
|
* Returns the visibility state of the window. This function can return false even if you previously called show()
|
||||||
* changed and everything must be reloaded
|
* on it, for example if the user minimized the window.
|
||||||
*/
|
*/
|
||||||
reset(): void;
|
get isVisible(): boolean;
|
||||||
|
|
||||||
|
/** Gets or sets the logical position of the window on the screen. */
|
||||||
|
logicalPosition: Point;
|
||||||
|
|
||||||
|
/** Gets or sets the physical position of the window on the screen. */
|
||||||
|
physicalPosition: Point;
|
||||||
|
|
||||||
|
/** Gets or sets the logical size of the window on the screen, */
|
||||||
|
logicalSize: Size;
|
||||||
|
|
||||||
|
/** Gets or sets the physical size of the window on the screen, */
|
||||||
|
physicalSize: Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An image data type that can be displayed by the Image element.
|
||||||
|
*
|
||||||
|
* This interface is inspired by the web [ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData) interface.
|
||||||
|
*/
|
||||||
|
export interface ImageData {
|
||||||
|
/**
|
||||||
|
* Returns the image as buffer.
|
||||||
|
*/
|
||||||
|
get data(): Uint8Array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the width of the image in pixels.
|
||||||
|
*/
|
||||||
|
get width(): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the height of the image in pixels.
|
||||||
|
*/
|
||||||
|
get height(): number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,11 +91,10 @@ export interface ModelPeer {
|
||||||
* ```js
|
* ```js
|
||||||
* export class ArrayModel<T> implements Model<T> {
|
* export class ArrayModel<T> implements Model<T> {
|
||||||
* private a: Array<T>
|
* private a: Array<T>
|
||||||
* notify: ModelPeer;
|
|
||||||
*
|
*
|
||||||
* constructor(arr: Array<T>) {
|
* constructor(arr: Array<T>) {
|
||||||
|
* super();
|
||||||
* this.a = arr;
|
* this.a = arr;
|
||||||
* this.notify = new NullPeer();
|
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* rowCount() {
|
* rowCount() {
|
||||||
|
@ -98,34 +135,38 @@ export interface ModelPeer {
|
||||||
*}
|
*}
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export interface Model<T> {
|
export abstract class Model<T> {
|
||||||
|
/**
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
notify: NullPeer;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.notify = new NullPeer();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementations of this function must return the current number of rows.
|
* Implementations of this function must return the current number of rows.
|
||||||
*/
|
*/
|
||||||
rowCount(): number;
|
abstract rowCount(): number;
|
||||||
/**
|
/**
|
||||||
* Implementations of this function must return the data at the specified row.
|
* Implementations of this function must return the data at the specified row.
|
||||||
* @param row
|
* @param row
|
||||||
*/
|
*/
|
||||||
rowData(row: number): T | undefined;
|
abstract rowData(row: number): T | undefined;
|
||||||
/**
|
/**
|
||||||
* Implementations of this function must store the provided data parameter
|
* Implementations of this function must store the provided data parameter
|
||||||
* in the model at the specified row.
|
* in the model at the specified row.
|
||||||
* @param row
|
* @param row
|
||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
setRowData(row: number, data: T): void;
|
abstract setRowData(row: number, data: T): void;
|
||||||
/**
|
|
||||||
* This public member is set by the run-time and implementation must use this
|
|
||||||
* to notify the run-time of changes in the model.
|
|
||||||
*/
|
|
||||||
notify: ModelPeer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
class NullPeer implements ModelPeer {
|
class NullPeer {
|
||||||
rowDataChanged(row: number): void { }
|
rowDataChanged(row: number): void { }
|
||||||
rowAdded(row: number, count: number): void { }
|
rowAdded(row: number, count: number): void { }
|
||||||
rowRemoved(row: number, count: number): void { }
|
rowRemoved(row: number, count: number): void { }
|
||||||
|
@ -136,12 +177,11 @@ class NullPeer implements ModelPeer {
|
||||||
* ArrayModel wraps a JavaScript array for use in `.slint` views. The underlying
|
* ArrayModel wraps a JavaScript array for use in `.slint` views. The underlying
|
||||||
* array can be modified with the [[ArrayModel.push]] and [[ArrayModel.remove]] methods.
|
* array can be modified with the [[ArrayModel.push]] and [[ArrayModel.remove]] methods.
|
||||||
*/
|
*/
|
||||||
export class ArrayModel<T> implements Model<T> {
|
export class ArrayModel<T> extends Model<T> {
|
||||||
/**
|
/**
|
||||||
* @hidden
|
* @hidden
|
||||||
*/
|
*/
|
||||||
private a: Array<T>
|
private a: Array<T>
|
||||||
notify: ModelPeer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new ArrayModel.
|
* Creates a new ArrayModel.
|
||||||
|
@ -149,8 +189,8 @@ export class ArrayModel<T> implements Model<T> {
|
||||||
* @param arr
|
* @param arr
|
||||||
*/
|
*/
|
||||||
constructor(arr: Array<T>) {
|
constructor(arr: Array<T>) {
|
||||||
|
super();
|
||||||
this.a = arr;
|
this.a = arr;
|
||||||
this.notify = new NullPeer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rowCount() {
|
rowCount() {
|
||||||
|
@ -176,9 +216,7 @@ export class ArrayModel<T> implements Model<T> {
|
||||||
// FIXME: should this be named splice and have the splice api?
|
// FIXME: should this be named splice and have the splice api?
|
||||||
/**
|
/**
|
||||||
* Removes the specified number of element from the array that's backing
|
* Removes the specified number of element from the array that's backing
|
||||||
* the model, starting at the specified index. This is equivalent to calling
|
* the model, starting at the specified index.
|
||||||
* Array.slice() on the array and notifying the run-time about the removed
|
|
||||||
* rows.
|
|
||||||
* @param index
|
* @param index
|
||||||
* @param size
|
* @param size
|
||||||
*/
|
*/
|
||||||
|
@ -225,7 +263,7 @@ export interface ComponentHandle {
|
||||||
* Returns the {@link Window} associated with this component instance.
|
* Returns the {@link Window} associated with this component instance.
|
||||||
* The window API can be used to control different aspects of the integration into the windowing system, such as the position on the screen.
|
* The window API can be used to control different aspects of the integration into the windowing system, such as the position on the screen.
|
||||||
*/
|
*/
|
||||||
get window(): napi.Window;
|
get window(): Window;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -253,7 +291,7 @@ class Component implements ComponentHandle {
|
||||||
this.instance.window().hide();
|
this.instance.window().hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
get window(): napi.Window {
|
get window(): Window {
|
||||||
return this.instance.window();
|
return this.instance.window();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,13 +303,6 @@ class Component implements ComponentHandle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @hidden
|
|
||||||
*/
|
|
||||||
interface Callback {
|
|
||||||
(): any;
|
|
||||||
setHandler(cb: any): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an errors that can be emitted by the compiler.
|
* Represents an errors that can be emitted by the compiler.
|
||||||
|
@ -292,17 +323,65 @@ export class CompileError extends Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the given slint file and returns a constructor to create an instance of the exported component.
|
* LoadFileOptions are used to defines different optional parameters that can be used to configure the compiler.
|
||||||
*/
|
*/
|
||||||
export function loadFile(filePath: string): Object {
|
export interface LoadFileOptions {
|
||||||
|
/**
|
||||||
|
* If set to true warnings from the compiler will not be printed to the console.
|
||||||
|
*/
|
||||||
|
quiet?: boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the widget style the compiler is currently using when compiling .slint files.
|
||||||
|
*/
|
||||||
|
style?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the include paths used for looking up `.slint` imports to the specified vector of paths.
|
||||||
|
*/
|
||||||
|
includePaths?: Array<string>,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets library paths used for looking up `@library` imports to the specified map of library names to paths.
|
||||||
|
*/
|
||||||
|
libraryPaths?: Record<string, string>
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the given slint file and returns an objects that contains a functions to construct the exported
|
||||||
|
* component of the slint file.
|
||||||
|
*
|
||||||
|
* ```js
|
||||||
|
* import * as slint from "slint-ui";
|
||||||
|
* let ui = slint.loadFile(".ui/main.slint");
|
||||||
|
* let main = new ui.Main();
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export function loadFile(filePath: string, options?: LoadFileOptions) : Object {
|
||||||
let compiler = new napi.ComponentCompiler;
|
let compiler = new napi.ComponentCompiler;
|
||||||
|
|
||||||
|
if (typeof options !== 'undefined') {
|
||||||
|
if (typeof options.style !== 'undefined') {
|
||||||
|
compiler.style = options.style;
|
||||||
|
}
|
||||||
|
if (typeof options.includePaths !== 'undefined') {
|
||||||
|
compiler.includePaths = options.includePaths;
|
||||||
|
}
|
||||||
|
if (typeof options.libraryPaths !== 'undefined') {
|
||||||
|
compiler.libraryPaths = options.libraryPaths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let definition = compiler.buildFromPath(filePath);
|
let definition = compiler.buildFromPath(filePath);
|
||||||
|
|
||||||
let diagnostics = compiler.diagnostics;
|
let diagnostics = compiler.diagnostics;
|
||||||
|
|
||||||
if (diagnostics.length > 0) {
|
if (diagnostics.length > 0) {
|
||||||
let warnings = diagnostics.filter((d) => d.level == napi.DiagnosticLevel.Warning);
|
let warnings = diagnostics.filter((d) => d.level == napi.DiagnosticLevel.Warning);
|
||||||
warnings.forEach((w) => console.log("Warning: " + w));
|
|
||||||
|
if (typeof options !== 'undefined' && options.quiet !== true) {
|
||||||
|
warnings.forEach((w) => console.warn("Warning: " + w));
|
||||||
|
}
|
||||||
|
|
||||||
let errors = diagnostics.filter((d) => d.level == napi.DiagnosticLevel.Error);
|
let errors = diagnostics.filter((d) => d.level == napi.DiagnosticLevel.Error);
|
||||||
|
|
||||||
|
@ -343,9 +422,10 @@ export function loadFile(filePath: string): Object {
|
||||||
instance!.definition().callbacks.forEach((cb) => {
|
instance!.definition().callbacks.forEach((cb) => {
|
||||||
Object.defineProperty(componentHandle, cb.replace(/-/g, '_') , {
|
Object.defineProperty(componentHandle, cb.replace(/-/g, '_') , {
|
||||||
get() {
|
get() {
|
||||||
let callback = function () { return instance!.invoke(cb, Array.from(arguments)); } as Callback;
|
return function () { return instance!.invoke(cb, Array.from(arguments)); };
|
||||||
callback.setHandler = function (callback) { instance!.setCallback(cb, callback) };
|
},
|
||||||
return callback;
|
set(callback) {
|
||||||
|
instance!.setCallback(cb, callback);
|
||||||
},
|
},
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
})
|
})
|
||||||
|
@ -375,6 +455,9 @@ export namespace private_api {
|
||||||
export import ComponentDefinition = napi.ComponentDefinition;
|
export import ComponentDefinition = napi.ComponentDefinition;
|
||||||
export import ComponentInstance = napi.ComponentInstance;
|
export import ComponentInstance = napi.ComponentInstance;
|
||||||
export import ValueType = napi.ValueType;
|
export import ValueType = napi.ValueType;
|
||||||
|
export import Window = napi.Window;
|
||||||
|
export import ImageData = napi.ImageData;
|
||||||
|
export import SlintColor = napi.SlintColor;
|
||||||
|
|
||||||
export function send_mouse_click(component: Component, x: number, y: number) {
|
export function send_mouse_click(component: Component, x: number, y: number) {
|
||||||
component.component_instance.sendMouseClick(x, y);
|
component.component_instance.sendMouseClick(x, y);
|
||||||
|
|
|
@ -71,6 +71,17 @@ impl JsComponentCompiler {
|
||||||
self.internal.set_library_paths(library_paths);
|
self.internal.set_library_paths(library_paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[napi(getter)]
|
||||||
|
pub fn library_paths(&self) -> HashMap<String, String> {
|
||||||
|
let mut library_paths = HashMap::new();
|
||||||
|
|
||||||
|
for (key, path) in self.internal.library_paths() {
|
||||||
|
library_paths.insert(key.clone(), path.to_str().unwrap_or_default().to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
library_paths
|
||||||
|
}
|
||||||
|
|
||||||
#[napi(setter)]
|
#[napi(setter)]
|
||||||
pub fn set_style(&mut self, style: String) {
|
pub fn set_style(&mut self, style: String) {
|
||||||
self.internal.set_style(style);
|
self.internal.set_style(style);
|
||||||
|
|
|
@ -35,14 +35,14 @@ pub struct JsDiagnostic {
|
||||||
/// Message for this diagnostic.
|
/// Message for this diagnostic.
|
||||||
pub message: String,
|
pub message: String,
|
||||||
|
|
||||||
/// The line number in the .slint source file.
|
/// The line number in the .slint source file. The line number starts with 1.
|
||||||
pub line_number: u32,
|
pub line_number: u32,
|
||||||
|
|
||||||
// The column in the .slint source file
|
// The column in the .slint source file. The column number starts with 1.
|
||||||
pub column: u32,
|
pub column_number: u32,
|
||||||
|
|
||||||
/// The path of the source file where this diagnostic occurred.
|
/// The path of the source file where this diagnostic occurred.
|
||||||
pub source_file: Option<String>,
|
pub file_name: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Diagnostic> for JsDiagnostic {
|
impl From<Diagnostic> for JsDiagnostic {
|
||||||
|
@ -52,8 +52,8 @@ impl From<Diagnostic> for JsDiagnostic {
|
||||||
level: internal_diagnostic.level().into(),
|
level: internal_diagnostic.level().into(),
|
||||||
message: internal_diagnostic.message().into(),
|
message: internal_diagnostic.message().into(),
|
||||||
line_number: line_number as u32,
|
line_number: line_number as u32,
|
||||||
column: column as u32,
|
column_number: column as u32,
|
||||||
source_file: internal_diagnostic
|
file_name: internal_diagnostic
|
||||||
.source_file()
|
.source_file()
|
||||||
.and_then(|path| path.to_str())
|
.and_then(|path| path.to_str())
|
||||||
.map(|str| str.into()),
|
.map(|str| str.into()),
|
||||||
|
|
|
@ -50,7 +50,7 @@ impl JsWindow {
|
||||||
|
|
||||||
/// Returns the visibility state of the window. This function can return false even if you previously called show()
|
/// Returns the visibility state of the window. This function can return false even if you previously called show()
|
||||||
/// on it, for example if the user minimized the window.
|
/// on it, for example if the user minimized the window.
|
||||||
#[napi(getter, js_name = "is_visible")]
|
#[napi(getter)]
|
||||||
pub fn is_visible(&self) -> bool {
|
pub fn is_visible(&self) -> bool {
|
||||||
self.inner.window().is_visible()
|
self.inner.window().is_visible()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,39 @@
|
||||||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
use i_slint_core::{Brush, Color};
|
use i_slint_core::{graphics::GradientStop, Brush, Color};
|
||||||
use napi::bindgen_prelude::External;
|
use napi::{bindgen_prelude::External, Error, Result};
|
||||||
|
|
||||||
/// Color represents a color in the Slint run-time, represented using 8-bit channels for red, green, blue and the alpha (opacity).
|
/// Color represents a color in the Slint run-time, represented using 8-bit channels for red, green, blue and the alpha (opacity).
|
||||||
#[napi(js_name = Color)]
|
#[napi(object, js_name = "Color")]
|
||||||
pub struct JsColor {
|
pub struct JsColor {
|
||||||
|
/// Represents the red channel of the color as u8 in the range 0..255.
|
||||||
|
pub red: f64,
|
||||||
|
|
||||||
|
/// Represents the green channel of the color as u8 in the range 0..255.
|
||||||
|
pub green: f64,
|
||||||
|
|
||||||
|
/// Represents the blue channel of the color as u8 in the range 0..255.
|
||||||
|
pub blue: f64,
|
||||||
|
|
||||||
|
/// Represents the alpha channel of the color as u8 in the range 0..255.
|
||||||
|
pub alpha: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Color represents a color in the Slint run-time, represented using 8-bit channels for red, green, blue and the alpha (opacity).
|
||||||
|
#[napi(js_name = SlintColor)]
|
||||||
|
pub struct JsSlintColor {
|
||||||
inner: Color,
|
inner: Color,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Color> for JsColor {
|
impl From<Color> for JsSlintColor {
|
||||||
fn from(color: Color) -> Self {
|
fn from(color: Color) -> Self {
|
||||||
Self { inner: color }
|
Self { inner: color }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
impl JsColor {
|
impl JsSlintColor {
|
||||||
/// Creates a new transparent color.
|
/// Creates a new transparent color.
|
||||||
#[napi(constructor)]
|
#[napi(constructor)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
@ -80,8 +96,8 @@ impl JsColor {
|
||||||
/// So for example `brighter(0.2)` will increase the brightness by 20%, and
|
/// So for example `brighter(0.2)` will increase the brightness by 20%, and
|
||||||
/// calling `brighter(-0.5)` will return a color that's 50% darker.
|
/// calling `brighter(-0.5)` will return a color that's 50% darker.
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn brighter(&self, factor: f64) -> JsColor {
|
pub fn brighter(&self, factor: f64) -> JsSlintColor {
|
||||||
JsColor::from(self.inner.brighter(factor as f32))
|
JsSlintColor::from(self.inner.brighter(factor as f32))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new version of this color that has the brightness decreased
|
/// Returns a new version of this color that has the brightness decreased
|
||||||
|
@ -90,29 +106,29 @@ impl JsColor {
|
||||||
/// result is converted back to RGB and the alpha channel is unchanged.
|
/// result is converted back to RGB and the alpha channel is unchanged.
|
||||||
/// So for example `darker(0.3)` will decrease the brightness by 30%.
|
/// So for example `darker(0.3)` will decrease the brightness by 30%.
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn darker(&self, factor: f64) -> JsColor {
|
pub fn darker(&self, factor: f64) -> JsSlintColor {
|
||||||
JsColor::from(self.inner.darker(factor as f32))
|
JsSlintColor::from(self.inner.darker(factor as f32))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new version of this color with the opacity decreased by `factor`.
|
/// Returns a new version of this color with the opacity decreased by `factor`.
|
||||||
///
|
///
|
||||||
/// The transparency is obtained by multiplying the alpha channel by `(1 - factor)`.
|
/// The transparency is obtained by multiplying the alpha channel by `(1 - factor)`.
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn transparentize(&self, amount: f64) -> JsColor {
|
pub fn transparentize(&self, amount: f64) -> JsSlintColor {
|
||||||
JsColor::from(self.inner.transparentize(amount as f32))
|
JsSlintColor::from(self.inner.transparentize(amount as f32))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new color that is a mix of `self` and `other`, with a proportion
|
/// Returns a new color that is a mix of `self` and `other`, with a proportion
|
||||||
/// factor given by `factor` (which will be clamped to be between `0.0` and `1.0`).
|
/// factor given by `factor` (which will be clamped to be between `0.0` and `1.0`).
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn mix(&self, other: &JsColor, factor: f64) -> JsColor {
|
pub fn mix(&self, other: &JsSlintColor, factor: f64) -> JsSlintColor {
|
||||||
JsColor::from(self.inner.mix(&other.inner, factor as f32))
|
JsSlintColor::from(self.inner.mix(&other.inner, factor as f32))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new version of this color with the opacity set to `alpha`.
|
/// Returns a new version of this color with the opacity set to `alpha`.
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn with_alpha(&self, alpha: f64) -> JsColor {
|
pub fn with_alpha(&self, alpha: f64) -> JsSlintColor {
|
||||||
JsColor::from(self.inner.with_alpha(alpha as f32))
|
JsSlintColor::from(self.inner.with_alpha(alpha as f32))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the color as string in hex representation e.g. `#000000` for black.
|
/// Returns the color as string in hex representation e.g. `#000000` for black.
|
||||||
|
@ -137,30 +153,38 @@ impl From<Brush> for JsBrush {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<JsColor> for JsBrush {
|
impl From<JsSlintColor> for JsBrush {
|
||||||
fn from(color: JsColor) -> Self {
|
fn from(color: JsSlintColor) -> Self {
|
||||||
Self::from(Brush::from(color.inner))
|
Self::from(Brush::from(color.inner))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[napi]
|
#[napi]
|
||||||
impl JsBrush {
|
impl JsBrush {
|
||||||
/// Creates a new transparent brush.
|
|
||||||
#[napi(constructor)]
|
#[napi(constructor)]
|
||||||
pub fn new() -> Self {
|
pub fn new_with_color(color: JsColor) -> Result<Self> {
|
||||||
Self { inner: Brush::default() }
|
if color.red < 0. || color.green < 0. || color.blue < 0. || color.alpha < 0. {
|
||||||
|
return Err(Error::from_reason("A channel of Color cannot be negative"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
inner: Brush::SolidColor(Color::from_argb_u8(
|
||||||
|
color.alpha.floor() as u8,
|
||||||
|
color.red.floor() as u8,
|
||||||
|
color.green.floor() as u8,
|
||||||
|
color.blue.floor() as u8,
|
||||||
|
)),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a brush form a `Color`.
|
/// Creates a brush form a `Color`.
|
||||||
#[napi(factory)]
|
pub fn from_slint_color(color: &JsSlintColor) -> Self {
|
||||||
pub fn from_color(color: &JsColor) -> Self {
|
|
||||||
Self { inner: Brush::SolidColor(color.inner) }
|
Self { inner: Brush::SolidColor(color.inner) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the brush is SolidColor, the contained color is returned.
|
/// @hidden
|
||||||
/// If the brush is a LinearGradient, the color of the first stop is returned.
|
|
||||||
#[napi(getter)]
|
#[napi(getter)]
|
||||||
pub fn color(&self) -> JsColor {
|
pub fn color(&self) -> JsSlintColor {
|
||||||
self.inner.color().into()
|
self.inner.color().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,11 +241,52 @@ impl JsBrush {
|
||||||
/// It is only implemented for solid color brushes.
|
/// It is only implemented for solid color brushes.
|
||||||
#[napi]
|
#[napi]
|
||||||
pub fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
if let Brush::SolidColor(_) = self.inner {
|
match &self.inner {
|
||||||
|
Brush::SolidColor(_) => {
|
||||||
return self.color().to_string();
|
return self.color().to_string();
|
||||||
}
|
}
|
||||||
|
Brush::LinearGradient(gradient) => {
|
||||||
println!("toString() is not yet implemented for gradient brushes.");
|
return format!(
|
||||||
String::default()
|
"linear-gradient({}deg, {})",
|
||||||
|
gradient.angle(),
|
||||||
|
gradient_stops_to_string(gradient.stops())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Brush::RadialGradient(gradient) => {
|
||||||
|
return format!(
|
||||||
|
"radial-gradient(circle, {})",
|
||||||
|
gradient_stops_to_string(gradient.stops())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => String::default(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gradient_stops_to_string<'a>(stops: impl Iterator<Item = &'a GradientStop>) -> String {
|
||||||
|
let stops: Vec<String> = stops
|
||||||
|
.map(|s| {
|
||||||
|
format!(
|
||||||
|
"rgba({}, {}, {}, {}) {}%",
|
||||||
|
s.color.red(),
|
||||||
|
s.color.green(),
|
||||||
|
s.color.blue(),
|
||||||
|
s.color.alpha(),
|
||||||
|
s.position * 100.
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut stops_string = String::default();
|
||||||
|
let len = stops.len();
|
||||||
|
|
||||||
|
for i in 0..len {
|
||||||
|
stops_string.push_str(stops[i].as_str());
|
||||||
|
|
||||||
|
if i < len - 1 {
|
||||||
|
stops_string.push_str(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stops_string
|
||||||
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ for (let i = tiles.length - 1; i > 0; i--) {
|
||||||
let model = new slint.ArrayModel(tiles);
|
let model = new slint.ArrayModel(tiles);
|
||||||
mainWindow.memory_tiles = model;
|
mainWindow.memory_tiles = model;
|
||||||
|
|
||||||
mainWindow.check_if_pair_solved.setHandler(function () {
|
mainWindow.check_if_pair_solved = function () {
|
||||||
let flipped_tiles = [];
|
let flipped_tiles = [];
|
||||||
tiles.forEach((tile, index) => {
|
tiles.forEach((tile, index) => {
|
||||||
if (tile.image_visible && !tile.solved) {
|
if (tile.image_visible && !tile.solved) {
|
||||||
|
@ -60,7 +60,7 @@ mainWindow.check_if_pair_solved.setHandler(function () {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
mainWindow.run();
|
mainWindow.run();
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ for (let i = tiles.length - 1; i > 0; i--) {
|
||||||
let model = new slint.ArrayModel(tiles);
|
let model = new slint.ArrayModel(tiles);
|
||||||
window.memory_tiles = model;
|
window.memory_tiles = model;
|
||||||
|
|
||||||
window.check_if_pair_solved.setHandler(function () {
|
window.check_if_pair_solved = function () {
|
||||||
let flipped_tiles = [];
|
let flipped_tiles = [];
|
||||||
tiles.forEach((tile, index) => {
|
tiles.forEach((tile, index) => {
|
||||||
if (tile.image_visible && !tile.solved) {
|
if (tile.image_visible && !tile.solved) {
|
||||||
|
@ -58,6 +58,6 @@ window.check_if_pair_solved.setHandler(function () {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
};
|
||||||
|
|
||||||
window.run();
|
window.run();
|
||||||
|
|
|
@ -12,12 +12,12 @@ window.ink_levels = [
|
||||||
{ color: "#ffff00", level: 0.60 },
|
{ color: "#ffff00", level: 0.60 },
|
||||||
{ color: "#000000", level: 0.90 }];
|
{ color: "#000000", level: 0.90 }];
|
||||||
|
|
||||||
window.fax_number_erase.setHandler(function () {
|
window.fax_number_erase = function () {
|
||||||
window.fax_number = window.fax_number.substring(0, window.fax_number.length - 1);
|
window.fax_number = window.fax_number.substring(0, window.fax_number.length - 1);
|
||||||
})
|
};
|
||||||
window.fax_send.setHandler(function () {
|
window.fax_send = function () {
|
||||||
console.log("Send fax to " + window.fax_number);
|
console.log("Send fax to " + window.fax_number);
|
||||||
window.fax_number = "";
|
window.fax_number = "";
|
||||||
})
|
};
|
||||||
|
|
||||||
window.run();
|
window.run();
|
||||||
|
|
|
@ -43,11 +43,11 @@ let model = new slint.ArrayModel([
|
||||||
]);
|
]);
|
||||||
app.todo_model = model;
|
app.todo_model = model;
|
||||||
|
|
||||||
app.todo_added.setHandler(function (text) {
|
app.todo_added = function (text) {
|
||||||
model.push({ title: text, checked: false })
|
model.push({ title: text, checked: false })
|
||||||
})
|
};
|
||||||
|
|
||||||
app.remove_done.setHandler(function () {
|
app.remove_done = function () {
|
||||||
let offset = 0;
|
let offset = 0;
|
||||||
const length = model.length;
|
const length = model.length;
|
||||||
for (let i = 0; i < length; ++i) {
|
for (let i = 0; i < length; ++i) {
|
||||||
|
@ -56,6 +56,6 @@ app.remove_done.setHandler(function () {
|
||||||
offset++;
|
offset++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
};
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
|
|
|
@ -84,11 +84,11 @@ try {
|
||||||
assert.equal(instance.callback_emission_count, 0);
|
assert.equal(instance.callback_emission_count, 0);
|
||||||
|
|
||||||
|
|
||||||
/// also test setHandler
|
/// also test assigning with a function
|
||||||
instance.test_callback2.setHandler(function(a) {
|
instance.test_callback2 = function(a) {
|
||||||
callback_3_emitted += 100;
|
callback_3_emitted += 100;
|
||||||
callback_3_string_value = a;
|
callback_3_string_value = a;
|
||||||
});
|
};
|
||||||
instance.test_callback2("salùt")
|
instance.test_callback2("salùt")
|
||||||
assert.equal(callback_3_emitted, 101);
|
assert.equal(callback_3_emitted, 101);
|
||||||
assert.equal(callback_3_string_value, "salùt");
|
assert.equal(callback_3_string_value, "salùt");
|
||||||
|
|
|
@ -204,11 +204,11 @@ assert!(!instance.window().is_visible());
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var instance = new slint.Hello();
|
var instance = new slint.Hello();
|
||||||
assert(!instance.window.is_visible);
|
assert(!instance.window.isVisible);
|
||||||
instance.window.show();
|
instance.window.show();
|
||||||
assert(instance.window.is_visible);
|
assert(instance.window.isVisible);
|
||||||
instance.window.hide();
|
instance.window.hide();
|
||||||
assert(!instance.window.is_visible);
|
assert(!instance.window.isVisible);
|
||||||
```
|
```
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue