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):
|
||||
grammar = AnyOf(
|
||||
UseExact("flag", "swapped"),
|
||||
UseExact("flag", "not-swapped"),
|
||||
UseExact("flag", "after"),
|
||||
)
|
||||
|
||||
|
@ -40,6 +41,27 @@ class SignalFlag(AstNode):
|
|||
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()
|
||||
def ref_docs(self):
|
||||
return get_docs_section("Syntax Signal")
|
||||
|
@ -92,9 +114,17 @@ class Signal(AstNode):
|
|||
def flags(self) -> T.List[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
|
||||
def is_swapped(self) -> bool:
|
||||
return any(x.flag == "swapped" for x in self.flags)
|
||||
def is_swapped(self) -> T.Optional[bool]:
|
||||
for flag in self.flags:
|
||||
if flag.flag == "swapped":
|
||||
return True
|
||||
elif flag.flag == "not-swapped":
|
||||
return False
|
||||
return None
|
||||
|
||||
@property
|
||||
def is_after(self) -> bool:
|
||||
|
@ -194,15 +224,16 @@ class Signal(AstNode):
|
|||
|
||||
|
||||
@decompiler("signal")
|
||||
def decompile_signal(
|
||||
ctx, gir, name, handler, swapped="false", after="false", object=None
|
||||
):
|
||||
def decompile_signal(ctx, gir, name, handler, swapped=None, after="false", object=None):
|
||||
object_name = object or ""
|
||||
name = name.replace("_", "-")
|
||||
line = f"{name} => ${handler}({object_name})"
|
||||
|
||||
if decompile.truthy(swapped):
|
||||
line += " swapped"
|
||||
elif swapped is not None:
|
||||
line += " not-swapped"
|
||||
|
||||
if decompile.truthy(after):
|
||||
line += " after"
|
||||
|
||||
|
|
|
@ -169,7 +169,7 @@ class XmlOutput(OutputFormat):
|
|||
"signal",
|
||||
name=name,
|
||||
handler=signal.handler,
|
||||
swapped=signal.is_swapped or None,
|
||||
swapped=signal.is_swapped,
|
||||
after=signal.is_after or None,
|
||||
object=(
|
||||
self._object_id(signal, signal.object_id) if signal.object_id else None
|
||||
|
|
|
@ -91,7 +91,7 @@ Signal Handlers
|
|||
.. 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)* ';'
|
||||
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>`_).
|
||||
|
||||
|
@ -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.
|
||||
|
||||
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
|
||||
~~~~~~~
|
||||
|
||||
|
@ -108,7 +110,6 @@ Example
|
|||
clicked => $on_button_clicked();
|
||||
}
|
||||
|
||||
|
||||
.. _Syntax Child:
|
||||
|
||||
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",
|
||||
"parseable",
|
||||
"signal",
|
||||
"signal_not_swapped",
|
||||
"template",
|
||||
"template_binding",
|
||||
"template_binding_extern",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue