Skip to content

Commit

Permalink
Merge pull request #685 from o-sdn-o/gui-bridge
Browse files Browse the repository at this point in the history
Allow keybinding to multiple actions
  • Loading branch information
o-sdn-o authored Nov 21, 2024
2 parents c830264 + 28c64c5 commit d6cb9c5
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 58 deletions.
5 changes: 5 additions & 0 deletions src/netxs/desktopio/ansivt.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1419,16 +1419,19 @@ namespace netxs::ansi
{
auto s = [&](auto const& traits, qiew utf8)
{
client->defer = faux;
intro.execute(traits.control, utf8, client); // Make one iteration using firstcmd and return.
return utf8;
};
auto y = [&](auto const& cluster)
{
client->post(cluster);
client->defer = true;
};
auto a = [&](view plain)
{
client->ascii(plain);
client->defer = true;
};
utf::decode(s, y, a, utf8, client->decsg);
client->flush();
Expand Down Expand Up @@ -1694,6 +1697,7 @@ namespace netxs::ansi
deco state{}; // parser: Parser style last state.
mark brush{}; // parser: Parser brush.
si32 decsg{}; // parser: DEC Special Graphics Mode.
bool defer{}; // parser: The last character was a cluster that could continue to grow.

private:
core::body proto_cells{}; // parser: Proto lyric.
Expand Down Expand Up @@ -1741,6 +1745,7 @@ namespace netxs::ansi
}
proto_count = 0;
proto_cells.clear();
defer = faux;
}
auto empty() const
{
Expand Down
18 changes: 10 additions & 8 deletions src/netxs/desktopio/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ namespace netxs::app

namespace netxs::app::shared
{
static const auto version = "v0.9.99.47";
static const auto version = "v0.9.99.48";
static const auto repository = "https://github.com/directvt/vtm";
static const auto usr_config = "~/.config/vtm/settings.xml"s;
static const auto sys_config = "/etc/vtm/settings.xml"s;
Expand Down Expand Up @@ -163,7 +163,6 @@ namespace netxs::app::shared
keybd.bind("F12" , "ToggleFullscreen", mode);
};
binding(0);
binding(1);
};

using builder_t = std::function<ui::sptr(eccc, xmls&)>;
Expand Down Expand Up @@ -663,7 +662,7 @@ namespace netxs::app::shared
twod gridsize{};
si32 cellsize{};
std::list<text> fontlist;
std::list<std::tuple<text, text, si32>> hotkeys;
std::list<std::tuple<text, std::vector<text>, si32>> hotkeys;
};

auto get_gui_config(xmls& config)
Expand All @@ -686,13 +685,16 @@ namespace netxs::app::shared
for (auto keybind_ptr : keybinds)
{
auto& keybind = *keybind_ptr;
if (!keybind.fake)
auto chord = keybind.take_value();
auto scheme = keybind.take("scheme", 0); //todo use text instead of si32 as a scheme identifier
auto action = keybind.take("action", ""s);
auto action_list = std::vector<text>{};
auto action_ptr_list = keybind.list("action");
for (auto action_ptr : action_ptr_list)
{
auto chord = keybind.take_value();
auto action = keybind.take("action", ""s);
auto scheme = keybind.take("scheme", 0);
gui_config.hotkeys.push_back({ chord, action, scheme });
action_list.push_back(action_ptr->take_value());
}
gui_config.hotkeys.push_back({ chord, action_list, scheme });
}
return gui_config;
}
Expand Down
70 changes: 40 additions & 30 deletions src/netxs/desktopio/controls.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1950,35 +1950,25 @@ namespace netxs::ui
}
}
template<si32 Tier = tier::release>
auto _set(qiew chord_str, sptr handler_ptr, si32 scheme)
auto _set(auto& chords, sptr handler_ptr, si32 scheme)
{
//todo unify
auto hscheme = scheme ? 1 : 0;
auto& handlers = Tier == tier::release ? handlers_release[hscheme] : handlers_preview[hscheme];
if (auto chords = _get_chords(chord_str))
for (auto& chord : chords)
{
for (auto& chord : chords.value())
{
handlers[chord].push_back(handler_ptr);
}
return true;
handlers[chord].push_back(handler_ptr);
}
else return faux;
}
template<si32 Tier = tier::release>
auto _reset(qiew chord_str, si32 scheme)
auto _reset(auto& chords, si32 scheme)
{
auto hscheme = scheme ? 1 : 0;
auto& handlers = Tier == tier::release ? handlers_release[hscheme] : handlers_preview[hscheme];
if (auto chords = _get_chords(chord_str))
for (auto& chord : chords)
{
for (auto& chord : chords.value())
{
handlers[chord].clear();
}
return true;
handlers[chord].clear();
}
else return faux;
}
template<si32 Tier = tier::release>
void _dispatch(hids& gear, qiew chord)
Expand Down Expand Up @@ -2054,20 +2044,38 @@ namespace netxs::ui
api_map[name] = ptr::shared(std::move(proc));
}
template<si32 Tier = tier::release>
auto bind(qiew chord_str, qiew proc_name, si32 scheme = 0)
auto bind(qiew chord_str, auto&& proc_names, si32 scheme = 0)
{
if (!chord_str) return;
if (proc_name)
if (auto chord_list = _get_chords(chord_str))
{
if (auto iter = api_map.find(proc_name); iter != api_map.end())
auto& chords = chord_list.value();
auto set = [&](qiew proc_name)
{
_set<Tier>(chord_str, iter->second, scheme);
if (proc_name)
{
if (auto iter = api_map.find(proc_name); iter != api_map.end())
{
_set<Tier>(chords, iter->second, scheme);
}
else log("%%Action '%proc%' not found", prompt::user, proc_name);
}
else
{
_reset<Tier>(chords, scheme);
}
};
if constexpr (std::is_same_v<char, std::decay_t<decltype(proc_names[0])>>) // The case it is a string.
{
set(proc_names);
}
else
{
for (auto& proc_name : proc_names)
{
set(proc_name);
}
}
else log("%%Action '%proc%' not found", prompt::user, proc_name);
}
else
{
_reset<Tier>(chord_str, scheme);
}
}
template<si32 Tier = tier::release>
Expand All @@ -2077,13 +2085,15 @@ namespace netxs::ui
for (auto keybind_ptr : keybinds)
{
auto& keybind = *keybind_ptr;
if (!keybind.fake)
auto chord = keybind.take_value();
auto scheme = keybind.take("scheme", 0); //todo use text instead of si32 as a scheme identifier
auto action_list = std::vector<text>{};
auto action_ptr_list = keybind.list("action");
for (auto action_ptr : action_ptr_list)
{
auto chord = keybind.take_value();
auto action = keybind.take("action", ""s);
auto scheme = keybind.take("scheme", 0);
bind<Tier>(chord, action, scheme);
action_list.push_back(action_ptr->take_value());
}
bind<Tier>(chord, action_list, scheme);
}
}
};
Expand Down
4 changes: 2 additions & 2 deletions src/netxs/desktopio/gui.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1970,7 +1970,7 @@ namespace netxs::gui
kmap chords; // winbase: Pressed key table (key chord).
si32 hotkey; // winbase: Alternate hotkey scheme.

winbase(auth& indexer, std::list<text>& font_names, si32 cell_height, bool antialiasing, span blink_rate, twod grip_cell, std::list<std::tuple<text, text, si32>>& hotkeys)
winbase(auth& indexer, std::list<text>& font_names, si32 cell_height, bool antialiasing, span blink_rate, twod grip_cell, std::list<std::tuple<text, std::vector<text>, si32>>& hotkeys)
: base{ indexer },
titles{ *this, "", "", faux },
wfocus{ *this, ui::pro::focus::mode::relay },
Expand Down Expand Up @@ -2012,7 +2012,7 @@ namespace netxs::gui
wkeybd.proc("_ResetWheelAccumulator", [&](hids& /*gear*/){ whlacc = {}; });
wkeybd.bind<tier::preview>("-Ctrl", "_ResetWheelAccumulator", 0);
wkeybd.bind<tier::preview>("-Ctrl", "_ResetWheelAccumulator", 1);
for (auto& [chord, action, scheme] : hotkeys) wkeybd.bind<tier::preview>(chord, action, scheme);
for (auto& [chord, action_list, scheme] : hotkeys) wkeybd.bind<tier::preview>(chord, action_list, scheme);
}

virtual bool layer_create(layer& s, winbase* host_ptr = nullptr, twod win_coord = {}, twod grid_size = {}, dent border_dent = {}, twod cell_size = {}) = 0;
Expand Down
71 changes: 67 additions & 4 deletions src/netxs/desktopio/richtext.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1403,7 +1403,50 @@ namespace netxs::ui
len.y * len.x);
while (dst != end) *dst++ = blank;
}

//todo make it 2D
// rich: Pop glyph matrix.
auto pop_cluster()
{
auto cluster = netxs::text{};
auto size = (si32)core::canvas.size();
if (size)
{
auto& back = canvas.back();
auto [w, h, x, y] = back.whxy();
if constexpr (debugmode) log("\tw=%%, h=%%, x=%%, y=%%", w, h, x, y);
if (w && x == w && size >= w)
{
auto current_x = w - 1;
auto head = canvas.rbegin() + 1;
auto tail = head + current_x;
while (head != tail)
{
auto& c = *head;
if (!c.same_txt(back) || !c.like(back))
{
break;
}
auto [cw, ch, cx, cy] = c.whxy();
if constexpr (debugmode) log("\t\tcurrent_x=%%, cw=%%, ch=%%, cx=%%, cy=%%", current_x, cw, ch, cx, cy);
if (cw != w || ch != h || cy != y || cx != current_x)
{
break;
}
head++;
current_x--;
}
if (head == tail)
{
cluster = back.txt();
if (cluster.size())
{
core::crop(size - w);
}
}
}
}
return cluster;
}
//todo unify
auto& at(si32 p) const
{
Expand Down Expand Up @@ -1439,7 +1482,27 @@ namespace netxs::ui
para(id_t id, auto utf8) { brush.link(id); ansi::parse(utf8, this); }
para(auto utf8) { ansi::parse(utf8, this); }
auto& operator = (auto utf8) { wipe(brush); ansi::parse(utf8, this); return *this; }
auto& operator += (auto utf8) { ansi::parse(utf8, this); return *this; }
auto& operator += (auto utf8)
{
if (parser::defer && caret && caret == length())
{
if constexpr (debugmode) log("try to reassemble cluster=", lyric->back().txt());
auto last_cluster = lyric->pop_cluster();
if (caret != length())
{
caret = length();
auto reassembled_cluster = text{};
reassembled_cluster.reserve(last_cluster.length() + utf8.length());
reassembled_cluster += last_cluster;
reassembled_cluster += utf8;
ansi::parse(reassembled_cluster, this);
if constexpr (debugmode) log("\treassembled_cluster=", utf::buffer_to_hex(reassembled_cluster, true));
return *this;
}
}
ansi::parse(utf8, this);
return *this;
}

operator writ const& () const { return locus; }

Expand All @@ -1452,15 +1515,15 @@ namespace netxs::ui
return shadow().substr(start, width);
}
bool bare() const { return locus.bare(); } // para: Does the paragraph have no locator.
auto length() const { return lyric->size().x; } // para: Return printable length.
si32 length() const { return lyric->size().x; } // para: Return printable length. //todo Apple clang doesn't get auto return.
auto empty() const { return !length(); } // para: Return true if empty.
auto size() const { return lyric->size(); } // para: Return 2D volume size.
auto& back() const { return brush; } // para: Return current brush.
bool busy() const { return length() || !parser::empty() || brush.busy(); } // para: Is it filled.
void ease() { lyric->each([&](auto& c){ c.clr({}); }); } // para: Reset color for all text.
void link(id_t id) { lyric->each([&](auto& c){ c.link(id); }); } // para: Set object ID for each cell.
template<bool ResetStyle = faux>
void wipe(cell c = cell{}) // para: Clear the text and locus, and reset SGR attributes.
void wipe(cell c = cell{}) // para: Clear the text and locus, and reset SGR attributes.
{
parser::reset<ResetStyle>(c);
caret = 0;
Expand Down
42 changes: 28 additions & 14 deletions src/vtm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -389,16 +389,26 @@ R"==(
<gui key*> <!-- Native GUI window layer key bindings. key* here is to clear all previous bindings and start a new list. -->
<key="CapsLock+UpArrow" action=IncreaseCellHeight/> <!-- Increase the text cell height by one pixel. -->
<key="CapsLock+DownArrow" action=DecreaseCellHeight/> <!-- Decrease the text cell height by one pixel. -->
<key="Ctrl+0" action=DropAutoRepeat/> <!-- Don't repeat the Reset text cell height. -->
<key="Ctrl+0" action=ResetCellHeight/> <!-- Reset text cell height. -->
<key="Alt+Enter" action=DropAutoRepeat/> <!-- Don't repeat the Toggle fullscreen mode. -->
<key="Alt+Enter" action=ToggleFullscreenMode/> <!-- Toggle fullscreen mode. -->
<key="Ctrl+CapsLock" action=DropAutoRepeat/> <!-- Don't repeat the Toggle text antialiasing mode. -->
<key="Ctrl+CapsLock" action=ToggleAntialiasingMode/> <!-- Toggle text antialiasing mode. -->
<key="Ctrl+Shift+F11" action=DropAutoRepeat/> <!-- Don't repeat the Roll font list backward. -->
<key="Ctrl+Shift+F11" action=RollFontsBackward/> <!-- Roll font list backward. -->
<key="Ctrl+Shift+F12" action=DropAutoRepeat/> <!-- Don't repeat the Roll font list forward. -->
<key="Ctrl+Shift+F12" action=RollFontsForward/> <!-- Roll font list forward. -->
<key="Ctrl+0">
<action=DropAutoRepeat/> <!-- Don't autorepeat the Reset text cell height. -->
<action=ResetCellHeight/> <!-- Reset text cell height. -->
</key>
<key="Alt+Enter">
<action=DropAutoRepeat/> <!-- Don't autorepeat the Toggle fullscreen mode. -->
<action=ToggleFullscreenMode/> <!-- Toggle fullscreen mode. -->
</key>
<key="Ctrl+CapsLock">
<action=DropAutoRepeat/> <!-- Don't autorepeat the Toggle text antialiasing mode. -->
<action=ToggleAntialiasingMode/> <!-- Toggle text antialiasing mode. -->
</key>
<key="Ctrl+Shift+F11">
<action=DropAutoRepeat/> <!-- Don't autorepeat the Roll font list backward. -->
<action=RollFontsBackward/> <!-- Roll font list backward. -->
</key>
<key="Ctrl+Shift+F12">
<action=DropAutoRepeat/> <!-- Don't autorepeat the Roll font list forward. -->
<action=RollFontsForward/> <!-- Roll font list forward. -->
</key>
</gui>
<tui key*> <!-- TUI matrix layer key bindings. The scheme=0 is implicitly used by default. -->
<key="Space-Backspace" action=ToggleDebugOverlay/> <!-- Toggle debug overlay. -->
Expand Down Expand Up @@ -428,10 +438,14 @@ R"==(
<key="Shift+Ctrl+DownArrow" action=TerminalViewportOneCharDown/> <!-- Scroll one line down. -->
<key="Shift+Ctrl+LeftArrow" action=TerminalViewportOneCharLeft/> <!-- Scroll one cell to the left. -->
<key="Shift+Ctrl+RightArrow" action=TerminalViewportOneCharRight/> <!-- Scroll one cell to the right. -->
<key="Shift+Ctrl+Home" action=DropAutoRepeat/> <!-- Don't repeat the Scroll to the scrollback top. -->
<key="Shift+Ctrl+Home" action=TerminalViewportTop/> <!-- Scroll to the scrollback top. -->
<key="Shift+Ctrl+End" action=DropAutoRepeat/> <!-- Don't repeat the Scroll to the scrollback bottom (reset viewport position). -->
<key="Shift+Ctrl+End" action=TerminalViewportEnd/> <!-- Scroll to the scrollback bottom (reset viewport position). -->
<key="Shift+Ctrl+Home">
<action=DropAutoRepeat/> <!-- Don't autorepeat the Scroll to the scrollback top. -->
<action=TerminalViewportTop/> <!-- Scroll to the scrollback top. -->
</key>
<key="Shift+Ctrl+End">
<action=DropAutoRepeat/> <!-- Don't autorepeat the Scroll to the scrollback bottom (reset viewport position). -->
<action=TerminalViewportEnd/> <!-- Scroll to the scrollback bottom (reset viewport position). -->
</key>
<key="" action=TerminalViewportCopy/> <!-- Сopy viewport to clipboard. -->
<key="" action=TerminalClipboardPaste/> <!-- Paste from clipboard. -->
<key="" action=TerminalClipboardWipe/> <!-- Reset clipboard. -->
Expand Down

0 comments on commit d6cb9c5

Please sign in to comment.