From a56a0f0da2a3780f39371dbf59d474cbfa59bbba Mon Sep 17 00:00:00 2001
From: Dmitry Sapozhnikov <11535558+o-sdn-o@users.noreply.github.com>
Date: Sat, 21 Dec 2024 12:30:51 +0500
Subject: [PATCH] #86 WIP: Revise pro::focus::cut

---
 src/netxs/desktopio/controls.hpp | 41 ++++++++++----------------------
 src/netxs/desktopio/input.hpp    |  3 +--
 src/vtm.hpp                      | 19 ++++++++-------
 3 files changed, 24 insertions(+), 39 deletions(-)

diff --git a/src/netxs/desktopio/controls.hpp b/src/netxs/desktopio/controls.hpp
index 706ce3a454..15a01ced8d 100644
--- a/src/netxs/desktopio/controls.hpp
+++ b/src/netxs/desktopio/controls.hpp
@@ -1373,17 +1373,13 @@ namespace netxs::ui
                 pro::focus::off(item_ptr, gear_id_list);
             }
             // pro::focus: Defocus all gears and clear chains (optionally remove_default route from parent) and return deleted active gear id's.
-            static auto cut(sptr item_ptr, bool remove_default = faux)
+            static auto cut(sptr item_ptr)
             {
                 auto lock = item_ptr->bell::sync();
-                auto gear_id_list = hids::events::focus::cut.param();
+                auto gear_id_list = item_ptr->base::riseup(tier::request, e2::form::state::keybd::enlist);
                 if (auto parent = item_ptr->parent())
                 {
-                    parent->base::riseup(tier::request, hids::events::focus::cut, gear_id_list);
-                    if (remove_default)
-                    {
-                        parent->base::riseup(tier::request, hids::events::focus::dry, { .item = item_ptr });
-                    }
+                    parent->base::riseup(tier::request, hids::events::focus::cut, { .item = item_ptr });
                 }
                 return gear_id_list;
             }
@@ -1710,35 +1706,22 @@ namespace netxs::ui
                     }
                 };
                 // pro::focus: Drop all downlinks (toward inside) from the boss and unfocus boss. Return dropped active gears.
-                boss.LISTEN(tier::request, hids::events::focus::cut, gear_id_list, memo)
+                boss.LISTEN(tier::request, hids::events::focus::cut, seed, memo)
                 {
-                    //todo cut a single item
+                    seed.treeid = treeid;
+                    seed.digest = ++digest;
                     for (auto& [gear_id, chain] : gears)
                     {
-                        auto live = faux;
-                        chain.foreach([&, gear_id = gear_id](auto& nexthop, auto& status) // Drop all downlinks (toward inside) from the boss. //todo Apple clang can't capture gear_id in lambda
+                        chain.next.remove_if([&](auto& next) // Drop all downlinks (toward inside) from the boss.
                         {
-                            if (gear_id && status == state::live)
+                            auto match = next.next_wptr.lock() == seed.item;
+                            if (match && gear_id && next.status == state::live)
                             {
-                                live = true;
-                                nexthop->bell::signal(tier::release, hids::events::focus::set::off, { .gear_id = gear_id });
+                                seed.gear_id = gear_id;
+                                seed.item->bell::signal(tier::release, hids::events::focus::set::off, seed);
                             }
-                            nexthop = {};
+                            return match;
                         });
-                        if (gear_id)
-                        {
-                            //todo revise
-                            //boss.bell::signal(tier::preview, hids::events::focus::set::off, { .gear_id = gear_id }); // The cutting object is changing its host along with focus.
-                            if (live) gear_id_list.push_back(gear_id); // Backup dropped active gears.
-                        }
-                    }
-                };
-                // pro::focus: .
-                boss.LISTEN(tier::request, hids::events::focus::dry, seed, memo)
-                {
-                    for (auto& [gear_id, chain] : gears)
-                    {
-                        chain.next.remove_if([&](auto& next){ return next.next_wptr.lock() == seed.item; });
                     }
                 };
                 // pro::focus: Switch all foci from the prev_ptr to the next_ptr (which must have a pro::focus on board).
diff --git a/src/netxs/desktopio/input.hpp b/src/netxs/desktopio/input.hpp
index e8219e1f32..c10bd3efa0 100644
--- a/src/netxs/desktopio/input.hpp
+++ b/src/netxs/desktopio/input.hpp
@@ -156,9 +156,8 @@ namespace netxs::events::userland
             };
             SUBSET_XS( focus )
             {
-                EVENT_XS( dry, input::foci ), // request: Remove the reference to the specified applet.
                 EVENT_XS( hop, input::foci ), // request: Switch focus branch to seed.item.
-                EVENT_XS( cut, ui::gear_id_list_t ), // request: Unfocus and delete downstream (to inside) focus route.
+                EVENT_XS( cut, input::foci ), // request: Unfocus and delete downstream (to inside) focus route.
                 EVENT_XS( add, input::foci ), // request: Initiate focus setting toward outside (used by gui and dtvt).
                 EVENT_XS( rem, input::foci ), // request: Initiate focus unsetting toward outside (used by gui and dtvt).
                 EVENT_XS( dup, input::foci ), // request: Make a focus tree copy from default.
diff --git a/src/vtm.hpp b/src/vtm.hpp
index 71721ac7c0..1707229bc4 100644
--- a/src/vtm.hpp
+++ b/src/vtm.hpp
@@ -122,7 +122,7 @@ namespace netxs::app::vtm
             void follow(vtm::link& new_what, dent pads = {})
             {
                 what = new_what;
-                auto gear_id_list = pro::focus::cut(what.applet, true);
+                auto gear_id_list = pro::focus::cut(what.applet);
                 auto window_ptr = new_what.applet;
                 saved = nexthop;
                 nexthop = new_what.applet;
@@ -781,18 +781,20 @@ namespace netxs::app::vtm
                 }
             };
             //todo mimic pro::focus
-            LISTEN(tier::request, hids::events::focus::cut, gear_id_list, tokens, (treeid = datetime::uniqueid(), digest = ui64{}))
+            LISTEN(tier::request, hids::events::focus::cut, seed, tokens, (treeid = datetime::uniqueid(), digest = ui64{}))
             {
                 if (align.what.applet)
                 {
+                    seed.treeid = treeid;
+                    seed.digest = ++digest;
                     for (auto& [ext_gear_id, gear_ptr] : input.gears)
                     {
                         if (ext_gear_id && !gear_ptr->keybd_disabled) // Ignore default and halted gears.
                         {
                             if (auto gear_id = gear_ptr->id)
                             {
-                                gear_id_list.push_back(gear_id);
-                                align.what.applet->bell::signal(tier::release, hids::events::focus::set::off, { .gear_id = gear_id, .treeid = treeid, .digest = ++digest });
+                                seed.gear_id = gear_id;
+                                align.what.applet->bell::signal(tier::release, hids::events::focus::set::off, seed);
                             }
                         }
                     }
@@ -1993,11 +1995,12 @@ namespace netxs::app::vtm
             };
             LISTEN(tier::release, vtm::events::gate::restore, what)
             {
-                auto gear_id_list = pro::focus::cut(what.applet);
-                what.applet->base::detach();
+                auto window_ptr = what.applet;
+                auto gear_id_list = pro::focus::cut(window_ptr);
+                window_ptr->base::detach();
                 auto& cfg = dbase.menu[what.menuid];
-                branch(what.menuid, what.applet, !cfg.hidden);
-                pro::focus::set(what.applet, gear_id_list, solo::on, true);
+                branch(what.menuid, window_ptr, !cfg.hidden);
+                pro::focus::set(window_ptr, gear_id_list, solo::on, true);
             };
             LISTEN(tier::request, vtm::events::apptype, what)
             {