wwivbbs / wwiv

WWIV BBS Software v5
http://www.wwivbbs.org
Other
186 stars 71 forks source link

Add hide/unhide cursor MCI code to Pipe Code expressions #1619

Open the-godfather-007 opened 9 months ago

the-godfather-007 commented 9 months ago

May a hide and unhide cursor MCI code be added to Pipe Code expressions? It would be nice to shut it off when using the sleep, spin, and backprint feature so that it does not distract from the animation. In Mystic it's |[0 for off and |[1 for on for reference. It would be a nice add to the menu editor as a "display text" feature also for instances when a prompt is not wanted and just an all ANSI menu without a blinking cursor sitting at x01 y25.

wwiv commented 1 month ago

I don't understand the second one, can you explain that a bit more.

Also offhand, do you know the ANSI escape string to hide and uhide a cursor?

wwiv commented 1 month ago

Looks like it's the following according to https://en.wikipedia.org/wiki/ANSI_escape_code

Show Cursor: ESCAPE ?25h HIde Cursor: ESCAPE ?25hl

the-godfather-007 commented 1 month ago

For logoff as an example, I want just a box with the options the person selects, without a prompt that has a blinking cursor to the bottom left of the screen. Rather I'd want it where I've drawn my ansi prompt to be specific to the x/y coordinate and or not blinking at all (hidden). If it's within the menu prompt, am I able to use the ANSI ESCAPE codes or am I limited to MCI codes?

wwiv commented 1 month ago

I think you can use ansi escape codes too. Give it a try, also happy to add those into the WWIV pipe codes (doc reference: https://docs.wwivbbs.org/en/latest/cfg/displaying_text/#pipe-screen-and-cursor-control )

Here's the source, should be easy to add:

case '[': {
      // movement
      const auto type = data.back();
      data.pop_back();
      wwiv::common::Interpreted res;
      res.cmd = wwiv::common::interpreted_cmd_t::movement;
      switch (type) {
        case 'A': res.up = data.empty() ? 1 : to_number<int>(data); break;
        case 'B': res.down = data.empty() ? 1 : to_number<int>(data); break;
        case 'C': res.right = data.empty() ? 1 : to_number<int>(data); break;
        case 'D': res.left = data.empty() ? 1 : to_number<int>(data); break;
        case 'H': {
          const auto semi = data.find(';');
          if (data.empty() || semi == std::string::npos) {
            return s;
          }
          const auto x = to_number<int>(data.substr(0, semi));
          res.x = std::max<int>(0, x);
          const auto y = to_number<int>(data.substr(semi + 1));
          res.y = std::max<int>(0,y);
          return res;
        }
        case 'J': {
          res.cls = true;
          return res;
        }
        case 'K': {
          if (const auto ct = data.empty() ? 0 : to_number<int>(data); ct == 0) {
            res.clreol = true;
          } else if (ct == 1) {
            res.clrbol = true;
          } else if (ct == 2) {
            res.clreol = true;
            res.clrbol = true;
          }
          return res;
        }
        case 'N': { // NL
          const auto ct = data.empty() ? 1 : to_number<int>(data);
          res.nl = ct;
          return res;
        }
        default:
          return s;
      }
      return res;
    }
    default:   return {};
  }
wwiv commented 1 month ago

Another option is do it like we have for pause.

For pause we have:

|{set pause=off}

Could add the following (which would work in all files, etc)

|{set cursor=off}

Any preference?