From 536f0a738ba3e997bcd8ded1e13d6bb43535c662 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Tue, 13 Dec 2022 21:32:06 -0800 Subject: [PATCH] Fix "replce" when moving children in the collection --- sdk/python/flet/control.py | 43 ++++++++++-------------- sdk/python/tests/test_moving_children.py | 41 ++++++++++++++++++++++ 2 files changed, 59 insertions(+), 25 deletions(-) create mode 100644 sdk/python/tests/test_moving_children.py diff --git a/sdk/python/flet/control.py b/sdk/python/flet/control.py index 256020184d..a49a9c6cec 100644 --- a/sdk/python/flet/control.py +++ b/sdk/python/flet/control.py @@ -297,7 +297,7 @@ def build_update_commands(self, index, added_controls, commands, isolated=False) n = 0 for tag, a1, a2, b1, b2 in sm.get_opcodes(): - if tag == "delete": + if tag == "delete" or tag == "replace": # deleted controls ids = [] for h in previous_ints[a1:a2]: @@ -321,6 +321,23 @@ def build_update_commands(self, index, added_controls, commands, isolated=False) ids.append(ctrl.__uid) if len(ids) > 0: commands.append(Command(0, "remove", ids)) + if tag == "replace": + # add + for h in current_ints[b1:b2]: + ctrl = hashes[h] + innerCmds = ctrl._build_add_commands( + index=index, added_controls=added_controls + ) + assert self.__uid is not None + commands.append( + Command( + indent=0, + name="add", + attrs={"to": self.__uid, "at": str(n)}, + commands=innerCmds, + ) + ) + n += 1 elif tag == "equal": # unchanged control for h in previous_ints[a1:a2]: @@ -329,30 +346,6 @@ def build_update_commands(self, index, added_controls, commands, isolated=False) index, added_controls, commands, isolated=ctrl._is_isolated() ) n += 1 - elif tag == "replace": - ids = [] - for h in previous_ints[a1:a2]: - # delete - ctrl = hashes[h] - self._remove_control_recursively(index, ctrl) - ids.append(ctrl.__uid) - commands.append(Command(0, "remove", ids)) - for h in current_ints[b1:b2]: - # add - ctrl = hashes[h] - innerCmds = ctrl._build_add_commands( - index=index, added_controls=added_controls - ) - assert self.__uid is not None - commands.append( - Command( - indent=0, - name="add", - attrs={"to": self.__uid, "at": str(n)}, - commands=innerCmds, - ) - ) - n += 1 elif tag == "insert": # add for h in current_ints[b1:b2]: diff --git a/sdk/python/tests/test_moving_children.py b/sdk/python/tests/test_moving_children.py new file mode 100644 index 0000000000..a4be138c6f --- /dev/null +++ b/sdk/python/tests/test_moving_children.py @@ -0,0 +1,41 @@ +import random + +import flet as ft + + +def test_moving_children(): + c = ft.Stack() + c._Control__uid = "0" + for i in range(0, 10): + c.controls.append(ft.Container()) + c.controls[i]._Control__uid = f"_{i}" + + index = [] + added_controls = [] + commands = [] + c.build_update_commands(index, added_controls, commands, False) + + def replace_controls(c): + random.shuffle(c.controls) + commands.clear() + + # print("=======") + r = set() + for ctrl in c.controls: + # print(ctrl._Control__uid) + r.add(ctrl._Control__uid) + c.build_update_commands(index, added_controls, commands, False) + for cmd in commands: + if cmd.name == "add": + for sub_cmd in cmd.commands: + # print("add", sub_cmd.attrs["id"], "at", cmd.attrs["at"]) + r.add(sub_cmd.attrs["id"]) + elif cmd.name == "remove": + for v in cmd.values: + # print("remove", v) + r.remove(v) + # print(r) + assert len(r) == len(c.controls) + + for i in range(0, 20): + replace_controls(c)