From bc4aeed93793881ef9c7d42019d3a33efd78dab6 Mon Sep 17 00:00:00 2001 From: Karol Lademan Date: Sun, 28 May 2023 18:09:17 +0200 Subject: [PATCH 1/9] library: Add Boxed lists entry --- src/Library/demos/Boxed lists/main.blp | 91 +++++++++++++++++++++++++ src/Library/demos/Boxed lists/main.js | 11 +++ src/Library/demos/Boxed lists/main.json | 10 +++ src/about.js | 1 + 4 files changed, 113 insertions(+) create mode 100644 src/Library/demos/Boxed lists/main.blp create mode 100644 src/Library/demos/Boxed lists/main.js create mode 100644 src/Library/demos/Boxed lists/main.json diff --git a/src/Library/demos/Boxed lists/main.blp b/src/Library/demos/Boxed lists/main.blp new file mode 100644 index 000000000..7cf09d147 --- /dev/null +++ b/src/Library/demos/Boxed lists/main.blp @@ -0,0 +1,91 @@ +using Gtk 4.0; +using Adw 1; + +Adw.StatusPage { + title: "Boxed Lists"; + + ListBox { + halign: center; + + Adw.PreferencesGroup { + title: "Rows can be groupped"; + Adw.ActionRow { + title: "Action row can have a prefix child"; + + [prefix] + CheckButton checkbox { + active: true; + } + } + + Adw.ActionRow { + title: "Action row can have a suffix child"; + subtitle: "Select checkbox above to show spinner"; + + [suffix] + Spinner { + spinning: bind checkbox.active; + } + } + + Adw.EntryRow { + title: "A row can be an entry"; + } + } + + Adw.PreferencesGroup { + title: "Preferences Groups can have a suffix"; + + [header-suffix] + Button { + Adw.ButtonContent { + label: "child"; + icon-name: "sidebar-toggle-right-symbolic"; + } + + } + + Adw.ComboRow { + title: "Choose an item"; + subtitle: "ComboRow can have a drop down list"; + model: StringList list { + strings ["this", "is", "a", "string", "list"] + }; + } + + Adw.ExpanderRow { + title: "Rows can be expandable"; + + // remove the line below if you don't want a switch + show-enable-switch: true; + + Adw.ActionRow { + title: "First row"; + } + Adw.ActionRow { + title: "Second row"; + } + } + + Adw.ActionRow { + title: "Row can have an interactive button"; + + [suffix] + Button button { + label: "click"; + valign: center; + } + } + } + + LinkButton { + label: "API Reference"; + uri: "https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/boxed-lists.html"; + } + + LinkButton { + label: "Human Interface Guidelines"; + uri: "https://developer.gnome.org/hig/patterns/containers/boxed-lists.html"; + } + } +} diff --git a/src/Library/demos/Boxed lists/main.js b/src/Library/demos/Boxed lists/main.js new file mode 100644 index 000000000..a2b4836d0 --- /dev/null +++ b/src/Library/demos/Boxed lists/main.js @@ -0,0 +1,11 @@ +const button = workbench.builder.get_object("button"); + +button.connect("clicked", () => { + if (button.has_css_class("accent")) { + button.remove_css_class("accent"); + button.set_label("click"); + } else { + button.add_css_class("accent"); + button.set_label("clicked"); + } +}); diff --git a/src/Library/demos/Boxed lists/main.json b/src/Library/demos/Boxed lists/main.json new file mode 100644 index 000000000..7bdb347da --- /dev/null +++ b/src/Library/demos/Boxed lists/main.json @@ -0,0 +1,10 @@ +{ + "name": "Boxed Lists", + "category": "user_interface", + "description": "Boxed lists are a common type of list that can contain both controls and information. Examples include app preferences or a short list of recent documents in a picker.", + "panels": [ + "preview", + "ui" + ], + "autorun": true +} diff --git a/src/about.js b/src/about.js index ddcbfd5ae..ce8ed3d88 100644 --- a/src/about.js +++ b/src/about.js @@ -59,6 +59,7 @@ ${getBlueprintVersion()} "Angelo Verlain https://www.vixalien.com", "bazylevnik0 https://github.com/bazylevnik0", "Felipe Kinoshita https://mastodon.social/@fkinoshita", + "Karol Lademan https://github.com/karl0d", "Nasah Kuma https://www.mantohnasah.com/", // Add yourself as // "John Doe", From f37e9d919fef41272367aa099f0cc2f04c156f39 Mon Sep 17 00:00:00 2001 From: Sonny Piers Date: Mon, 29 May 2023 10:38:13 +0200 Subject: [PATCH 2/9] Remove unecessary gresource --- po/POTFILES | 15 +++++++++++++++ src/app.gresource.xml | 7 ------- src/bin.js | 6 +----- src/main.js | 2 ++ src/meson.build | 10 ++-------- 5 files changed, 20 insertions(+), 20 deletions(-) delete mode 100644 src/app.gresource.xml diff --git a/po/POTFILES b/po/POTFILES index d3376cc27..bd794f473 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -41,3 +41,18 @@ src/Library/Library.blp troll/src/widgets/ThemeSelector.blp troll/src/widgets/ThemeSelector.js + +src/init.js +src/langs/xml/xml.js +src/langs/blueprint/blueprint.js +src/langs/vala/vala.js +src/langs/javascript/javascript.js +src/langs/vala/Compiler.js +src/widgets/Modal.blp +src/widgets/Modal.js +src/widgets/CodeView.blp +src/widgets/CodeView.js +src/IconLibrary/IconWidget.blp +src/IconLibrary/IconWidget.js +src/IconLibrary/main.blp +src/IconLibrary/main.js \ No newline at end of file diff --git a/src/app.gresource.xml b/src/app.gresource.xml deleted file mode 100644 index e6fcaa35c..000000000 --- a/src/app.gresource.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - style.css - language-specs/blueprint.lang - - diff --git a/src/bin.js b/src/bin.js index 7d78a28cf..44ee59397 100755 --- a/src/bin.js +++ b/src/bin.js @@ -3,7 +3,6 @@ import { exit, programArgs } from "system"; import GLib from "gi://GLib"; import { setConsoleLogDomain } from "console"; -import Gio from "gi://Gio"; import Xdp from "gi://Xdp"; imports.package.init({ @@ -23,14 +22,11 @@ if (!Xdp.Portal.running_under_flatpak()) { exit(1); } -const resource = Gio.resource_load("@pkgdatadir@/@app_id@.gresource"); -Gio.resources_register(resource); - globalThis.__DEV__ = pkg.name.endsWith(".Devel"); if (__DEV__) { pkg.sourcedir = "@sourcedir@"; } -const module = await import("resource:///re/sonny/Workbench/src/main.js"); +const module = await import("resource:///re/sonny/Workbench/main.js"); const exit_code = await module.main(programArgs); exit(exit_code); diff --git a/src/main.js b/src/main.js index 53d474538..742076415 100644 --- a/src/main.js +++ b/src/main.js @@ -4,6 +4,8 @@ import application from "./application.js"; pkg.initGettext(); +import "./language-specs/blueprint.lang"; + export function main(argv) { return application.runAsync(argv); } diff --git a/src/meson.build b/src/meson.build index 517d9ff10..612bd1a6e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -29,13 +29,6 @@ custom_target('blueprints', ], ) -gnome.compile_resources(app_id, - 'app.gresource.xml', - gresource_bundle: true, - install: true, - install_dir: pkgdatadir, -) - configure_file( input: 'bin.js', output: app_id, @@ -63,7 +56,8 @@ gresource = custom_target('gjspack', gjspack, '--appid=' + app_id, '--prefix', '/re/sonny/Workbench', - '--resource-root', meson.project_source_root(), + '--project-root', meson.source_root(), + '--resource-root', meson.project_source_root() / 'src', '--blueprint-compiler', blueprint_compiler, '--no-executable', '@INPUT0@', From 3b7956c25643c362095338e2775e8da4ea9d5247 Mon Sep 17 00:00:00 2001 From: Sriyansh Shivam <96797205+SoNiC-HeRE@users.noreply.github.com> Date: Tue, 30 May 2023 14:58:46 +0530 Subject: [PATCH 3/9] library: Add libportal screenshot entry (#208) --- src/Library/Library.blp | 4 +++ src/Library/demos/Screenshot/main.blp | 32 +++++++++++++++++ src/Library/demos/Screenshot/main.js | 48 ++++++++++++++++++++++++++ src/Library/demos/Screenshot/main.json | 10 ++++++ 4 files changed, 94 insertions(+) create mode 100644 src/Library/demos/Screenshot/main.blp create mode 100644 src/Library/demos/Screenshot/main.js create mode 100644 src/Library/demos/Screenshot/main.json diff --git a/src/Library/Library.blp b/src/Library/Library.blp index 7f7483f4b..625288e93 100644 --- a/src/Library/Library.blp +++ b/src/Library/Library.blp @@ -43,6 +43,10 @@ Adw.PreferencesWindow library { title: "User Interface"; } + Adw.PreferencesGroup library_platform { + title: "Platform APIs"; + } + Adw.PreferencesGroup { vexpand: true; valign: end; diff --git a/src/Library/demos/Screenshot/main.blp b/src/Library/demos/Screenshot/main.blp new file mode 100644 index 000000000..fc58b839e --- /dev/null +++ b/src/Library/demos/Screenshot/main.blp @@ -0,0 +1,32 @@ +using Gtk 4.0; +using Adw 1; + +Adw.StatusPage { + title: "Screenshot"; + description: _("Take a picture of the screen"); + margin-top: 48; + + Box { + orientation: vertical; + halign: center; + + Box { + Picture picture {} + margin-bottom: 12; + width-request: 256; + height-request: 256; + } + + Button button { + label: _("Take Screenshot"); + margin-bottom: 42; + halign: center; + styles ["suggested-action"] + } + + LinkButton { + label: "API Reference"; + uri: "https://libportal.org/method.Portal.take_screenshot.html"; + } + } +} diff --git a/src/Library/demos/Screenshot/main.js b/src/Library/demos/Screenshot/main.js new file mode 100644 index 000000000..50179f75d --- /dev/null +++ b/src/Library/demos/Screenshot/main.js @@ -0,0 +1,48 @@ +import Xdp from "gi://Xdp"; +import XdpGtk from "gi://XdpGtk4"; +import Gio from "gi://Gio"; +import Adw from "gi://Adw"; + +const portal = new Xdp.Portal(); +const parent = XdpGtk.parent_new_gtk(workbench.window); + +const button = workbench.builder.get_object("button"); +const picture = workbench.builder.get_object("picture"); + +Gio._promisify( + Xdp.Portal.prototype, + "take_screenshot", + "take_screenshot_finish", +); + +button.connect("clicked", () => { + takeScreenshot().catch(logError); +}); + +async function takeScreenshot() { + const flags = Xdp.ScreenshotFlags.NONE; + + let uri; + try { + uri = await portal.take_screenshot(parent, flags, null); + } catch (err) { + showPermissionError(); + return; + } + + const file = Gio.File.new_for_uri(uri); + picture.set_file(file); +} + +function showPermissionError() { + const dialog = new Adw.MessageDialog({ + heading: "Permission Error", + body: "Ensure Screenshot permission is enabled in\nSettings → Apps → Workbench", + close_response: "ok", + modal: true, + transient_for: workbench.window, + }); + + dialog.add_response("ok", "OK"); + dialog.present(); +} diff --git a/src/Library/demos/Screenshot/main.json b/src/Library/demos/Screenshot/main.json new file mode 100644 index 000000000..dd9e649d1 --- /dev/null +++ b/src/Library/demos/Screenshot/main.json @@ -0,0 +1,10 @@ +{ + "name": "Screenshot", + "category": "platform", + "description": "Take a picture of the screen", + "panels": [ + "code", + "preview" + ], + "autorun": true +} From 3fb6c5d14ff7ee37df899041bfb0bc8fc3a7081c Mon Sep 17 00:00:00 2001 From: AkshayWarrier <58233418+AkshayWarrier@users.noreply.github.com> Date: Wed, 31 May 2023 00:42:41 +0530 Subject: [PATCH 4/9] library: Add Header Bar entry (#260) --- src/Library/demos/Header Bar/main.blp | 80 ++++++++++++++++++++++++++ src/Library/demos/Header Bar/main.json | 10 ++++ 2 files changed, 90 insertions(+) create mode 100644 src/Library/demos/Header Bar/main.blp create mode 100644 src/Library/demos/Header Bar/main.json diff --git a/src/Library/demos/Header Bar/main.blp b/src/Library/demos/Header Bar/main.blp new file mode 100644 index 000000000..80cacc447 --- /dev/null +++ b/src/Library/demos/Header Bar/main.blp @@ -0,0 +1,80 @@ +using Gtk 4.0; +using Adw 1; + +Gtk.Window { + default-width: 800; + default-height: 600; + title: _("Header Bar"); + titlebar: Adw.HeaderBar { + + [start] + MenuButton{ + label: _("Open"); + menu-model: open_menu; + } + [start] + Button { + icon-name: "tab-new-filled-symbolic"; + } + [end] + MenuButton { + icon-name: "open-menu-symbolic"; + tooltip-text: _("Main Menu"); + primary: true; + menu-model: window_menu; + } + [end] + Button { + icon-name: "loupe-large-symbolic"; + } + }; + + Adw.StatusPage { + title: "Header Bar"; + description: _("Custom titlebars for windows"); + + Box{ + orientation:vertical; + + LinkButton { + label: "API Reference"; + uri: "https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1.3/class.HeaderBar.html"; + } + + LinkButton { + label: "Human Interface Guidelines"; + uri: "https://developer.gnome.org/hig/patterns/containers/header-bars.html"; + } + } + } +} + +menu window_menu { + section { + item { + label: _("Keyboard Shortcuts"); + action: "app.shortcuts"; + } + + item { + label: _("About App"); + action: "app.about"; + } + } +} + +menu open_menu { + section { + item { + label: _("Item 1"); + } + item { + label: _("Item 2"); + } + item { + label: _("Item 3"); + } + } +} + + diff --git a/src/Library/demos/Header Bar/main.json b/src/Library/demos/Header Bar/main.json new file mode 100644 index 000000000..b8da790d4 --- /dev/null +++ b/src/Library/demos/Header Bar/main.json @@ -0,0 +1,10 @@ +{ + "name": "Header Bar", + "category": "user_interface", + "description": "Custom titlebars for windows", + "panels": [ + "ui", + "preview" + ], + "autorun": true +} From 1e7c3525748510b68da8a2a65849e8be0e5a6236 Mon Sep 17 00:00:00 2001 From: Sonny Piers Date: Wed, 31 May 2023 01:58:18 +0200 Subject: [PATCH 5/9] Improve screenshot preview experience --- src/Library/demos/View Switcher/main.blp | 38 +++++--------- src/Previewer/Previewer.js | 59 ++++++++++----------- src/actions.js | 65 ++++++++++++++++-------- src/init.js | 3 +- src/main.js | 1 + src/window.blp | 4 +- 6 files changed, 92 insertions(+), 78 deletions(-) diff --git a/src/Library/demos/View Switcher/main.blp b/src/Library/demos/View Switcher/main.blp index 60e8d53bb..6d4fee760 100644 --- a/src/Library/demos/View Switcher/main.blp +++ b/src/Library/demos/View Switcher/main.blp @@ -2,17 +2,14 @@ using Gtk 4.0; using Adw 1; Adw.Window { - modal: true; width-request: 360; height-request: 360; - content: - Box { + content: Box { orientation: vertical; Adw.HeaderBar { centering-policy: strict; - title-widget: - Adw.ViewSwitcherTitle switcher_title { + title-widget: Adw.ViewSwitcherTitle switcher_title { stack: stack; title: _("AdwViewSwitcher Demo"); }; @@ -26,9 +23,7 @@ Adw.Window { title: _("Favorites"); icon-name: "star-filled-rounded-symbolic"; use-underline: true; - child: - - Adw.StatusPage{ + child: Adw.StatusPage{ title: bind page1.title; icon-name: bind page1.icon-name; child: @@ -54,14 +49,12 @@ Adw.Window { title: _("Recents"); icon-name: "clock-alt-symbolic"; use-underline: true; - child: - - Adw.StatusPage{ + child: Adw.StatusPage { title: bind page2.title; icon-name: bind page2.icon-name; child: - Box{ + Box { orientation: vertical; valign: center; @@ -87,37 +80,32 @@ Adw.Window { use-underline: true; child: - Adw.StatusPage{ + Adw.StatusPage { title: bind page3.title; valign: start; margin-start: 15; margin-end: 15; child: - Adw.Clamp{ + Adw.Clamp { maximum-size: 500; - ListBox notification_list{ - halign: baseline; - styles["boxed-list"] - + ListBox notification_list { + halign: baseline; + styles["boxed-list"] } }; }; } - Adw.ViewStackPage page4{ + Adw.ViewStackPage page4 { name: "page4"; title: _("Account"); icon-name: "person-symbolic"; use-underline: true; - child: - - Adw.StatusPage{ + child: Adw.StatusPage{ title: bind page4.title; icon-name: bind page4.icon-name; - child: - - Box{ + child: Box{ orientation: vertical; valign: center; diff --git a/src/Previewer/Previewer.js b/src/Previewer/Previewer.js index 7a83e13fd..ae653a847 100644 --- a/src/Previewer/Previewer.js +++ b/src/Previewer/Previewer.js @@ -3,11 +3,6 @@ import GObject from "gi://GObject"; import GLib from "gi://GLib"; import Gio from "gi://Gio"; -import Xdp from "gi://Xdp"; -import XdpGtk from "gi://XdpGtk4"; - -import { portal } from "../util.js"; - import * as xml from "../langs/xml/xml.js"; import * as postcss from "../lib/postcss.js"; @@ -291,31 +286,8 @@ export default function Previewer({ } builder.get_object("button_screenshot").connect("clicked", () => { - screenshot().catch(logError); + screenshot({ application, window, data_dir, current }).catch(logError); }); - async function screenshot() { - const path = GLib.build_filenamev([data_dir, "Workbench screenshot.png"]); - - const success = await current.screenshot({ window, path }); - if (!success) return; - - const parent = XdpGtk.parent_new_gtk(window); - - try { - await portal.open_uri( - parent, - `file://${path}`, - Xdp.OpenUriFlags.NONE, // flags - null, // cancellable - ); - } catch (err) { - if (err.code !== Gio.IOErrorEnum.CANCELLED) { - logError(err); - } else { - throw err; - } - } - } setPreviewer(internal); start(); @@ -489,3 +461,32 @@ function makeWorkbenchTargetId() { function isWorkbenchTargetId(id) { return id.startsWith(target_id_prefix); } + +async function screenshot({ application, window, data_dir, current }) { + const date = new GLib.DateTime().format("%Y-%m-%d %H-%M-%S"); + // FIXME: GJS does not have Gio.File.new_build_filename + const file = Gio.File.new_for_path( + GLib.build_filenamev([data_dir, "screenshots", `${date}.png`]), + ); + + try { + file.get_parent().make_directory_with_parents(null); + } catch (err) { + if (err.code !== Gio.IOErrorEnum.EXISTS) throw err; + } + + const success = await current.screenshot({ window, path: file.get_path() }); + if (!success) return; + + const notification = new Gio.Notification(); + const action = Gio.Action.print_detailed_name( + "app.show-screenshot", + new GLib.Variant("s", file.get_uri()), + ); + notification.set_icon(new Gio.ThemedIcon({ name: "re.sonny.Workbench" })); + notification.set_title("Workbench"); + notification.set_body(_("Screenshot of preview captured")); + notification.set_default_action(action); + notification.add_button(_("Show in Files"), action); + application.send_notification(null, notification); +} diff --git a/src/actions.js b/src/actions.js index 4f84ac7e9..132932156 100644 --- a/src/actions.js +++ b/src/actions.js @@ -47,27 +47,7 @@ export default function Actions({ application }) { parameter_type: null, }); action_open_file.connect("activate", () => { - const parent = XdpGtk.parent_new_gtk(application.get_active_window()); - portal.open_file( - parent, - _("Import File"), - filters, - null, // current_filter - null, // choices - Xdp.OpenFileFlags.NONE, - null, // cancellable, - (_self, res) => { - let uri; - try { - const results = portal.open_file_finish(res); - [uri] = results.recursiveUnpack().uris; - } catch { - return; - } - - application.open([Gio.File.new_for_uri(uri)], "open"); - }, - ); + openFile({ application }).catch(logError); }); application.add_action(action_open_file); application.set_accels_for_action("app.open", ["O"]); @@ -137,6 +117,16 @@ export default function Actions({ application }) { application.add_action(settings.create_action("color-scheme")); application.add_action(settings.create_action("safe-mode")); application.add_action(settings.create_action("auto-preview")); + + const action_show_screenshot = new Gio.SimpleAction({ + name: "show-screenshot", + parameter_type: new GLib.VariantType("s"), + }); + action_show_screenshot.connect("activate", (_self, target) => { + const uri = target.unpack(); + showScreenshot({ application, uri }).catch(logError); + }); + application.add_action(action_show_screenshot); } const lang_filters = languages.map((language) => { @@ -149,3 +139,36 @@ const filters = new GLib.Variant("a(sa(us))", [ [_("All supported"), lang_filters.flatMap(([, types]) => types)], ...lang_filters, ]); + +async function openFile({ application }) { + const parent = XdpGtk.parent_new_gtk(application.get_active_window()); + + let uri; + + try { + const results = await portal.open_file( + parent, + _("Import File"), + filters, + null, // current_filter + null, // choices + Xdp.OpenFileFlags.NONE, + null, // cancellable + ); + [uri] = results.recursiveUnpack().uris; + } catch (err) { + if (err.code !== Gio.IOErrorEnum.CANCELLED) throw err; + } + + application.open([Gio.File.new_for_uri(uri)], "open"); +} + +async function showScreenshot({ application, uri }) { + const parent = XdpGtk.parent_new_gtk(application.get_active_window()); + await portal.open_directory( + parent, + uri, + Xdp.OpenUriFlags.NONE, + null, // cancellable + ); +} diff --git a/src/init.js b/src/init.js index bd2ab3031..269074933 100644 --- a/src/init.js +++ b/src/init.js @@ -9,7 +9,8 @@ import Gio from "gi://Gio"; import Xdp from "gi://Xdp"; import Source from "gi://GtkSource"; -Gio._promisify(Xdp.Portal.prototype, "open_uri", "open_uri_finish"); +Gio._promisify(Xdp.Portal.prototype, "open_file", "open_file_finish"); +Gio._promisify(Xdp.Portal.prototype, "open_directory", "open_directory_finish"); Gio._promisify( Gio.InputStream.prototype, diff --git a/src/main.js b/src/main.js index 742076415..53bd97214 100644 --- a/src/main.js +++ b/src/main.js @@ -5,6 +5,7 @@ import application from "./application.js"; pkg.initGettext(); import "./language-specs/blueprint.lang"; +import "./style.css"; export function main(argv) { return application.runAsync(argv); diff --git a/src/window.blp b/src/window.blp index cfbd9cd27..225c45d56 100644 --- a/src/window.blp +++ b/src/window.blp @@ -290,9 +290,9 @@ Gtk.ApplicationWindow window { [end] Button button_screenshot { icon-name: "re.sonny.Workbench-screenshot-symbolic"; - tooltip-text: _("Take Screenshot of Preview"); + tooltip-text: _("Screenshot Preview"); accessibility { - label: _("Take Screenshot of Preview"); + label: _("Screenshot Preview"); } } } From 947129b1a29f4a7e3b257999a3100de9d4e36ffa Mon Sep 17 00:00:00 2001 From: Sriyansh Shivam <96797205+SoNiC-HeRE@users.noreply.github.com> Date: Sat, 3 Jun 2023 17:20:26 +0530 Subject: [PATCH 6/9] library: Add Font Dialog Entry (#244) --- src/Library/demos/Font Dialog/main.blp | 61 +++++++++++++++++++++++++ src/Library/demos/Font Dialog/main.js | 46 +++++++++++++++++++ src/Library/demos/Font Dialog/main.json | 10 ++++ 3 files changed, 117 insertions(+) create mode 100644 src/Library/demos/Font Dialog/main.blp create mode 100644 src/Library/demos/Font Dialog/main.js create mode 100644 src/Library/demos/Font Dialog/main.json diff --git a/src/Library/demos/Font Dialog/main.blp b/src/Library/demos/Font Dialog/main.blp new file mode 100644 index 000000000..23e8a03bd --- /dev/null +++ b/src/Library/demos/Font Dialog/main.blp @@ -0,0 +1,61 @@ +using Gtk 4.0; +using Adw 1; + +Adw.StatusPage { + title: "Font Dialog"; + description: _("Show a dialog to select a font"); + + Box { + orientation: vertical; + halign: center; + spacing: 42; + + Box{ + orientation: vertical; + + Label { + label: _("Dialog Button"); + margin-bottom: 12; + styles ["title-4"] + } + + FontDialogButton font_dialog_button { + halign: center; + margin-bottom: 12; + use-font: true; + use-size: true; + } + + + LinkButton { + label: _("API Reference"); + uri: "https://docs.gtk.org/gtk4/class.FontDialogButton.html"; + } + } + + Box{ + orientation: vertical; + + Label { + label: _("Dialog with Custom Button"); + margin-bottom: 12; + styles ["title-4"] + } + + Button custom_button { + label: _("Select Font…"); + halign: center; + margin-bottom: 12; + styles ["pill"] + } + + LinkButton { + label: _("API Reference"); + uri: "https://docs.gtk.org/gtk4/class.FontDialog.html"; + } + } + } +} + + + diff --git a/src/Library/demos/Font Dialog/main.js b/src/Library/demos/Font Dialog/main.js new file mode 100644 index 000000000..166c1d83c --- /dev/null +++ b/src/Library/demos/Font Dialog/main.js @@ -0,0 +1,46 @@ +import Gtk from "gi://Gtk"; +import Gio from "gi://Gio"; + +Gio._promisify( + Gtk.FontDialog.prototype, + "choose_font_and_features", + "choose_font_and_features_finish", +); + +Gio._promisify( + Gtk.FontDialog.prototype, + "choose_family", + "choose_family_finish", +); + +const font_dialog_button = workbench.builder.get_object("font_dialog_button"); +const custom_button = workbench.builder.get_object("custom_button"); + +const dialog_standard = new Gtk.FontDialog({ + title: "Select a Font", + modal: true, +}); +font_dialog_button.set_dialog(dialog_standard); + +font_dialog_button.connect("notify::font-desc", () => { + const font_name = font_dialog_button.get_font_desc().to_string(); + console.log(`Font: ${font_name}`); +}); + +const dialog_custom = new Gtk.FontDialog({ + title: "Select a Font Family", + modal: true, +}); + +async function onClicked() { + let result; + try { + result = await dialog_custom.choose_family(workbench.window, null, null); + } catch (err) { + logError(err); + return; + } + console.log(`Font Family: ${result.get_name()}`); +} + +custom_button.connect("clicked", onClicked); diff --git a/src/Library/demos/Font Dialog/main.json b/src/Library/demos/Font Dialog/main.json new file mode 100644 index 000000000..3e8e89f46 --- /dev/null +++ b/src/Library/demos/Font Dialog/main.json @@ -0,0 +1,10 @@ +{ + "name": "Font Dialog", + "category": "controls", + "description": "Show a dialog to select a font", + "panels": [ + "ui", + "preview" + ], + "autorun": true +} From 92896af8224263a197e55fc98e75c3139df837ee Mon Sep 17 00:00:00 2001 From: halfmexican <103920890+halfmexican@users.noreply.github.com> Date: Sat, 3 Jun 2023 13:27:23 -0500 Subject: [PATCH 7/9] library: add PreferencesWindow entry (#297) --- src/Library/demos/Preferences Window/main.blp | 182 ++++++++++++++++++ src/Library/demos/Preferences Window/main.js | 37 ++++ .../demos/Preferences Window/main.json | 7 + 3 files changed, 226 insertions(+) create mode 100644 src/Library/demos/Preferences Window/main.blp create mode 100644 src/Library/demos/Preferences Window/main.js create mode 100644 src/Library/demos/Preferences Window/main.json diff --git a/src/Library/demos/Preferences Window/main.blp b/src/Library/demos/Preferences Window/main.blp new file mode 100644 index 000000000..9dde9a994 --- /dev/null +++ b/src/Library/demos/Preferences Window/main.blp @@ -0,0 +1,182 @@ +using Gtk 4.0; +using Adw 1; + +Adw.PreferencesWindow pref_window { + default-width: 800; + default-height: 600; + title: _("Preferences"); + + Adw.PreferencesPage appearance_page { + title: _("Appearance"); + icon-name: "brush-monitor-symbolic"; + + Adw.PreferencesGroup { + title: _("Color Settings"); + description: _("Change the color-scheme of the application."); + + Adw.ActionRow { + title: _("Use Dark Mode"); + activatable-widget: dm_switch; + + [suffix] + Switch dm_switch { + halign: center; + valign: center; + } + } + } + + Adw.PreferencesGroup { + title: _("Text Settings"); + description: _("Customize the appearance of text in the application."); + + Adw.ActionRow { + title: _("Font Size"); + + [suffix] + Gtk.SpinButton { + halign: center; + valign: center; + adjustment: + Gtk.Adjustment { + lower: 5; + upper: 20; + step-increment: 1; + value: 11; + }; + } + } + + Adw.ActionRow { + title: _("Font Color"); + + [suffix] + Gtk.ColorDialogButton { + halign: center; + valign: center; + dialog: ColorDialog {}; + } + } + } + + Adw.PreferencesGroup { + title: _("API References"); + + Box { + orientation: horizontal; + margin-top: 12; + + LinkButton { + label: _("PreferencesWindow"); + uri: "https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1.3/class.PreferencesWindow.html"; + } + + LinkButton { + label: _("PreferencesPage"); + uri: "https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1.3/class.PreferencesPage.html"; + } + + LinkButton { + label: _("PreferencesGroup"); + uri: "https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1.3/class.PreferencesGroup.html"; + } + + LinkButton { + label: _("PreferencesRow"); + uri: "https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1.3/class.PreferencesRow.html"; + } + } + } + } + + Adw.PreferencesPage { + title: _("Behavior"); + icon-name: "settings-symbolic"; + + Adw.PreferencesGroup { + title: _("Interaction Settings"); + description: _("Change how the app behaves during user interaction."); + + // Adw.PreferencesGroup can have suffix widgets like Adw.ActionRows + [header-suffix] + Button{ + halign: center; + valign: center; + icon-name: "settings-symbolic"; + } + + Adw.ActionRow { + title: _("Run on Startup"); + activatable-widget: startup_switch; + + [suffix] + Switch startup_switch { + halign: center; + valign: center; + } + } + + Adw.ActionRow { + title: _("Show Toast"); + activatable-widget: toast_button; + + [suffix] + Button toast_button { + halign: center; + valign: center; + label: _("show toast"); + icon-name: "bread-symbolic"; + } + } + } + + Adw.PreferencesGroup { + title: _("Data Settings"); + description: _("Manage user data related settings."); + + Adw.ActionRow { + title: _("Enable Telemetry"); + activatable-widget: telemetry_switch; + + [suffix] + Switch telemetry_switch{ + halign: center; + valign: center; + } + } + + Adw.ActionRow { + title: _("Enable Auto-Updates"); + activatable-widget: update_switch; + + [suffix] + Switch update_switch { + halign: center; + valign: center; + } + } + + Adw.ActionRow subpage_row { + title: _("Additional Preferences"); + activatable: true; + + [suffix] + Gtk.Image { + icon-name: "go-next-symbolic"; + styles ["dim-label"] + } + } + } + } +} + +Adw.StatusPage subpage { + description: _("Custom Subpage"); + + Gtk.Button subpage_button { + label: _("Go back"); + halign: center; + valign: center; + styles ["suggested-action", "pill"] + } +} diff --git a/src/Library/demos/Preferences Window/main.js b/src/Library/demos/Preferences Window/main.js new file mode 100644 index 000000000..67a19e8cd --- /dev/null +++ b/src/Library/demos/Preferences Window/main.js @@ -0,0 +1,37 @@ +import Adw from "gi://Adw"; + +const pref_window = workbench.builder.get_object("pref_window"); +const dm_switch = workbench.builder.get_object("dm_switch"); +const subpage = workbench.builder.get_object("subpage"); +const subpage_row = workbench.builder.get_object("subpage_row"); +const subpage_button = workbench.builder.get_object("subpage_button"); +const toast_button = workbench.builder.get_object("toast_button"); +const style_manager = Adw.StyleManager.get_default(); + +dm_switch.active = style_manager.dark; + +dm_switch.connect("notify::active", () => { + // When the Switch is toggled, set the color scheme + if (dm_switch.active) { + style_manager.color_scheme = Adw.ColorScheme.FORCE_DARK; + } else { + style_manager.color_scheme = Adw.ColorScheme.FORCE_LIGHT; + } +}); + +// Preferences windows can display subpages +subpage_row.connect("activated", () => { + pref_window.present_subpage(subpage); +}); + +subpage_button.connect("clicked", () => { + pref_window.close_subpage(); +}); + +toast_button.connect("clicked", () => { + const toast = new Adw.Toast({ + title: "Preferences windows can display toasts", + }); + + pref_window.add_toast(toast); +}); diff --git a/src/Library/demos/Preferences Window/main.json b/src/Library/demos/Preferences Window/main.json new file mode 100644 index 000000000..59727ec0a --- /dev/null +++ b/src/Library/demos/Preferences Window/main.json @@ -0,0 +1,7 @@ +{ + "name": "Preferences Window", + "category": "user_interface", + "description": "A window containing an application's preferences", + "panels": ["ui", "preview"], + "autorun": true +} From 5594a03112344bf7fc06183b760752399eae84e6 Mon Sep 17 00:00:00 2001 From: AkshayWarrier <58233418+AkshayWarrier@users.noreply.github.com> Date: Sun, 4 Jun 2023 00:20:52 +0530 Subject: [PATCH 8/9] library: Add WebView entry (#299) --- src/Library/demos/Web View/main.blp | 70 ++++++++++++++++++++++ src/Library/demos/Web View/main.js | 90 ++++++++++++++++++++++++++++ src/Library/demos/Web View/main.json | 7 +++ 3 files changed, 167 insertions(+) create mode 100644 src/Library/demos/Web View/main.blp create mode 100644 src/Library/demos/Web View/main.js create mode 100644 src/Library/demos/Web View/main.json diff --git a/src/Library/demos/Web View/main.blp b/src/Library/demos/Web View/main.blp new file mode 100644 index 000000000..163b3f607 --- /dev/null +++ b/src/Library/demos/Web View/main.blp @@ -0,0 +1,70 @@ +using Gtk 4.0; +using Adw 1; + +Adw.Clamp { + maximum-size: 700; + + Box { + orientation: vertical; + + Box { + orientation: vertical; + margin-top: 12; + margin-bottom: 12; + spacing: 6; + + Label { + label: "Web View"; + + styles ["title-1"] + } + + Label { + label: "Load and display webpages and HTML"; + } + } + + Box controls { + spacing: 6; + + Button button_back { + icon-name: "arrow1-left-symbolic"; + tooltip-text: _("Back"); + } + + Button button_forward { + icon-name: "arrow1-right-symbolic"; + tooltip-text: _("Forward"); + } + + Entry url_bar { + input-purpose: url; + hexpand: true; + } + + Button button_reload { + icon-name: "refresh-symbolic"; + tooltip-text: _("Reload"); + } + + Button button_stop { + icon-name: "stop-sign-symbolic"; + tooltip-text: _("Stop"); + } + } + + Adw.Bin container { + margin-top: 18; + margin-bottom: 18; + vexpand: true; + hexpand: true; + styles ["view"] + } + + LinkButton { + margin-bottom: 12; + label: "API Reference"; + uri: "https://webkitgtk.org/reference/webkit2gtk/stable/class.WebView.html"; + } + } +} diff --git a/src/Library/demos/Web View/main.js b/src/Library/demos/Web View/main.js new file mode 100644 index 000000000..a680dad6f --- /dev/null +++ b/src/Library/demos/Web View/main.js @@ -0,0 +1,90 @@ +import WebKit from "gi://WebKit?version=6.0"; +import GObject from "gi://GObject"; +import GLib from "gi://GLib"; + +const container = workbench.builder.get_object("container"); +const button_back = workbench.builder.get_object("button_back"); +const button_forward = workbench.builder.get_object("button_forward"); +const button_reload = workbench.builder.get_object("button_reload"); +const button_stop = workbench.builder.get_object("button_stop"); +const url_bar = workbench.builder.get_object("url_bar"); +const web_view = new WebKit.WebView({ + zoom_level: 0.8, +}); +container.child = web_view; + +// URL bar displays the current loaded page +web_view.bind_property( + "uri", + url_bar.buffer, + "text", + GObject.BindingFlags.DEFAULT, +); + +web_view.load_uri("https://www.gnome.org/"); + +url_bar.connect("activate", () => { + let url = url_bar.buffer.text; + const scheme = GLib.Uri.peek_scheme(url); + if (scheme == null) { + url = `http://${url}`; + } + web_view.load_uri(url); +}); + +button_forward.connect("clicked", () => { + web_view.go_forward(); +}); + +button_back.connect("clicked", () => { + web_view.go_back(); +}); + +button_reload.connect("clicked", () => { + web_view.reload(); +}); + +button_stop.connect("clicked", () => { + web_view.stop_loading(); +}); + +web_view.connect("load-changed", (view, load_event) => { + switch (load_event) { + case WebKit.LoadEvent.STARTED: + console.log("Page loading started"); + break; + case WebKit.LoadEvent.FINISHED: + console.log("Page loading has finished "); + break; + } +}); + +web_view.connect("load-failed", (view, load_event, fail_url, error) => { + // Dont display error page if it is caused by stop_loading() + if (error.code !== WebKit.NetworkError.CANCELLED) { + web_view.load_alternate_html( + error_page(fail_url, error.message), + fail_url, + null, + ); + } +}); + +web_view.connect("notify::estimated-load-progress", () => { + url_bar.progress_fraction = web_view.estimated_load_progress; + if (url_bar.progress_fraction === 1) { + setTimeout(() => { + url_bar.progress_fraction = 0; + }, 500); + } +}); + +function error_page(fail_url, msg) { + const error = ` +
+

An error occurred while loading ${fail_url}

+

${msg}

+
+ `; + return error; +} diff --git a/src/Library/demos/Web View/main.json b/src/Library/demos/Web View/main.json new file mode 100644 index 000000000..5eef92941 --- /dev/null +++ b/src/Library/demos/Web View/main.json @@ -0,0 +1,7 @@ +{ + "name": "Web View", + "category": "network", + "description": "Load and display webpages and HTML", + "panels": ["code", "preview"], + "autorun": true +} From 0313e124d0054162ffedcb0921729c0c2d27723b Mon Sep 17 00:00:00 2001 From: Sonny Piers Date: Sat, 3 Jun 2023 21:27:39 +0200 Subject: [PATCH 9/9] fixes --- src/Library/demos/Boxed Lists/main.blp | 74 ++++++++++++++++++++ src/Library/demos/Boxed Lists/main.json | 10 +++ src/Library/demos/Boxed lists/main.blp | 91 ------------------------- src/Library/demos/Boxed lists/main.js | 11 --- src/Library/demos/Boxed lists/main.json | 10 --- 5 files changed, 84 insertions(+), 112 deletions(-) create mode 100644 src/Library/demos/Boxed Lists/main.blp create mode 100644 src/Library/demos/Boxed Lists/main.json delete mode 100644 src/Library/demos/Boxed lists/main.blp delete mode 100644 src/Library/demos/Boxed lists/main.js delete mode 100644 src/Library/demos/Boxed lists/main.json diff --git a/src/Library/demos/Boxed Lists/main.blp b/src/Library/demos/Boxed Lists/main.blp new file mode 100644 index 000000000..474bb44e7 --- /dev/null +++ b/src/Library/demos/Boxed Lists/main.blp @@ -0,0 +1,74 @@ +using Gtk 4.0; +using Adw 1; + +Adw.StatusPage { + title: _("Boxed Lists"); + description: _("List to present both controls and information"); + + Adw.Clamp { + maximum-size: 500; + + Box { + orientation: vertical; + + ListBox { + selection-mode: none; + styles ["boxed-list"] + + Adw.ActionRow { + title: _("ActionRow can have a prefix child"); + + [prefix] + CheckButton checkbox { + active: true; + } + } + + Adw.ActionRow { + title: _("ActionRow can have a suffix child"); + subtitle: _("The checkbox above controls the spinner"); + + [suffix] + Spinner { + spinning: bind checkbox.active; + } + } + + Adw.EntryRow { + title: _("A row can be an entry"); + } + + Adw.ComboRow { + title: _("Choose an item"); + subtitle: _("ComboRow can have a drop down list"); + model: StringList list { + strings ["this", "is", "a", "string", "list"] + }; + } + + Adw.ExpanderRow { + title: _("Rows can be expandable"); + show-enable-switch: true; + + Adw.ActionRow { + title: _("First row"); + } + Adw.ActionRow { + title: _("Second row"); + } + } + } + + LinkButton { + margin-top: 24; + label: "API Reference"; + uri: "https://gnome.pages.gitlab.gnome.org/libadwaita/doc/1-latest/boxed-lists.html"; + } + + LinkButton { + label: "Human Interface Guidelines"; + uri: "https://developer.gnome.org/hig/patterns/containers/boxed-lists.html"; + } + } + } +} diff --git a/src/Library/demos/Boxed Lists/main.json b/src/Library/demos/Boxed Lists/main.json new file mode 100644 index 000000000..cd9a19b2a --- /dev/null +++ b/src/Library/demos/Boxed Lists/main.json @@ -0,0 +1,10 @@ +{ + "name": "Boxed Lists", + "category": "user_interface", + "description": "List to present both controls and information", + "panels": [ + "preview", + "ui" + ], + "autorun": true +} diff --git a/src/Library/demos/Boxed lists/main.blp b/src/Library/demos/Boxed lists/main.blp deleted file mode 100644 index 7cf09d147..000000000 --- a/src/Library/demos/Boxed lists/main.blp +++ /dev/null @@ -1,91 +0,0 @@ -using Gtk 4.0; -using Adw 1; - -Adw.StatusPage { - title: "Boxed Lists"; - - ListBox { - halign: center; - - Adw.PreferencesGroup { - title: "Rows can be groupped"; - Adw.ActionRow { - title: "Action row can have a prefix child"; - - [prefix] - CheckButton checkbox { - active: true; - } - } - - Adw.ActionRow { - title: "Action row can have a suffix child"; - subtitle: "Select checkbox above to show spinner"; - - [suffix] - Spinner { - spinning: bind checkbox.active; - } - } - - Adw.EntryRow { - title: "A row can be an entry"; - } - } - - Adw.PreferencesGroup { - title: "Preferences Groups can have a suffix"; - - [header-suffix] - Button { - Adw.ButtonContent { - label: "child"; - icon-name: "sidebar-toggle-right-symbolic"; - } - - } - - Adw.ComboRow { - title: "Choose an item"; - subtitle: "ComboRow can have a drop down list"; - model: StringList list { - strings ["this", "is", "a", "string", "list"] - }; - } - - Adw.ExpanderRow { - title: "Rows can be expandable"; - - // remove the line below if you don't want a switch - show-enable-switch: true; - - Adw.ActionRow { - title: "First row"; - } - Adw.ActionRow { - title: "Second row"; - } - } - - Adw.ActionRow { - title: "Row can have an interactive button"; - - [suffix] - Button button { - label: "click"; - valign: center; - } - } - } - - LinkButton { - label: "API Reference"; - uri: "https://gnome.pages.gitlab.gnome.org/libadwaita/doc/main/boxed-lists.html"; - } - - LinkButton { - label: "Human Interface Guidelines"; - uri: "https://developer.gnome.org/hig/patterns/containers/boxed-lists.html"; - } - } -} diff --git a/src/Library/demos/Boxed lists/main.js b/src/Library/demos/Boxed lists/main.js deleted file mode 100644 index a2b4836d0..000000000 --- a/src/Library/demos/Boxed lists/main.js +++ /dev/null @@ -1,11 +0,0 @@ -const button = workbench.builder.get_object("button"); - -button.connect("clicked", () => { - if (button.has_css_class("accent")) { - button.remove_css_class("accent"); - button.set_label("click"); - } else { - button.add_css_class("accent"); - button.set_label("clicked"); - } -}); diff --git a/src/Library/demos/Boxed lists/main.json b/src/Library/demos/Boxed lists/main.json deleted file mode 100644 index 7bdb347da..000000000 --- a/src/Library/demos/Boxed lists/main.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "Boxed Lists", - "category": "user_interface", - "description": "Boxed lists are a common type of list that can contain both controls and information. Examples include app preferences or a short list of recent documents in a picker.", - "panels": [ - "preview", - "ui" - ], - "autorun": true -}