Skip to content

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

Open
@rolandlo

Description

@rolandlo

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions