Builder list factory

This commit is contained in:
Cameron Dehning 2023-04-08 01:34:47 +00:00 committed by James Westman
parent 0cf9a8e4fc
commit a2fb86bc31
9 changed files with 98 additions and 1 deletions

4
.gitignore vendored
View file

@ -11,4 +11,6 @@ coverage.xml
/blueprint-regression-tests /blueprint-regression-tests
/corpus /corpus
/crashes /crashes
.vscode

View file

@ -1,3 +1,4 @@
from .gtk_list_item_factory import ListItemFactory
from .adw_message_dialog import Responses from .adw_message_dialog import Responses
from .attributes import BaseAttribute, BaseTypedAttribute from .attributes import BaseAttribute, BaseTypedAttribute
from .binding import Binding from .binding import Binding
@ -57,6 +58,7 @@ OBJECT_CONTENT_HOOKS.children = [
Widgets, Widgets,
Items, Items,
Strings, Strings,
ListItemFactory,
Responses, Responses,
Child, Child,
] ]

View file

@ -0,0 +1,32 @@
from .gobject_object import ObjectContent, validate_parent_type
from ..parse_tree import Keyword
from ..ast_utils import AstNode, validate
class ListItemFactory(AstNode):
grammar = [Keyword("template"), ObjectContent]
@property
def gir_class(self):
return self.root.gir.get_type("ListItem", "Gtk")
@validate("template")
def container_is_builder_list(self):
validate_parent_type(
self,
"Gtk",
"BuilderListItemFactory",
"sub-templates",
)
@property
def content(self) -> ObjectContent:
return self.children[ObjectContent][0]
@property
def action_widgets(self):
"""
The sub-template shouldn't have it`s own actions this is
just hear to satisfy XmlOutput._emit_object_or_template
"""
return None

View file

@ -304,6 +304,16 @@ class XmlOutput(OutputFormat):
self._emit_value(value, xml) self._emit_value(value, xml)
xml.end_tag() xml.end_tag()
xml.end_tag() xml.end_tag()
elif isinstance(extension, ListItemFactory):
child_xml = XmlEmitter()
child_xml.start_tag("interface")
child_xml.start_tag("template", **{"class": "GtkListItem"})
self._emit_object_or_template(extension, child_xml)
child_xml.end_tag()
child_xml.end_tag()
xml.start_tag("property", name="bytes")
xml.put_cdata(child_xml.result)
xml.end_tag()
elif isinstance(extension, Styles): elif isinstance(extension, Styles):
xml.start_tag("style") xml.start_tag("style")

View file

@ -62,6 +62,10 @@ class XmlEmitter:
self.result += saxutils.escape(str(text)) self.result += saxutils.escape(str(text))
self._needs_newline = False self._needs_newline = False
def put_cdata(self, text: str):
self.result += f"<![CDATA[{text}]]>"
self._needs_newline = False
def _indent(self): def _indent(self):
if self.indent is not None: if self.indent is not None:
self.result += "\n" + " " * (self.indent * len(self._tag_stack)) self.result += "\n" + " " * (self.indent * len(self._tag_stack))

View file

@ -414,6 +414,21 @@ Gtk.SizeGroup
Gtk.Label label1 {} Gtk.Label label1 {}
Gtk.Label label2 {} Gtk.Label label2 {}
Gtk.BuilderListItemFactory
~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code-block::
Gtk.ListView {
factory: Gtk.BuilderListItemFactory {
template {
child: Label {
label: "Hello";
};
}
};
}
Gtk.StringList Gtk.StringList
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~

View file

@ -0,0 +1,11 @@
using Gtk 4.0;
Gtk.ListView {
factory: Gtk.BuilderListItemFactory list_item_factory {
template {
child: Label {
label: "Hello";
};
}
};
}

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<object class="GtkListView">
<property name="factory">
<object class="GtkBuilderListItemFactory" id="list_item_factory">
<property name="bytes"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<interface>
<template class="GtkListItem">
<property name="child">
<object class="GtkLabel">
<property name="label">Hello</property>
</object>
</property>
</template>
</interface>]]></property>
</object>
</property>
</object>
</interface>

View file

@ -169,6 +169,7 @@ class TestSamples(unittest.TestCase):
self.assert_sample("flags") self.assert_sample("flags")
self.assert_sample("id_prop") self.assert_sample("id_prop")
self.assert_sample("layout") self.assert_sample("layout")
self.assert_sample("list_factory")
self.assert_sample("menu") self.assert_sample("menu")
self.assert_sample("numbers") self.assert_sample("numbers")
self.assert_sample("object_prop") self.assert_sample("object_prop")