簡體   English   中英

如何使鼠標支持適用於 OSX 上的 ncurses?

[英]How can I make mouse support work for ncurses on OSX?

我目前已在 OSX 上編譯並運行本教程中的示例,發現捕獲鼠標事件不起作用。

我稍微修改了一下,使它更容易調試。 看起來 wgetch 永遠不會返回KEY_MOUSE ,而是在我單擊時返回一些任意字符。 我也相當確定這不是終端設置問題,因為 Vim 在完全相同的終端中捕獲鼠標點擊沒有問題。

我懷疑這個例子已經過時了。

有誰知道使用 ncurses 捕獲鼠標的現代方法?

下面是我修改后的代碼版本,用於上下文。

另外,我用g++ -std=c++17 -o curses_play curses_play.cc -lncurses

#include <ncurses.h>
#include <string.h>
#include <stdio.h>

#define WIDTH 30
#define HEIGHT 10

int startx = 0;
int starty = 0;

char *choices[] = {   "Choice 1",
  "Choice 2",
  "Choice 3",
  "Choice 4",
  "Exit",
};

int n_choices = sizeof(choices) / sizeof(char *);

void print_menu(WINDOW *menu_win, int highlight);
void report_choice(int mouse_x, int mouse_y, int *p_choice);

int main()
{ int c, choice = 0;
  WINDOW *menu_win;
  MEVENT event;

  /* Initialize curses */
  initscr();
  clear();
  noecho();
  cbreak(); //Line buffering disabled. pass on everything

  /* Try to put the window in the middle of screen */
  startx = (80 - WIDTH) / 2;
  starty = (24 - HEIGHT) / 2;

  attron(A_REVERSE);
  mvprintw(23, 1, "Click on Exit to quit (Works best in a virtual console)");
  refresh();
  attroff(A_REVERSE);

  /* Print the menu for the first time */
  menu_win = newwin(HEIGHT, WIDTH, starty, startx);
  print_menu(menu_win, 1);
  /* Get all the mouse events */
  mousemask(ALL_MOUSE_EVENTS  | REPORT_MOUSE_POSITION, NULL);

  while(1)
  { c = wgetch(menu_win);
    switch(c)
    { case KEY_MOUSE:
      mvprintw(24, 0, "Found mouse!");
      if(getmouse(&event) == OK)
      { /* When the user clicks left mouse button */
        if(event.bstate & BUTTON1_PRESSED)
        { report_choice(event.x + 1, event.y + 1, &choice);
          if(choice == -1) //Exit chosen
            goto end;
          mvprintw(22, 1, "Choice made is : %d String Chosen is \"%10s\"", choice, choices[choice - 1]);
          refresh();
        }
      }
      print_menu(menu_win, choice);
      break;
      default:
      mvprintw(24, 0, "Charcter pressed is = %3d Hopefully it can be printed as '%c'", c, c);
      refresh();
      break;
    }
  }
end:
  endwin();
  return 0;
}


void print_menu(WINDOW *menu_win, int highlight)
{
  int x, y, i;

  x = 2;
  y = 2;
  box(menu_win, 0, 0);
  for(i = 0; i < n_choices; ++i)
  { if(highlight == i + 1)
    { wattron(menu_win, A_REVERSE);
      mvwprintw(menu_win, y, x, "%s", choices[i]);
      wattroff(menu_win, A_REVERSE);
    }
    else
      mvwprintw(menu_win, y, x, "%s", choices[i]);
    ++y;
  }
  wrefresh(menu_win);
}

/* Report the choice according to mouse position */
void report_choice(int mouse_x, int mouse_y, int *p_choice)
{ int i,j, choice;

  i = startx + 2;
  j = starty + 3;

  for(choice = 0; choice < n_choices; ++choice)
    if(mouse_y == j + choice && mouse_x >= i && mouse_x <= i + strlen(choices[choice]))
    { if(choice == n_choices - 1)
      *p_choice = -1;
      else
        *p_choice = choice + 1;
      break;
    }
}

我讓它工作了,我不確定哪個特定的調整是重要的調整(我改變了大約十幾個東西)。 我也有一堆我沒有去掉的儀器

希望這足以讓你繼續前進。

/*
brew install ncurses
clang++ -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-padded -Wno-c99-compat -Wno-poison-system-directories -pedantic -fsanitize=undefined,null -std=c++17 -cxx-isystem /usr/local/include -o Merlin2011 Merlin2011.cpp -lncurses
./Merlin2011
*/
#include <ncurses.h>
#include <clocale>
#include <cstring>

#define WIDTH 30
#define HEIGHT 10

static int startx = 0;
static int starty = 0;

static char const* choices[] = {
    "Choice 1", "Choice 2", "Choice 3", "Choice 4", "Exit",
};

static int n_choices = sizeof(choices) / sizeof(char*);

static void print_menu(WINDOW* menu_win, int highlight);
static void report_choice(int mouse_x, int mouse_y, int* p_choice);

static
char sane(int c) {
    if (c > ' ' && c <= '~')
        return static_cast<char>(c);
    return ' ';
}

int main() {
    int choice = 0;
    WINDOW* menu_win;

    setlocale(LC_ALL, "");

    /* Initialize curses */
    initscr();
    clear();
    noecho();
    cbreak();  // Line buffering disabled. pass on everything
    keypad(stdscr, TRUE);
    halfdelay(1);

    /* Try to put the window in the middle of screen */
    startx = (80 - WIDTH) / 2;
    starty = (24 - HEIGHT) / 2;

    attron(A_REVERSE);
    mvprintw(23, 1, "Click on Exit to quit (Works best in a virtual console)");
    refresh();
    attroff(A_REVERSE);

    /* Print the menu for the first time */
    menu_win = newwin(HEIGHT, WIDTH, starty, startx);
    scrollok(menu_win, TRUE);
    keypad(menu_win, TRUE);
    print_menu(menu_win, 1);
    /* Get all the mouse events */
    //auto mm_success = mousemask(ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION, nullptr);
    /* Get just just the click event. */
    mmask_t mousemask_setting = NCURSES_BUTTON_CLICKED;
    auto mm_success = mousemask(mousemask_setting, nullptr);

    if (!mm_success) {
        mvprintw(22, 1, "FAIL: mousemask");
    } else if (mm_success == mousemask_setting) {
        mvprintw(22, 1, "SUCCESS: mousemask");
    } else {
        mvprintw(22, 1, "Partial success: mousemask %x of %x", mm_success, mousemask_setting);
    }
    refresh();

    bool loop{ true };

    while (loop) {
        auto c = wgetch(menu_win);

        switch (c) {
            case KEY_MOUSE: {
                MEVENT event;
                mvprintw(20, 1, "Found mouse!");
                if (getmouse(&event) == OK) { /* When the user clicks left mouse button */
                    mvprintw(20, 1, "Found mouse! %3d %3d %d", event.x, event.y, event.bstate);
                    //if (event.bstate & BUTTON1_PRESSED) { ... }
                    if (event.bstate & NCURSES_BUTTON_CLICKED) {
                        mvprintw(20, 1, "Found mouse! %3d %3d MOUSE_CLICK", event.x, event.y);
                        report_choice(event.x + 1, event.y + 1, &choice);
                        if (choice == -1) { // Exit chosen
                            loop = false;
                            break;
                        }
                        mvprintw(22, 1, "Choice made is : %d String Chosen is \"%10s\"", choice, choices[choice - 1]);
                        refresh();
                    }
                }
                print_menu(menu_win, choice);
            } break;

            case ERR: {
                static int count = 0;
                ++count;
                mvprintw(21, 0, "Nothing happened (%d).", count);
                refresh();
            } break;

            default: {
                static int i = 0;
                mvprintw(24+i, 0, "Key pressed is = %3d '%c'", c, sane(c));
                if (++i == 30)
                    i = 0;
                mvprintw(24+i, 0, "-------------------------");
                refresh();
                if (c == 'q')
                    loop = false;
            } break;
        }
    }

    endwin();
}

void print_menu(WINDOW* menu_win, int highlight) {
    int x, y, i;

    x = 2;
    y = 2;
    box(menu_win, 0, 0);
    for (i = 0; i < n_choices; ++i) {
        if (highlight == i + 1) {
            wattron(menu_win, A_REVERSE);
            mvwprintw(menu_win, y, x, "%s", choices[i]);
            wattroff(menu_win, A_REVERSE);
        } else
            mvwprintw(menu_win, y, x, "%s", choices[i]);
        ++y;
    }
    wrefresh(menu_win);
}

/* Report the choice according to mouse position */
void report_choice(int mouse_x, int mouse_y, int* p_choice) {
    int i, j, choice;

    i = startx + 2;
    j = starty + 3;

    for (choice = 0; choice < n_choices; ++choice)
        if (mouse_y == j + choice && mouse_x >= i && mouse_x <= i + strlen(choices[choice])) {
            if (choice == n_choices - 1)
                *p_choice = -1;
            else
                *p_choice = choice + 1;
            break;
        }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM