mirror of
https://gitlab.gnome.org/jwestman/blueprint-compiler.git
synced 2025-05-04 15:59:08 -04:00
language: Add not-swapped flag for signals
This is needed because GtkBuilder defaults to swapped when you specify the object attribute.
This commit is contained in:
parent
9b9fab832b
commit
a6d57cebec
10 changed files with 72 additions and 8 deletions
|
@ -27,6 +27,7 @@ from .gtkbuilder_template import Template
|
||||||
class SignalFlag(AstNode):
|
class SignalFlag(AstNode):
|
||||||
grammar = AnyOf(
|
grammar = AnyOf(
|
||||||
UseExact("flag", "swapped"),
|
UseExact("flag", "swapped"),
|
||||||
|
UseExact("flag", "not-swapped"),
|
||||||
UseExact("flag", "after"),
|
UseExact("flag", "after"),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,6 +41,27 @@ class SignalFlag(AstNode):
|
||||||
f"Duplicate flag '{self.flag}'", lambda x: x.flag == self.flag
|
f"Duplicate flag '{self.flag}'", lambda x: x.flag == self.flag
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@validate()
|
||||||
|
def swapped_exclusive(self):
|
||||||
|
if self.flag in ["swapped", "not-swapped"]:
|
||||||
|
self.validate_unique_in_parent(
|
||||||
|
"'swapped' and 'not-swapped' flags cannot be used together",
|
||||||
|
lambda x: x.flag in ["swapped", "not-swapped"],
|
||||||
|
)
|
||||||
|
|
||||||
|
@validate()
|
||||||
|
def swapped_unnecessary(self):
|
||||||
|
if self.flag == "not-swapped" and self.parent.object_id is None:
|
||||||
|
raise CompileWarning(
|
||||||
|
"'not-swapped' is the default for handlers that do not specify an object",
|
||||||
|
actions=[CodeAction("Remove 'not-swapped' flag", "")],
|
||||||
|
)
|
||||||
|
elif self.flag == "swapped" and self.parent.object_id is not None:
|
||||||
|
raise CompileWarning(
|
||||||
|
"'swapped' is the default for handlers that specify an object",
|
||||||
|
actions=[CodeAction("Remove 'swapped' flag", "")],
|
||||||
|
)
|
||||||
|
|
||||||
@docs()
|
@docs()
|
||||||
def ref_docs(self):
|
def ref_docs(self):
|
||||||
return get_docs_section("Syntax Signal")
|
return get_docs_section("Syntax Signal")
|
||||||
|
@ -92,9 +114,17 @@ class Signal(AstNode):
|
||||||
def flags(self) -> T.List[SignalFlag]:
|
def flags(self) -> T.List[SignalFlag]:
|
||||||
return self.children[SignalFlag]
|
return self.children[SignalFlag]
|
||||||
|
|
||||||
|
# Returns True if the "swapped" flag is present, False if "not-swapped" is present, and None if neither are present.
|
||||||
|
# GtkBuilder's default if swapped is not specified is to not swap the arguments if no object is specified, and to
|
||||||
|
# swap them if an object is specified.
|
||||||
@property
|
@property
|
||||||
def is_swapped(self) -> bool:
|
def is_swapped(self) -> T.Optional[bool]:
|
||||||
return any(x.flag == "swapped" for x in self.flags)
|
for flag in self.flags:
|
||||||
|
if flag.flag == "swapped":
|
||||||
|
return True
|
||||||
|
elif flag.flag == "not-swapped":
|
||||||
|
return False
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_after(self) -> bool:
|
def is_after(self) -> bool:
|
||||||
|
@ -194,15 +224,16 @@ class Signal(AstNode):
|
||||||
|
|
||||||
|
|
||||||
@decompiler("signal")
|
@decompiler("signal")
|
||||||
def decompile_signal(
|
def decompile_signal(ctx, gir, name, handler, swapped=None, after="false", object=None):
|
||||||
ctx, gir, name, handler, swapped="false", after="false", object=None
|
|
||||||
):
|
|
||||||
object_name = object or ""
|
object_name = object or ""
|
||||||
name = name.replace("_", "-")
|
name = name.replace("_", "-")
|
||||||
line = f"{name} => ${handler}({object_name})"
|
line = f"{name} => ${handler}({object_name})"
|
||||||
|
|
||||||
if decompile.truthy(swapped):
|
if decompile.truthy(swapped):
|
||||||
line += " swapped"
|
line += " swapped"
|
||||||
|
elif swapped is not None:
|
||||||
|
line += " not-swapped"
|
||||||
|
|
||||||
if decompile.truthy(after):
|
if decompile.truthy(after):
|
||||||
line += " after"
|
line += " after"
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ class XmlOutput(OutputFormat):
|
||||||
"signal",
|
"signal",
|
||||||
name=name,
|
name=name,
|
||||||
handler=signal.handler,
|
handler=signal.handler,
|
||||||
swapped=signal.is_swapped or None,
|
swapped=signal.is_swapped,
|
||||||
after=signal.is_after or None,
|
after=signal.is_after or None,
|
||||||
object=(
|
object=(
|
||||||
self._object_id(signal, signal.object_id) if signal.object_id else None
|
self._object_id(signal, signal.object_id) if signal.object_id else None
|
||||||
|
|
|
@ -91,7 +91,7 @@ Signal Handlers
|
||||||
.. rst-class:: grammar-block
|
.. rst-class:: grammar-block
|
||||||
|
|
||||||
Signal = <name::ref:`IDENT<Syntax IDENT>`> ('::' <detail::ref:`IDENT<Syntax IDENT>`>)? '=>' '$' <handler::ref:`IDENT<Syntax IDENT>`> '(' <object::ref:`IDENT<Syntax IDENT>`>? ')' (SignalFlag)* ';'
|
Signal = <name::ref:`IDENT<Syntax IDENT>`> ('::' <detail::ref:`IDENT<Syntax IDENT>`>)? '=>' '$' <handler::ref:`IDENT<Syntax IDENT>`> '(' <object::ref:`IDENT<Syntax IDENT>`>? ')' (SignalFlag)* ';'
|
||||||
SignalFlag = 'after' | 'swapped'
|
SignalFlag = 'after' | 'swapped' | 'not-swapped'
|
||||||
|
|
||||||
Signals are one way to respond to user input (another is `actions <https://docs.gtk.org/gtk4/actions.html>`_, which use the `action-name property <https://docs.gtk.org/gtk4/property.Actionable.action-name.html>`_).
|
Signals are one way to respond to user input (another is `actions <https://docs.gtk.org/gtk4/actions.html>`_, which use the `action-name property <https://docs.gtk.org/gtk4/property.Actionable.action-name.html>`_).
|
||||||
|
|
||||||
|
@ -99,6 +99,8 @@ Signals provide a handle for your code to listen to events in the UI. The handle
|
||||||
|
|
||||||
Optionally, you can provide an object ID to use when connecting the signal.
|
Optionally, you can provide an object ID to use when connecting the signal.
|
||||||
|
|
||||||
|
The ``swapped`` flag is used to swap the order of the object and userdata arguments in C applications. If an object argument is specified, then this is the default behavior, so the ``not-swapped`` flag can be used to prevent the swap.
|
||||||
|
|
||||||
Example
|
Example
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
|
@ -108,7 +110,6 @@ Example
|
||||||
clicked => $on_button_clicked();
|
clicked => $on_button_clicked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.. _Syntax Child:
|
.. _Syntax Child:
|
||||||
|
|
||||||
Children
|
Children
|
||||||
|
|
5
tests/sample_errors/signal_exclusive_flags.blp
Normal file
5
tests/sample_errors/signal_exclusive_flags.blp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
using Gtk 4.0;
|
||||||
|
|
||||||
|
$MyObject obj {
|
||||||
|
signal1 => $handler() swapped not-swapped;
|
||||||
|
}
|
1
tests/sample_errors/signal_exclusive_flags.err
Normal file
1
tests/sample_errors/signal_exclusive_flags.err
Normal file
|
@ -0,0 +1 @@
|
||||||
|
4,33,11,'swapped' and 'not-swapped' flags cannot be used together
|
6
tests/sample_errors/signal_unnecessary_flags.blp
Normal file
6
tests/sample_errors/signal_unnecessary_flags.blp
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
using Gtk 4.0;
|
||||||
|
|
||||||
|
$MyObject obj {
|
||||||
|
signal1 => $handler() not-swapped;
|
||||||
|
signal2 => $handler(obj) swapped;
|
||||||
|
}
|
2
tests/sample_errors/signal_unnecessary_flags.err
Normal file
2
tests/sample_errors/signal_unnecessary_flags.err
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
4,25,11,'not-swapped' is the default for handlers that do not specify an object
|
||||||
|
5,28,7,'swapped' is the default for handlers that specify an object
|
5
tests/samples/signal_not_swapped.blp
Normal file
5
tests/samples/signal_not_swapped.blp
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
using Gtk 4.0;
|
||||||
|
|
||||||
|
Button obj {
|
||||||
|
clicked => $handler(obj) not-swapped;
|
||||||
|
}
|
12
tests/samples/signal_not_swapped.ui
Normal file
12
tests/samples/signal_not_swapped.ui
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
DO NOT EDIT!
|
||||||
|
This file was @generated by blueprint-compiler. Instead, edit the
|
||||||
|
corresponding .blp file and regenerate this file with blueprint-compiler.
|
||||||
|
-->
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk" version="4.0"/>
|
||||||
|
<object class="GtkButton" id="obj">
|
||||||
|
<signal name="clicked" handler="handler" swapped="False" object="obj"/>
|
||||||
|
</object>
|
||||||
|
</interface>
|
|
@ -200,6 +200,7 @@ class TestSamples(unittest.TestCase):
|
||||||
"expr_closure_args",
|
"expr_closure_args",
|
||||||
"parseable",
|
"parseable",
|
||||||
"signal",
|
"signal",
|
||||||
|
"signal_not_swapped",
|
||||||
"template",
|
"template",
|
||||||
"template_binding",
|
"template_binding",
|
||||||
"template_binding_extern",
|
"template_binding_extern",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue