bduggan / raku-terminal-ui

A framework for building terminal inferfaces in Raku
MIT License
2 stars 0 forks source link

selected highlight and reversible #1

Closed vincentaxhe closed 1 month ago

vincentaxhe commented 1 month ago

glad to find an terminal tui module developed by Raku, its simple interface is a great advantage. I have write my first raku tui program 'nmtui.raku' which is for switching wifi connection,

#!/bin/env raku
use Terminal::UI 'ui';

my $connections = run <nmcli connection show>, :out;
my %name;
for $connections.out.slurp.lines[1..*] {
    my $name = $_.comb(/\S+ \s? \S+/, 4).[0];
    my $show = run qqww{nmcli connection show "$name"}, :out;
    for $show.out.lines {
        if /^802\-11\-wireless\.ssid:/ {
            my $ssid = .split(/\s+/, 2)[1];
            %name{$ssid} = $name;
        }
    }
}

ui.setup(:2panes);
ui.panes[0].put($_) for getSsids;
ui.panes[0].on: select => -> :$raw, :$meta {
  my @ssids = $raw.words;
  my $select = @ssids[0] eq '*' ?? @ssids[2] !! @ssids[1];
  ui.panes[1].put("connect to $select");
  run qqww{nmcli connection up "%name{$select}"};
  refresh ui.panes[0];
}
ui.interact;
ui.shutdown;
sub getSsids{
  my $list = run <nmcli device wifi list>, :out;
  my @devices = $list.out.slurp.lines;
  return @devices;
}
sub refresh($pane){
    $pane.clear;
    $pane.put($_) for getSsids;
}

The selection support is sufficient for such work But I want write another one. for example 'divide.raku', put 0-9,I want to calculate 9 / 4 / 1, I can select '9', '4', '1', then '9', '4', '1' is stay highlighted until I reverse select any of them, the color is attached to the number when scroll, then I want to do some check, if '0' is selected ,there is a warning on second pane 'divide by zero is illegal' or output the result.

vincentaxhe commented 1 month ago

if I select and colorize it, and update pane, maybe will do what I want

bduggan commented 1 month ago

Thanks! Your program is nice! I had to make a little change to use slurp(:close) instead of slurp in a few places to stop nmcli from waiting, but otherwise it worked well.

For divide.raku, colorizing and updating sounds like the way to go, something like:

#!/usr/bin/env raku

use Terminal::UI 'ui';
use Terminal::ANSI::OO 't';

ui.setup: :2panes;
my (\top,\bottom) = ui.panes;
top.put: [ t.white => "$_" ], meta => %( :line($_) ) for 0..9;
my $last;
top.on: select => -> :$raw, :%meta {
  my $line = +%meta<line>;
  top.update: :$line, [ t.yellow => +$line ];
  ui.refresh;
  bottom.put: "selected $line";
  with $last {
    if ($line == 0) {
      bottom.put: "cannot divide by zero";
    } else {
      bottom.put: "$last / $line = {$last / $line}";
    }
  }
  $last = $line;
};
ui.interact;
ui.shutdown;
vincentaxhe commented 1 month ago

use update method is the right way instead of reput everything, it's annoying to back from top. your example help me on that. It take me some time to recognize the flexibility of bind, pane on, %meta, in general it's great design! maybe some more examples will be helpful. Like the sticky color example above. I finished my pactl-tui in two days, it's a great journey.

bduggan commented 1 month ago

There are a number of examples here:

https://github.com/bduggan/raku-terminal-ui/tree/master/eg

But always happy to add more!

Thanks for the nice feedback!