Skip to content

Commit

Permalink
Add new pure TypeScript compiler example, fixes #183
Browse files Browse the repository at this point in the history
  • Loading branch information
JumpLink committed Jul 22, 2024
1 parent 51d36e2 commit 83ce03d
Show file tree
Hide file tree
Showing 20 changed files with 262 additions and 36 deletions.
26 changes: 20 additions & 6 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,24 +173,24 @@ cd /examples/gtk-4-custom-widget
yarn start
```

## Gtk4 Template
![gtk-4-template](gtk-4-template/preview.png)
## Gtk4 Template (esbuild)
![gtk-4-template-esbuild](gtk-4-template-esbuild/preview.png)

This example shows how to use the Gtk4 template engine to create a custom widget.
This example shows how to use the Gtk4 template engine to create a custom widget. It's also showing how to load the template `.ui` and style `.css` files from the file system using ESBuild.

Source: [gtk-4-template](gtk-4-template)
Source: [gtk-4-template-esbuild](gtk-4-template-esbuild)
Bundler: ESBuild

Build and run:
```bash
cd /examples/gtk-4-template
cd /examples/gtk-4-template-esbuild
yarn start
```

## Gtk4 Template (Vite)
![gtk-4-template-vite](gtk-4-template-vite/preview.png)

This example is largely identical to the example above, but uses Vite to inject the template `.ui` file into the source code.
This example is largely identical to the example above, but uses Vite to inject the template `.ui` and style `.css` files into the source code.

Source: [gtk-4-template-vite](gtk-4-template-vite)
Bundler: Vite
Expand All @@ -199,4 +199,18 @@ Build and run:
```bash
cd /examples/gtk-4-template-vite
yarn start
```

## Gtk4 Template (TSC)
![gtk-4-template-tsc](gtk-4-template-tsc/preview.png)

This example is largely identical to the examples above, but uses the TypeScript compiler to compile the source code. No assets can be resolved with the TypeScript compiler, so this example shows how this can be done on runtime.

Source: [gtk-4-template-tsc](gtk-4-template-tsc)
Bundler: TSC

Build and run:
```bash
cd /examples/gtk-4-template-tsc
yarn start
```
9 changes: 9 additions & 0 deletions examples/gtk-4-template-esbuild/env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
declare module '*.ui' {
const content: string
export default content
}

declare module '*.css' {
const content: string
export default content
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ await build({
target: "firefox115", // Since GJS 1.77.2
format: 'esm',
external: ['gi://*', 'resource://*', 'gettext', 'system', 'cairo'],
loader: {
'.css': 'text',
'.ui': 'text',
},
})
3 changes: 3 additions & 0 deletions examples/gtk-4-template-esbuild/gtk4-template.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
window {
background-color: green;
}
File renamed without changes.
79 changes: 79 additions & 0 deletions examples/gtk-4-template-esbuild/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/usr/bin/env gjs -m
// SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
// SPDX-FileCopyrightText: 2021 Andy Holmes <[email protected]>
// Based on https://gitlab.gnome.org/GNOME/gjs/-/blob/master/examples/gtk4-template.js

import GObject from 'gi://GObject?version=2.0';
import GLib from 'gi://GLib?version=2.0';
import Gtk from 'gi://Gtk?version=4.0';
import Gdk from 'gi://Gdk?version=4.0';

import Template from './gtk4-template.ui';
import Style from './gtk4-template.css';

Gtk.init();

const ExampleWindow = GObject.registerClass({
GTypeName: 'ExampleWindow',
Template: Template,
Children: [
'box',
],
InternalChildren: [
'button',
],
}, class ExampleWindow extends Gtk.Window {

box: Gtk.Box | null = null;
_button: Gtk.Button | null = null;

constructor() {
super();

// The template has been initialized and you can access the children
if (this.box) this.box.visible = true;

// Internal children are set on the instance prefixed with a `_`
if (this._button) this._button.visible = true;

this.initStyles()
}

// The signal handler bound in the UI file
_onButtonClicked(button: Gtk.Button) {
if (this instanceof Gtk.Window)
log('Callback scope is bound to `ExampleWindow`');

button.label = 'Button was clicked!';
}

/** Load the stylesheet in a CssProvider and add it to the Gtk.StyleContext */
protected initStyles() {
const provider = new Gtk.CssProvider();
console.log("Style", Style)
provider.load_from_string(Style)
const display = Gdk.Display.get_default()

if (!display) {
console.error('No display found')
return
}

Gtk.StyleContext.add_provider_for_display(
display,
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
}
});


// Create a window that stops the program when it is closed
const loop = GLib.MainLoop.new(null, false);

const win = new ExampleWindow();
win.connect('close-request', () => loop.quit());
win.present();

loop.run();

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@ts-for-gir-example/gtk-4-template",
"name": "@ts-for-gir-example/gtk-4-template-esbuild",
"version": "4.0.0-beta.10",
"description": "Simple GJS Gtk 4 example app to demonstrate how you can use .ui template XML files over GJS itself",
"type": "module",
Expand Down
Binary file added examples/gtk-4-template-esbuild/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions examples/gtk-4-template-esbuild/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"types": ["@girs/gjs", "@girs/gjs/dom", "@girs/gio-2.0", "@girs/glib-2.0", "@girs/gtk-4.0"],
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"noImplicitThis": true,
"alwaysStrict": true,
},
"files": [
"main.ts",
],
"include": ["env.d.ts"]
}
3 changes: 3 additions & 0 deletions examples/gtk-4-template-tsc/gtk4-template.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
window {
background-color: yellow;
}
44 changes: 44 additions & 0 deletions examples/gtk-4-template-tsc/gtk4-template.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<!-- SPDX-License-Identifier: MIT OR LGPL-2.0-or-later -->
<!-- SPDX-FileCopyrightText: 2021 Andy Holmes <[email protected]> -->
<interface>
<!-- Template
* class: must be the `GTypeName` given in the class definition, or the
class name prefixed with `Gjs_` if not given (eg `Gjs_ExampleWinow`)
* parent: the GType name of the derived class
-->
<template class="ExampleWindow" parent="GtkWindow">
<property name="default-width">480</property>
<property name="default-height">320</property>
<child>
<object class="GtkBox" id="box">
<property name="visible">True</property>
<child>
<object class="GtkButton" id="button">
<property name="label">Button</property>
<property name="halign">center</property>
<property name="hexpand">True</property>
<property name="valign">center</property>
<property name="visible">True</property>

<!-- Signals
* name: the signal name
* handler: the name of method on the subclass to call when emitted
* swapped: must always be "no" in GJS applications
* object: the object bound to `this` in the callback. This is
usually the template class (eg. `ExampleClass`) but may also be
an object ID (eg. `box` or `button`).
-->
<signal name="clicked"
handler="_onButtonClicked"
swapped="no"
object="ExampleWindow"/>
</object>
</child>
</object>
</child>
</template>
</interface>
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import GObject from 'gi://GObject?version=2.0';
import Gio from 'gi://Gio?version=2.0';
import GLib from 'gi://GLib?version=2.0';
import Gtk from 'gi://Gtk?version=4.0';
import Gdk from 'gi://Gdk?version=4.0';

Gtk.init();

Expand All @@ -18,13 +19,12 @@ Gtk.init();
* - an absolute file URI, such as `file:///home/user/window.ui`
* - a GResource URI, such as `resource:///org/gnome/AppName/window.ui`
*/
const file = Gio.File.new_for_path('gtk4-template.ui');
const [, template] = file.load_contents(null);

const templateFile = Gio.File.new_for_path('gtk4-template.ui');
const [, Template] = templateFile.load_contents(null);

const ExampleWindow = GObject.registerClass({
GTypeName: 'ExampleWindow',
Template: template,
Template: Template,
Children: [
'box',
],
Expand All @@ -44,6 +44,8 @@ const ExampleWindow = GObject.registerClass({

// Internal children are set on the instance prefixed with a `_`
if (this._button) this._button.visible = true;

this.initStyles()
}

// The signal handler bound in the UI file
Expand All @@ -53,6 +55,24 @@ const ExampleWindow = GObject.registerClass({

button.label = 'Button was clicked!';
}

/** Load the stylesheet in a CssProvider and add it to the Gtk.StyleContext */
protected initStyles() {
const provider = new Gtk.CssProvider();
provider.load_from_path('gtk4-template.css')
const display = Gdk.Display.get_default()

if (!display) {
console.error('No display found')
return
}

Gtk.StyleContext.add_provider_for_display(
display,
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
}
});


Expand Down
29 changes: 29 additions & 0 deletions examples/gtk-4-template-tsc/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "@ts-for-gir-example/gtk-4-template-tsc",
"version": "4.0.0-beta.10",
"description": "Simple GJS Gtk 4 example app to demonstrate how you can use .ui template XML files over GJS itself",
"type": "module",
"private": true,
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build:app": "tsc",
"build": "yarn build:app",
"start:app": "gjs -m dist/main.js",
"debug:app": "GTK_DEBUG=interactive yarn start:app",
"start": "yarn build && yarn start:app",
"validate": "yarn validate:types",
"validate:types": "tsc --noEmit",
"clear": "rm -rf dist @types"
},
"author": "Pascal Garber <[email protected]>",
"license": "MIT",
"devDependencies": {
"typescript": "^5.5.3"
},
"dependencies": {
"@girs/gio-2.0": "workspace:^",
"@girs/gjs": "workspace:^",
"@girs/glib-2.0": "workspace:^",
"@girs/gtk-4.0": "workspace:^"
}
}
Binary file added examples/gtk-4-template-tsc/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"strictNullChecks": true,
"noImplicitThis": true,
"alwaysStrict": true,
"outDir": "./dist"
},
"files": [
"main.ts",
Expand Down
18 changes: 4 additions & 14 deletions examples/gtk-4-template-vite/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,10 @@
// SPDX-FileCopyrightText: 2021 Andy Holmes <[email protected]>
// Based on https://gitlab.gnome.org/GNOME/gjs/-/blob/master/examples/gtk4-template.js

import '@girs/gjs';
import '@girs/gjs/dom';

import GObject from '@girs/gobject-2.0';
import GLib from '@girs/glib-2.0';
import Gtk from '@girs/gtk-4.0';
import Gdk from '@girs/gdk-4.0'
import GObject from 'gi://GObject?version=2.0';
import GLib from 'gi://GLib?version=2.0';
import Gtk from 'gi://Gtk?version=4.0';
import Gdk from 'gi://Gdk?version=4.0';

import Template from './gtk4-template.ui?raw';
import Style from './gtk4-template.css?inline';
Expand All @@ -33,15 +30,12 @@ const ExampleWindow = GObject.registerClass({
constructor() {
super();

this.onStartup = this.onStartup.bind(this)

// The template has been initialized and you can access the children
if (this.box) this.box.visible = true;

// Internal children are set on the instance prefixed with a `_`
if (this._button) this._button.visible = true;

// this.connect('startup', this.onStartup)
this.initStyles()
}

Expand All @@ -53,10 +47,6 @@ const ExampleWindow = GObject.registerClass({
button.label = 'Button was clicked!';
}

protected onStartup(): void {
this.initStyles()
}

/** Load the stylesheet in a CssProvider and add it to the Gtk.StyleContext */
protected initStyles() {
const provider = new Gtk.CssProvider();
Expand Down
Binary file modified examples/gtk-4-template-vite/preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions examples/gtk-4-template-vite/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"types": [],
"types": ["@girs/gjs", "@girs/gjs/dom", "@girs/gio-2.0", "@girs/glib-2.0", "@girs/gtk-4.0"],
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
Expand All @@ -11,8 +11,8 @@
"noImplicitThis": true,
"alwaysStrict": true,
},
"include": ["env.d.ts"],
"files": [
"main.ts",
]
],
"include": ["env.d.ts"]
}
Binary file removed examples/gtk-4-template/preview.png
Binary file not shown.
Loading

0 comments on commit 83ce03d

Please sign in to comment.