From c155ba7b15f91daf51a514085902ed5fa8e51c1e Mon Sep 17 00:00:00 2001 From: James Westman Date: Sat, 30 Oct 2021 20:03:37 -0500 Subject: [PATCH] Add layouts --- docs/examples.rst | 18 ++++++++++++++++++ gtkblueprinttool/ast.py | 34 ++++++++++++++++++++++++++++++---- gtkblueprinttool/parser.py | 19 +++++++++++++++++++ 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/docs/examples.rst b/docs/examples.rst index 093c2cb..402d4dd 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -243,3 +243,21 @@ on one line. The action and icon are optional. menu { item _("Copy") "app.copy" "copy-symbolic"; } + + +Layout Properties +----------------- + +Basic Usage +~~~~~~~~~~~ + +.. code-block:: + + Gtk.Grid { + Gtk.Label { + layout { + row: 0; + column: 1; + } + } + } diff --git a/gtkblueprinttool/ast.py b/gtkblueprinttool/ast.py index 2225b31..b0b699a 100644 --- a/gtkblueprinttool/ast.py +++ b/gtkblueprinttool/ast.py @@ -263,12 +263,13 @@ class Child(AstNode): class ObjectContent(AstNode): child_type = "object_content" - def __init__(self, properties=[], signals=[], children=[], style=[]): + def __init__(self, properties=[], signals=[], children=[], style=[], layout=None): super().__init__() self.properties = properties self.signals = signals self.children = children self.style = style + self.layout = layout or [] @validate() @@ -290,7 +291,7 @@ class ObjectContent(AstNode): ) def emit_xml(self, xml: XmlEmitter): - for x in [*self.properties, *self.signals, *self.children, *self.style]: + for x in self.child_nodes: x.emit_xml(xml) @@ -476,8 +477,9 @@ class Menu(AstNode): xml.end_tag() -class MenuAttribute(AstNode): +class BaseAttribute(AstNode): child_type = "attributes" + tag_name: str = "" def __init__(self, name=None, value=None, translatable=False): super().__init__() @@ -487,9 +489,33 @@ class MenuAttribute(AstNode): def emit_xml(self, xml: XmlEmitter): xml.start_tag( - "attribute", + self.tag_name, name=self.name, translatable="yes" if self.translatable else None, ) xml.put_text(str(self.value)) xml.end_tag() + + +class MenuAttribute(BaseAttribute): + child_type = "attributes" + tag_name = "attribute" + + +class Layout(AstNode): + child_type = "layout" + + def __init__(self, layout_props=None): + super().__init__() + self.layout_props = layout_props or [] + + def emit_xml(self, xml: XmlEmitter): + xml.start_tag("layout") + for prop in self.layout_props: + prop.emit_xml(xml) + xml.end_tag() + + +class LayoutProperty(BaseAttribute): + child_type = "layout_props" + tag_name = "property" diff --git a/gtkblueprinttool/parser.py b/gtkblueprinttool/parser.py index 9017bca..3855bfe 100644 --- a/gtkblueprinttool/parser.py +++ b/gtkblueprinttool/parser.py @@ -244,12 +244,31 @@ def parse(tokens) -> T.Tuple[ast.UI, T.Optional[MultipleErrors]]: ), ) + layout_prop = Group( + ast.LayoutProperty, + Statement( + UseIdent("name"), + Op(":"), + value.expected("a value"), + ) + ) + + layout = Group( + ast.Layout, + Sequence( + Keyword("layout"), + OpenBlock().expected("`{`"), + Until(layout_prop, CloseBlock()), + ) + ) + object_content = Group( ast.ObjectContent, Sequence( OpenBlock(), Until(AnyOf( style, + layout, binding, property, signal,