[ncurses] Grundlegende Fragen zum Aufbau eines TUI



  • Hallo,

    Ich habe vor eine ncurses Applikation für mein Handy(Openmoko NeoFreerunner, kennt vlt der ein oder andere) zu schreiben, und zwar um SMS über meine laptop zu schrieben, aber ich habe noch nie zuvor was groeßeres programmiert und auch noch nie GUI/TUI.

    Hab dann mal munter mit ncurses angefangen und ein wenig rumprobiert, und mehr und mehr entwickelte sich das rumspielen zu dem gewuenschten Programm. Doch ich bin mir nicht sicher ob ich das Programm so richtig aufbaue(wie gesagt, noch nie wirklich GUI programmiert) und daher würde ich gerne von erfahrenen Leute ein wenig Feedback bekommen. Hier mal der Code, ich hoffe er ist verständlich, obwohl er eig aus Spielerei hervorging:

    #include<ncurses.h>
    
    using namespace std;
    
    // Funktionen um das obere Menue und die untere Infobar zu erstellen
    void print_menu(short choice);
    void print_info(short bar);
    
    // Funktionen um die Fenster zu erstellen, und in ihren Event-Loop zu gelangen
    void win_inbox();
    void win_outbox();
    void win_options();
    void win_msg_del();
    
    // Die Fenster
    WINDOW *mainwin;
    WINDOW *menu;
    WINDOW *info;
    WINDOW *msg_del;
    
    int main()
    {
            initscr();
            start_color();
    
            short row,col;
            getmaxyx(stdscr,row,col);
    
            //Fenster Posistion und Groesse mittels max-X und max-Y bestimmen
            mainwin=newwin(row-2,col,1,0);
            wrefresh(mainwin);
            menu=newwin(1,col,0,0);
            info=newwin(row,col,row-1,0);
            msg_del=newwin(6,30,row/2-5,col/2-20);
            box(msg_del,0,0);
    
            noecho();
            keypad(mainwin,true);
            curs_set(0);
    
            win_inbox(); //Kontrolle an win_inbox(das erste Fenster)
    
            endwin();
            return 0;
    }
    
    void win_inbox()
    {
            print_menu(0); //Menue fuer inbox erstellen
            print_info(0); //Infobar fuer inbox erstellen
    
            wclear(mainwin);
    
            //mit text fuellen
            for(short i=1; i<11; i++)
                    mvwprintw(mainwin,i,1,"<contact>\t<message>\t<time>");
    
            wrefresh(mainwin);
    
            //Event Loop fuer inbox
            int c=-1;
    
            while(c!=KEY_RIGHT && c!=113) // falls ein anderes Fenster ausgewaehlt wird oder "q" gedrueckt wird, beenden
            {
                    c=wgetch(mainwin);
                    switch(c)
                    {
                            case KEY_RIGHT:
                                    break;
                            case 107:
                            case KEY_UP:
                                    //up
                                    break;
                            case 106:
                            case KEY_DOWN:
                                    //down
                                    break;
                            case 113:
                                    //quit
                                    break;
                            //case KEY ...
            }
            //falls rechts gedrueckt wurde, zum naechsten fenster, sonst beenden
            if(c==KEY_RIGHT)
                    win_outbox();
    }
    
    void win_outbox()
    {
            //aehnlich wie win_inbox()
    }
    
    void win_options()
    {
            // aehnlich wie win_inbox()
    }
    
    void win_msg_del()
    {
            mvwprintw(msg_del,2,5,"Delete this Message?");
            mvwprintw(msg_del,4,5,"[y]es\t[n]o");
    
            wrefresh(msg_del);
    }
    
    void print_menu(short choice) //menue ausgeben und gegebenes element markieren
    {
            init_pair(1,COLOR_WHITE,COLOR_BLUE);
            init_pair(2,COLOR_YELLOW,COLOR_BLUE);
    
            if(choice==0)
            {
                    wattron(menu,COLOR_PAIR(2)|A_BOLD);
                    mvwprintw(menu,0,0,"  INBOX  ");
                    wattroff(menu,COLOR_PAIR(2)|A_BOLD);
    
                    wattron(menu,COLOR_PAIR(1));
                    mvwprintw(menu,0,10,"  OUTBOX  ");
                    wattroff(menu,COLOR_PAIR(1));
    
                    wattron(menu,COLOR_PAIR(1));
                    mvwprintw(menu,0,21,"  OPTIONS  ");
                    wattroff(menu,COLOR_PAIR(1));
            }
            else if(choice==1)
            //...
    
            wrefresh(menu);
    }       
    
    void print_info(short bar) //infobar fuer uebergebenes fenster erstellen
    {
            char *infos[4]={ "[a]nswer;   [d]elete;   [r]ead;   [f]orward;   [n]ew;   next [u]nread;   [q]uit;", 
                            "[r]ead;   [f]orward;   [d]elete;   [q]uit;",
                            "[s]ave;   [c]ancel;    [q]uit;" 
                            ""}; //inbox //outbox //options //leer
    
            wclear(info);
    
            mvwprintw(info,0,0,infos[bar]);
            wrefresh(info);
    }
    

    Ich weiß zb nicht ob es klug war, für jedes der Fenster(Inbox, Outbox und Options) einen eigenen Event-loop zu erstellen. Ob man das highlighten im oberen Menü noch leichter machen könnte, sei dahingestellt 😛

    Danke schonmal für eure Hilfe

    mfg peel


Log in to reply