workbenchdev / workbenchdev/Workbench

Define Gtk closure expressions in code when the UI file is NOT a template.

Open
#667 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
844
Forks
91
Avg merge
7h 12m
Merged PRs (30d)
1

Description

Suppose we have a .blp-file that defines a template. Then we can use Gtk closure expression defined in the (say javascript) code like this for example:

UI file main.blp

using Gtk 4.0;
using Adw 1;

template $CustomWidget : Adw.PreferencesGroup {
  Adw.ComboRow cb {
    title: _("Make a selection:");
    
    model:
    StringList {
      strings ["One", "Two", "Three", "Four"]
    };
  }
  
  Adw.SwitchRow sw1 {  // should only be visible when option "One", "Two" or "Three" is selected.
    title: _("Switch one");
    active: true;
    visible: bind $onlyOneTwoThree(cb.selected-item) as <bool>;
  }
  
  Adw.SwitchRow sw2 { // should only be visible when option "Three" or "Four" is selected
    title: _("Switch two");
    visible: bind $onlyThreeFour(cb.selected-item) as <bool>;
  }
  
  Adw.ActionRow {
    title: _("Status:");
    Label { // should display some status message depending on sw1.visible, sw2.visible and cb.selected-item
      label: bind $msg(sw1.visible, sw2.visible, cb.selected-item) as <string>;
    }
  }
 }

Code file main.js

import GObject from "gi://GObject";
import Gtk from "gi://Gtk";
import Adw from "gi://Adw";

const CustomWidget = GObject.registerClass(
  {
    GTypeName: "CustomWidget",
    Template: workbench.template,
  },
  class CustomWidget extends Adw.PreferencesGroup {
    onlyOneTwoThree(_self, item) {
      const str = item.string;
      return str === "One" || str === "Two" || str === "Three";
    }
    onlyThreeFour(_self, item) {
      const str = item.string;
      return str === "Three" || str === "Four";
    }
    msg(_self, active1, active2, item) {
      const str = item.string;
      if (active1 && active2) {
        return `"${str}" was selected, 2 visible`;
      } else if (active1 || active2) {
        return `"${str}" was selected, 1 visible`;
      } else {
        return "0 active. Discard selection";
      }
    }
  },
);

const box = new Gtk.Box({ orientation: "vertical" });
box.append(new CustomWidget());
workbench.preview(box);

Now suppose I want to have the same behavior in case that the UI file does NOT define a template (remove

template $CustomWidget : 

from the fourth line of main.blp)

How can we define the Gtk closure expressions onlyOneTwoThree, onlyThreeFour and msg in the code? There doesn't seem to be an easy way to do so. According to @andyholmes (conversation in the matrix channel) these closures should be added to Workbench's builder scope in some way (compare gjs guide), yet apparently Workbench is not set up to use closures at the moment.

So I'd like to request Workbench to support closures in a way that it is easy to use and documented (maybe in a Library demo).

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the main.blp and main.js examples, then read the linked GJS guide section about template-file closures and inspect how Workbench currently creates its builder scope. Done means non-template UI files can use the three demonstrated closures, with an easy usage path documented in a Library demo.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
desktop, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.