Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

library: Add Language and Category filters #967

Merged
merged 9 commits into from
Sep 23, 2024
24 changes: 24 additions & 0 deletions src/Library/Library.blp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ Adw.Window window {
}
}

Box {
DropDown dropdown_language {
BharatAtbrat marked this conversation as resolved.
Show resolved Hide resolved
halign: end;
margin-end: 12;
hexpand: true;
}

DropDown dropdown_category {
halign: end;
}
}

ListBox library_uncategorized {
BharatAtbrat marked this conversation as resolved.
Show resolved Hide resolved
selection-mode: none;

Expand Down Expand Up @@ -215,6 +227,18 @@ Adw.Window window {
halign: center;
margin-bottom: 24;
margin-top: 12;
orientation: vertical;

Label results_empty {
visible: false;
margin-top: 46;
margin-bottom: 70;
label: _("No results");

styles [
"title-4"
]
}

Label {
label: _("All examples are dedicated to the public domain\nand <b>can be used freely</b> under the terms of <a href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0 1.0</a>");
Expand Down
113 changes: 103 additions & 10 deletions src/Library/Library.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import Gio from "gi://Gio";
import Gtk from "gi://Gtk";

import {
decode,
demos_dir,
getLanguage,
makeDropdownFlat,
settings as global_settings,
quitOnLastWindowClose,
} from "../util.js";
Expand All @@ -14,27 +16,78 @@ import { createSessionFromDemo } from "../sessions.js";
import EntryRow from "./EntryRow.js";

import illustration from "./library.svg";
import { gettext as _ } from "gettext";

import { build } from "../../troll/src/builder.js";

export default function Library({ application }) {
const objects = build(resource);
const { window, picture_illustration, search_entry } = objects;
const {
window,
picture_illustration,
search_entry,
dropdown_category,
dropdown_language,
results_empty,
} = objects;
window.application = application;
picture_illustration.set_resource(illustration);
makeDropdownFlat(dropdown_category);
makeDropdownFlat(dropdown_language);

if (__DEV__) {
window.add_css_class("devel");
}

let last_triggered;
let current_category = 0;
let current_language = 0;

window.connect("close-request", quitOnLastWindowClose);

const demos = getDemos();
const widgets_map = new Map();
const category_map = new Map();
const language_model = new Gtk.StringList();
const category_model = new Gtk.StringList();
language_model.append("All Languages");
category_model.append("All Categories");
const language_check = ["All Languages"];
const category_check = ["All Categories"];
BharatAtbrat marked this conversation as resolved.
Show resolved Hide resolved
BharatAtbrat marked this conversation as resolved.
Show resolved Hide resolved

const language_labels = {
javascript: _("JavaScript"),
python: _("Python"),
rust: _("Rust"),
vala: _("Vala"),
typescript: _("TypeScript"),
};

const category_labels = {
user_interface: _("User Interface"),
platform: _("Platform APIs"),
controls: _("Controls"),
feedback: _("Feedback"),
layout: _("Layout"),
network: _("Network"),
navigation: _("Navigation"),
tools: _("Tools"),
uncategorized: _("Uncategorized"),
};

demos.forEach((demo) => {
demo.languages.forEach((lang) => {
if (!language_check.includes(lang)) {
language_check.push(lang);
language_model.append(language_labels[lang]);
}
});

if (!category_check.includes(demo.category)) {
category_check.push(demo.category);
category_model.append(category_labels[demo.category]);
}

const entry_row = new EntryRow({ demo: demo });
if (demo.name === "Welcome") last_triggered = entry_row;

Expand All @@ -51,25 +104,65 @@ export default function Library({ application }) {
category_map.set(demo.category, objects[`library_${demo.category}`]);
}
objects[`library_${demo.category}`].append(entry_row);
widgets_map.set(demo.name, { entry_row, category: demo.category });
widgets_map.set(demo.name, {
entry_row,
category_index: category_check.indexOf(demo.category),
languages_index: demo.languages.map((lang) =>
language_check.indexOf(lang),
),
});
});

search_entry.connect("search-changed", () => {
dropdown_language.set_model(language_model);
dropdown_category.set_model(category_model);

function updateList() {
const search_term = search_entry.get_text().toLowerCase();
const visible_categories = new Set();

widgets_map.forEach(({ entry_row, category }, demo_name) => {
const is_match = demo_name.toLowerCase().includes(search_term);
entry_row.visible = is_match;
if (is_match) visible_categories.add(category);
});
let results_found = false;
widgets_map.forEach(
({ entry_row, category_index, languages_index }, demo_name) => {
const category_match =
current_category === 0 || category_index === current_category;
const language_match =
current_language === 0 || languages_index.includes(current_language);
const search_match = demo_name.toLowerCase().includes(search_term);
const is_match =
category_match &&
language_match &&
(search_term === "" || search_match);
entry_row.visible = is_match;
if (is_match) {
results_found = true;
visible_categories.add(category_check[category_index]);
}
},
);

category_map.forEach((category_widget, category_name) => {
const label = objects[`label_${category_name}`];
if (label) label.visible = search_term === "";
if (label)
label.visible =
current_category === 0 &&
current_language === 0 &&
search_term === "";
category_widget.visible = visible_categories.has(category_name);
});
results_empty.set_visible(!results_found);
}

search_entry.connect("search-changed", updateList);

dropdown_category.connect("notify::selected", () => {
current_category = dropdown_category.get_selected();
updateList();
});

dropdown_language.connect("notify::selected", () => {
current_language = dropdown_language.get_selected();
updateList();
});

const action_library = new Gio.SimpleAction({
name: "library",
parameter_type: null,
Expand Down
Loading