gtk_comfy

Crates.iogtk_comfy
lib.rsgtk_comfy
version0.4.4
sourcesrc
created_at2021-09-04 08:35:26.275799
updated_at2022-02-06 10:46:31.458598
descriptionGtk Comfy offers a solution to use serde formats in GTK builder files
homepage
repositoryhttps://gitlab.com/john_t/gtk-comfy
max_upload_size
id446749
size60,521
John Toohey (greenfierydragon)

documentation

README

Gtk Comfy

Gtk Comfy is an effort to improve GTK builder files. Whilst the separation between code and interface is a good one, but the implementation is poor. XML is tricky and obtuse:

Example

<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <object class="GtkApplicationWindow" id="window">
    <property name="title">My GTK App</property>
    <child>
      <object class="GtkButton" id="button">
        <property name="label">Press me!</property>
        <property name="margin-top">12</property>
        <property name="margin-bottom">12</property>
        <property name="margin-start">12</property>
        <property name="margin-end">12</property>  
      </object>
    </child>
  </object>
</interface>

So with GTK Comfy you can instead use any serde compatable format, as shown in the example below:

# The root interface
interface:
  # The class of the object (reserverd keyword)
  class: GtkApplicationWindow

  # The id of the widget (reserved keyword)
  id: window

  # The title property. See that properties are automatically infered
  title: My Gtk App

  # The children
  children:
    - class: GtkButton
      id: Button
      label: Press me!
      margin-start: "12"
      margin-top: "12"
      margin-bottom: "12"
      margin-end: "12"

Features

Gtk Comfy provides many convinience features, such as:

  • Inferred properties, if it does not recognise a variable it will infer it as a property (see the title in the above example.)
  • Child types, if a widget is given the child_type property than you can set the child type (I can’t remember when you need this but you do.)
  • Pango Attributes. For labels (and suchlike) you can use attributes to provide a map of attributes (example below.)
  • Style classes, provided in a style array.
  • Grids, support for layout in children.
  • Translation domain for interface.
  • Translations

Examples

Use in rust

Put something along these lines in your build script:

use std::fs;

// Load the UI.
let interface: gtk_comfy::Interface =
    serde_yaml::from_str(include_str!("ui.yaml"))?;

// Write it as xml.
fs::write(
    "ui.xml",
    interface.to_string(),
)?;

Attributes

class: GtkLabel
label: "This is a red label"
attributes:
  foreground: '#FF0000'

Styles

class: GtkBox
orientation: "horizontal"
style:
  - linked
children:
# ...

Grids

class: GtkGrid
  id: grid
  children:
  - class: GtkButton
    id: button1
    label: Button 1
    layout:
      column: 0
      row: 0
  - class: GtkButton
    id: button2
    label: Button 2
    layout:
      column: 1
      row: 0
  - class: GtkButton
    id: button3
    label: Button 3
    layout:
      column: 2
      row: 0
      row-span: 2
  - class: GtkButton
    id: button4
    label: Button 4
    layout:
      column: 0
      row: 1
      column-span: 2

Translation domains

domain: "whatever_this_value_does_i_have_no_idea_what_it_is"
interface:
  class: GtkWindow
  #...

Translations

Translations can be done as follows:

label:
  translatable: Save
  comment: For saving the state

Extensibility

If you need to extend it to add custom XML (because this app is not perfect) you can use the xml property:

xml: <property name="label">
Commit count: 35

cargo fmt