Skip to content

Commit c4ee997

Browse files
authored
Add GOM demo (#200)
1 parent fae40ed commit c4ee997

File tree

5 files changed

+246
-1
lines changed

5 files changed

+246
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ src/*/*.gresource
3434
src/*/*.gresource.xml
3535
src/*/jsconfig.json
3636
src/*/rustc-ice-*.txt
37+
src/*/*.sqlite*

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ SHELL:=/bin/bash -O globstar
44

55
setup:
66
flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
7-
flatpak install --or-update --user --noninteractive flathub org.freedesktop.Sdk.Extension.rust-stable//24.08 org.freedesktop.Sdk.Extension.vala//24.08 org.freedesktop.Sdk.Extension.node20//24.08 #org.freedesktop.Sdk.Extension.typescript//24.08
7+
flatpak install --or-update --user --noninteractive flathub org.freedesktop.Sdk.Extension.rust-stable//24.08 org.freedesktop.Sdk.Extension.vala//24.08 org.freedesktop.Sdk.Extension.node20//24.08 org.freedesktop.Sdk.Extension.typescript//24.08
88
# flatpak remote-add --user --if-not-exists flathub-beta https://flathub.org/beta-repo/flathub-beta.flatpakrepo
99
flatpak remote-add --user --if-not-exists gnome-nightly https://nightly.gnome.org/gnome-nightly.flatpakrepo
1010
flatpak install --or-update --user --noninteractive gnome-nightly re.sonny.Workbench.Devel

src/Database/main.blp

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
using Gtk 4.0;
2+
using Adw 1;
3+
4+
Adw.StatusPage {
5+
title: _("Database");
6+
description: _("Search, load and store data using SQLite");
7+
8+
Box {
9+
orientation: vertical;
10+
halign: center;
11+
spacing: 18;
12+
13+
Box {
14+
styles [
15+
"linked"
16+
]
17+
18+
Entry text_entry {
19+
placeholder-text: _("Enter Text");
20+
hexpand: true;
21+
}
22+
23+
Button insert_button {
24+
label: _("Insert");
25+
}
26+
}
27+
28+
Box {
29+
orientation: horizontal;
30+
spacing: 18;
31+
32+
Box {
33+
orientation: vertical;
34+
spacing: 12;
35+
hexpand: true;
36+
37+
Label {
38+
label: _("Search by Text");
39+
}
40+
41+
SearchEntry search_entry {
42+
search-delay: 100;
43+
}
44+
}
45+
46+
Box {
47+
spacing: 12;
48+
orientation: vertical;
49+
50+
Label {
51+
label: _("Find by ID");
52+
}
53+
54+
SearchEntry id_entry {
55+
search-delay: 100;
56+
}
57+
}
58+
}
59+
60+
ScrolledWindow {
61+
height-request: 340;
62+
has-frame: true;
63+
64+
ColumnView column_view {
65+
show-column-separators: true;
66+
67+
ColumnViewColumn column_text {
68+
title: _("Text");
69+
expand: true;
70+
71+
factory: SignalListItemFactory {};
72+
}
73+
74+
ColumnViewColumn column_id {
75+
title: _("ID");
76+
expand: true;
77+
78+
factory: SignalListItemFactory {};
79+
}
80+
}
81+
}
82+
83+
Box {
84+
orientation: horizontal;
85+
halign: center;
86+
87+
LinkButton {
88+
label: _("API Reference");
89+
uri: "https://gjs-docs.gnome.org/gom10~1.0/";
90+
}
91+
92+
LinkButton {
93+
label: _("SQLite");
94+
uri: "https://www.sqlite.org/";
95+
}
96+
}
97+
}
98+
}

src/Database/main.js

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import GObject from "gi://GObject";
2+
import Gom from "gi://Gom";
3+
import Gtk from "gi://Gtk";
4+
import GLib from "gi://GLib";
5+
import Gio from "gi://Gio";
6+
7+
Gio._promisify(Gom.Adapter.prototype, "open_async", "open_finish");
8+
9+
Gio._promisify(
10+
Gom.Repository.prototype,
11+
"automatic_migrate_async",
12+
"automatic_migrate_finish",
13+
);
14+
Gio._promisify(Gom.Repository.prototype, "find_async", "find_finish");
15+
16+
Gio._promisify(Gom.Resource.prototype, "save_async", "save_finish");
17+
Gio._promisify(Gom.ResourceGroup.prototype, "fetch_async", "fetch_finish");
18+
19+
const text_entry = workbench.builder.get_object("text_entry");
20+
const insert_button = workbench.builder.get_object("insert_button");
21+
const search_entry = workbench.builder.get_object("search_entry");
22+
const column_view = workbench.builder.get_object("column_view");
23+
const column_text = workbench.builder.get_object("column_text");
24+
const column_id = workbench.builder.get_object("column_id");
25+
26+
const ItemClass = GObject.registerClass(
27+
{
28+
Properties: {
29+
id: GObject.ParamSpec.int(
30+
"id",
31+
"ID",
32+
"An ID",
33+
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
34+
0,
35+
GLib.MAXINT32,
36+
0,
37+
),
38+
text: GObject.ParamSpec.string(
39+
"text",
40+
"Text",
41+
"Some Text",
42+
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT,
43+
"",
44+
),
45+
},
46+
},
47+
class ItemClass extends Gom.Resource {},
48+
);
49+
50+
const data_model = new Gio.ListStore({ item_type: ItemClass });
51+
let adapter;
52+
let repository;
53+
54+
async function initDatabase() {
55+
adapter = new Gom.Adapter();
56+
await adapter.open_async(workbench.resolve("db.sqlite"));
57+
repository = new Gom.Repository({ adapter });
58+
59+
// Set up table and primary key
60+
ItemClass.set_table("items");
61+
ItemClass.set_primary_key("id");
62+
63+
// Perform automatic migration
64+
await repository.automatic_migrate_async(1, [ItemClass]);
65+
}
66+
67+
async function onInsert() {
68+
const text = text_entry.text;
69+
const item = new ItemClass({ repository, text });
70+
const success = await item.save_async();
71+
if (!success) {
72+
console.error("Failed to insert");
73+
return;
74+
}
75+
76+
await load();
77+
}
78+
79+
async function load() {
80+
const text = search_entry.text || "";
81+
82+
data_model.remove_all();
83+
// Create a filter for Text matching
84+
const filter = Gom.Filter.new_glob(ItemClass, "text", `*${text}*`);
85+
const resource_group = await repository.find_async(ItemClass, filter);
86+
87+
await resource_group.fetch_async(0, resource_group.count);
88+
for (let i = 0; i < resource_group.count; i++) {
89+
const item = resource_group.get_index(i);
90+
if (item) data_model.append(item);
91+
}
92+
}
93+
94+
column_text.factory.connect("setup", (_self, list_item) => {
95+
const label = new Gtk.Label({
96+
margin_start: 12,
97+
margin_end: 12,
98+
});
99+
list_item.set_child(label);
100+
});
101+
102+
column_text.factory.connect("bind", (_self, list_item) => {
103+
const label_widget = list_item.get_child();
104+
const model_item = list_item.get_item();
105+
label_widget.label = model_item.text;
106+
});
107+
108+
column_id.factory.connect("setup", (_self, list_item) => {
109+
const label = new Gtk.Label({
110+
margin_start: 12,
111+
margin_end: 12,
112+
});
113+
list_item.set_child(label);
114+
});
115+
116+
column_id.factory.connect("bind", (_self, list_item) => {
117+
const label_widget = list_item.get_child();
118+
const model_item = list_item.get_item();
119+
label_widget.label = model_item.id.toString();
120+
});
121+
122+
column_view.model = new Gtk.SingleSelection({
123+
model: data_model,
124+
});
125+
126+
try {
127+
await initDatabase();
128+
129+
search_entry.connect("search-changed", () => {
130+
load().catch(console.error);
131+
});
132+
133+
insert_button.connect("clicked", () => {
134+
onInsert().catch(console.error);
135+
});
136+
137+
await load();
138+
} catch (err) {
139+
console.error(err);
140+
}

src/Database/main.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"category": "platform",
3+
"description": "Search, load and store data using SQLite",
4+
"panels": ["code", "preview"],
5+
"autorun": true
6+
}

0 commit comments

Comments
 (0)