From 2861e7bca47f9868530a5289ba2265accb157389 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Sat, 4 Dec 2021 16:12:35 +0500 Subject: [PATCH 01/12] UI: Broadcast architecture revision --- src/netxs/apps.hpp | 74 +++++++++++++-------- src/netxs/apps/desk.hpp | 19 ++++-- src/netxs/apps/logs.hpp | 60 +++++++++-------- src/netxs/apps/term.hpp | 67 +++++++++++-------- src/netxs/apps/tile.hpp | 121 ++++++++++++++++++---------------- src/netxs/console/console.hpp | 68 ++++++++++++------- src/netxs/ui/events.hpp | 13 ++++ 7 files changed, 257 insertions(+), 165 deletions(-) diff --git a/src/netxs/apps.hpp b/src/netxs/apps.hpp index 3c65e97512..c4a0f1d11d 100644 --- a/src/netxs/apps.hpp +++ b/src/netxs/apps.hpp @@ -29,7 +29,7 @@ namespace netxs::app::shared X(Logs , "Logs" , ("Logs \nDebug output console") , "" ) \ X(View , "View" , (ansi::jet(bias::center).add("View \n Region 1")) , "" ) \ X(Tile , "Tile" , ("Tiling Window Manager") , "VTM_PROFILE_1=\"Tile\", \"Tiling Window Manager\", h()" ) \ - X(RefreshRate , "Settings" , ("Settings: Frame Rate Limit") , "" ) \ + X(Settings , "Settings" , ("Settings: Frame Rate Limit") , "" ) \ X(PowerShell , "pwsh PowerShell" , ("Term \nPowerShell") , "" ) \ X(CommandPrompt, "cmd Command Prompt" , ("Term \nCommand Prompt") , "" ) \ X(Bash , "Bash/Zsh/CMD" , ("Term \nBash/Zsh/CMD") , "" ) \ @@ -143,13 +143,16 @@ namespace netxs::app::shared boss.reflow(); gear.dismiss(); }; - boss.base::broadcast->SUBMIT(tier::release, e2::form::prop::menusize, size) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - auto& limit = boss.plugins(); - auto limits = limit.get(); - limits.min.y = limits.max.y = std::max(0, size); - limit.set(limits); - boss.reflow(); + bcast->SUBMIT_T(tier::release, e2::form::prop::menusize, boss.bcastsubs, size) + { + auto& limit = boss.plugins(); + auto limits = limit.get(); + limits.min.y = limits.max.y = std::max(0, size); + limit.set(limits); + boss.reflow(); + }; }; }); auto menu_area = menu_block->attach(snap::stretch, snap::center, ui::fork::ctor()) @@ -265,7 +268,7 @@ namespace netxs::app::shared }; return window; }; - auto build_RefreshRate = [](view v) + auto build_Settings = [](view v) { auto window = ui::cake::ctor(); window->plugin() @@ -495,9 +498,12 @@ namespace netxs::app::shared (*c)--; log("main: vtm recursive conn destoyed"); }; - boss.base::broadcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bell::tracker, root) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - boss.start(); + bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) + { + boss.start(); + }; }; }); } @@ -530,10 +536,13 @@ namespace netxs::app::shared ->colors(whitelt, blackdk) ->invoke([&](auto& boss) { - boss.base::broadcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bell::tracker, root) - { - boss.start(); - }; + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + { + bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) + { + boss.start(); + }; + }; }); layers->attach(app::shared::scroll_bars_term(scroll)); return window; @@ -571,9 +580,12 @@ namespace netxs::app::shared inst->colors(whitelt, blackdk) ->invoke([&](auto& boss) { - boss.base::broadcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bell::tracker, root) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - boss.start(); + bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) + { + boss.start(); + }; }; }); layers->attach(app::shared::scroll_bars(scroll)); @@ -618,10 +630,13 @@ namespace netxs::app::shared ->colors(whitelt, 0xFF562401) ->invoke([&](auto& boss) { - boss.base::broadcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bell::tracker, root) - { - boss.start(); - }; + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + { + bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) + { + boss.start(); + }; + }; }); auto scroll_bars = layers->attach(ui::fork::ctor()); @@ -677,9 +692,12 @@ namespace netxs::app::shared inst->colors(whitelt, blackdk) ->invoke([&](auto& boss) { - boss.base::broadcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bell::tracker, root) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - boss.start(); + bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) + { + boss.start(); + }; }; }); @@ -690,7 +708,7 @@ namespace netxs::app::shared }; app::shared::initialize builder_Strobe { "Strobe" , build_Strobe }; - app::shared::initialize builder_RefreshRate { "RefreshRate" , build_RefreshRate }; + app::shared::initialize builder_Settings { "Settings" , build_Settings }; app::shared::initialize builder_Empty { "Empty" , build_Empty }; app::shared::initialize builder_View { "View" , build_View }; app::shared::initialize builder_Truecolor { "Truecolor" , build_Truecolor }; @@ -711,9 +729,9 @@ namespace netxs::app::shared #ifdef DEMO auto shell = os::get_shell(); #ifdef PROD - app::shared::objs_config[objs_lookup["Tile"]].data = "VTM_PROFILE_1=\"Tile\", \"Tiling Window Manager\", h(v(\"" + shell + " -c 'LC_ALL=en_US.UTF-8 mc -c -x -d; cat'\", h(\"" + shell + " -c 'ls /bin | nl | ccze -A; " + shell + "'\", a(\"RefreshRate\",\"\",\"\"))), a(\"Calc\",\"\",\"\"))"; + app::shared::objs_config[objs_lookup["Tile"]].data = "VTM_PROFILE_1=\"Tile\", \"Tiling Window Manager\", h(v(\"" + shell + " -c 'LC_ALL=en_US.UTF-8 mc -c -x -d; cat'\", h(\"" + shell + " -c 'ls /bin | nl | ccze -A; " + shell + "'\", a(\"Settings\",\"\",\"\"))), a(\"Calc\",\"\",\"\"))"; #else - app::shared::objs_config[objs_lookup["Tile"]].data = "VTM_PROFILE_1=\"Tile\", \"Tiling Window Manager\", h1:1(v1:1(\"" + shell + " -c 'LC_ALL=en_US.UTF-8 mc -c -x -d; cat'\", h1:1(\"" + shell + " -c 'ls /bin | nl | ccze -A; " + shell + "'\", a(\"RefreshRate\",\"\",\"\"))), a(\"Calc\",\"\",\"\"))"; + app::shared::objs_config[objs_lookup["Tile"]].data = "VTM_PROFILE_1=\"Tile\", \"Tiling Window Manager\", h1:1(v1:1(\"" + shell + " -c 'LC_ALL=en_US.UTF-8 mc -c -x -d; cat'\", h1:1(\"" + shell + " -c 'ls /bin | nl | ccze -A; " + shell + "'\", a(\"Settings\",\"\",\"\"))), a(\"Calc\",\"\",\"\"))"; #endif for (auto& [menu_item_id, app_data] : app::shared::objs_config) @@ -726,13 +744,13 @@ namespace netxs::app::shared menu_list[objs_lookup["Tile"]]; menu_list[objs_lookup["Logs"]]; menu_list[objs_lookup["View"]]; - menu_list[objs_lookup["RefreshRate"]]; + menu_list[objs_lookup["Settings"]]; #else menu_list[objs_lookup["Term"]]; menu_list[objs_lookup["Tile"]]; menu_list[objs_lookup["Logs"]]; menu_list[objs_lookup["View"]]; - menu_list[objs_lookup["RefreshRate"]]; + menu_list[objs_lookup["Settings"]]; #endif // Add custom commands to the menu. @@ -786,7 +804,7 @@ namespace netxs::app::shared sub_pos = twod{-120, 60}; creator(objs_lookup["Truecolor" ], { twod{ 20, 15 } + sub_pos, { 70, 30 } }); creator(objs_lookup["Logs" ], { twod{ 52, 33 } + sub_pos, { 45, 12 } }); - creator(objs_lookup["RefreshRate"], { twod{ 60, 41 } + sub_pos, { 35, 10 } }); + creator(objs_lookup["Settings" ], { twod{ 60, 41 } + sub_pos, { 35, 10 } }); #endif }; } diff --git a/src/netxs/apps/desk.hpp b/src/netxs/apps/desk.hpp index 464727f5e7..5670634830 100644 --- a/src/netxs/apps/desk.hpp +++ b/src/netxs/apps/desk.hpp @@ -340,9 +340,12 @@ namespace netxs::app::desk auto taskbar_viewport = window->attach(ui::fork::ctor(axis::X)) ->invoke([](auto& boss) { - boss.broadcast->SUBMIT(tier::request, e2::form::prop::viewport, viewport) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - viewport = boss.base::area(); + bcast->SUBMIT_T(tier::request, e2::form::prop::viewport, boss.bcastsubs, viewport) + { + viewport = boss.base::area(); + }; }; }); auto taskbar = taskbar_viewport->attach(slot::_1, ui::fork::ctor(axis::Y)) @@ -394,11 +397,15 @@ namespace netxs::app::desk else timer.actify(faux, MENU_TIMEOUT, apply); } }; - boss.broadcast->SUBMIT_T_BYVAL(tier::request, e2::form::prop::viewport, boss.tracker, viewport) + auto& size_inst = *size_config; // Its lifetime eq boss livetime (sptr is captured by boss.SUBMIT_BYVAL). + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - auto& [uibar_full_size, uibar_min_size] = *size_config; - viewport.coor.x += uibar_min_size; - viewport.size.x -= uibar_min_size; + bcast->SUBMIT_T(tier::request, e2::form::prop::viewport, boss.bcastsubs, viewport) + { + auto& [uibar_full_size, uibar_min_size] = size_inst; + viewport.coor.x += uibar_min_size; + viewport.size.x -= uibar_min_size; + }; }; }); auto apps_users = taskbar->attach(slot::_1, ui::fork::ctor(axis::Y, 0, 100)); diff --git a/src/netxs/apps/logs.hpp b/src/netxs/apps/logs.hpp index 80dc5cde7d..01a8a87876 100644 --- a/src/netxs/apps/logs.hpp +++ b/src/netxs/apps/logs.hpp @@ -188,33 +188,36 @@ namespace netxs::app::logs clear(); gear.dismiss(); }; - broadcast->SUBMIT(tier::request, e2::command::custom, status) + SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, broadcast) { - switch (status) + bcast->SUBMIT_T(tier::request, e2::command::custom, bcastsubs, status) { - case 1: - status = worker->show_codepoints ? 1 : 2; - break; - default: - break; - } - }; - broadcast->SUBMIT(tier::preview, e2::command::custom, cmd_id) - { - switch (cmd_id) + switch (status) + { + case 1: + status = worker->show_codepoints ? 1 : 2; + break; + default: + break; + } + }; + bcast->SUBMIT_T(tier::preview, e2::command::custom, bcastsubs, cmd_id) { - case 0: - clear(); - break; - case 1: - case 2: - itsme = true; - worker->enable_codepoints(cmd_id == 1 ? true : faux); - itsme = faux; - break; - default: - break; - } + switch (cmd_id) + { + case 0: + clear(); + break; + case 1: + case 2: + itsme = true; + worker->enable_codepoints(cmd_id == 1 ? true : faux); + itsme = faux; + break; + default: + break; + } + }; }; broadcast->SIGNAL(tier::release, e2::command::custom, worker->show_codepoints ? 1 : 2); SUBMIT(tier::preview, e2::size::set, newsize) @@ -267,10 +270,13 @@ namespace netxs::app::logs boss.base::broadcast->SIGNAL(tier::preview, e2::command::custom, status == 2 ? 1/*show*/ : 2/*hide*/); gear.dismiss(true); }; - boss.base::broadcast->SUBMIT(tier::release, e2::command::custom, status) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - //todo unify, get boss base colors, don't use x3 - boss.color(status == 1 ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + bcast->SUBMIT_T(tier::release, e2::command::custom, boss.bcastsubs, status) + { + //todo unify, get boss base colors, don't use x3 + boss.color(status == 1 ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + }; }; }}, std::pair>{ "Clear", diff --git a/src/netxs/apps/term.hpp b/src/netxs/apps/term.hpp index 26206e7e19..4b62b7b659 100644 --- a/src/netxs/apps/term.hpp +++ b/src/netxs/apps/term.hpp @@ -102,10 +102,13 @@ namespace netxs::app::term boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::left); gear.dismiss(true); }; - boss.base::broadcast->SUBMIT(tier::release, app::term::events::layout::align, align) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - //todo unify, get boss base colors, don't use x3 - boss.color(align == bias::left ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + bcast->SUBMIT_T(tier::release, app::term::events::layout::align, boss.bcastsubs, align) + { + //todo unify, get boss base colors, don't use x3 + boss.color(align == bias::left ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + }; }; }}, std::pair>{ "─=─", @@ -116,10 +119,13 @@ namespace netxs::app::term boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::center); gear.dismiss(true); }; - boss.base::broadcast->SUBMIT(tier::release, app::term::events::layout::align, align) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - //todo unify, get boss base colors, don't use x3 - boss.color(align == bias::center ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + bcast->SUBMIT_T(tier::release, app::term::events::layout::align, boss.bcastsubs, align) + { + //todo unify, get boss base colors, don't use x3 + boss.color(align == bias::center ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + }; }; }}, std::pair>{ "─=", @@ -130,10 +136,13 @@ namespace netxs::app::term boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::right); gear.dismiss(true); }; - boss.base::broadcast->SUBMIT(tier::release, app::term::events::layout::align, align) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - //todo unify, get boss base colors, don't use x3 - boss.color(align == bias::right ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + bcast->SUBMIT_T(tier::release, app::term::events::layout::align, boss.bcastsubs, align) + { + //todo unify, get boss base colors, don't use x3 + boss.color(align == bias::right ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + }; }; }}, std::pair>{ "Wrap", @@ -144,10 +153,13 @@ namespace netxs::app::term boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::togglewrp); gear.dismiss(true); }; - boss.base::broadcast->SUBMIT(tier::release, app::term::events::layout::wrapln, wrapln) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - //todo unify, get boss base colors, don't use x3 - boss.color(wrapln == wrap::on ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + bcast->SUBMIT_T(tier::release, app::term::events::layout::wrapln, boss.bcastsubs, wrapln) + { + //todo unify, get boss base colors, don't use x3 + boss.color(wrapln == wrap::on ? 0xFF00ff00 : x3.fgc(), x3.bgc()); + }; }; }}, }; @@ -195,21 +207,24 @@ namespace netxs::app::term { boss.base::broadcast->SIGNAL(tier::release, app::term::events::layout::align, status); }; - boss.base::broadcast->SUBMIT_T(tier::preview, app::term::events::cmd, boss.bell::tracker, cmd) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - boss.exec_cmd(static_cast(cmd)); - }; - boss.base::broadcast->SUBMIT_T(tier::preview, app::term::events::data::in, boss.bell::tracker, data) - { - boss.data_in(data); - }; - boss.base::broadcast->SUBMIT_T(tier::preview, app::term::events::data::out, boss.bell::tracker, data) - { - boss.data_out(data); - }; - boss.base::broadcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bell::tracker, root) - { - boss.start(); + bcast->SUBMIT_T(tier::preview, app::term::events::cmd, boss.bcastsubs, cmd) + { + boss.exec_cmd(static_cast(cmd)); + }; + bcast->SUBMIT_T(tier::preview, app::term::events::data::in, boss.bcastsubs, data) + { + boss.data_in(data); + }; + bcast->SUBMIT_T(tier::preview, app::term::events::data::out, boss.bcastsubs, data) + { + boss.data_out(data); + }; + bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) + { + boss.start(); + }; }; }); } diff --git a/src/netxs/apps/tile.hpp b/src/netxs/apps/tile.hpp index 8045863e55..13f00783c2 100644 --- a/src/netxs/apps/tile.hpp +++ b/src/netxs/apps/tile.hpp @@ -295,16 +295,37 @@ namespace netxs::app::tile parent_memo.reset(); }; }; - boss.broadcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.tracker, root) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - if (auto item_ptr = boss.back()) + bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) { - auto& item = *item_ptr; + if (auto item_ptr = boss.back()) + { + auto& item = *item_ptr; + if (item.base::root()) + { + item.broadcast->SIGNAL(tier::release, e2::form::upon::started, item_ptr); + } + } + }; + bcast->SUBMIT_T(tier::release, app::tile::events::ui::select, boss.bcastsubs, gear) + { + auto& item =*boss.back(); if (item.base::root()) { - item.broadcast->SIGNAL(tier::release, e2::form::upon::started, item_ptr); + if (item.base::kind() != 1) + { + //todo unify + gear.force_group_focus = true; + gear.kb_focus_taken = faux; + gear.combine_focus = true; + item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); + gear.combine_focus = faux; + gear.force_group_focus = faux; + } + else item.SIGNAL(tier::release, hids::events::upevent::kbannul, gear); // Exclude grips. } - } + }; }; boss.SUBMIT_BYVAL(tier::release, e2::form::maximize, gear) { @@ -509,24 +530,6 @@ namespace netxs::app::tile } } }; - boss.broadcast->SUBMIT_T(tier::release, app::tile::events::ui::select, boss.tracker, gear) - { - auto& item =*boss.back(); - if (item.base::root()) - { - if (item.base::kind() != 1) - { - //todo unify - gear.force_group_focus = true; - gear.kb_focus_taken = faux; - gear.combine_focus = true; - item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); - gear.combine_focus = faux; - gear.force_group_focus = faux; - } - else item.SIGNAL(tier::release, hids::events::upevent::kbannul, gear); // Exclude grips. - } - }; }) ->branch ( @@ -658,25 +661,28 @@ namespace netxs::app::tile object->invoke([&](auto& boss) { - auto oneoff = std::make_shared(); - auto objs_config_ptr = &app::shared::objs_config; - boss.broadcast->SUBMIT_T_BYVAL(tier::release, e2::form::upon::created, *oneoff, gear) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - if (auto gate_ptr = bell::getref(gear.id)) + auto oneoff = std::make_shared(); + auto objs_config_ptr = &app::shared::objs_config; + bcast->SUBMIT_T_BYVAL(tier::release, e2::form::upon::created, *oneoff, gear) { - auto& gate = *gate_ptr; - auto& objs_config = *objs_config_ptr; - auto menu_item_id = decltype(e2::data::changed)::type{}; - gate.SIGNAL(tier::request, e2::data::changed, menu_item_id); - //todo unify - auto config = objs_config[menu_item_id]; - if (config.type == "Tile") // Reset the currently selected application to the previous one. + if (auto gate_ptr = bell::getref(gear.id)) { - gate.SIGNAL(tier::preview, e2::data::changed, menu_item_id); // Get previous default; - gate.SIGNAL(tier::release, e2::data::changed, menu_item_id); // Set current default; + auto& gate = *gate_ptr; + auto& objs_config = *objs_config_ptr; + auto menu_item_id = decltype(e2::data::changed)::type{}; + gate.SIGNAL(tier::request, e2::data::changed, menu_item_id); + //todo unify + auto config = objs_config[menu_item_id]; + if (config.type == "Tile") // Reset the currently selected application to the previous one. + { + gate.SIGNAL(tier::preview, e2::data::changed, menu_item_id); // Get previous default; + gate.SIGNAL(tier::release, e2::data::changed, menu_item_id); // Set current default; + } } - } - oneoff.reset(); + oneoff.reset(); + }; }; boss.SUBMIT_BYVAL(tier::release, e2::form::upon::vtree::attached, parent) { @@ -800,30 +806,33 @@ namespace netxs::app::tile auto item = boss.pop_back(); if (item) fullscreen_item = item; }; - boss.broadcast->SUBMIT_T(tier::preview, app::tile::events::ui::any, boss.tracker, gear) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - if (auto deed = boss.broadcast->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 + bcast->SUBMIT_T(tier::preview, app::tile::events::ui::any, boss.bcastsubs, gear) { - if (boss.count() > 2 && deed != app::tile::events::ui::toggle.id) // Restore the window before any action if maximized. + if (auto deed = boss.broadcast->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 { - auto gear_state = gear.state(); - auto& item =*boss.back(); - if (item.base::root()) // Pass focus to the maximized window. + if (boss.count() > 2 && deed != app::tile::events::ui::toggle.id) // Restore the window before any action if maximized. { - //todo unify - gear.force_group_focus = true; - gear.kb_focus_taken = faux; - gear.combine_focus = true; - item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); - gear.combine_focus = faux; - gear.force_group_focus = faux; + auto gear_state = gear.state(); + auto& item =*boss.back(); + if (item.base::root()) // Pass focus to the maximized window. + { + //todo unify + gear.force_group_focus = true; + gear.kb_focus_taken = faux; + gear.combine_focus = true; + item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); + gear.combine_focus = faux; + gear.force_group_focus = faux; + } + gear.countdown = 1; + boss.base::broadcast->SIGNAL(tier::release, app::tile::events::ui::toggle, gear); + gear.state(gear_state); } - gear.countdown = 1; - boss.base::broadcast->SIGNAL(tier::release, app::tile::events::ui::toggle, gear); - gear.state(gear_state); + boss.broadcast->bell::template signal(deed, gear); } - boss.broadcast->bell::template signal(deed, gear); - } + }; }; }); return object; diff --git a/src/netxs/console/console.hpp b/src/netxs/console/console.hpp index 98b7cd6944..d0c11f7286 100644 --- a/src/netxs/console/console.hpp +++ b/src/netxs/console/console.hpp @@ -109,10 +109,10 @@ namespace netxs::events::userland SUBSET_XS( config ) { EVENT_XS( whereami , sptr ), // request: pointer to world object. - EVENT_XS( broadcast, sptr ), // release: broadcast source changed. EVENT_XS( fps , iota ), // request to set new fps, arg: new fps (iota); the value == -1 is used to request current fps. GROUP_XS( caret , period ), // any kind of intervals property. GROUP_XS( plugins , iota ), + GROUP_XS( broadcast, sptr ), // release: broadcast source changed. SUBSET_XS( caret ) { @@ -130,6 +130,11 @@ namespace netxs::events::userland EVENT_XS( outer, dent ), // release: set outer size; request: request outer size. }; }; + SUBSET_XS( broadcast ) + { + EVENT_XS( attached, sptr ), // release: broadcast source changed when attached. + EVENT_XS( reinit , sptr ), // release: broadcast source changed when detached. + }; }; SUBSET_XS( conio ) { @@ -857,6 +862,7 @@ namespace netxs::console iota object_kind = {}; public: + subs bcastsubs; sptr broadcast = std::make_shared(); // base: Broadcast bus. // On attach the broadcast is merged with parent (bell::merge). // On detach the broadcast is duplicated from parent (bell::reset). @@ -870,7 +876,7 @@ namespace netxs::console if (parent_bus != broadcast) // Reattaching is allowed within the same visual tree. { parent_bus->merge(broadcast); - broadcast->SIGNAL(tier::release, e2::config::broadcast, parent_bus); + broadcast->SIGNAL(tier::release, e2::config::broadcast::attached, parent_bus); } } @@ -884,9 +890,13 @@ namespace netxs::console SUBMIT(tier::release, e2::size::set, new_size) { square.size = new_size; }; SUBMIT(tier::request, e2::size::set, size_var) { size_var = square.size; }; - broadcast->SUBMIT_T(tier::release, e2::config::broadcast, bell::tracker, new_broadcast) + //SUBMIT_T(tier::release, e2::config::broadcast::reinit, bell::tracker, old_broadcast) + SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, this->broadcast) { - broadcast = new_broadcast; + bcast->SUBMIT_T(tier::release, e2::config::broadcast::attached, bcastsubs, new_broadcast) + { + broadcast = new_broadcast; + }; }; /* * Only visual_root can be reattached multiple times! @@ -897,6 +907,10 @@ namespace netxs::console { auto bcast_backup = broadcast; base::switch_to_bus(parent_ptr->base::broadcast); + parent_ptr->SUBMIT_T(tier::release, e2::config::broadcast::reinit, bcastsubs, broadcast) + { + this->SIGNAL(tier::release, e2::config::broadcast::reinit, broadcast); + }; } parent_shadow = parent_ptr; // Propagate form events up to the visual branch. @@ -926,6 +940,12 @@ namespace netxs::console kb_token.reset(); //todo revise //parent_shadow.reset(); + if (!visual_root) + { + bcastsubs.clear(); + broadcast = std::make_shared(); + this->SIGNAL(tier::release, e2::config::broadcast::reinit, broadcast); + } } if (parent_ptr) parent_ptr->base::reflow(); //todo too expensive }; @@ -3488,31 +3508,35 @@ namespace netxs::console focus(base& boss) : skill{ boss } { - boss.broadcast->SUBMIT_T(tier::request, e2::form::state::keybd::find, memo, gear_test) + boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) { - if (find(gear_test.first)) + //todo how to reset boss.bcastsubs on ui::form::unplug? + bcast->SUBMIT_T(tier::request, e2::form::state::keybd::find, boss.bcastsubs, gear_test) { - gear_test.second++; - } - }; - boss.broadcast->SUBMIT_T(tier::request, e2::form::state::keybd::handover, memo, gear_id_list) - { - if (pool.size()) + if (find(gear_test.first)) + { + gear_test.second++; + } + }; + bcast->SUBMIT_T(tier::request, e2::form::state::keybd::handover, boss.bcastsubs, gear_id_list) { - auto This = boss.This(); - auto head = gear_id_list.end(); - gear_id_list.insert(head, pool.begin(), pool.end()); - auto tail = gear_id_list.end(); - while (head != tail) + if (pool.size()) { - auto gear_id = *head++; - if (auto gate_ptr = bell::getref(gear_id)) + auto This = boss.This(); + auto head = gear_id_list.end(); + gear_id_list.insert(head, pool.begin(), pool.end()); + auto tail = gear_id_list.end(); + while (head != tail) { - gate_ptr->SIGNAL(tier::preview, e2::form::proceed::unfocus, This); + auto gear_id = *head++; + if (auto gate_ptr = bell::getref(gear_id)) + { + gate_ptr->SIGNAL(tier::preview, e2::form::proceed::unfocus, This); + } } + boss.base::deface(); } - boss.base::deface(); - } + }; }; boss.SUBMIT_T(tier::release, e2::form::state::keybd::got, memo, gear) { diff --git a/src/netxs/ui/events.hpp b/src/netxs/ui/events.hpp index 82e0aa5769..dc6ec2bead 100644 --- a/src/netxs/ui/events.hpp +++ b/src/netxs/ui/events.hpp @@ -316,6 +316,8 @@ namespace netxs::events #define SIGNAL_GLOBAL( event, param) bell::template signal_global(decltype( event )::id, static_cast(param)) #define SUBMIT_GLOBAL( event, token, param) bell::template submit_global( token ) = [&] (typename decltype( event )::type && param) + #define SUBMIT_AND_RUN(level, event, param, arg) bell::template submit2( arg ) = [&] (typename decltype( event )::type && param) + #define EVENTPACK( name, base ) using _group_type = name; \ static constexpr auto _counter_base = __COUNTER__; \ public: static constexpr auto any = type_clue<_group_type, decltype(base)::type, decltype(base)::id> @@ -358,6 +360,15 @@ namespace netxs::events fwd_reactor request; fwd_reactor release; + template + struct submit_helper2 + { + using type = typename EVENT::type; + bell& owner; + type& p; + submit_helper2(bell& owner, type& p) : owner{ owner }, p{p} { } + template void operator=(F h) { owner.submit(h); h(static_cast(p)); } + }; template struct submit_helper { @@ -390,6 +401,8 @@ namespace netxs::events request.merge(s.request); release.merge(s.release); } + template auto submit2(typename EVENT::type & p) { return submit_helper2(*this, p); } + template auto submit() { return submit_helper (*this); } template auto submit(hook& token) { return submit_helper_token(*this, token); } template auto submit(subs& tokens) { return submit_helper_token(*this, tokens.extra()); } From 4bc76ac9575698c9244be9ed1451ba1deaaf0e01 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Sun, 5 Dec 2021 15:26:12 +0500 Subject: [PATCH 02/12] UI: Broadcast architecture revision --- src/netxs/apps/tile.hpp | 96 +++++++++++++++++++---------------- src/netxs/console/console.hpp | 23 +++++++++ src/netxs/ui/events.hpp | 77 ++++++++++++++++++++++------ 3 files changed, 135 insertions(+), 61 deletions(-) diff --git a/src/netxs/apps/tile.hpp b/src/netxs/apps/tile.hpp index 13f00783c2..678e450673 100644 --- a/src/netxs/apps/tile.hpp +++ b/src/netxs/apps/tile.hpp @@ -65,62 +65,68 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, e2::form::upon::vtree::attached, parent) { - auto parent_memo = std::make_shared(); - parent->broadcast->SUBMIT_T(tier::release, app::tile::events::ui::any, *parent_memo, gear) + auto parent_memo = std::make_shared(); + auto parent_bcast_memo = std::make_shared(); + parent->SUBMIT_AND_RUN_T(tier::release, e2::config::broadcast::reinit, *parent_memo, bcast, parent->broadcast) { - auto gear_test = decltype(e2::form::state::keybd::find)::type{ gear.id, 0 }; - boss.broadcast->SIGNAL(tier::request, e2::form::state::keybd::find, gear_test); - if (gear_test.second) + parent_bcast_memo->clear(); + bcast->SUBMIT_T(tier::release, app::tile::events::ui::any, *parent_bcast_memo, gear) { - if (auto parent = boss.parent()) - if (auto deed = parent->broadcast->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 + auto gear_test = decltype(e2::form::state::keybd::find)::type{ gear.id, 0 }; + boss.broadcast->SIGNAL(tier::request, e2::form::state::keybd::find, gear_test); + if (gear_test.second) { - switch (deed) + if (auto parent = boss.parent()) + if (auto deed = parent->broadcast->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 { - case app::tile::events::ui::create.id: - gear.force_group_focus = true; - boss.template riseup(e2::form::proceed::createby, gear); - gear.force_group_focus = faux; - break; - case app::tile::events::ui::close.id: - boss.template riseup(e2::form::quit, boss.This()); - break; - case app::tile::events::ui::toggle.id: - if (boss.base::kind() == 0) // Only apps can be maximized. - if (gear.countdown > 0) - { - gear.countdown--; - // Removing multifocus - The only one can be maximized if several are selected. + switch (deed) + { + case app::tile::events::ui::create.id: + gear.force_group_focus = true; + boss.template riseup(e2::form::proceed::createby, gear); gear.force_group_focus = faux; - gear.kb_focus_taken = faux; - boss.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); + break; + case app::tile::events::ui::close.id: + boss.template riseup(e2::form::quit, boss.This()); + break; + case app::tile::events::ui::toggle.id: + if (boss.base::kind() == 0) // Only apps can be maximized. + if (gear.countdown > 0) + { + gear.countdown--; + // Removing multifocus - The only one can be maximized if several are selected. + gear.force_group_focus = faux; + gear.kb_focus_taken = faux; + boss.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); - boss.template riseup(e2::form::maximize, gear); - //todo parent_memo is reset by the empty slot here (pop_back), undefined behavior from here - } - break; - case app::tile::events::ui::swap.id: - boss.template riseup(app::tile::events::ui::swap, gear); - break; - case app::tile::events::ui::rotate.id: - boss.template riseup(app::tile::events::ui::rotate, gear); - break; - case app::tile::events::ui::equalize.id: - boss.template riseup(app::tile::events::ui::equalize, gear); - break; - case app::tile::events::ui::split::vt.id: - boss.template riseup(app::tile::events::ui::split::vt, gear); - break; - case app::tile::events::ui::split::hz.id: - boss.template riseup(app::tile::events::ui::split::hz, gear); - break; + boss.template riseup(e2::form::maximize, gear); + //todo parent_memo is reset by the empty slot here (pop_back), undefined behavior from here + } + break; + case app::tile::events::ui::swap.id: + boss.template riseup(app::tile::events::ui::swap, gear); + break; + case app::tile::events::ui::rotate.id: + boss.template riseup(app::tile::events::ui::rotate, gear); + break; + case app::tile::events::ui::equalize.id: + boss.template riseup(app::tile::events::ui::equalize, gear); + break; + case app::tile::events::ui::split::vt.id: + boss.template riseup(app::tile::events::ui::split::vt, gear); + break; + case app::tile::events::ui::split::hz.id: + boss.template riseup(app::tile::events::ui::split::hz, gear); + break; + } } } - } + }; }; boss.SUBMIT_T_BYVAL(tier::release, e2::form::upon::vtree::detached, *parent_memo, parent) { parent_memo.reset(); + parent_bcast_memo.reset(); }; }; }; @@ -515,7 +521,7 @@ namespace netxs::app::tile }; } #endif - host->SUBMIT(tier::release, netxs::events::userland::root::dtor, id) + host->SUBMIT(tier::release, e2::dtor, id) { insts_count--; log("tile: inst: detached: ", insts_count, " id=", id); diff --git a/src/netxs/console/console.hpp b/src/netxs/console/console.hpp index d0c11f7286..dd6bdfdc26 100644 --- a/src/netxs/console/console.hpp +++ b/src/netxs/console/console.hpp @@ -61,6 +61,7 @@ namespace netxs::events::userland { using type = netxs::events::type; static constexpr auto dtor = netxs::events::userland::root::dtor; + static constexpr auto cascade = netxs::events::userland::root::cascade; EVENTPACK( e2, netxs::events::userland::root::base ) { @@ -859,9 +860,11 @@ namespace netxs::console bool invalid = true; // base: Should the object be redrawn. bool visual_root = faux; // Whether the size is tied to the size of the clients. hook kb_token; + hook cascade_token; iota object_kind = {}; public: + //todo deprecated subs bcastsubs; sptr broadcast = std::make_shared(); // base: Broadcast bus. // On attach the broadcast is merged with parent (bell::merge). @@ -871,6 +874,8 @@ namespace netxs::console protected: bool is_attached() const { return kb_token.operator bool(); } + + //todo deprecated void switch_to_bus(sptr parent_bus) { if (parent_bus != broadcast) // Reattaching is allowed within the same visual tree. @@ -890,6 +895,7 @@ namespace netxs::console SUBMIT(tier::release, e2::size::set, new_size) { square.size = new_size; }; SUBMIT(tier::request, e2::size::set, size_var) { size_var = square.size; }; + //todo deprecated //SUBMIT_T(tier::release, e2::config::broadcast::reinit, bell::tracker, old_broadcast) SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, this->broadcast) { @@ -905,6 +911,13 @@ namespace netxs::console { if (!visual_root) { + parent_ptr->SUBMIT_T(tier::release, e2::cascade, cascade_token, proc) + { + auto keepon = proc(*this); + if (keepon) this->SIGNAL(tier::release, e2::cascade, proc); + }; + + //todo deprecated auto bcast_backup = broadcast; base::switch_to_bus(parent_ptr->base::broadcast); parent_ptr->SUBMIT_T(tier::release, e2::config::broadcast::reinit, bcastsubs, broadcast) @@ -915,6 +928,7 @@ namespace netxs::console parent_shadow = parent_ptr; // Propagate form events up to the visual branch. // Exec after all subscriptions. + //todo implement via e2::cascade parent_ptr->SUBMIT_T(tier::release, hids::events::upevent::any, kb_token, gear) { if (auto parent_ptr = parent_shadow.lock()) @@ -938,10 +952,12 @@ namespace netxs::console if (this->bell::protos(e2::form::upon::vtree::detached)) { kb_token.reset(); + cascade_token.reset(); //todo revise //parent_shadow.reset(); if (!visual_root) { + //todo deprecated bcastsubs.clear(); broadcast = std::make_shared(); this->SIGNAL(tier::release, e2::config::broadcast::reinit, broadcast); @@ -1119,6 +1135,13 @@ namespace netxs::console parent_ptr->global(coor); } } + // base: Recursively find the root of the visual tree. + bell& gettop() override + { + auto parent_ptr = parent(); + if (!visual_root && parent_ptr) return parent_ptr->gettop(); + else return *this; + } // base: Invoke a lambda with parent as a parameter. // Usage example: // toboss([&](auto& parent_ptr) { c.fuse(parent.brush); }); diff --git a/src/netxs/ui/events.hpp b/src/netxs/ui/events.hpp index dc6ec2bead..2d89a2271a 100644 --- a/src/netxs/ui/events.hpp +++ b/src/netxs/ui/events.hpp @@ -32,6 +32,7 @@ namespace netxs::events preview, // events: Run reverse handlers with fixed a param intended to change. Preserve subscription order. general, // events: Run forwrad handlers for all objects. Preserve subscription order. request, // events: Run forwrad a handler that provides the current value of the param. To avoid being overridden, the handler should be the only one. Preserve subscription order. + anycast, // events: Run reverse handlers along the entire visual tree. Preserve subscription order. }; template struct _globals { static std::recursive_mutex mutex; }; @@ -316,7 +317,8 @@ namespace netxs::events #define SIGNAL_GLOBAL( event, param) bell::template signal_global(decltype( event )::id, static_cast(param)) #define SUBMIT_GLOBAL( event, token, param) bell::template submit_global( token ) = [&] (typename decltype( event )::type && param) - #define SUBMIT_AND_RUN(level, event, param, arg) bell::template submit2( arg ) = [&] (typename decltype( event )::type && param) + #define SUBMIT_AND_RUN_T(level, event, token, param, arg) bell::template submit2( arg, token ) = [&] (typename decltype( event )::type && param) + #define SUBMIT_AND_RUN( level, event, param, arg) bell::template submit2( arg ) = [&] (typename decltype( event )::type && param) #define EVENTPACK( name, base ) using _group_type = name; \ static constexpr auto _counter_base = __COUNTER__; \ @@ -327,6 +329,10 @@ namespace netxs::events #define INDEX_XS( ... ) }; template static constexpr \ auto _ = std::get( std::tuple{ __VA_ARGS__ } ); \ private: static constexpr auto _dummy = { 777 + + class bell; + using ftor = std::function; + //todo unify seeding namespace userland { @@ -335,17 +341,19 @@ namespace netxs::events static constexpr auto root_event = type_clue{}; EVENTPACK( root, root_event ) { - EVENT_XS( dtor , const id_t ), - EVENT_XS( base , root ), - EVENT_XS( hids , root ), - EVENT_XS( custom, root ), + EVENT_XS( dtor , const id_t ), + EVENT_XS( cascade, ftor ), + EVENT_XS( base , root ), + EVENT_XS( hids , root ), + EVENT_XS( custom , root ), }; }; } // events: Event x-mitter. - struct bell : public indexer + class bell : public indexer { + public: static constexpr auto noid = std::numeric_limits::max(); subs tracker; @@ -356,10 +364,12 @@ namespace netxs::events template struct _globals { static fwd_reactor general; }; fwd_reactor& general{ _globals::general }; - rev_reactor preview; - fwd_reactor request; fwd_reactor release; + fwd_reactor request; + rev_reactor preview; + rev_reactor anycast; + //todo deprecated template struct submit_helper2 { @@ -369,6 +379,21 @@ namespace netxs::events submit_helper2(bell& owner, type& p) : owner{ owner }, p{p} { } template void operator=(F h) { owner.submit(h); h(static_cast(p)); } }; + //todo deprecated + template + struct submit_helper2_token + { + using type = typename EVENT::type; + bell& owner; + type& p; + hook& token; + submit_helper2_token(bell& owner, type& p, hook& token) + : owner{ owner }, + p{p}, + token{ token } + { } + template void operator=(F h) { owner.submit(token, h); h(static_cast(p)); } + }; template struct submit_helper { @@ -393,6 +418,7 @@ namespace netxs::events }; public: + //todo deprecated void merge(sptr source_ptr) { auto& s = *source_ptr; @@ -401,7 +427,10 @@ namespace netxs::events request.merge(s.request); release.merge(s.release); } - template auto submit2(typename EVENT::type & p) { return submit_helper2(*this, p); } + + //todo deprecated + template auto submit2(typename EVENT::type & p) { return submit_helper2 (*this, p); } + template auto submit2(typename EVENT::type & p, subs& tokens) { return submit_helper2_token(*this, p, tokens.extra()); } template auto submit() { return submit_helper (*this); } template auto submit(hook& token) { return submit_helper_token(*this, token); } @@ -412,7 +441,8 @@ namespace netxs::events if constexpr (TIER == tier::preview) tracker.admit(preview.subscribe(EVENT::id, handler)); else if constexpr (TIER == tier::general) tracker.admit(general.subscribe(EVENT::id, handler)); else if constexpr (TIER == tier::request) tracker.admit(request.subscribe(EVENT::id, handler)); - else tracker.admit(release.subscribe(EVENT::id, handler)); + else if constexpr (TIER == tier::release) tracker.admit(release.subscribe(EVENT::id, handler)); + else tracker.admit(anycast.subscribe(EVENT::id, handler)); } template void submit(hook& token, std::function handler) @@ -420,7 +450,8 @@ namespace netxs::events if constexpr (TIER == tier::preview) token = preview.subscribe(EVENT::id, handler); else if constexpr (TIER == tier::general) token = general.subscribe(EVENT::id, handler); else if constexpr (TIER == tier::request) token = request.subscribe(EVENT::id, handler); - else token = release.subscribe(EVENT::id, handler); + else if constexpr (TIER == tier::release) token = release.subscribe(EVENT::id, handler); + else token = anycast.subscribe(EVENT::id, handler); } template auto signal(type event, F&& data) @@ -428,7 +459,17 @@ namespace netxs::events if constexpr (TIER == tier::preview) return preview.notify(event, std::forward(data)); else if constexpr (TIER == tier::general) return general.notify(event, std::forward(data)); else if constexpr (TIER == tier::request) return request.notify(event, std::forward(data)); - else return release.notify(event, std::forward(data)); + else if constexpr (TIER == tier::release) return release.notify(event, std::forward(data)); + else /* TIER == tier::anycast */ + { + auto& root = gettop(); + ftor proc = [&](bell& boss) -> bool + { + boss.anycast.notify(event, std::forward(data)); + return true; + }; + return root.release.notify(userland::root::cascade, proc); + } } template static auto submit_global(hook& token) { return submit_helper_token_global(token); } template static auto signal_global(type event, F&& data) { return _globals::general.notify(event, std::forward(data)); } @@ -439,7 +480,8 @@ namespace netxs::events if constexpr (TIER == tier::preview) return preview.queue.empty() ? type{} : preview.queue.back(); else if constexpr (TIER == tier::general) return general.queue.empty() ? type{} : general.queue.back(); else if constexpr (TIER == tier::request) return request.queue.empty() ? type{} : request.queue.back(); - else return release.queue.empty() ? type{} : release.queue.back(); + else if constexpr (TIER == tier::release) return release.queue.empty() ? type{} : release.queue.back(); + else return anycast.queue.empty() ? type{} : anycast.queue.back(); } template auto protos(EVENT) { return bell::protos() == EVENT::id; } template @@ -448,7 +490,8 @@ namespace netxs::events if constexpr (TIER == tier::preview) return preview; else if constexpr (TIER == tier::general) return general; else if constexpr (TIER == tier::request) return request; - else return release; + else if constexpr (TIER == tier::release) return release; + else return anycast; } template void expire() @@ -456,12 +499,14 @@ namespace netxs::events if constexpr (TIER == tier::preview) return preview.stop(); else if constexpr (TIER == tier::general) return general.stop(); else if constexpr (TIER == tier::request) return request.stop(); - else return release.stop(); + else if constexpr (TIER == tier::release) return release.stop(); + else return anycast.stop(); } ~bell() { sync lock; SIGNAL(tier::release, userland::root::dtor, id); } - virtual void global(twod& coor) { } // bell: Recursively calculate global coordinate. + virtual void global(twod& coor) { } // bell: Recursively calculate global coordinate. + virtual bell& gettop() { return *this; } // bell: Recursively find the root of the visual tree. }; template bell::fwd_reactor bell::_globals::general; From 0942c2839c07dea31cff9f8c0ca32ad1a8c1f1ed Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Sun, 5 Dec 2021 19:35:20 +0500 Subject: [PATCH 03/12] UI: Broadcast architecture revision --- src/netxs/apps.hpp | 58 +++---- src/netxs/apps/desk.hpp | 19 +-- src/netxs/apps/logs.hpp | 88 +++++----- src/netxs/apps/term.hpp | 89 +++++----- src/netxs/apps/tile.hpp | 300 +++++++++++++++++++--------------- src/netxs/console/console.hpp | 49 +++--- src/netxs/ui/events.hpp | 2 +- src/vtmd.cpp | 2 +- 8 files changed, 299 insertions(+), 308 deletions(-) diff --git a/src/netxs/apps.hpp b/src/netxs/apps.hpp index c4a0f1d11d..8c219b64fb 100644 --- a/src/netxs/apps.hpp +++ b/src/netxs/apps.hpp @@ -143,16 +143,13 @@ namespace netxs::app::shared boss.reflow(); gear.dismiss(); }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, e2::form::prop::menusize, size) { - bcast->SUBMIT_T(tier::release, e2::form::prop::menusize, boss.bcastsubs, size) - { - auto& limit = boss.plugins(); - auto limits = limit.get(); - limits.min.y = limits.max.y = std::max(0, size); - limit.set(limits); - boss.reflow(); - }; + auto& limit = boss.plugins(); + auto limits = limit.get(); + limits.min.y = limits.max.y = std::max(0, size); + limit.set(limits); + boss.reflow(); }; }); auto menu_area = menu_block->attach(snap::stretch, snap::center, ui::fork::ctor()) @@ -498,12 +495,9 @@ namespace netxs::app::shared (*c)--; log("main: vtm recursive conn destoyed"); }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, e2::form::upon::started, root) { - bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) - { - boss.start(); - }; + boss.start(); }; }); } @@ -536,12 +530,9 @@ namespace netxs::app::shared ->colors(whitelt, blackdk) ->invoke([&](auto& boss) { - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, e2::form::upon::started, root) { - bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) - { - boss.start(); - }; + boss.start(); }; }); layers->attach(app::shared::scroll_bars_term(scroll)); @@ -580,12 +571,9 @@ namespace netxs::app::shared inst->colors(whitelt, blackdk) ->invoke([&](auto& boss) { - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, e2::form::upon::started, root) { - bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) - { - boss.start(); - }; + boss.start(); }; }); layers->attach(app::shared::scroll_bars(scroll)); @@ -607,7 +595,7 @@ namespace netxs::app::shared { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::clear); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::clear); gear.dismiss(true); }; }}, @@ -616,7 +604,7 @@ namespace netxs::app::shared { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::reset); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::reset); gear.dismiss(true); }; }}, @@ -630,12 +618,9 @@ namespace netxs::app::shared ->colors(whitelt, 0xFF562401) ->invoke([&](auto& boss) { - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, e2::form::upon::started, root) { - bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) - { - boss.start(); - }; + boss.start(); }; }); @@ -660,7 +645,7 @@ namespace netxs::app::shared { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::clear); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::clear); gear.dismiss(true); }; }}, @@ -669,7 +654,7 @@ namespace netxs::app::shared { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::reset); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::reset); gear.dismiss(true); }; }}, @@ -692,12 +677,9 @@ namespace netxs::app::shared inst->colors(whitelt, blackdk) ->invoke([&](auto& boss) { - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, e2::form::upon::started, root) { - bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) - { - boss.start(); - }; + boss.start(); }; }); diff --git a/src/netxs/apps/desk.hpp b/src/netxs/apps/desk.hpp index 5670634830..f7dc95bd73 100644 --- a/src/netxs/apps/desk.hpp +++ b/src/netxs/apps/desk.hpp @@ -340,12 +340,9 @@ namespace netxs::app::desk auto taskbar_viewport = window->attach(ui::fork::ctor(axis::X)) ->invoke([](auto& boss) { - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, e2::form::prop::viewport, viewport) { - bcast->SUBMIT_T(tier::request, e2::form::prop::viewport, boss.bcastsubs, viewport) - { - viewport = boss.base::area(); - }; + viewport = boss.base::area(); }; }); auto taskbar = taskbar_viewport->attach(slot::_1, ui::fork::ctor(axis::Y)) @@ -397,15 +394,11 @@ namespace netxs::app::desk else timer.actify(faux, MENU_TIMEOUT, apply); } }; - auto& size_inst = *size_config; // Its lifetime eq boss livetime (sptr is captured by boss.SUBMIT_BYVAL). - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT_BYVAL(tier::anycast, e2::form::prop::viewport, viewport) { - bcast->SUBMIT_T(tier::request, e2::form::prop::viewport, boss.bcastsubs, viewport) - { - auto& [uibar_full_size, uibar_min_size] = size_inst; - viewport.coor.x += uibar_min_size; - viewport.size.x -= uibar_min_size; - }; + auto& [uibar_full_size, uibar_min_size] = *size_config; + viewport.coor.x += uibar_min_size; + viewport.size.x -= uibar_min_size; }; }); auto apps_users = taskbar->attach(slot::_1, ui::fork::ctor(axis::Y, 0, 100)); diff --git a/src/netxs/apps/logs.hpp b/src/netxs/apps/logs.hpp index 01a8a87876..ab5aea748b 100644 --- a/src/netxs/apps/logs.hpp +++ b/src/netxs/apps/logs.hpp @@ -12,17 +12,13 @@ namespace netxs::events::userland { EVENTPACK( logs, netxs::events::userland::root::custom ) { - GROUP_XS( ui, input::hids ), + GROUP_XS( codepoints, iota ), - SUBSET_XS( ui ) + SUBSET_XS( codepoints ) { - EVENT_XS( create , input::hids ), - GROUP_XS( split , input::hids ), - - SUBSET_XS( split ) - { - EVENT_XS( hz, input::hids ), - }; + EVENT_XS( release, iota ), + EVENT_XS( preview, iota ), + EVENT_XS( request, iota ), }; }; }; @@ -73,7 +69,7 @@ namespace netxs::app::logs auto msg = ansi::bgc(s ? greendk : yellowdk).fgc(whitelt) .add(" show codepoints: ", s ? "on":"off", "\n").nil(); SIGNAL(tier::general, e2::debug::logs, msg); - SIGNAL(tier::release, e2::command::custom, s ? 1 : 2); + SIGNAL(tier::release, events::codepoints::release, s ? 1 : 2); } void worker() { @@ -188,38 +184,35 @@ namespace netxs::app::logs clear(); gear.dismiss(); }; - SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, broadcast) + SUBMIT(tier::anycast, events::codepoints::request, status) { - bcast->SUBMIT_T(tier::request, e2::command::custom, bcastsubs, status) + switch (status) { - switch (status) - { - case 1: - status = worker->show_codepoints ? 1 : 2; - break; - default: - break; - } - }; - bcast->SUBMIT_T(tier::preview, e2::command::custom, bcastsubs, cmd_id) + case 1: + status = worker->show_codepoints ? 1 : 2; + break; + default: + break; + } + }; + SUBMIT(tier::anycast, events::codepoints::preview, cmd_id) + { + switch (cmd_id) { - switch (cmd_id) - { - case 0: - clear(); - break; - case 1: - case 2: - itsme = true; - worker->enable_codepoints(cmd_id == 1 ? true : faux); - itsme = faux; - break; - default: - break; - } - }; + case 0: + clear(); + break; + case 1: + case 2: + itsme = true; + worker->enable_codepoints(cmd_id == 1 ? true : faux); + itsme = faux; + break; + default: + break; + } }; - broadcast->SIGNAL(tier::release, e2::command::custom, worker->show_codepoints ? 1 : 2); + SIGNAL(tier::anycast, events::codepoints::release, worker->show_codepoints ? 1 : 2); SUBMIT(tier::preview, e2::size::set, newsize) { caret.coor(flow::cp()); @@ -229,9 +222,9 @@ namespace netxs::app::logs topic += utf8; update(); }; - worker->SUBMIT_T(tier::release, e2::command::custom, token, status) + worker->SUBMIT_T(tier::release, events::codepoints::release, token, status) { - broadcast->SIGNAL(tier::release, e2::command::custom, status); + this->SIGNAL(tier::anycast, events::codepoints::release, status); }; worker->SUBMIT_T(tier::release, e2::debug::parsed, token, parsed_page) { @@ -266,17 +259,14 @@ namespace netxs::app::logs boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { iota status = 1; - boss.base::broadcast->SIGNAL(tier::request, e2::command::custom, status); - boss.base::broadcast->SIGNAL(tier::preview, e2::command::custom, status == 2 ? 1/*show*/ : 2/*hide*/); + boss.SIGNAL(tier::anycast, app::logs::events::codepoints::request, status); + boss.SIGNAL(tier::anycast, app::logs::events::codepoints::preview, status == 2 ? 1/*show*/ : 2/*hide*/); gear.dismiss(true); }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, app::logs::events::codepoints::release, status) { - bcast->SUBMIT_T(tier::release, e2::command::custom, boss.bcastsubs, status) - { - //todo unify, get boss base colors, don't use x3 - boss.color(status == 1 ? 0xFF00ff00 : x3.fgc(), x3.bgc()); - }; + //todo unify, get boss base colors, don't use x3 + boss.color(status == 1 ? 0xFF00ff00 : x3.fgc(), x3.bgc()); }; }}, std::pair>{ "Clear", @@ -284,7 +274,7 @@ namespace netxs::app::logs { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, e2::command::custom, 0); + boss.SIGNAL(tier::anycast, app::logs::events::codepoints::preview, 0); gear.dismiss(true); }; }}, diff --git a/src/netxs/apps/term.hpp b/src/netxs/apps/term.hpp index 4b62b7b659..b42ec8d993 100644 --- a/src/netxs/apps/term.hpp +++ b/src/netxs/apps/term.hpp @@ -49,7 +49,7 @@ namespace netxs::app::term boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { auto data = "ls /bin\n"s; - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::data::out, data); + boss.SIGNAL(tier::anycast, app::term::events::data::out, data); gear.dismiss(true); }; }}, @@ -59,7 +59,7 @@ namespace netxs::app::term boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { auto data = "ping -c 3 127.0.0.1 | ccze -A\n"s; - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::data::out, data); + boss.SIGNAL(tier::anycast, app::term::events::data::out, data); gear.dismiss(true); }; }}, @@ -69,7 +69,7 @@ namespace netxs::app::term boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { auto data = "curl wttr.in\n"s; - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::data::out, data); + boss.SIGNAL(tier::anycast, app::term::events::data::out, data); gear.dismiss(true); }; }}, @@ -80,7 +80,7 @@ namespace netxs::app::term { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::clear); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::clear); gear.dismiss(true); }; }}, @@ -90,7 +90,7 @@ namespace netxs::app::term { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::reset); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::reset); gear.dismiss(true); }; }}, @@ -99,16 +99,13 @@ namespace netxs::app::term { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::left); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::left); gear.dismiss(true); }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, app::term::events::layout::align, align) { - bcast->SUBMIT_T(tier::release, app::term::events::layout::align, boss.bcastsubs, align) - { - //todo unify, get boss base colors, don't use x3 - boss.color(align == bias::left ? 0xFF00ff00 : x3.fgc(), x3.bgc()); - }; + //todo unify, get boss base colors, don't use x3 + boss.color(align == bias::left ? 0xFF00ff00 : x3.fgc(), x3.bgc()); }; }}, std::pair>{ "─=─", @@ -116,16 +113,13 @@ namespace netxs::app::term { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::center); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::center); gear.dismiss(true); }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, app::term::events::layout::align, align) { - bcast->SUBMIT_T(tier::release, app::term::events::layout::align, boss.bcastsubs, align) - { - //todo unify, get boss base colors, don't use x3 - boss.color(align == bias::center ? 0xFF00ff00 : x3.fgc(), x3.bgc()); - }; + //todo unify, get boss base colors, don't use x3 + boss.color(align == bias::center ? 0xFF00ff00 : x3.fgc(), x3.bgc()); }; }}, std::pair>{ "─=", @@ -133,16 +127,13 @@ namespace netxs::app::term { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::right); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::right); gear.dismiss(true); }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, app::term::events::layout::align, align) { - bcast->SUBMIT_T(tier::release, app::term::events::layout::align, boss.bcastsubs, align) - { - //todo unify, get boss base colors, don't use x3 - boss.color(align == bias::right ? 0xFF00ff00 : x3.fgc(), x3.bgc()); - }; + //todo unify, get boss base colors, don't use x3 + boss.color(align == bias::right ? 0xFF00ff00 : x3.fgc(), x3.bgc()); }; }}, std::pair>{ "Wrap", @@ -150,16 +141,13 @@ namespace netxs::app::term { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::term::events::cmd, ui::term::commands::ui::togglewrp); + boss.SIGNAL(tier::anycast, app::term::events::cmd, ui::term::commands::ui::togglewrp); gear.dismiss(true); }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, app::term::events::layout::wrapln, wrapln) { - bcast->SUBMIT_T(tier::release, app::term::events::layout::wrapln, boss.bcastsubs, wrapln) - { - //todo unify, get boss base colors, don't use x3 - boss.color(wrapln == wrap::on ? 0xFF00ff00 : x3.fgc(), x3.bgc()); - }; + //todo unify, get boss base colors, don't use x3 + boss.color(wrapln == wrap::on ? 0xFF00ff00 : x3.fgc(), x3.bgc()); }; }}, }; @@ -201,30 +189,27 @@ namespace netxs::app::term { boss.SUBMIT(tier::release, ui::term::events::layout::wrapln, status) { - boss.base::broadcast->SIGNAL(tier::release, app::term::events::layout::wrapln, status); + boss.SIGNAL(tier::anycast, app::term::events::layout::wrapln, status); }; boss.SUBMIT(tier::release, ui::term::events::layout::align, status) { - boss.base::broadcast->SIGNAL(tier::release, app::term::events::layout::align, status); + boss.SIGNAL(tier::anycast, app::term::events::layout::align, status); }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, app::term::events::cmd, cmd) { - bcast->SUBMIT_T(tier::preview, app::term::events::cmd, boss.bcastsubs, cmd) - { - boss.exec_cmd(static_cast(cmd)); - }; - bcast->SUBMIT_T(tier::preview, app::term::events::data::in, boss.bcastsubs, data) - { - boss.data_in(data); - }; - bcast->SUBMIT_T(tier::preview, app::term::events::data::out, boss.bcastsubs, data) - { - boss.data_out(data); - }; - bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) - { - boss.start(); - }; + boss.exec_cmd(static_cast(cmd)); + }; + boss.SUBMIT(tier::anycast, app::term::events::data::in, data) + { + boss.data_in(data); + }; + boss.SUBMIT(tier::anycast, app::term::events::data::out, data) + { + boss.data_out(data); + }; + boss.SUBMIT(tier::anycast, e2::form::upon::started, root) + { + boss.start(); }; }); } diff --git a/src/netxs/apps/tile.hpp b/src/netxs/apps/tile.hpp index 678e450673..011a2767ae 100644 --- a/src/netxs/apps/tile.hpp +++ b/src/netxs/apps/tile.hpp @@ -28,6 +28,63 @@ namespace netxs::events::userland EVENT_XS( vt, input::hids ), EVENT_XS( hz, input::hids ), }; + + +// GROUP_XS( preview, input::hids ), +// GROUP_XS( release, input::hids ), +// GROUP_XS( request, input::hids ), +// +// SUBSET_XS( preview ) +// { +// EVENT_XS( create , input::hids ), +// EVENT_XS( close , input::hids ), +// EVENT_XS( toggle , input::hids ), // toggle window size: maximize/restore. +// EVENT_XS( swap , input::hids ), +// EVENT_XS( rotate , input::hids ), // change nested objects order. See tilimg manager (ui::fork). +// EVENT_XS( equalize, input::hids ), +// EVENT_XS( select , input::hids ), +// GROUP_XS( split , input::hids ), +// +// SUBSET_XS( split ) +// { +// EVENT_XS( vt, input::hids ), +// EVENT_XS( hz, input::hids ), +// }; +// }; +// SUBSET_XS( release ) +// { +// EVENT_XS( create , input::hids ), +// EVENT_XS( close , input::hids ), +// EVENT_XS( toggle , input::hids ), // toggle window size: maximize/restore. +// EVENT_XS( swap , input::hids ), +// EVENT_XS( rotate , input::hids ), // change nested objects order. See tilimg manager (ui::fork). +// EVENT_XS( equalize, input::hids ), +// EVENT_XS( select , input::hids ), +// GROUP_XS( split , input::hids ), +// +// SUBSET_XS( split ) +// { +// EVENT_XS( vt, input::hids ), +// EVENT_XS( hz, input::hids ), +// }; +// }; +// SUBSET_XS( request ) +// { +// EVENT_XS( create , input::hids ), +// EVENT_XS( close , input::hids ), +// EVENT_XS( toggle , input::hids ), // toggle window size: maximize/restore. +// EVENT_XS( swap , input::hids ), +// EVENT_XS( rotate , input::hids ), // change nested objects order. See tilimg manager (ui::fork). +// EVENT_XS( equalize, input::hids ), +// EVENT_XS( select , input::hids ), +// GROUP_XS( split , input::hids ), +// +// SUBSET_XS( split ) +// { +// EVENT_XS( vt, input::hids ), +// EVENT_XS( hz, input::hids ), +// }; +// }; }; }; }; @@ -46,13 +103,13 @@ namespace netxs::app::tile { auto parent_memo = std::make_shared(); auto shadow = ptr::shadow(boss.This()); - parent->broadcast->SUBMIT_T_BYVAL(tier::release, app::tile::events::ui::any, *parent_memo, gear) + parent->SUBMIT_T_BYVAL(tier::anycast, app::tile::events::ui::any, *parent_memo, gear) { if (auto master = shadow.lock()) if (auto parent = master->parent()) - if (auto action = parent->broadcast->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 + if (auto action = parent->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 { - master->broadcast->bell::template signal(action, gear); + master->bell::template signal(action, gear); } }; boss.SUBMIT_T_BYVAL(tier::release, e2::form::upon::vtree::detached, *parent_memo, parent) @@ -65,68 +122,62 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, e2::form::upon::vtree::attached, parent) { - auto parent_memo = std::make_shared(); - auto parent_bcast_memo = std::make_shared(); - parent->SUBMIT_AND_RUN_T(tier::release, e2::config::broadcast::reinit, *parent_memo, bcast, parent->broadcast) + auto parent_memo = std::make_shared(); + parent->SUBMIT_T(tier::anycast, app::tile::events::ui::any, *parent_memo, gear) { - parent_bcast_memo->clear(); - bcast->SUBMIT_T(tier::release, app::tile::events::ui::any, *parent_bcast_memo, gear) + auto gear_test = decltype(e2::form::state::keybd::find)::type{ gear.id, 0 }; + boss.SIGNAL(tier::anycast, e2::form::state::keybd::find, gear_test); + if (gear_test.second) { - auto gear_test = decltype(e2::form::state::keybd::find)::type{ gear.id, 0 }; - boss.broadcast->SIGNAL(tier::request, e2::form::state::keybd::find, gear_test); - if (gear_test.second) + if (auto parent = boss.parent()) + if (auto deed = parent->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 { - if (auto parent = boss.parent()) - if (auto deed = parent->broadcast->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 + switch (deed) { - switch (deed) - { - case app::tile::events::ui::create.id: - gear.force_group_focus = true; - boss.template riseup(e2::form::proceed::createby, gear); + case app::tile::events::ui::create.id: + gear.force_group_focus = true; + boss.template riseup(e2::form::proceed::createby, gear); + gear.force_group_focus = faux; + break; + case app::tile::events::ui::close.id: + boss.template riseup(e2::form::quit, boss.This()); + break; + case app::tile::events::ui::toggle.id: + if (boss.base::kind() == 0) // Only apps can be maximized. + if (gear.countdown > 0) + { + gear.countdown--; + // Removing multifocus - The only one can be maximized if several are selected. gear.force_group_focus = faux; - break; - case app::tile::events::ui::close.id: - boss.template riseup(e2::form::quit, boss.This()); - break; - case app::tile::events::ui::toggle.id: - if (boss.base::kind() == 0) // Only apps can be maximized. - if (gear.countdown > 0) - { - gear.countdown--; - // Removing multifocus - The only one can be maximized if several are selected. - gear.force_group_focus = faux; - gear.kb_focus_taken = faux; - boss.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); - - boss.template riseup(e2::form::maximize, gear); - //todo parent_memo is reset by the empty slot here (pop_back), undefined behavior from here - } - break; - case app::tile::events::ui::swap.id: - boss.template riseup(app::tile::events::ui::swap, gear); - break; - case app::tile::events::ui::rotate.id: - boss.template riseup(app::tile::events::ui::rotate, gear); - break; - case app::tile::events::ui::equalize.id: - boss.template riseup(app::tile::events::ui::equalize, gear); - break; - case app::tile::events::ui::split::vt.id: - boss.template riseup(app::tile::events::ui::split::vt, gear); - break; - case app::tile::events::ui::split::hz.id: - boss.template riseup(app::tile::events::ui::split::hz, gear); - break; - } + gear.kb_focus_taken = faux; + boss.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); + boss.template riseup(e2::form::maximize, gear); + //todo parent_memo is reset by the empty slot here (pop_back), undefined behavior from here + } + break; + case app::tile::events::ui::swap.id: + boss.template riseup(app::tile::events::ui::swap, gear); + break; + case app::tile::events::ui::rotate.id: + boss.template riseup(app::tile::events::ui::rotate, gear); + break; + case app::tile::events::ui::equalize.id: + boss.template riseup(app::tile::events::ui::equalize, gear); + break; + case app::tile::events::ui::split::vt.id: + boss.template riseup(app::tile::events::ui::split::vt, gear); + break; + case app::tile::events::ui::split::hz.id: + boss.template riseup(app::tile::events::ui::split::hz, gear); + break; } } - }; + } }; boss.SUBMIT_T_BYVAL(tier::release, e2::form::upon::vtree::detached, *parent_memo, parent) { parent_memo.reset(); - parent_bcast_memo.reset(); + //parent_bcast_memo.reset(); }; }; }; @@ -150,7 +201,7 @@ namespace netxs::app::tile }; auto box_with_title = [](view title, auto branch) { - branch->base::broadcast->SIGNAL(tier::release, e2::form::prop::menusize, 1); + branch->SIGNAL(tier::anycast, e2::form::prop::menusize, 1); return ui::fork::ctor(axis::Y) ->plugin("", true, faux, true) ->plugin(twod{ 10,-1 }, twod{ -1,-1 }) @@ -301,37 +352,34 @@ namespace netxs::app::tile parent_memo.reset(); }; }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, e2::form::upon::started, root) { - bcast->SUBMIT_T(tier::release, e2::form::upon::started, boss.bcastsubs, root) + if (auto item_ptr = boss.back()) { - if (auto item_ptr = boss.back()) + auto& item = *item_ptr; + if (item.base::root()) { - auto& item = *item_ptr; - if (item.base::root()) - { - item.broadcast->SIGNAL(tier::release, e2::form::upon::started, item_ptr); - } + item.SIGNAL(tier::anycast, e2::form::upon::started, item_ptr); } - }; - bcast->SUBMIT_T(tier::release, app::tile::events::ui::select, boss.bcastsubs, gear) + } + }; + boss.SUBMIT(tier::anycast, app::tile::events::ui::select, gear) + { + auto& item =*boss.back(); + if (item.base::root()) { - auto& item =*boss.back(); - if (item.base::root()) + if (item.base::kind() != 1) { - if (item.base::kind() != 1) - { - //todo unify - gear.force_group_focus = true; - gear.kb_focus_taken = faux; - gear.combine_focus = true; - item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); - gear.combine_focus = faux; - gear.force_group_focus = faux; - } - else item.SIGNAL(tier::release, hids::events::upevent::kbannul, gear); // Exclude grips. + //todo unify + gear.force_group_focus = true; + gear.kb_focus_taken = faux; + gear.combine_focus = true; + item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); + gear.combine_focus = faux; + gear.force_group_focus = faux; } - }; + else item.SIGNAL(tier::release, hids::events::upevent::kbannul, gear); // Exclude grips. + } }; boss.SUBMIT_BYVAL(tier::release, e2::form::maximize, gear) { @@ -430,7 +478,7 @@ namespace netxs::app::tile auto& item = *nested_item_ptr; using type = decltype(e2::form::state::keybd::handover)::type; type gear_id_list; - item.broadcast->SIGNAL(tier::request, e2::form::state::keybd::handover, gear_id_list); + item.SIGNAL(tier::anycast, e2::form::state::keybd::handover, gear_id_list); if (auto boss_ptr = shadow.lock()) { @@ -527,7 +575,7 @@ namespace netxs::app::tile log("tile: inst: detached: ", insts_count, " id=", id); }; } - app->broadcast->SIGNAL(tier::release, e2::form::upon::started, app); + app->SIGNAL(tier::anycast, e2::form::upon::started, app); //todo unify gear.kb_focus_taken = faux; @@ -667,28 +715,25 @@ namespace netxs::app::tile object->invoke([&](auto& boss) { - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + auto oneoff = std::make_shared(); + auto objs_config_ptr = &app::shared::objs_config; + boss.SUBMIT_T_BYVAL(tier::anycast, e2::form::upon::created, *oneoff, gear) { - auto oneoff = std::make_shared(); - auto objs_config_ptr = &app::shared::objs_config; - bcast->SUBMIT_T_BYVAL(tier::release, e2::form::upon::created, *oneoff, gear) + if (auto gate_ptr = bell::getref(gear.id)) { - if (auto gate_ptr = bell::getref(gear.id)) + auto& gate = *gate_ptr; + auto& objs_config = *objs_config_ptr; + auto menu_item_id = decltype(e2::data::changed)::type{}; + gate.SIGNAL(tier::request, e2::data::changed, menu_item_id); + //todo unify + auto config = objs_config[menu_item_id]; + if (config.type == "Tile") // Reset the currently selected application to the previous one. { - auto& gate = *gate_ptr; - auto& objs_config = *objs_config_ptr; - auto menu_item_id = decltype(e2::data::changed)::type{}; - gate.SIGNAL(tier::request, e2::data::changed, menu_item_id); - //todo unify - auto config = objs_config[menu_item_id]; - if (config.type == "Tile") // Reset the currently selected application to the previous one. - { - gate.SIGNAL(tier::preview, e2::data::changed, menu_item_id); // Get previous default; - gate.SIGNAL(tier::release, e2::data::changed, menu_item_id); // Set current default; - } + gate.SIGNAL(tier::preview, e2::data::changed, menu_item_id); // Get previous default; + gate.SIGNAL(tier::release, e2::data::changed, menu_item_id); // Set current default; } - oneoff.reset(); - }; + } + oneoff.reset(); }; boss.SUBMIT_BYVAL(tier::release, e2::form::upon::vtree::attached, parent) { @@ -710,7 +755,7 @@ namespace netxs::app::tile boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { gear.countdown = 1; - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::toggle, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::toggle, gear); gear.dismiss(true); }; }}, @@ -719,7 +764,7 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::create, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::create, gear); gear.dismiss(true); }; }}, @@ -728,7 +773,7 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::select, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::select, gear); gear.dismiss(true); }; }}, @@ -737,7 +782,7 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::split::hz, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::split::hz, gear); gear.dismiss(true); }; }}, @@ -746,7 +791,7 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::split::vt, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::split::vt, gear); gear.dismiss(true); }; }}, @@ -755,7 +800,7 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::rotate, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::rotate, gear); gear.dismiss(true); }; }}, @@ -764,7 +809,7 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::swap, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::swap, gear); gear.dismiss(true); }; }}, @@ -773,7 +818,7 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::equalize, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::equalize, gear); gear.dismiss(true); }; }}, @@ -782,7 +827,7 @@ namespace netxs::app::tile { boss.SUBMIT(tier::release, hids::events::mouse::button::click::left, gear) { - boss.base::broadcast->SIGNAL(tier::preview, app::tile::events::ui::close, gear); + boss.SIGNAL(tier::anycast, app::tile::events::ui::close, gear); gear.dismiss(true); }; }}, @@ -812,33 +857,30 @@ namespace netxs::app::tile auto item = boss.pop_back(); if (item) fullscreen_item = item; }; - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT(tier::anycast, app::tile::events::ui::any, gear) { - bcast->SUBMIT_T(tier::preview, app::tile::events::ui::any, boss.bcastsubs, gear) + if (auto deed = boss.bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 { - if (auto deed = boss.broadcast->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 + if (boss.count() > 2 && deed != app::tile::events::ui::toggle.id) // Restore the window before any action if maximized. { - if (boss.count() > 2 && deed != app::tile::events::ui::toggle.id) // Restore the window before any action if maximized. + auto gear_state = gear.state(); + auto& item =*boss.back(); + if (item.base::root()) // Pass focus to the maximized window. { - auto gear_state = gear.state(); - auto& item =*boss.back(); - if (item.base::root()) // Pass focus to the maximized window. - { - //todo unify - gear.force_group_focus = true; - gear.kb_focus_taken = faux; - gear.combine_focus = true; - item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); - gear.combine_focus = faux; - gear.force_group_focus = faux; - } - gear.countdown = 1; - boss.base::broadcast->SIGNAL(tier::release, app::tile::events::ui::toggle, gear); - gear.state(gear_state); + //todo unify + gear.force_group_focus = true; + gear.kb_focus_taken = faux; + gear.combine_focus = true; + item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); + gear.combine_focus = faux; + gear.force_group_focus = faux; } - boss.broadcast->bell::template signal(deed, gear); + gear.countdown = 1; + boss.SIGNAL(tier::anycast, app::tile::events::ui::toggle, gear); + gear.state(gear_state); } - }; + boss.bell::template signal(deed, gear); + } }; }); return object; diff --git a/src/netxs/console/console.hpp b/src/netxs/console/console.hpp index dd6bdfdc26..9bdc0739e3 100644 --- a/src/netxs/console/console.hpp +++ b/src/netxs/console/console.hpp @@ -113,6 +113,7 @@ namespace netxs::events::userland EVENT_XS( fps , iota ), // request to set new fps, arg: new fps (iota); the value == -1 is used to request current fps. GROUP_XS( caret , period ), // any kind of intervals property. GROUP_XS( plugins , iota ), + //todo deprecated GROUP_XS( broadcast, sptr ), // release: broadcast source changed. SUBSET_XS( caret ) @@ -131,6 +132,7 @@ namespace netxs::events::userland EVENT_XS( outer, dent ), // release: set outer size; request: request outer size. }; }; + //todo deprecated SUBSET_XS( broadcast ) { EVENT_XS( attached, sptr ), // release: broadcast source changed when attached. @@ -866,6 +868,7 @@ namespace netxs::console public: //todo deprecated subs bcastsubs; + //todo deprecated sptr broadcast = std::make_shared(); // base: Broadcast bus. // On attach the broadcast is merged with parent (bell::merge). // On detach the broadcast is duplicated from parent (bell::reset). @@ -3531,35 +3534,31 @@ namespace netxs::console focus(base& boss) : skill{ boss } { - boss.SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, boss.broadcast) + boss.SUBMIT_T(tier::anycast, e2::form::state::keybd::find, memo, gear_test) { - //todo how to reset boss.bcastsubs on ui::form::unplug? - bcast->SUBMIT_T(tier::request, e2::form::state::keybd::find, boss.bcastsubs, gear_test) + if (find(gear_test.first)) { - if (find(gear_test.first)) - { - gear_test.second++; - } - }; - bcast->SUBMIT_T(tier::request, e2::form::state::keybd::handover, boss.bcastsubs, gear_id_list) + gear_test.second++; + } + }; + boss.SUBMIT_T(tier::anycast, e2::form::state::keybd::handover, memo, gear_id_list) + { + if (pool.size()) { - if (pool.size()) + auto This = boss.This(); + auto head = gear_id_list.end(); + gear_id_list.insert(head, pool.begin(), pool.end()); + auto tail = gear_id_list.end(); + while (head != tail) { - auto This = boss.This(); - auto head = gear_id_list.end(); - gear_id_list.insert(head, pool.begin(), pool.end()); - auto tail = gear_id_list.end(); - while (head != tail) + auto gear_id = *head++; + if (auto gate_ptr = bell::getref(gear_id)) { - auto gear_id = *head++; - if (auto gate_ptr = bell::getref(gear_id)) - { - gate_ptr->SIGNAL(tier::preview, e2::form::proceed::unfocus, This); - } + gate_ptr->SIGNAL(tier::preview, e2::form::proceed::unfocus, This); } - boss.base::deface(); } - }; + boss.base::deface(); + } }; boss.SUBMIT_T(tier::release, e2::form::state::keybd::got, memo, gear) { @@ -4207,7 +4206,7 @@ namespace netxs::console gear.kb_focus_taken = faux; frame->SIGNAL(tier::release, hids::events::upevent::kboffer, gear); - frame->broadcast->SIGNAL(tier::release, e2::form::upon::created, gear); // The Tile should change the menu item. + frame->SIGNAL(tier::anycast, e2::form::upon::created, gear); // The Tile should change the menu item. } } } @@ -5414,7 +5413,7 @@ namespace netxs::console }; SUBMIT(tier::request, e2::form::prop::viewport, viewport) { - broadcast->SIGNAL(tier::request, e2::form::prop::viewport, viewport); + this->SIGNAL(tier::anycast, e2::form::prop::viewport, viewport); viewport.coor += base::coor(); }; //todo unify creation (delete simple create wo gear) @@ -5593,7 +5592,7 @@ namespace netxs::console { uibar = item; item->SIGNAL(tier::release, e2::form::upon::vtree::attached, This()); - //item->broadcast->SIGNAL(tier::release, e2::form::upon::started, This()); + //item->SIGNAL(tier::anycast, e2::form::upon::started, This()); return item; } // gate: Create a new item of the specified subtype and attach it. diff --git a/src/netxs/ui/events.hpp b/src/netxs/ui/events.hpp index 2d89a2271a..d65abec80c 100644 --- a/src/netxs/ui/events.hpp +++ b/src/netxs/ui/events.hpp @@ -468,7 +468,7 @@ namespace netxs::events boss.anycast.notify(event, std::forward(data)); return true; }; - return root.release.notify(userland::root::cascade, proc); + return root.release.notify(userland::root::cascade.id, proc); } } template static auto submit_global(hook& token) { return submit_helper_token_global(token); } diff --git a/src/vtmd.cpp b/src/vtmd.cpp index adb7b2b473..ff93a0b328 100644 --- a/src/vtmd.cpp +++ b/src/vtmd.cpp @@ -160,7 +160,7 @@ int main(int argc, char* argv[]) window->attach(creator(config.data)); log(" world create type=", config.type, " menu_item_id=", what.menu_item_id); world->branch(what.menu_item_id, window); - window->broadcast->SIGNAL(tier::release, e2::form::upon::started, world); + window->SIGNAL(tier::anycast, e2::form::upon::started, world); what.frame = window; }; From b0f983462571917348eab25ff7bff1d05ec36fe2 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Sun, 5 Dec 2021 22:21:17 +0500 Subject: [PATCH 04/12] UI: Broadcast architecture revision --- src/netxs/apps/tile.hpp | 27 ++-------------- src/netxs/console/console.hpp | 61 ++++------------------------------- src/netxs/ui/events.hpp | 17 +++------- 3 files changed, 12 insertions(+), 93 deletions(-) diff --git a/src/netxs/apps/tile.hpp b/src/netxs/apps/tile.hpp index 011a2767ae..5518942b9a 100644 --- a/src/netxs/apps/tile.hpp +++ b/src/netxs/apps/tile.hpp @@ -97,27 +97,6 @@ namespace netxs::app::tile namespace { - auto bcast_onsplit = [](auto& boss) - { - boss.SUBMIT(tier::release, e2::form::upon::vtree::attached, parent) - { - auto parent_memo = std::make_shared(); - auto shadow = ptr::shadow(boss.This()); - parent->SUBMIT_T_BYVAL(tier::anycast, app::tile::events::ui::any, *parent_memo, gear) - { - if (auto master = shadow.lock()) - if (auto parent = master->parent()) - if (auto action = parent->bell::template protos()) //todo "template" keyword is required by FreeBSD clang 11.0.1 - { - master->bell::template signal(action, gear); - } - }; - boss.SUBMIT_T_BYVAL(tier::release, e2::form::upon::vtree::detached, *parent_memo, parent) - { - parent_memo.reset(); - }; - }; - }; auto bcast_forward = [](auto& boss) { boss.SUBMIT(tier::release, e2::form::upon::vtree::attached, parent) @@ -177,7 +156,6 @@ namespace netxs::app::tile boss.SUBMIT_T_BYVAL(tier::release, e2::form::upon::vtree::detached, *parent_memo, parent) { parent_memo.reset(); - //parent_bcast_memo.reset(); }; }; }; @@ -249,12 +227,11 @@ namespace netxs::app::tile { auto node = tag == 'h' ? ui::fork::ctor(axis::X, w == -1 ? 2 : w, s1, s2) : ui::fork::ctor(axis::Y, w == -1 ? 1 : w, s1, s2); - node->isroot(true, 1) // Set object kind to 1 to be different from others. See empty_slot::select. + node->isroot(faux, 1) // Set object kind to 1 to be different from others. See empty_slot::select. ->template plugin(dot_00) ->invoke([&](auto& boss) { mouse_actions(boss); - bcast_onsplit(boss); boss.SUBMIT(tier::release, app::tile::events::ui::swap , gear) { boss.swap(); }; boss.SUBMIT(tier::release, app::tile::events::ui::rotate , gear) { boss.rotate(); }; boss.SUBMIT(tier::release, app::tile::events::ui::equalize, gear) { boss.config(1, 1); }; @@ -879,7 +856,7 @@ namespace netxs::app::tile boss.SIGNAL(tier::anycast, app::tile::events::ui::toggle, gear); gear.state(gear_state); } - boss.bell::template signal(deed, gear); + //boss.bell::template signal(deed, gear); } }; }); diff --git a/src/netxs/console/console.hpp b/src/netxs/console/console.hpp index 9bdc0739e3..cce633356b 100644 --- a/src/netxs/console/console.hpp +++ b/src/netxs/console/console.hpp @@ -113,8 +113,6 @@ namespace netxs::events::userland EVENT_XS( fps , iota ), // request to set new fps, arg: new fps (iota); the value == -1 is used to request current fps. GROUP_XS( caret , period ), // any kind of intervals property. GROUP_XS( plugins , iota ), - //todo deprecated - GROUP_XS( broadcast, sptr ), // release: broadcast source changed. SUBSET_XS( caret ) { @@ -132,12 +130,6 @@ namespace netxs::events::userland EVENT_XS( outer, dent ), // release: set outer size; request: request outer size. }; }; - //todo deprecated - SUBSET_XS( broadcast ) - { - EVENT_XS( attached, sptr ), // release: broadcast source changed when attached. - EVENT_XS( reinit , sptr ), // release: broadcast source changed when detached. - }; }; SUBSET_XS( conio ) { @@ -866,28 +858,10 @@ namespace netxs::console iota object_kind = {}; public: - //todo deprecated - subs bcastsubs; - //todo deprecated - sptr broadcast = std::make_shared(); // base: Broadcast bus. - // On attach the broadcast is merged with parent (bell::merge). - // On detach the broadcast is duplicated from parent (bell::reset). side oversz; // base: Oversize, margin. twod anchor; // base: Object balance point. Center point for any transform (on preview). protected: - bool is_attached() const { return kb_token.operator bool(); } - - //todo deprecated - void switch_to_bus(sptr parent_bus) - { - if (parent_bus != broadcast) // Reattaching is allowed within the same visual tree. - { - parent_bus->merge(broadcast); - broadcast->SIGNAL(tier::release, e2::config::broadcast::attached, parent_bus); - } - } - virtual ~base() = default; base() { @@ -898,34 +872,19 @@ namespace netxs::console SUBMIT(tier::release, e2::size::set, new_size) { square.size = new_size; }; SUBMIT(tier::request, e2::size::set, size_var) { size_var = square.size; }; - //todo deprecated - //SUBMIT_T(tier::release, e2::config::broadcast::reinit, bell::tracker, old_broadcast) - SUBMIT_AND_RUN(tier::release, e2::config::broadcast::reinit, bcast, this->broadcast) + SUBMIT(tier::release, e2::cascade, proc) { - bcast->SUBMIT_T(tier::release, e2::config::broadcast::attached, bcastsubs, new_broadcast) - { - broadcast = new_broadcast; - }; + auto keepon = proc(*this); + //if (keepon) + //... }; - /* - * Only visual_root can be reattached multiple times! - */ SUBMIT(tier::release, e2::form::upon::vtree::attached, parent_ptr) { if (!visual_root) { parent_ptr->SUBMIT_T(tier::release, e2::cascade, cascade_token, proc) { - auto keepon = proc(*this); - if (keepon) this->SIGNAL(tier::release, e2::cascade, proc); - }; - - //todo deprecated - auto bcast_backup = broadcast; - base::switch_to_bus(parent_ptr->base::broadcast); - parent_ptr->SUBMIT_T(tier::release, e2::config::broadcast::reinit, bcastsubs, broadcast) - { - this->SIGNAL(tier::release, e2::config::broadcast::reinit, broadcast); + this->SIGNAL(tier::release, e2::cascade, proc); }; } parent_shadow = parent_ptr; @@ -956,15 +915,6 @@ namespace netxs::console { kb_token.reset(); cascade_token.reset(); - //todo revise - //parent_shadow.reset(); - if (!visual_root) - { - //todo deprecated - bcastsubs.clear(); - broadcast = std::make_shared(); - this->SIGNAL(tier::release, e2::config::broadcast::reinit, broadcast); - } } if (parent_ptr) parent_ptr->base::reflow(); //todo too expensive }; @@ -3562,6 +3512,7 @@ namespace netxs::console }; boss.SUBMIT_T(tier::release, e2::form::state::keybd::got, memo, gear) { + log(" boss.id=", boss.id); pool.push_back(gear.id); boss.base::deface(); }; diff --git a/src/netxs/ui/events.hpp b/src/netxs/ui/events.hpp index d65abec80c..b6982417a7 100644 --- a/src/netxs/ui/events.hpp +++ b/src/netxs/ui/events.hpp @@ -317,6 +317,7 @@ namespace netxs::events #define SIGNAL_GLOBAL( event, param) bell::template signal_global(decltype( event )::id, static_cast(param)) #define SUBMIT_GLOBAL( event, token, param) bell::template submit_global( token ) = [&] (typename decltype( event )::type && param) + //todo deprecated? #define SUBMIT_AND_RUN_T(level, event, token, param, arg) bell::template submit2( arg, token ) = [&] (typename decltype( event )::type && param) #define SUBMIT_AND_RUN( level, event, param, arg) bell::template submit2( arg ) = [&] (typename decltype( event )::type && param) @@ -369,7 +370,7 @@ namespace netxs::events rev_reactor preview; rev_reactor anycast; - //todo deprecated + //todo deprecated? template struct submit_helper2 { @@ -379,7 +380,7 @@ namespace netxs::events submit_helper2(bell& owner, type& p) : owner{ owner }, p{p} { } template void operator=(F h) { owner.submit(h); h(static_cast(p)); } }; - //todo deprecated + //todo deprecated? template struct submit_helper2_token { @@ -418,17 +419,7 @@ namespace netxs::events }; public: - //todo deprecated - void merge(sptr source_ptr) - { - auto& s = *source_ptr; - tracker.merge(s.tracker); //todo deprecate tokens copying - preview.merge(s.preview); - request.merge(s.request); - release.merge(s.release); - } - - //todo deprecated + //todo deprecated? template auto submit2(typename EVENT::type & p) { return submit_helper2 (*this, p); } template auto submit2(typename EVENT::type & p, subs& tokens) { return submit_helper2_token(*this, p, tokens.extra()); } From 6428d6b2850781f74a1dc8ffc6f84ab8d6c26d58 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Mon, 6 Dec 2021 10:43:27 +0500 Subject: [PATCH 05/12] UI: Broadcast architecture revision --- src/netxs/apps/tile.hpp | 51 +++++------ src/netxs/console/console.hpp | 162 +++++++++++++++++----------------- src/netxs/ui/events.hpp | 12 +-- 3 files changed, 109 insertions(+), 116 deletions(-) diff --git a/src/netxs/apps/tile.hpp b/src/netxs/apps/tile.hpp index 5518942b9a..8350786e1f 100644 --- a/src/netxs/apps/tile.hpp +++ b/src/netxs/apps/tile.hpp @@ -343,20 +343,17 @@ namespace netxs::app::tile boss.SUBMIT(tier::anycast, app::tile::events::ui::select, gear) { auto& item =*boss.back(); - if (item.base::root()) + if (item.base::kind() != 1) { - if (item.base::kind() != 1) - { - //todo unify - gear.force_group_focus = true; - gear.kb_focus_taken = faux; - gear.combine_focus = true; - item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); - gear.combine_focus = faux; - gear.force_group_focus = faux; - } - else item.SIGNAL(tier::release, hids::events::upevent::kbannul, gear); // Exclude grips. + //todo unify + gear.force_group_focus = true; + gear.kb_focus_taken = faux; + gear.combine_focus = true; + item.SIGNAL(tier::release, hids::events::upevent::kboffer, gear); + gear.combine_focus = faux; + gear.force_group_focus = faux; } + else item.SIGNAL(tier::release, hids::events::upevent::kbannul, gear); // Exclude grips. }; boss.SUBMIT_BYVAL(tier::release, e2::form::maximize, gear) { @@ -425,25 +422,21 @@ namespace netxs::app::tile log(" depth=", depth); if (depth > INHERITANCE_LIMIT) return; - if (boss.back()->base::root()) + auto heading = deed == app::tile::events::ui::split::vt.id; + auto newnode = built_node(heading ? 'v':'h', 1, 1, heading ? 1 : 2); + auto empty_1 = empty_slot(empty_slot); + auto empty_2 = empty_slot(empty_slot); + auto curitem = boss.pop_back(); // In order to preserve all foci. + gate_ptr->SIGNAL(tier::preview, e2::form::proceed::focus, empty_1); + gate_ptr->SIGNAL(tier::preview, e2::form::proceed::unfocus, curitem); + if (boss.empty()) { - auto heading = deed == app::tile::events::ui::split::vt.id; - auto newnode = built_node(heading ? 'v':'h', 1, 1, heading ? 1 : 2); - auto empty_1 = empty_slot(empty_slot); - auto empty_2 = empty_slot(empty_slot); - auto curitem = boss.pop_back(); // In order to preserve all foci. - gate_ptr->SIGNAL(tier::preview, e2::form::proceed::focus, empty_1); - gate_ptr->SIGNAL(tier::preview, e2::form::proceed::unfocus, curitem); - if (boss.empty()) - { - boss.attach(place_holder()); - empty_2->pop_back(); - } - auto slot_1 = newnode->attach(slot::_1, empty_1); - auto slot_2 = newnode->attach(slot::_2, empty_2->branch(curitem)); - boss.attach(newnode); + boss.attach(place_holder()); + empty_2->pop_back(); } - else log(" empty_slot split: defective structure, count=", boss.count()); + auto slot_1 = newnode->attach(slot::_1, empty_1); + auto slot_2 = newnode->attach(slot::_2, empty_2->branch(curitem)); + boss.attach(newnode); } } } diff --git a/src/netxs/console/console.hpp b/src/netxs/console/console.hpp index cce633356b..39ea78cad8 100644 --- a/src/netxs/console/console.hpp +++ b/src/netxs/console/console.hpp @@ -861,85 +861,6 @@ namespace netxs::console side oversz; // base: Oversize, margin. twod anchor; // base: Object balance point. Center point for any transform (on preview). - protected: - virtual ~base() = default; - base() - { - SUBMIT(tier::request, e2::depth, depth) { depth++; }; - - SUBMIT(tier::release, e2::coor::set, new_coor) { square.coor = new_coor; }; - SUBMIT(tier::request, e2::coor::set, coor_var) { coor_var = square.coor; }; - SUBMIT(tier::release, e2::size::set, new_size) { square.size = new_size; }; - SUBMIT(tier::request, e2::size::set, size_var) { size_var = square.size; }; - - SUBMIT(tier::release, e2::cascade, proc) - { - auto keepon = proc(*this); - //if (keepon) - //... - }; - SUBMIT(tier::release, e2::form::upon::vtree::attached, parent_ptr) - { - if (!visual_root) - { - parent_ptr->SUBMIT_T(tier::release, e2::cascade, cascade_token, proc) - { - this->SIGNAL(tier::release, e2::cascade, proc); - }; - } - parent_shadow = parent_ptr; - // Propagate form events up to the visual branch. - // Exec after all subscriptions. - //todo implement via e2::cascade - parent_ptr->SUBMIT_T(tier::release, hids::events::upevent::any, kb_token, gear) - { - if (auto parent_ptr = parent_shadow.lock()) - { - if (gear.focus_taken()) //todo unify, upevent::kbannul using it - { - parent_ptr->bell::expire(); - } - else - { - if (auto deed = parent_ptr->bell::protos()) - { - this->bell::signal(deed, gear); - } - } - } - }; - }; - SUBMIT(tier::release, e2::form::upon::vtree::any, parent_ptr) - { - if (this->bell::protos(e2::form::upon::vtree::detached)) - { - kb_token.reset(); - cascade_token.reset(); - } - if (parent_ptr) parent_ptr->base::reflow(); //todo too expensive - }; - - // Propagate form events down to the visual branch. - // Exec after all subscriptions. - SUBMIT(tier::release, hids::events::notify::any, gear) - { - if (auto parent_ptr = parent_shadow.lock()) - { - if (auto deed = this->bell::protos()) - { - parent_ptr->bell::signal(deed, gear); - } - } - //strike(); - }; - SUBMIT(tier::release, e2::render::any, parent_canvas) - { - if (base::brush.wdt()) - parent_canvas.fill([&](cell& c) { c.fusefull(base::brush); }); - }; - } - - public: template auto This() { return std::static_pointer_cast>(shared_from_this()); } auto& coor() const { return square.coor; } @@ -1089,11 +1010,11 @@ namespace netxs::console } } // base: Recursively find the root of the visual tree. - bell& gettop() override + sptr gettop() override { auto parent_ptr = parent(); if (!visual_root && parent_ptr) return parent_ptr->gettop(); - else return *this; + else return This(); } // base: Invoke a lambda with parent as a parameter. // Usage example: @@ -1131,6 +1052,85 @@ namespace netxs::console } } } + + protected: + virtual ~base() = default; + base() + { + SUBMIT(tier::request, e2::depth, depth) { depth++; }; + + SUBMIT(tier::release, e2::coor::set, new_coor) { square.coor = new_coor; }; + SUBMIT(tier::request, e2::coor::set, coor_var) { coor_var = square.coor; }; + SUBMIT(tier::release, e2::size::set, new_size) { square.size = new_size; }; + SUBMIT(tier::request, e2::size::set, size_var) { size_var = square.size; }; + + SUBMIT(tier::release, e2::cascade, proc) + { + auto backup = This(); + auto keepon = proc(backup); + if (!keepon) this->bell::expire(); + }; + SUBMIT(tier::release, e2::form::upon::vtree::attached, parent_ptr) + { + if (!visual_root) + { + parent_ptr->SUBMIT_T(tier::release, e2::cascade, cascade_token, proc) + { + auto backup = This(); + backup->SIGNAL(tier::release, e2::cascade, proc); + }; + } + parent_shadow = parent_ptr; + // Propagate form events up to the visual branch. + // Exec after all subscriptions. + //todo implement via e2::cascade + parent_ptr->SUBMIT_T(tier::release, hids::events::upevent::any, kb_token, gear) + { + if (auto parent_ptr = parent_shadow.lock()) + { + if (gear.focus_taken()) //todo unify, upevent::kbannul using it + { + parent_ptr->bell::expire(); + } + else + { + if (auto deed = parent_ptr->bell::protos()) + { + this->bell::signal(deed, gear); + } + } + } + }; + }; + SUBMIT(tier::release, e2::form::upon::vtree::any, parent_ptr) + { + if (this->bell::protos(e2::form::upon::vtree::detached)) + { + kb_token.reset(); + cascade_token.reset(); + } + if (parent_ptr) parent_ptr->base::reflow(); //todo too expensive + }; + + // Propagate form events down to the visual branch. + // Exec after all subscriptions. + SUBMIT(tier::release, hids::events::notify::any, gear) + { + if (auto parent_ptr = parent_shadow.lock()) + { + if (auto deed = this->bell::protos()) + { + parent_ptr->bell::signal(deed, gear); + } + } + //strike(); + }; + SUBMIT(tier::release, e2::render::any, parent_canvas) + { + if (base::brush.wdt()) + parent_canvas.fill([&](cell& c) { c.fusefull(base::brush); }); + }; + } }; // console: Template modules for the base class behavior extension. diff --git a/src/netxs/ui/events.hpp b/src/netxs/ui/events.hpp index b6982417a7..c36b6aaea8 100644 --- a/src/netxs/ui/events.hpp +++ b/src/netxs/ui/events.hpp @@ -332,7 +332,7 @@ namespace netxs::events private: static constexpr auto _dummy = { 777 class bell; - using ftor = std::function; + using ftor = std::function)>; //todo unify seeding namespace userland @@ -453,13 +453,13 @@ namespace netxs::events else if constexpr (TIER == tier::release) return release.notify(event, std::forward(data)); else /* TIER == tier::anycast */ { - auto& root = gettop(); - ftor proc = [&](bell& boss) -> bool + auto root = gettop(); + ftor proc = [&](auto boss_ptr) -> bool { - boss.anycast.notify(event, std::forward(data)); + boss_ptr->anycast.notify(event, std::forward(data)); return true; }; - return root.release.notify(userland::root::cascade.id, proc); + return root->release.notify(userland::root::cascade.id, proc); } } template static auto submit_global(hook& token) { return submit_helper_token_global(token); } @@ -497,7 +497,7 @@ namespace netxs::events ~bell() { sync lock; SIGNAL(tier::release, userland::root::dtor, id); } virtual void global(twod& coor) { } // bell: Recursively calculate global coordinate. - virtual bell& gettop() { return *this; } // bell: Recursively find the root of the visual tree. + virtual sptr gettop() { return sptr(this, noop{}); } // bell: Recursively find the root of the visual tree. }; template bell::fwd_reactor bell::_globals::general; From 397ab80546c75b998ece5afb89537c9c74a581a8 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Mon, 6 Dec 2021 10:51:05 +0500 Subject: [PATCH 06/12] UI: Broadcast architecture revision --- src/netxs/apps/logs.hpp | 5 ++++- src/vtmd.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/netxs/apps/logs.hpp b/src/netxs/apps/logs.hpp index ab5aea748b..03f2110cc9 100644 --- a/src/netxs/apps/logs.hpp +++ b/src/netxs/apps/logs.hpp @@ -212,7 +212,10 @@ namespace netxs::app::logs break; } }; - SIGNAL(tier::anycast, events::codepoints::release, worker->show_codepoints ? 1 : 2); + SUBMIT(tier::anycast, e2::form::upon::started, root) + { + this->SIGNAL(tier::anycast, events::codepoints::release, worker->show_codepoints ? 1 : 2); + }; SUBMIT(tier::preview, e2::size::set, newsize) { caret.coor(flow::cp()); diff --git a/src/vtmd.cpp b/src/vtmd.cpp index ff93a0b328..4c4fce7c4f 100644 --- a/src/vtmd.cpp +++ b/src/vtmd.cpp @@ -4,7 +4,7 @@ #define MONOTTY_VER "Monotty Desktopio v0.5.9999b" // Enable demo apps and assign Esc key to log off. -//#define DEMO +#define DEMO // Enable keyboard input and unassign Esc key. #define PROD From 3228e11b0aa97e0d4c5dafd7e1b74338bbba482e Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Mon, 6 Dec 2021 11:28:44 +0500 Subject: [PATCH 07/12] UI: Broadcast architecture revision --- src/CMakeSettings.json | 2 +- src/netxs/apps.hpp | 8 ++++---- src/netxs/apps/term.hpp | 14 +++----------- src/netxs/os/system.hpp | 10 +++++++--- src/vtmd.cpp | 4 ++-- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/CMakeSettings.json b/src/CMakeSettings.json index 42cd91435c..782337c06a 100644 --- a/src/CMakeSettings.json +++ b/src/CMakeSettings.json @@ -11,7 +11,7 @@ "buildCommandArgs": "-v", "ctestCommandArgs": "", "inheritEnvironments": [ "linux_x64" ], - "wslPath": "${defaultWSLPath}", + "wslPath": "C:\\Users\\sdn\\AppData\\Local\\Microsoft\\WindowsApps\\ubuntu1804.exe", "addressSanitizerRuntimeFlags": "detect_leaks=0", "remoteCopyUseCompilerDefaults": true, "intelliSenseMode": "linux-gcc-x64", diff --git a/src/netxs/apps.hpp b/src/netxs/apps.hpp index 8c219b64fb..be7fecae6c 100644 --- a/src/netxs/apps.hpp +++ b/src/netxs/apps.hpp @@ -28,15 +28,15 @@ namespace netxs::app::shared X(Shop , "Shop" , ("Desktopio App Store") , "" ) \ X(Logs , "Logs" , ("Logs \nDebug output console") , "" ) \ X(View , "View" , (ansi::jet(bias::center).add("View \n Region 1")) , "" ) \ - X(Tile , "Tile" , ("Tiling Window Manager") , "VTM_PROFILE_1=\"Tile\", \"Tiling Window Manager\", h()" ) \ + X(Tile , "Tile" , ("Tiling Window Manager") , "VTM_PROFILE_1=\"Tile\", \"Tiling Window Manager\", h(a(\"Term\" ,\"\" ,\"\"), a(\"Term\" ,\"\" ,\"\"))" ) \ X(Settings , "Settings" , ("Settings: Frame Rate Limit") , "" ) \ - X(PowerShell , "pwsh PowerShell" , ("Term \nPowerShell") , "" ) \ - X(CommandPrompt, "cmd Command Prompt" , ("Term \nCommand Prompt") , "" ) \ + X(PowerShell , "PowerShell" , ("Term \nPowerShell") , "" ) \ + X(CommandPrompt, "Command Prompt" , ("Term \nCommand Prompt") , "" ) \ X(Bash , "Bash/Zsh/CMD" , ("Term \nBash/Zsh/CMD") , "" ) \ X(Far , "Far Manager" , ("Term \nFar Manager") , "" ) \ X(VTM , "vtm (recursively)" , ("Term \nvtm (recursively)") , "" ) \ X(MC , "mc Midnight Commander", ("Term \nMidnight Commander") , "" ) \ - X(Truecolor , "RGB Truecolor image" , (ansi::jet(bias::right).add("True color ANSI/ASCII image test")), "" ) \ + X(Truecolor , "Truecolor image" , (ansi::jet(bias::right).add("True color ANSI/ASCII image test")), "" ) \ X(Strobe , "Strobe" , (ansi::jet(bias::center).add("Strobe")) , "" ) \ X(Test , "Test Window" , (ansi::jet(bias::center).add("Test Page")) , "" ) \ X(Empty , "Empty Window" , (ansi::mgl(1).mgr(1).add("Empty Instance \nid: ")) , "" ) diff --git a/src/netxs/apps/term.hpp b/src/netxs/apps/term.hpp index b42ec8d993..fcd910304c 100644 --- a/src/netxs/apps/term.hpp +++ b/src/netxs/apps/term.hpp @@ -173,17 +173,9 @@ namespace netxs::app::term { scroll->plugin(twod{ 10,1 }); // mc crashes when window is too small - #if defined(_WIN32) - - auto inst = scroll->attach(ui::term::ctor("cmd")); - - #else - - auto shell = os::get_shell(); - auto inst = scroll->attach(ui::term::ctor(shell + " -i")); - - #endif - + auto shell = os::get_shell(); + auto inst = scroll->attach(ui::term::ctor(v.empty() ? shell + " -i" + : text{ v })); inst->colors(whitelt, blackdk) ->invoke([](auto& boss) { diff --git a/src/netxs/os/system.hpp b/src/netxs/os/system.hpp index 51d5cfbac5..6921a9367e 100644 --- a/src/netxs/os/system.hpp +++ b/src/netxs/os/system.hpp @@ -232,9 +232,13 @@ namespace netxs::os } static text get_shell() { - auto shell = os::get_env("SHELL"); - return shell.ends_with("vtm") ? "bash" - : shell; + #if defined(_WIN32) + return "cmd"; + #else + auto shell = os::get_env("SHELL"); + return shell.ends_with("vtm") ? "bash" + : shell; + #endif } //system: Get list of envvars using wildcard. static auto get_envars(text&& var) diff --git a/src/vtmd.cpp b/src/vtmd.cpp index 4c4fce7c4f..70669290fa 100644 --- a/src/vtmd.cpp +++ b/src/vtmd.cpp @@ -1,10 +1,10 @@ // Copyright (c) NetXS Group. // Licensed under the MIT license. -#define MONOTTY_VER "Monotty Desktopio v0.5.9999b" +#define MONOTTY_VER "Monotty Desktopio v0.5.9999c" // Enable demo apps and assign Esc key to log off. -#define DEMO +//#define DEMO // Enable keyboard input and unassign Esc key. #define PROD From d3b29c44d8ffb760537765f22632316997c89459 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Mon, 6 Dec 2021 11:31:33 +0500 Subject: [PATCH 08/12] Update src/CMakeSettings.json --- src/CMakeSettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeSettings.json b/src/CMakeSettings.json index 782337c06a..42cd91435c 100644 --- a/src/CMakeSettings.json +++ b/src/CMakeSettings.json @@ -11,7 +11,7 @@ "buildCommandArgs": "-v", "ctestCommandArgs": "", "inheritEnvironments": [ "linux_x64" ], - "wslPath": "C:\\Users\\sdn\\AppData\\Local\\Microsoft\\WindowsApps\\ubuntu1804.exe", + "wslPath": "${defaultWSLPath}", "addressSanitizerRuntimeFlags": "detect_leaks=0", "remoteCopyUseCompilerDefaults": true, "intelliSenseMode": "linux-gcc-x64", From df83ecb94f4f47d9d8719d6bde08214353346478 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Tue, 7 Dec 2021 00:09:09 +0500 Subject: [PATCH 09/12] WIP: Term: Support custom palette --- src/netxs/abstract/ring.hpp | 2 -- src/netxs/console/ansi.hpp | 54 +++++++++++++++++++++++++++++----- src/netxs/console/richtext.hpp | 1 - src/netxs/console/terminal.hpp | 12 ++++++++ src/netxs/math/intmath.hpp | 1 + 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/netxs/abstract/ring.hpp b/src/netxs/abstract/ring.hpp index 12638bebe3..277a69250d 100644 --- a/src/netxs/abstract/ring.hpp +++ b/src/netxs/abstract/ring.hpp @@ -6,8 +6,6 @@ #include "../math/intmath.hpp" -#include - namespace netxs::generics { template diff --git a/src/netxs/console/ansi.hpp b/src/netxs/console/ansi.hpp index 4617b8ef17..a5860e387c 100644 --- a/src/netxs/console/ansi.hpp +++ b/src/netxs/console/ansi.hpp @@ -128,13 +128,20 @@ namespace netxs::ansi static const iota W32_FOCUS_EVENT = 10004; static const iota W32_FINAL_EVENT = 10005; // for quick recognition. - static const auto OSC_LABEL_TITLE = "0" ; // Set icon label and title. - static const auto OSC_LABEL = "1" ; // Set icon label. - static const auto OSC_TITLE = "2" ; // Set title. - static const auto OSC_XPROP = "3" ; // Set xprop. - static const auto OSC_CLIPBRD = "52"; // Set clipboard. - static const auto OSC_TITLE_REPORT = "l" ; // Get terminal window title. - static const auto OSC_LABEL_REPORT = "L" ; // Get terminal window icon label. + static const auto OSC_LABEL_TITLE = "0" ; // Set icon label and title. + static const auto OSC_LABEL = "1" ; // Set icon label. + static const auto OSC_TITLE = "2" ; // Set title. + static const auto OSC_XPROP = "3" ; // Set xprop. + static const auto OSC_LINUX_COLOR = "P" ; // Set 16/256 colors palette. (Linux console) + static const auto OSC_SET_PALETTE = "4" ; // Set 16/256 colors palette. + static const auto OSC_SET_FGCOLOR = "10" ; // Set fg color. + static const auto OSC_SET_BGCOLOR = "11" ; // Set bg color. + static const auto OSC_RESET_COLOR = "104" ; // Reset color N to default palette. Without params all palette reset. + static const auto OSC_RESET_FGCLR = "110" ; // Reset fg color to default. + static const auto OSC_RESET_BGCLR = "111" ; // Reset bg color to default. + static const auto OSC_CLIPBRD = "52" ; // Set clipboard. + static const auto OSC_TITLE_REPORT = "l" ; // Get terminal window title. + static const auto OSC_LABEL_REPORT = "L" ; // Get terminal window icon label. static const iota SGR_RST = 0; static const iota SGR_SAV = 10; @@ -1251,10 +1258,28 @@ namespace netxs::ansi // ESC ] I ; _text_ ST Set icon to file. // ESC ] l ; _text_ ST Set window title. // ESC ] L ; _text_ ST Set window icon label. + // + // ESC ] P Nrrggbb Set N (hex) of 16color palette to rrggbb (hex). // Find ST and ';', if no ST or no ';' when drop if (ascii) { + if (ascii.front() == 'P') // OSC_LINUX_COLOR Set linux console 16 colors palette. + { + assert(ascii.length() >= 8); + auto& oscer = _glb::vt_parser.oscer; + text cmd = OSC_LINUX_COLOR; + if (auto it = oscer.find(cmd); it != oscer.end()) + { + auto size = 7; // Nrrggbb + auto data = ascii.substr(1, size); + auto proc = (*it).second; + proc(data, client); + } + ascii.remove_prefix(8); // PNrrggbb + return; + } + auto base = ascii.data(); auto head = base; auto tail = head + ascii.length(); @@ -1521,6 +1546,21 @@ namespace netxs::ansi // test OSC: ESC ] ... BEL else if (c == ']') { + // test OSC: ESC ] P Nrrggbb + auto step = start + 1; + if (step < crop.size() && crop[step] == 'P') + { + if (crop.size() < step + 8) + { + crop = crop.substr(0, size); + } + else + { + utf::purify(crop); + } + return crop; + } + // find BEL while (++start < crop.size()) { diff --git a/src/netxs/console/richtext.hpp b/src/netxs/console/richtext.hpp index 009fbfa060..b903df5492 100644 --- a/src/netxs/console/richtext.hpp +++ b/src/netxs/console/richtext.hpp @@ -8,7 +8,6 @@ #include "../text/logger.hpp" #include "../abstract/ring.hpp" -#include #include namespace netxs::console diff --git a/src/netxs/console/terminal.hpp b/src/netxs/console/terminal.hpp index 69c6717774..5d8dc19902 100644 --- a/src/netxs/console/terminal.hpp +++ b/src/netxs/console/terminal.hpp @@ -481,6 +481,13 @@ namespace netxs::ui vt.oscer[OSC_LABEL] = VT_PROC{ p->owner.wtrack.set(OSC_LABEL, q); }; vt.oscer[OSC_TITLE] = VT_PROC{ p->owner.wtrack.set(OSC_TITLE, q); }; vt.oscer[OSC_XPROP] = VT_PROC{ p->owner.wtrack.set(OSC_XPROP, q); }; + vt.oscer[OSC_LINUX_COLOR] = VT_PROC{ p->owner.set_colors(OSC_LINUX_COLOR, q); }; + vt.oscer[OSC_SET_PALETTE] = VT_PROC{ p->owner.set_colors(OSC_SET_PALETTE, q); }; + vt.oscer[OSC_SET_FGCOLOR] = VT_PROC{ p->owner.set_colors(OSC_SET_FGCOLOR, q); }; + vt.oscer[OSC_SET_BGCOLOR] = VT_PROC{ p->owner.set_colors(OSC_SET_BGCOLOR, q); }; + vt.oscer[OSC_RESET_COLOR] = VT_PROC{ p->owner.set_colors(OSC_RESET_COLOR, q); }; + vt.oscer[OSC_RESET_FGCLR] = VT_PROC{ p->owner.set_colors(OSC_RESET_FGCLR, q); }; + vt.oscer[OSC_RESET_BGCLR] = VT_PROC{ p->owner.set_colors(OSC_RESET_BGCLR, q); }; // Log all unimplemented CSI commands. for (auto i = 0; i < 0x100; ++i) @@ -3355,6 +3362,11 @@ namespace netxs::ui } } + void set_colors(text const& property, view txt) + { + log(" OSC=", property, " DATA=", txt, " HEX=", utf::to_hex(txt)); + } + public: void exec_cmd(commands::ui::commands cmd) { diff --git a/src/netxs/math/intmath.hpp b/src/netxs/math/intmath.hpp index bd10fa05d9..113b2c382f 100644 --- a/src/netxs/math/intmath.hpp +++ b/src/netxs/math/intmath.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #ifndef faux #define faux (false) From f4b1b5b999c063c09df18a0c77d799c41cee9d85 Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Tue, 7 Dec 2021 01:23:58 +0500 Subject: [PATCH 10/12] WIP: Term: Support custom palette (OSC P) --- src/netxs/console/ansi.hpp | 4 +-- src/netxs/console/terminal.hpp | 64 ++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/netxs/console/ansi.hpp b/src/netxs/console/ansi.hpp index a5860e387c..913e0d1265 100644 --- a/src/netxs/console/ansi.hpp +++ b/src/netxs/console/ansi.hpp @@ -132,8 +132,8 @@ namespace netxs::ansi static const auto OSC_LABEL = "1" ; // Set icon label. static const auto OSC_TITLE = "2" ; // Set title. static const auto OSC_XPROP = "3" ; // Set xprop. - static const auto OSC_LINUX_COLOR = "P" ; // Set 16/256 colors palette. (Linux console) - static const auto OSC_SET_PALETTE = "4" ; // Set 16/256 colors palette. + static const auto OSC_LINUX_COLOR = "P" ; // Set 16 colors palette. (Linux console) + static const auto OSC_SET_PALETTE = "4" ; // Set 256 colors palette. static const auto OSC_SET_FGCOLOR = "10" ; // Set fg color. static const auto OSC_SET_BGCOLOR = "11" ; // Set bg color. static const auto OSC_RESET_COLOR = "104" ; // Reset color N to default palette. Without params all palette reset. diff --git a/src/netxs/console/terminal.hpp b/src/netxs/console/terminal.hpp index 5d8dc19902..6bcc3add35 100644 --- a/src/netxs/console/terminal.hpp +++ b/src/netxs/console/terminal.hpp @@ -421,6 +421,39 @@ namespace netxs::ui vt.csier.table_hash [CSI_HSH_RCP] = VT_PROC{ p->na("CSI n # Q Pop current palette colors onto stack. n default is 0."); }; // CSI n # Q Pop current palette colors onto stack. n default is 0. vt.csier.table_excl [CSI_EXL_RST] = VT_PROC{ p->owner.decstr( ); }; // CSI ! p Soft terminal reset (DECSTR) + vt.csier.table[CSI_SGR][SGR_FG_BLK ] = VT_PROC{ p->owner.fgc(tint::blackdk ); }; + vt.csier.table[CSI_SGR][SGR_FG_RED ] = VT_PROC{ p->owner.fgc(tint::reddk ); }; + vt.csier.table[CSI_SGR][SGR_FG_GRN ] = VT_PROC{ p->owner.fgc(tint::greendk ); }; + vt.csier.table[CSI_SGR][SGR_FG_YLW ] = VT_PROC{ p->owner.fgc(tint::yellowdk ); }; + vt.csier.table[CSI_SGR][SGR_FG_BLU ] = VT_PROC{ p->owner.fgc(tint::bluedk ); }; + vt.csier.table[CSI_SGR][SGR_FG_MGT ] = VT_PROC{ p->owner.fgc(tint::magentadk); }; + vt.csier.table[CSI_SGR][SGR_FG_CYN ] = VT_PROC{ p->owner.fgc(tint::cyandk ); }; + vt.csier.table[CSI_SGR][SGR_FG_WHT ] = VT_PROC{ p->owner.fgc(tint::whitedk ); }; + vt.csier.table[CSI_SGR][SGR_FG_BLK_LT] = VT_PROC{ p->owner.fgc(tint::blacklt ); }; + vt.csier.table[CSI_SGR][SGR_FG_RED_LT] = VT_PROC{ p->owner.fgc(tint::redlt ); }; + vt.csier.table[CSI_SGR][SGR_FG_GRN_LT] = VT_PROC{ p->owner.fgc(tint::greenlt ); }; + vt.csier.table[CSI_SGR][SGR_FG_YLW_LT] = VT_PROC{ p->owner.fgc(tint::yellowlt ); }; + vt.csier.table[CSI_SGR][SGR_FG_BLU_LT] = VT_PROC{ p->owner.fgc(tint::bluelt ); }; + vt.csier.table[CSI_SGR][SGR_FG_MGT_LT] = VT_PROC{ p->owner.fgc(tint::magentalt); }; + vt.csier.table[CSI_SGR][SGR_FG_CYN_LT] = VT_PROC{ p->owner.fgc(tint::cyanlt ); }; + vt.csier.table[CSI_SGR][SGR_FG_WHT_LT] = VT_PROC{ p->owner.fgc(tint::whitelt ); }; + vt.csier.table[CSI_SGR][SGR_BG_BLK ] = VT_PROC{ p->owner.bgc(tint::blackdk ); }; + vt.csier.table[CSI_SGR][SGR_BG_RED ] = VT_PROC{ p->owner.bgc(tint::reddk ); }; + vt.csier.table[CSI_SGR][SGR_BG_GRN ] = VT_PROC{ p->owner.bgc(tint::greendk ); }; + vt.csier.table[CSI_SGR][SGR_BG_YLW ] = VT_PROC{ p->owner.bgc(tint::yellowdk ); }; + vt.csier.table[CSI_SGR][SGR_BG_BLU ] = VT_PROC{ p->owner.bgc(tint::bluedk ); }; + vt.csier.table[CSI_SGR][SGR_BG_MGT ] = VT_PROC{ p->owner.bgc(tint::magentadk); }; + vt.csier.table[CSI_SGR][SGR_BG_CYN ] = VT_PROC{ p->owner.bgc(tint::cyandk ); }; + vt.csier.table[CSI_SGR][SGR_BG_WHT ] = VT_PROC{ p->owner.bgc(tint::whitedk ); }; + vt.csier.table[CSI_SGR][SGR_BG_BLK_LT] = VT_PROC{ p->owner.bgc(tint::blacklt ); }; + vt.csier.table[CSI_SGR][SGR_BG_RED_LT] = VT_PROC{ p->owner.bgc(tint::redlt ); }; + vt.csier.table[CSI_SGR][SGR_BG_GRN_LT] = VT_PROC{ p->owner.bgc(tint::greenlt ); }; + vt.csier.table[CSI_SGR][SGR_BG_YLW_LT] = VT_PROC{ p->owner.bgc(tint::yellowlt ); }; + vt.csier.table[CSI_SGR][SGR_BG_BLU_LT] = VT_PROC{ p->owner.bgc(tint::bluelt ); }; + vt.csier.table[CSI_SGR][SGR_BG_MGT_LT] = VT_PROC{ p->owner.bgc(tint::magentalt); }; + vt.csier.table[CSI_SGR][SGR_BG_CYN_LT] = VT_PROC{ p->owner.bgc(tint::cyanlt ); }; + vt.csier.table[CSI_SGR][SGR_BG_WHT_LT] = VT_PROC{ p->owner.bgc(tint::whitelt ); }; + vt.csier.table[CSI_CUU] = VT_PROC{ p->up ( q(1)); }; // CSI n A (CUU) vt.csier.table[CSI_CUD] = VT_PROC{ p->dn ( q(1)); }; // CSI n B (CUD) vt.csier.table[CSI_CUF] = VT_PROC{ p->cuf( q(1)); }; // CSI n C (CUF) @@ -3074,6 +3107,7 @@ namespace netxs::ui }; using buffer_ptr = bufferbase*; + using palette_t = std::remove_const_t; pro::caret cursor; // term: Text cursor controller. term_state status; // term: Screen buffer status info. @@ -3091,6 +3125,8 @@ namespace netxs::ui bool active; // term: Terminal lifetime. bool decckm; // term: Cursor keys Application(true)/ANSI(faux) mode. bool bpmode; // term: Bracketed paste mode. + palette_t clr256; // term: Custom terminal palette. + // term: Soft terminal reset (DECSTR). void decstr() @@ -3365,7 +3401,34 @@ namespace netxs::ui void set_colors(text const& property, view txt) { log(" OSC=", property, " DATA=", txt, " HEX=", utf::to_hex(txt)); + if (property == "P") + { + if (txt.length() >= 7) + { + auto to_byte = [](char c) -> byte + { + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + return 0; + }; + auto head = txt.begin(); + auto n = to_byte(*head++); + auto r1 = to_byte(*head++); + auto r2 = to_byte(*head++); + auto g1 = to_byte(*head++); + auto g2 = to_byte(*head++); + auto b1 = to_byte(*head++); + auto b2 = to_byte(*head++); + clr256[n] = (r1 << 4 ) + (r2 ) + + (g1 << 12) + (g2 << 8 ) + + (b1 << 20) + (b2 << 16) + + 0xFF000000; + } + } } + void fgc(tint c) { target->brush.fgc(clr256[c]); } + void bgc(tint c) { target->brush.bgc(clr256[c]); } public: void exec_cmd(commands::ui::commands cmd) @@ -3436,6 +3499,7 @@ namespace netxs::ui decckm{ faux }, bpmode{ faux } { + std::copy(std::begin(rgba::color256), std::end(rgba::color256), std::begin(clr256)); cmdarg = command_line; target = &normal; //cursor.style(commands::cursor::def_style); // default=blinking_box From 6e7f51e99c60b5f59e1281474254df1abba10f0f Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Tue, 7 Dec 2021 01:56:15 +0500 Subject: [PATCH 11/12] WIP: Term: Support custom palette (OSC 104 reset color) --- src/netxs/console/terminal.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/netxs/console/terminal.hpp b/src/netxs/console/terminal.hpp index 6bcc3add35..d3b461d7e5 100644 --- a/src/netxs/console/terminal.hpp +++ b/src/netxs/console/terminal.hpp @@ -3426,6 +3426,16 @@ namespace netxs::ui + 0xFF000000; } } + else if (property == "104") + { + //todo reset the list of colors: ESC ] 104; 1; 2; 3 ST + if (auto value = utf::to_int(txt)) + { + auto n = value.value(); + clr256[n] = rgba::color256[n]; + } + else std::copy(std::begin(rgba::color256), std::end(rgba::color256), std::begin(clr256)); + } } void fgc(tint c) { target->brush.fgc(clr256[c]); } void bgc(tint c) { target->brush.bgc(clr256[c]); } From 8320e971fa224942ef8f22c72bd50c94f002624f Mon Sep 17 00:00:00 2001 From: Dmitry Sapozhnikov Date: Tue, 7 Dec 2021 18:41:59 +0500 Subject: [PATCH 12/12] WIP: Term: Support custom palette (OSC 4, OSC R) --- src/netxs/console/ansi.hpp | 38 ++++-- src/netxs/console/terminal.hpp | 242 +++++++++++++++++++++------------ src/netxs/text/utf.hpp | 9 +- 3 files changed, 194 insertions(+), 95 deletions(-) diff --git a/src/netxs/console/ansi.hpp b/src/netxs/console/ansi.hpp index 913e0d1265..86133c1f75 100644 --- a/src/netxs/console/ansi.hpp +++ b/src/netxs/console/ansi.hpp @@ -133,6 +133,7 @@ namespace netxs::ansi static const auto OSC_TITLE = "2" ; // Set title. static const auto OSC_XPROP = "3" ; // Set xprop. static const auto OSC_LINUX_COLOR = "P" ; // Set 16 colors palette. (Linux console) + static const auto OSC_LINUX_RESET = "R" ; // Reset 16/256 colors palette. (Linux console) static const auto OSC_SET_PALETTE = "4" ; // Set 256 colors palette. static const auto OSC_SET_FGCOLOR = "10" ; // Set fg color. static const auto OSC_SET_BGCOLOR = "11" ; // Set bg color. @@ -1264,10 +1265,11 @@ namespace netxs::ansi // Find ST and ';', if no ST or no ';' when drop if (ascii) { - if (ascii.front() == 'P') // OSC_LINUX_COLOR Set linux console 16 colors palette. + auto& oscer = _glb::vt_parser.oscer; + auto c = ascii.front(); + if (c == 'P') // OSC_LINUX_COLOR Set linux console 16 colors palette. { assert(ascii.length() >= 8); - auto& oscer = _glb::vt_parser.oscer; text cmd = OSC_LINUX_COLOR; if (auto it = oscer.find(cmd); it != oscer.end()) { @@ -1279,6 +1281,18 @@ namespace netxs::ansi ascii.remove_prefix(8); // PNrrggbb return; } + else if (c == 'R') // OSC_LINUX_RESET Reset linux console 16/256 colors palette. + { + text cmd = OSC_LINUX_RESET; + if (auto it = oscer.find(cmd); it != oscer.end()) + { + auto data = view{}; + auto proc = (*it).second; + proc(data, client); + } + ascii.remove_prefix(1); // R + return; + } auto base = ascii.data(); auto head = base; @@ -1286,7 +1300,6 @@ namespace netxs::ansi auto delm = tail; // Semicolon ';' position auto exec = [&](auto pad) { - auto& oscer = _glb::vt_parser.oscer; text cmd(base, delm); ++delm; auto size = head - delm; @@ -1548,17 +1561,26 @@ namespace netxs::ansi { // test OSC: ESC ] P Nrrggbb auto step = start + 1; - if (step < crop.size() && crop[step] == 'P') + if (step < crop.size()) { - if (crop.size() < step + 8) + auto c = crop[step]; + if(c == 'P') // Set linux console palette. { - crop = crop.substr(0, size); + if (crop.size() < step + 8) + { + crop = crop.substr(0, size); + } + else + { + utf::purify(crop); + } + return crop; } - else + else if(c == 'R') // Reset linux console palette. { utf::purify(crop); + return crop; } - return crop; } // find BEL diff --git a/src/netxs/console/terminal.hpp b/src/netxs/console/terminal.hpp index d3b461d7e5..706bf57e79 100644 --- a/src/netxs/console/terminal.hpp +++ b/src/netxs/console/terminal.hpp @@ -406,6 +406,121 @@ namespace netxs::ui } }; + // term: Terminal 16/256 color palette tracking functionality. + struct c_tracking + { + using pals = std::remove_const_t; + using func = std::unordered_map>; + + term& owner; // c_tracking: Terminal object reference. + pals color; // c_tracking: 16/256 colors palette. + func procs; // c_tracking: Handlers. + + void reset() + { + std::copy(std::begin(rgba::color256), std::end(rgba::color256), std::begin(color)); + } + auto to_byte(char c) + { + if (c >= '0' && c <= '9') return c - '0'; + if (c >= 'A' && c <= 'F') return c - 'A' + 10; + if (c >= 'a' && c <= 'f') return c - 'a' + 10; + return 0; + } + + c_tracking(term& owner) + : owner{ owner } + { + reset(); + procs[ansi::OSC_LINUX_COLOR] = [&](view data) // ESC ] P Nrrggbb + { + if (data.length() >= 7) + { + auto n = to_byte(data[0]); + auto r1 = to_byte(data[1]); + auto r2 = to_byte(data[2]); + auto g1 = to_byte(data[3]); + auto g2 = to_byte(data[4]); + auto b1 = to_byte(data[5]); + auto b2 = to_byte(data[6]); + color[n] = (r1 << 4 ) + (r2 ) + + (g1 << 12) + (g2 << 8 ) + + (b1 << 20) + (b2 << 16) + + 0xFF000000; + } + }; + procs[ansi::OSC_RESET_COLOR] = [&](view data) // ESC ] 104 ; 0; 1;... + { + auto empty = true; + while(data.length()) + { + utf::trim_front_if(data, [](char c){ return c >= '0' && c <= '9'; }); + if (auto value = utf::to_int(data)) + { + auto n = value.value(); + color[n] = rgba::color256[n]; + empty = faux; + } + } + if (empty) reset(); + }; + procs[ansi::OSC_SET_PALETTE] = [&](view data) // ESC ] 4 ; 0;rgb:00/00/00;1;rgb:00/00/00;... + { + while (data.length()) + { + utf::trim_front(data, " ;"); + if (auto value = utf::to_int(data)) + { + auto n = value.value(); + utf::trim_front(data, " ;"); + if (data.length() >= 12 && data.starts_with("rgb:")) + { + auto r1 = to_byte(data[ 4]); + auto r2 = to_byte(data[ 5]); + auto g1 = to_byte(data[ 7]); + auto g2 = to_byte(data[ 8]); + auto b1 = to_byte(data[10]); + auto b2 = to_byte(data[11]); + color[n] = (r1 << 4 ) + (r2 ) + + (g1 << 12) + (g2 << 8 ) + + (b1 << 20) + (b2 << 16) + + 0xFF000000; + data.remove_prefix(12); // rgb:00/00/00 + } + else + { + //todo impl request "?" + log(" OSC=", ansi::OSC_SET_PALETTE, " unsupported format DATA=", utf::to_hex(data)); + break; + } + } + } + }; + procs[ansi::OSC_LINUX_RESET] = [&](view data) // ESC ] R + { + reset(); + }; + //todo implement + //procs[ansi::OSC_SET_FGCOLOR] = [&](view data) { }; + //procs[ansi::OSC_SET_BGCOLOR] = [&](view data) { }; + //procs[ansi::OSC_RESET_COLOR] = [&](view data) { }; + //procs[ansi::OSC_RESET_FGCLR] = [&](view data) { }; + //procs[ansi::OSC_RESET_BGCLR] = [&](view data) { }; + } + + void set(text const& property, view data) + { + auto proc = procs.find(property); + if (proc != procs.end()) + { + proc->second(data); + } + else log(" Not supported: OSC=", property, " DATA=", data, " HEX=", utf::to_hex(data)); + } + void fgc(tint c) { owner.target->brush.fgc(color[c]); } + void bgc(tint c) { owner.target->brush.bgc(color[c]); } + }; + // term: Generic terminal buffer. struct bufferbase : public ansi::parser @@ -421,38 +536,38 @@ namespace netxs::ui vt.csier.table_hash [CSI_HSH_RCP] = VT_PROC{ p->na("CSI n # Q Pop current palette colors onto stack. n default is 0."); }; // CSI n # Q Pop current palette colors onto stack. n default is 0. vt.csier.table_excl [CSI_EXL_RST] = VT_PROC{ p->owner.decstr( ); }; // CSI ! p Soft terminal reset (DECSTR) - vt.csier.table[CSI_SGR][SGR_FG_BLK ] = VT_PROC{ p->owner.fgc(tint::blackdk ); }; - vt.csier.table[CSI_SGR][SGR_FG_RED ] = VT_PROC{ p->owner.fgc(tint::reddk ); }; - vt.csier.table[CSI_SGR][SGR_FG_GRN ] = VT_PROC{ p->owner.fgc(tint::greendk ); }; - vt.csier.table[CSI_SGR][SGR_FG_YLW ] = VT_PROC{ p->owner.fgc(tint::yellowdk ); }; - vt.csier.table[CSI_SGR][SGR_FG_BLU ] = VT_PROC{ p->owner.fgc(tint::bluedk ); }; - vt.csier.table[CSI_SGR][SGR_FG_MGT ] = VT_PROC{ p->owner.fgc(tint::magentadk); }; - vt.csier.table[CSI_SGR][SGR_FG_CYN ] = VT_PROC{ p->owner.fgc(tint::cyandk ); }; - vt.csier.table[CSI_SGR][SGR_FG_WHT ] = VT_PROC{ p->owner.fgc(tint::whitedk ); }; - vt.csier.table[CSI_SGR][SGR_FG_BLK_LT] = VT_PROC{ p->owner.fgc(tint::blacklt ); }; - vt.csier.table[CSI_SGR][SGR_FG_RED_LT] = VT_PROC{ p->owner.fgc(tint::redlt ); }; - vt.csier.table[CSI_SGR][SGR_FG_GRN_LT] = VT_PROC{ p->owner.fgc(tint::greenlt ); }; - vt.csier.table[CSI_SGR][SGR_FG_YLW_LT] = VT_PROC{ p->owner.fgc(tint::yellowlt ); }; - vt.csier.table[CSI_SGR][SGR_FG_BLU_LT] = VT_PROC{ p->owner.fgc(tint::bluelt ); }; - vt.csier.table[CSI_SGR][SGR_FG_MGT_LT] = VT_PROC{ p->owner.fgc(tint::magentalt); }; - vt.csier.table[CSI_SGR][SGR_FG_CYN_LT] = VT_PROC{ p->owner.fgc(tint::cyanlt ); }; - vt.csier.table[CSI_SGR][SGR_FG_WHT_LT] = VT_PROC{ p->owner.fgc(tint::whitelt ); }; - vt.csier.table[CSI_SGR][SGR_BG_BLK ] = VT_PROC{ p->owner.bgc(tint::blackdk ); }; - vt.csier.table[CSI_SGR][SGR_BG_RED ] = VT_PROC{ p->owner.bgc(tint::reddk ); }; - vt.csier.table[CSI_SGR][SGR_BG_GRN ] = VT_PROC{ p->owner.bgc(tint::greendk ); }; - vt.csier.table[CSI_SGR][SGR_BG_YLW ] = VT_PROC{ p->owner.bgc(tint::yellowdk ); }; - vt.csier.table[CSI_SGR][SGR_BG_BLU ] = VT_PROC{ p->owner.bgc(tint::bluedk ); }; - vt.csier.table[CSI_SGR][SGR_BG_MGT ] = VT_PROC{ p->owner.bgc(tint::magentadk); }; - vt.csier.table[CSI_SGR][SGR_BG_CYN ] = VT_PROC{ p->owner.bgc(tint::cyandk ); }; - vt.csier.table[CSI_SGR][SGR_BG_WHT ] = VT_PROC{ p->owner.bgc(tint::whitedk ); }; - vt.csier.table[CSI_SGR][SGR_BG_BLK_LT] = VT_PROC{ p->owner.bgc(tint::blacklt ); }; - vt.csier.table[CSI_SGR][SGR_BG_RED_LT] = VT_PROC{ p->owner.bgc(tint::redlt ); }; - vt.csier.table[CSI_SGR][SGR_BG_GRN_LT] = VT_PROC{ p->owner.bgc(tint::greenlt ); }; - vt.csier.table[CSI_SGR][SGR_BG_YLW_LT] = VT_PROC{ p->owner.bgc(tint::yellowlt ); }; - vt.csier.table[CSI_SGR][SGR_BG_BLU_LT] = VT_PROC{ p->owner.bgc(tint::bluelt ); }; - vt.csier.table[CSI_SGR][SGR_BG_MGT_LT] = VT_PROC{ p->owner.bgc(tint::magentalt); }; - vt.csier.table[CSI_SGR][SGR_BG_CYN_LT] = VT_PROC{ p->owner.bgc(tint::cyanlt ); }; - vt.csier.table[CSI_SGR][SGR_BG_WHT_LT] = VT_PROC{ p->owner.bgc(tint::whitelt ); }; + vt.csier.table[CSI_SGR][SGR_FG_BLK ] = VT_PROC{ p->owner.ctrack.fgc(tint::blackdk ); }; + vt.csier.table[CSI_SGR][SGR_FG_RED ] = VT_PROC{ p->owner.ctrack.fgc(tint::reddk ); }; + vt.csier.table[CSI_SGR][SGR_FG_GRN ] = VT_PROC{ p->owner.ctrack.fgc(tint::greendk ); }; + vt.csier.table[CSI_SGR][SGR_FG_YLW ] = VT_PROC{ p->owner.ctrack.fgc(tint::yellowdk ); }; + vt.csier.table[CSI_SGR][SGR_FG_BLU ] = VT_PROC{ p->owner.ctrack.fgc(tint::bluedk ); }; + vt.csier.table[CSI_SGR][SGR_FG_MGT ] = VT_PROC{ p->owner.ctrack.fgc(tint::magentadk); }; + vt.csier.table[CSI_SGR][SGR_FG_CYN ] = VT_PROC{ p->owner.ctrack.fgc(tint::cyandk ); }; + vt.csier.table[CSI_SGR][SGR_FG_WHT ] = VT_PROC{ p->owner.ctrack.fgc(tint::whitedk ); }; + vt.csier.table[CSI_SGR][SGR_FG_BLK_LT] = VT_PROC{ p->owner.ctrack.fgc(tint::blacklt ); }; + vt.csier.table[CSI_SGR][SGR_FG_RED_LT] = VT_PROC{ p->owner.ctrack.fgc(tint::redlt ); }; + vt.csier.table[CSI_SGR][SGR_FG_GRN_LT] = VT_PROC{ p->owner.ctrack.fgc(tint::greenlt ); }; + vt.csier.table[CSI_SGR][SGR_FG_YLW_LT] = VT_PROC{ p->owner.ctrack.fgc(tint::yellowlt ); }; + vt.csier.table[CSI_SGR][SGR_FG_BLU_LT] = VT_PROC{ p->owner.ctrack.fgc(tint::bluelt ); }; + vt.csier.table[CSI_SGR][SGR_FG_MGT_LT] = VT_PROC{ p->owner.ctrack.fgc(tint::magentalt); }; + vt.csier.table[CSI_SGR][SGR_FG_CYN_LT] = VT_PROC{ p->owner.ctrack.fgc(tint::cyanlt ); }; + vt.csier.table[CSI_SGR][SGR_FG_WHT_LT] = VT_PROC{ p->owner.ctrack.fgc(tint::whitelt ); }; + vt.csier.table[CSI_SGR][SGR_BG_BLK ] = VT_PROC{ p->owner.ctrack.bgc(tint::blackdk ); }; + vt.csier.table[CSI_SGR][SGR_BG_RED ] = VT_PROC{ p->owner.ctrack.bgc(tint::reddk ); }; + vt.csier.table[CSI_SGR][SGR_BG_GRN ] = VT_PROC{ p->owner.ctrack.bgc(tint::greendk ); }; + vt.csier.table[CSI_SGR][SGR_BG_YLW ] = VT_PROC{ p->owner.ctrack.bgc(tint::yellowdk ); }; + vt.csier.table[CSI_SGR][SGR_BG_BLU ] = VT_PROC{ p->owner.ctrack.bgc(tint::bluedk ); }; + vt.csier.table[CSI_SGR][SGR_BG_MGT ] = VT_PROC{ p->owner.ctrack.bgc(tint::magentadk); }; + vt.csier.table[CSI_SGR][SGR_BG_CYN ] = VT_PROC{ p->owner.ctrack.bgc(tint::cyandk ); }; + vt.csier.table[CSI_SGR][SGR_BG_WHT ] = VT_PROC{ p->owner.ctrack.bgc(tint::whitedk ); }; + vt.csier.table[CSI_SGR][SGR_BG_BLK_LT] = VT_PROC{ p->owner.ctrack.bgc(tint::blacklt ); }; + vt.csier.table[CSI_SGR][SGR_BG_RED_LT] = VT_PROC{ p->owner.ctrack.bgc(tint::redlt ); }; + vt.csier.table[CSI_SGR][SGR_BG_GRN_LT] = VT_PROC{ p->owner.ctrack.bgc(tint::greenlt ); }; + vt.csier.table[CSI_SGR][SGR_BG_YLW_LT] = VT_PROC{ p->owner.ctrack.bgc(tint::yellowlt ); }; + vt.csier.table[CSI_SGR][SGR_BG_BLU_LT] = VT_PROC{ p->owner.ctrack.bgc(tint::bluelt ); }; + vt.csier.table[CSI_SGR][SGR_BG_MGT_LT] = VT_PROC{ p->owner.ctrack.bgc(tint::magentalt); }; + vt.csier.table[CSI_SGR][SGR_BG_CYN_LT] = VT_PROC{ p->owner.ctrack.bgc(tint::cyanlt ); }; + vt.csier.table[CSI_SGR][SGR_BG_WHT_LT] = VT_PROC{ p->owner.ctrack.bgc(tint::whitelt ); }; vt.csier.table[CSI_CUU] = VT_PROC{ p->up ( q(1)); }; // CSI n A (CUU) vt.csier.table[CSI_CUD] = VT_PROC{ p->dn ( q(1)); }; // CSI n B (CUD) @@ -514,13 +629,14 @@ namespace netxs::ui vt.oscer[OSC_LABEL] = VT_PROC{ p->owner.wtrack.set(OSC_LABEL, q); }; vt.oscer[OSC_TITLE] = VT_PROC{ p->owner.wtrack.set(OSC_TITLE, q); }; vt.oscer[OSC_XPROP] = VT_PROC{ p->owner.wtrack.set(OSC_XPROP, q); }; - vt.oscer[OSC_LINUX_COLOR] = VT_PROC{ p->owner.set_colors(OSC_LINUX_COLOR, q); }; - vt.oscer[OSC_SET_PALETTE] = VT_PROC{ p->owner.set_colors(OSC_SET_PALETTE, q); }; - vt.oscer[OSC_SET_FGCOLOR] = VT_PROC{ p->owner.set_colors(OSC_SET_FGCOLOR, q); }; - vt.oscer[OSC_SET_BGCOLOR] = VT_PROC{ p->owner.set_colors(OSC_SET_BGCOLOR, q); }; - vt.oscer[OSC_RESET_COLOR] = VT_PROC{ p->owner.set_colors(OSC_RESET_COLOR, q); }; - vt.oscer[OSC_RESET_FGCLR] = VT_PROC{ p->owner.set_colors(OSC_RESET_FGCLR, q); }; - vt.oscer[OSC_RESET_BGCLR] = VT_PROC{ p->owner.set_colors(OSC_RESET_BGCLR, q); }; + vt.oscer[OSC_LINUX_COLOR] = VT_PROC{ p->owner.ctrack.set(OSC_LINUX_COLOR, q); }; + vt.oscer[OSC_LINUX_RESET] = VT_PROC{ p->owner.ctrack.set(OSC_LINUX_RESET, q); }; + vt.oscer[OSC_SET_PALETTE] = VT_PROC{ p->owner.ctrack.set(OSC_SET_PALETTE, q); }; + vt.oscer[OSC_SET_FGCOLOR] = VT_PROC{ p->owner.ctrack.set(OSC_SET_FGCOLOR, q); }; + vt.oscer[OSC_SET_BGCOLOR] = VT_PROC{ p->owner.ctrack.set(OSC_SET_BGCOLOR, q); }; + vt.oscer[OSC_RESET_COLOR] = VT_PROC{ p->owner.ctrack.set(OSC_RESET_COLOR, q); }; + vt.oscer[OSC_RESET_FGCLR] = VT_PROC{ p->owner.ctrack.set(OSC_RESET_FGCLR, q); }; + vt.oscer[OSC_RESET_BGCLR] = VT_PROC{ p->owner.ctrack.set(OSC_RESET_BGCLR, q); }; // Log all unimplemented CSI commands. for (auto i = 0; i < 0x100; ++i) @@ -3107,13 +3223,13 @@ namespace netxs::ui }; using buffer_ptr = bufferbase*; - using palette_t = std::remove_const_t; pro::caret cursor; // term: Text cursor controller. term_state status; // term: Screen buffer status info. w_tracking wtrack; // term: Terminal title tracking object. f_tracking ftrack; // term: Keyboard focus tracking object. m_tracking mtrack; // term: VT-style mouse tracking object. + c_tracking ctrack; // term: Custom terminal palette tracking object. scroll_buf normal; // term: Normal screen buffer. alt_screen altbuf; // term: Alternate screen buffer. buffer_ptr target; // term: Current screen buffer pointer. @@ -3125,8 +3241,6 @@ namespace netxs::ui bool active; // term: Terminal lifetime. bool decckm; // term: Cursor keys Application(true)/ANSI(faux) mode. bool bpmode; // term: Bracketed paste mode. - palette_t clr256; // term: Custom terminal palette. - // term: Soft terminal reset (DECSTR). void decstr() @@ -3398,48 +3512,6 @@ namespace netxs::ui } } - void set_colors(text const& property, view txt) - { - log(" OSC=", property, " DATA=", txt, " HEX=", utf::to_hex(txt)); - if (property == "P") - { - if (txt.length() >= 7) - { - auto to_byte = [](char c) -> byte - { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'A' && c <= 'F') return c - 'A' + 10; - if (c >= 'a' && c <= 'f') return c - 'a' + 10; - return 0; - }; - auto head = txt.begin(); - auto n = to_byte(*head++); - auto r1 = to_byte(*head++); - auto r2 = to_byte(*head++); - auto g1 = to_byte(*head++); - auto g2 = to_byte(*head++); - auto b1 = to_byte(*head++); - auto b2 = to_byte(*head++); - clr256[n] = (r1 << 4 ) + (r2 ) - + (g1 << 12) + (g2 << 8 ) - + (b1 << 20) + (b2 << 16) - + 0xFF000000; - } - } - else if (property == "104") - { - //todo reset the list of colors: ESC ] 104; 1; 2; 3 ST - if (auto value = utf::to_int(txt)) - { - auto n = value.value(); - clr256[n] = rgba::color256[n]; - } - else std::copy(std::begin(rgba::color256), std::end(rgba::color256), std::begin(clr256)); - } - } - void fgc(tint c) { target->brush.fgc(clr256[c]); } - void bgc(tint c) { target->brush.bgc(clr256[c]); } - public: void exec_cmd(commands::ui::commands cmd) { @@ -3505,11 +3577,11 @@ namespace netxs::ui mtrack{ *this }, ftrack{ *this }, wtrack{ *this }, + ctrack{ *this }, active{ true }, decckm{ faux }, bpmode{ faux } { - std::copy(std::begin(rgba::color256), std::end(rgba::color256), std::begin(clr256)); cmdarg = command_line; target = &normal; //cursor.style(commands::cursor::def_style); // default=blinking_box diff --git a/src/netxs/text/utf.hpp b/src/netxs/text/utf.hpp index 26d0a423d6..176cda3aa6 100644 --- a/src/netxs/text/utf.hpp +++ b/src/netxs/text/utf.hpp @@ -1377,18 +1377,23 @@ namespace netxs::utf } return head; }; - auto trim_front(view& utf8, view delims) + template + void trim_front_if(view& utf8, P pred) { auto head = utf8.begin(); auto tail = utf8.end(); while (head != tail) { auto c = *head; - if (delims.find(c) == text::npos) break; + if (pred(c)) break; ++head; } utf8.remove_prefix(std::distance(utf8.begin(), head)); }; + void trim_front(view& utf8, view delims) + { + trim_front_if(utf8, [&](char c){ return delims.find(c) == text::npos; }); + }; auto get_quote(view& utf8, char delim, view skip = {}) { auto head = utf8.begin();