Ncurses将光标放置在正确的面板中 [英] Ncurses place cursor in correct panel

查看:255
本文介绍了Ncurses将光标放置在正确的面板中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个具有多个窗口的应用程序,每个窗口都包含在面板内部.特别是这些窗口之一必须从键盘获取输入.我还需要能够检测特殊键,例如F键和箭头键.我当前的应用程序当前正在执行此操作.但是,即使在我调用wmove(my_wins[1], 3, 2)之后,光标也没有位于正确的位置.

I am making an application which has several windows, each contained inside of a panel. One of these windows in particular must take input from the keyboard. I also need to be able to detect special keys like the F keys and the arrow keys. My current application is doing this currently. However the cursor is not in the proper location even after I call wmove(my_wins[1], 3, 2).

如何将光标移动到适当位置的适当面板中?我希望终端光标位于第二个窗口(my_wins[1])中,我想从中获取字符的下一个空白处.在这种情况下,这是my_wins[1]的第三行,该字符输入到此行的最后一个字符之后.

How do I move the cursor to be in the proper panel at the proper location? I would like the terminal cursor to be in my second window (my_wins[1]), at the next empty space that I want to take characters from. In this case, this is the 3rd row of my_wins[1] after the last character entered into this line.

我的代码:

#include <panel.h>
#include <ncurses.h>
#include <string>
#include <stdlib.h>
#include <unistd.h>
#include <vector>

WINDOW *my_wins[4];
PANEL* my_panels[4];

// forward declarations
void make_screen();
void clear_win1();
void get_input();

int main()
{
    initscr();
    cbreak();
    noecho();

    make_screen();
    get_input();
    endwin();
}

void get_input()
{   
    // enable f-keys and arrow keys
    keypad(my_wins[1], TRUE);

    int ch;
    std::string str = "";
    std::vector<std::string> cmds;

    while ((ch = wgetch(my_wins[1])) != KEY_F(1))
    {   
        switch(ch)
        {   
            case 127: // delete
                if (str.size() > 0)
                {   
                    str.erase(str.size()-1);
                }
                break;
            case '\n':
                cmds.push_back(str);
                str = "";
                break;
            default:
                if (ch >= ' ' || ch <= 126)
                {   
                    str += (char) ch;
                }
                break;
        }
        clear_win1();
        mvwprintw(my_wins[1], 3, 2, "%s", str.c_str());
        wmove(my_wins[1], 3, 2+str.size()); 
        update_panels();
        doupdate();
    }
}

void make_screen()
{
    int maxx, maxy;
    getmaxyx(stdscr, maxy, maxx);

    float win1y = maxy;
    float win1x = (2.0/7)*maxx;

    float win2y = (3.0/5)*maxy;
    float win2x = (3.0/7)*maxx;

    float win3y = (3.0/5)*maxy; 
    float win3x = (2.0/7)*maxx;

    float win4y = (2.0/5)*maxy + 1;  
    float win4x = (5.0/7)*maxx;

    my_wins[0] = newwin(win1y, win1x, 0, 0); 
    my_wins[1] = newwin(win2y, win2x, 0, win1x);
    my_wins[2] = newwin(win3y, win3x, 0, win1x+win2x);
    my_wins[3] = newwin(win4y, win4x, win2y, win1x);

    /*  
     * Create borders around the windows so that you can see the effect
     * of panels
     */
    for(int i = 0; i < 4; ++i)
    {   
        box(my_wins[i], 0, 0); 
    }   

    my_panels[0] = new_panel(my_wins[0]);
    my_panels[1] = new_panel(my_wins[1]);
    my_panels[2] = new_panel(my_wins[2]);
    my_panels[3] = new_panel(my_wins[3]);

    mvwprintw(my_wins[0], 2, 2, "Yelp data");
    mvwprintw(my_wins[1], 2, 2, "I/O Window");
    mvwprintw(my_wins[2], 2, 2, "Menu items");
    mvwprintw(my_wins[3], 2, 2, "Tables");
    mvwprintw(my_wins[3], 3, 2, "maxy: %d, maxx: %d", maxy, maxx);
    mvwprintw(my_wins[3], 4, 2, "win1y: %f, win1x: %f", win1y, win1x);
    mvwprintw(my_wins[3], 5, 2, "win2y: %f, win2x: %f", win2y, win2x);
    mvwprintw(my_wins[3], 6, 2, "win3y: %f, win3x: %f", win3y, win3x);
    mvwprintw(my_wins[3], 7, 2, "win4y: %f, win4x: %f", win4y, win4x);
    mvwprintw(my_wins[1], 3, 2, "");

    update_panels();

    doupdate();
}

void clear_win1()
{
    werase(my_wins[1]);
    box(my_wins[1], 0, 0); 
    mvwprintw(my_wins[1], 2, 2, "I/O Window");
    update_panels();
    doupdate();
}

推荐答案

您的示例将wmove放在屏幕更新之前.这些更新将光标留在任何有意义的位置,以在更新屏幕时将光标移动到最少.

Your example puts the wmove before the updates to the screen. Those updates leave the cursor in whatever location made sense for minimal cursor movement when updating the screen.

此更改显示了如何执行您要问的事情:

This change shows how to do what you're asking:

$ diff -u foo.c.orig foo.c
--- foo.c.orig  2017-03-06 18:56:26.000000000 -0500
+++ foo.c       2017-03-06 19:00:03.568868347 -0500
@@ -33,6 +33,7 @@
     std::string str = "";
     std::vector<std::string> cmds;

+    wmove(my_wins[1], 3, 2+str.size()); 
     while ((ch = wgetch(my_wins[1])) != KEY_F(1))
     {   
         switch(ch)
@@ -56,9 +57,9 @@
         }
         clear_win1();
         mvwprintw(my_wins[1], 3, 2, "%s", str.c_str());
-        wmove(my_wins[1], 3, 2+str.size()); 
         update_panels();
         doupdate();
+        wmove(my_wins[1], 3, 2+str.size()); 
     }
 }

这篇关于Ncurses将光标放置在正确的面板中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆