Making our menu from scratch with ncurses

interrupts
key 3 years ago
parent e51885a007
commit 225871dba4

@ -1,5 +1,9 @@
#!/bin/bash
clear
rm menu
g++ main.cpp -o menu -lncurses
./menu

@ -1,58 +1,60 @@
#include <ncurses.h>
#include "menu.h"
#include "main.h"
#define ctrl(x) (x & 0x1F) // Detection of ctrl+x presses please do not forget that in unix ctrl+c and ctrl+z are special commands.
#include "terminal.h"
#include "menuBar.h"
// INFO: wgetch(win); or getch(); // getch will make a refresh for us.
int main(int argv, char ** argc)
{
//Variables
int xMax, yMax = 0;
int xMax, yMax, xMouse, yMouse= 0;
char pressed;
//Init Ncurses
initscr();
if(has_colors() == false) // If the terminal does have colors
{
printf("This menu is not supported by terminals without colors\n");
return -1;
}
start_color();
noecho();
curs_set(0); // Cursor won't show up
getmaxyx(stdscr, yMax, xMax);
// size y size x pos y pos x
WINDOW *win = newwin(yMax/2, xMax/2, yMax/4, xMax/4);
box(win,0,0);
//Setc colors
init_pair(1, COLOR_WHITE, COLOR_BLUE);
std::string menu1[4]={"New","Open","Save","Exit"};
std::string menu2[3]={"Copy","Cut","Paste"};
std::string menu3[5]={"Terminal","Help","Info","Update","Manual"};
// Second stage declarations
Menu menus[3]={ // init the menus
Menu("File", 'f', menu1, 4),
Menu("Edit", 'e', menu2, 3),
Menu("Options", 'o', menu3, 5),
Menu("File", 0, 0, 'f', menu1, 4),
Menu("Edit", 1, 0, 'e', menu2, 3),
Menu("Options", 2, 0, 'o', menu3, 5),
};
MenuBar menuBar = MenuBar(win, menus, 3); // init the menu bar
menuBar.draw();
Terminal terminal;
MenuBar menuBar = MenuBar(menus,1,5,5,3);
while(pressed = wgetch(win))
xMax = terminal.getXMax();
yMax = terminal.getYMax();
std::string termToPrint = "Terminal with ";
termToPrint += std::to_string(xMax);
termToPrint += "x";
termToPrint += std::to_string(yMax);
termToPrint += " is drawn";
terminal.draw(1,1,termToPrint);
terminal.draw(1,3,"Press f For Files e For Edit and o for Options");
terminal.draw(1,2,"Press K to kill the menu");
refresh();
menuBar.drawBox();
menuBar.drawMenus();
while(pressed != 'k')
{
pressed = menuBar.getKey();
menuBar.handleTrigger(pressed);
menuBar.draw();
menuBar.drawMenus();
}
menuBar.~MenuBar();
refresh();
endwin();
terminal.draw(1,2,"Press any key to exit the application");
terminal.getKey();
terminal.tearDown();
return 0;
}

@ -0,0 +1,4 @@
#include <ncurses.h>
#include <string>
#define ctrl(x) (x & 0x1F) // Detection of ctrl+x presses please do not forget that in unix ctrl+c and ctrl+z are special commands.

Binary file not shown.

@ -1,180 +1,174 @@
#include <curses.h>
#include <string>
#include "main.h"
#ifndef _MENU_H_
#define _MENU_H_
class Menu
{
public:
Menu(std::string name, char trigger, std::string *items, int itemCount);
void selectNextItem();
void selectPrevItem();
int startX, startY;
std::string name;
char trigger;
int selectedItem = 0; // alyas have the first one selected
std::string *items;
int itemCount=0;
Menu(std::string name, int menuNo, int direction, char trigger, std::string *items, int itemCount);
~Menu();
void draw();
void nextItem();
void prevItem();
int getSelectedItem();
void setSelectedItem();
void setPosX(int x);
void setPosY(int y);
int getPosX();
int getPosY();
void setMenuBarBegX(int x); // it must be indicated from menu bar so that we can print the box on the right place
void setMenuBarBegY(int y); // it must be indicated from menu bar so that we can print the box on the right place
void setMenuBarSizeX(int x); // it must be indicated from menu bar so that we can print the box on the right place
std::string getName();
int getNameLenght();
int getLongestItemLenght();
char getTrigger();
void drawBox();
void drawItems();
int getBoxBegY();
int getBoxBegX();
void eraseBox();
private:
WINDOW * menuItemsWin;
std::string name;
std::string *items;
int menuNo, currPos, direction= 0;
int posX, xSize, menuBarBegX = 0;
int posY, ySize, menuBarBegY = 0;
int menuBarSizeX = 0;
int selected_item = 0;
int itemCount = 0;
int itemLenght = 0;
char trigger;
};
Menu::Menu(std::string name, char trigger, std::string *items, int itemCount)
Menu::Menu(std::string name, int menuNo, int direction, char trigger, std::string *items, int itemCount)
{
this->name = name;
this->trigger = trigger;
this->items = items;
this->itemCount = itemCount;
this->name = name; //Name of the menu
this->menuNo = menuNo; //No of the menu so that we can index it with the menuBar.handdleTrigger option.
this->direction = direction; //Direction o the menu Bar Horizontal = 0, vertical = 1
this->trigger = trigger; //The trigger for the given menu
this->items = items; //Items present in thei menu
this->itemCount = itemCount; //Nouber of item present in this menu
//To be sure
xSize = 0;
ySize = 0;
selected_item = -1; // No menus are selected a the beggining
// Vertical Alignment
if(direction)
{
}
else // Horizontal Alignment -> The Deffault
{
}
}
void Menu::selectNextItem()
Menu::~Menu()
{
selectedItem ++;
if(selectedItem >= itemCount)
{
selectedItem = 0;
}
werase(menuItemsWin);
wrefresh(menuItemsWin);
}
void Menu::selectPrevItem()
void Menu::eraseBox()
{
selectedItem--;
if(selectedItem < 0)
{
selectedItem = itemCount-1;
}
werase(menuItemsWin);
wrefresh(menuItemsWin);
}
class MenuBar
{
public:
MenuBar(WINDOW * win, Menu * menus, int menuCnt);
void draw();
void handleTrigger(char trigger);
void reset();
void drawMenu(Menu menu, int currIndex);
void drawMenuItems(Menu menu);
WINDOW * win;
WINDOW * menuwin;
Menu * menus;
int menuCnt;
int i =0;
int selected_menu = 90;
int start_pos = 0;
std::string name;
};
void Menu::setPosX(int x)
{
this->posX = x;
}
void Menu::setPosY(int y)
{
this->posY = y;
}
MenuBar::MenuBar(WINDOW * win, Menu * menus, int menuCnt)
int Menu::getPosX()
{
this->win = win;
this->menus = menus;
this->menuCnt = menuCnt;
int currPos = 2;
return posX;
}
int Menu::getPosY()
{
return posY;
}
//Initialize the menu window
int xMax, yMax, xBeg, yBeg = 0;
getmaxyx(win, yMax, xMax);
getbegyx(win, yBeg, xBeg);
menuwin = newwin(yMax-2, xMax-2, yBeg+1, xBeg+1);
keypad(menuwin, true);
wrefresh(menuwin);
void Menu::setMenuBarBegX(int x)
{
this->menuBarBegX = x;
}
for(i = 0; i < menuCnt ; i ++)
{
this->menus[i].startX = currPos;
currPos += this->menus[i].name.length() + 1;
}
void Menu::setMenuBarBegY(int y)
{
this->menuBarBegY = y;
}
void MenuBar::draw()
void Menu::setMenuBarSizeX(int x)
{
for(i = 0; i < menuCnt ; i ++)
{
drawMenu(menus[i], i);
}
selected_menu = -1;
this->menuBarSizeX = x;
}
std::string Menu::getName()
{
return name;
}
void MenuBar::drawMenu(Menu menu,int currIndex)
int Menu::getNameLenght()
{
start_pos = menu.startX;
name = menu.name;
if(currIndex == selected_menu)
{
wattron(win, A_STANDOUT);
}
mvwprintw(win, 0, start_pos, name.c_str());
wattroff(win, A_STANDOUT);
wrefresh(win);
return name.length();
}
int ch = 0;
drawMenuItems(menu);
while(currIndex == selected_menu && (ch = wgetch(menuwin)))
{
switch(ch)
{
case KEY_UP:
menu.selectPrevItem();
break;
case KEY_DOWN:
menu.selectNextItem();
break;
default:
currIndex = -1;
break;
}
drawMenuItems(menu);
}
werase(menuwin);
wrefresh(menuwin);
reset();
int Menu::getLongestItemLenght()
{
return xSize;
}
void MenuBar::drawMenuItems(Menu menu)
char Menu::getTrigger()
{
int yMax, xMax;
getmaxyx(menuwin, yMax, xMax);
return trigger;
}
for(i=0; i < menu.itemCount ; i ++)
{
mvwprintw(menuwin,i,0,menu.items[i].c_str());
if(menu.selectedItem == i)
{
//if selected change to color pair 1
mvwchgat(menuwin,i,0,xMax,A_NORMAL,1, NULL);
}
else
{
// Not selected but we still want it to be reversed
mvwchgat(menuwin,i,0,xMax,A_STANDOUT,0, NULL);
}
int Menu::getBoxBegX()
{
// Vertical Alignment
if(direction)
{
}
else // Horizontal Alignment -> The Deffault
{
return menuBarSizeX+posX+menuBarBegX-1;
}
}
void MenuBar::reset()
int Menu::getBoxBegY()
{
for(i = 0; i < menuCnt ; i ++)
{
start_pos = this->menus[i].startX;
name = this->menus[i].name;
mvwprintw(win, 0, start_pos, name.c_str());
// Vertical Alignment
if(direction)
{
}
wrefresh(win);
else // Horizontal Alignment -> The Deffault
{
return posY+menuBarBegY-1;
}
}
void MenuBar::handleTrigger(char trigger)
void Menu::drawBox()
{
for(i = 0; i < menuCnt ; i ++)
{
if(trigger == this->menus[i].trigger)
{
selected_menu = i;
}
}
// Creates a box with caclulated dimention xSize & ySize and user given position
menuItemsWin = newwin(20, 20, getBoxBegY(), getBoxBegX());
box(menuItemsWin ,0,0); //Here we can define other cahr insterad of 0,0
mvwprintw(menuItemsWin,1,1,"PosY:%d PosX:%d",getBoxBegY(), getBoxBegX());
wrefresh(menuItemsWin); //Refresh so that we can see it
}
void Menu::drawItems()
{
}
#endif

@ -0,0 +1,174 @@
#include "main.h"
#include "menu.h"
#ifndef _MENU_BAR_H_
#define _MENU_BAR_H_
class MenuBar
{
public:
MenuBar(Menu *menus, int direction, int xBeg, int yBeg, int menuCount);
~MenuBar();
void drawBox();
void drawMenus();
void handleTrigger(char trig);
char getKey();
void reset();
int getPosX();
int getPosY();
int getSizeX();
int getSizeY();
private:
int i, xSize, ySize, xBeg, yBeg, menuCount, direction, currPos = 0;
int selected_menu = -1;
int prevSelected_menu = -1;
char currIndex;
Menu *menus;
WINDOW *menuBarWin;
};
MenuBar::MenuBar(Menu *menus, int direction, int xBeg, int yBeg, int menuCount)
{
this->menus = menus; // All the menu class
this->direction = direction; // Direction o the menu Bar Horizontal = 0, vertical = 1
this->xSize = xSize; // Size x of the menuBar box
this->ySize = ySize; // Size y of the menuBar box
this->xBeg = xBeg; // beginnin x Coordinate for the menuBar Box
this->yBeg = yBeg; // beginnin y Coordinate for the menuBar Box
this->menuCount = menuCount; // Total Menu class element count
// Jsut to be sure
xSize = 0;
ySize = 0;
selected_menu = -1; // No menus are selected a the beggining
// Vertical Alignment
if(direction)
{
currPos = 1; // So that it doesn write the first item on the top border
// Finding the longest word between the disponible menus
for(i = 0; i < menuCount ; i ++)
{
if(xSize < this->menus[i].getNameLenght())
{
xSize = this->menus[i].getNameLenght()+2; // +1 for left +1 lor right = +2
}
}
// Defining vertical separations
for(i = 0; i < menuCount ; i ++)
{
this->menus[i].setPosY(currPos);
this->menus[i].setPosX(1); // So tha it write in the middle
currPos ++;
this->menus[i].setMenuBarBegX(xBeg);
this->menus[i].setMenuBarBegY(yBeg);
this->menus[i].setMenuBarSizeX(xSize);
}
ySize = menuCount + 2;
}
else // Horizontal Alignment -> The Deffault
{
currPos = 1; // So that it doesn write the first item on the left border
for(i = 0; i < menuCount ; i ++) // Defining horizontal distances
{
this->menus[i].setPosX(currPos);
this->menus[i].setPosY(1); // So tha it write in the middle
currPos += this->menus[i].getNameLenght() + 1;
this->menus[i].setMenuBarBegX(xBeg);
this->menus[i].setMenuBarBegY(yBeg);
this->menus[i].setMenuBarSizeX(xSize);
}
xSize = currPos;
ySize = 3;
}
}
MenuBar::~MenuBar()
{
werase(menuBarWin);
wrefresh(menuBarWin);
}
void MenuBar::drawBox()
{
// Creates a box with caclulated dimention xSize & ySize and user given position
menuBarWin = newwin(ySize, xSize, yBeg, xBeg);
box(menuBarWin,0,0); //Here we can define other cahr insterad of 0,0
wrefresh(menuBarWin); //Refresh so that we can see it
}
// Draws menus and highlight the selected one selection in made on the handdleTrigger() Function
void MenuBar::drawMenus()
{
for(i = 0; i < menuCount ; i ++)
{
if(i == selected_menu) // If the iterration come to the selected menu than it will highlight it
{
prevSelected_menu = i;
wattron(menuBarWin, A_STANDOUT);
mvwprintw(menuBarWin, menus[i].getPosY(),menus[i].getPosX(), menus[i].getName().c_str());
wattroff(menuBarWin, A_STANDOUT);
menus[i].drawBox(); // Draws the lesefted Menus Items
}
else // Otherwise do not hightlight
{
mvwprintw(menuBarWin, menus[i].getPosY(),menus[i].getPosX(), menus[i].getName().c_str());
}
}
selected_menu = - 1; // Deselect for the next itteration. (unless handleTrigger has a new trigger)
wrefresh(menuBarWin); // so we can see it
}
// recieves a char an checks it fo ot corrensponds to a Menu Trigger
void MenuBar::handleTrigger(char trig)
{
for(i = 0; i < menuCount ; i ++)
{
if(trig == this->menus[i].getTrigger()) // If the recieved trigger matches the one from a menu
{
selected_menu = i;
}
}
}
char MenuBar::getKey()
{
return wgetch(menuBarWin);
}
// Will draw the menu as for the first time
void MenuBar::reset()
{
for(i = 0; i < menuCount ; i ++)
{
mvwprintw(menuBarWin, menus[i].getPosY(),menus[i].getPosX(), menus[i].getName().c_str());
}
selected_menu = - 1; // Deselect for the next itteration. (unless handleTrigger has a new trigger)
wrefresh(menuBarWin); // so we can see it
}
int MenuBar::getPosX()
{
return xBeg;
}
int MenuBar::getPosY()
{
return yBeg;
}
int MenuBar::getSizeX()
{
return xSize;
}
int MenuBar::getSizeY()
{
return ySize;
}
#endif

@ -0,0 +1,110 @@
#include "main.h"
#ifndef _TEMINAL_H_
#define _TEMINAL_H_
// This calls is used to initilaize ncurses terminal the correct way depending of the terminalk
class Terminal
{
public:
// Constuctor & Destructor
Terminal();
~Terminal();
//Functions
int setup();
void tearDown();
int getKey();
int getXMax();
int getYMax();
void startDraw();
void endDraw();
bool isDone();
void quit();
void draw(int x, int y, const std::string& toDraw);
private:
int xMax, yMax, mouseX, mouseY = 0;
bool m_done = false;
};
Terminal::Terminal()
{
setup();
}
Terminal::~Terminal()
{
tearDown();
}
int Terminal::setup()
{
initscr(); // Inits ncurses screen in memory
raw(); // raw input sor ctrl-c and ctrl-z wont work
noecho(); // don't show the user inputs
curs_set(0); // Cursor won't show up
getmaxyx(stdscr, yMax, xMax);
box(stdscr,0,0);
if(!has_colors()) // If the terminal doesn't have colors
{
tearDown(); // Destroys the mains window
printf("This menu is not supported by terminals without colors\n");
return -1; // Return an error.
}
getyx(stdscr, mouseY, mouseX);
start_color(); // Otherwise init colors
return 0;
}
void Terminal::tearDown()
{
endwin();
}
int Terminal::getKey()
{
return getch();
}
int Terminal::getXMax()
{
return xMax;
}
int Terminal::getYMax()
{
return yMax;
}
void Terminal::startDraw()
{
clear();
}
void Terminal::endDraw()
{
refresh();
}
bool Terminal::isDone()
{
return m_done;
}
void Terminal::quit()
{
m_done = true;
}
void Terminal::draw(int x, int y, const std::string& toDraw)
{
mvprintw(y,x,toDraw.c_str());
}
#endif

@ -0,0 +1,7 @@
#!/bin/bash
rm menu
g++ main.cpp -o menu -lncurses
./menu

@ -0,0 +1,58 @@
#include <ncurses.h>
#include "menu.h"
#define ctrl(x) (x & 0x1F) // Detection of ctrl+x presses please do not forget that in unix ctrl+c and ctrl+z are special commands.
// INFO: wgetch(win); or getch(); // getch will make a refresh for us.
int main(int argv, char ** argc)
{
//Variables
int xMax, yMax = 0;
char pressed;
j
//Init Ncurses
initscr();
if(has_colors() == false) // If the terminal does have colors
{
printf("This menu is not supported by terminals without colors\n");
return -1;
}
start_color();
noecho();
curs_set(0); // Cursor won't show up
getmaxyx(stdscr, yMax, xMax);
// size y size x pos y pos x
WINDOW *win = newwin(yMax/2, xMax/2, yMax/4, xMax/4);
box(win,0,0);
//Setc colors
init_pair(1, COLOR_WHITE, COLOR_BLUE);
std::string menu1[4]={"New","Open","Save","Exit"};
std::string menu2[3]={"Copy","Cut","Paste"};
std::string menu3[5]={"Terminal","Help","Info","Update","Manual"};
// Second stage declarations
Menu menus[3]={ // init the menus
Menu("File", 'f', menu1, 4),
Menu("Edit", 'e', menu2, 3),
Menu("Options", 'o', menu3, 5),
};
MenuBar menuBar = MenuBar(win, menus, 3); // init the menu bar
menuBar.draw();
while(pressed = wgetch(win))
{
menuBar.handleTrigger(pressed);
menuBar.draw();
}
endwin();
return 0;
}

@ -0,0 +1,180 @@
#include <curses.h>
#include <string>
#ifndef _MENU_H_
#define _MENU_H_
class Menu
{
public:
Menu(std::string name, char trigger, std::string *items, int itemCount);
void selectNextItem();
void selectPrevItem();
int startX, startY;
std::string name;
char trigger;
int selectedItem = 0; // alyas have the first one selected
std::string *items;
int itemCount=0;
};
Menu::Menu(std::string name, char trigger, std::string *items, int itemCount)
{
this->name = name;
this->trigger = trigger;
this->items = items;
this->itemCount = itemCount;
}
void Menu::selectNextItem()
{
selectedItem ++;
if(selectedItem >= itemCount)
{
selectedItem = 0;
}
}
void Menu::selectPrevItem()
{
selectedItem--;
if(selectedItem < 0)
{
selectedItem = itemCount-1;
}
}
class MenuBar
{
public:
MenuBar(WINDOW * win, Menu * menus, int menuCnt);
void draw();
void handleTrigger(char trigger);
void reset();
void drawMenu(Menu menu, int currIndex);
void drawMenuItems(Menu menu);
WINDOW * win;
WINDOW * menuwin;
Menu * menus;
int menuCnt;
int i =0;
int selected_menu = 90;
int start_pos = 0;
std::string name;
};
MenuBar::MenuBar(WINDOW * win, Menu * menus, int menuCnt)
{
this->win = win;
this->menus = menus;
this->menuCnt = menuCnt;
int currPos = 2;
//Initialize the menu window
int xMax, yMax, xBeg, yBeg = 0;
getmaxyx(win, yMax, xMax);
getbegyx(win, yBeg, xBeg);
menuwin = newwin(yMax-2, xMax-2, yBeg+1, xBeg+1);
keypad(menuwin, true);
wrefresh(menuwin);
for(i = 0; i < menuCnt ; i ++)
{
this->menus[i].startX = currPos;
currPos += this->menus[i].name.length() + 1;
}
}
void MenuBar::draw()
{
for(i = 0; i < menuCnt ; i ++)
{
drawMenu(menus[i], i);
}
selected_menu = -1;
}
void MenuBar::drawMenu(Menu menu,int currIndex)
{
start_pos = menu.startX;
name = menu.name;
if(currIndex == selected_menu)
{
wattron(win, A_STANDOUT);
}
mvwprintw(win, 0, start_pos, name.c_str());
wattroff(win, A_STANDOUT);
wrefresh(win);
int ch = 0;
drawMenuItems(menu);
while(currIndex == selected_menu && (ch = wgetch(menuwin)))
{
switch(ch)
{
case KEY_UP:
menu.selectPrevItem();
break;
case KEY_DOWN:
menu.selectNextItem();
break;
default:
currIndex = -1;
break;
}
drawMenuItems(menu);
}
werase(menuwin);
wrefresh(menuwin);
reset();
}
void MenuBar::drawMenuItems(Menu menu)
{
int yMax, xMax;
getmaxyx(menuwin, yMax, xMax);
for(i=0; i < menu.itemCount ; i ++)
{
mvwprintw(menuwin,i,0,menu.items[i].c_str());
if(menu.selectedItem == i)
{
//if selected change to color pair 1
mvwchgat(menuwin,i,0,xMax,A_NORMAL,1, NULL);
}
else
{
// Not selected but we still want it to be reversed
mvwchgat(menuwin,i,0,xMax,A_STANDOUT,0, NULL);
}
}
}
void MenuBar::reset()
{
for(i = 0; i < menuCnt ; i ++)
{
start_pos = this->menus[i].startX;
name = this->menus[i].name;
mvwprintw(win, 0, start_pos, name.c_str());
}
wrefresh(win);
}
void MenuBar::handleTrigger(char trigger)
{
for(i = 0; i < menuCnt ; i ++)
{
if(trigger == this->menus[i].trigger)
{
selected_menu = i;
}
}
}
#endif

@ -0,0 +1,7 @@
#!/bin/bash
rm ./menu
gcc main.c -o menu -lncurses
./menu

@ -0,0 +1,108 @@
#include <ncurses.h>
#include <string.h>
#include <menu.h>
#include <stdlib.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, NULL);
while(1)
{ c = wgetch(menu_win);
switch(c)
{ case KEY_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;
}
}
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;
}
}

Binary file not shown.

@ -0,0 +1,102 @@
#ifndef _PLAYER_H_
#define _PLAYER_H_
class Player
{
public:
Player(WINDOW* win, int y, int x, char c);
void mvUp();
void mvDown();
void mvLeft();
void mvRight();
int getMv();
void display();
private:
int xLoc, yLoc, xMax, yMax;
char playerChar;
WINDOW * curWin;
};
Player::Player(WINDOW* win, int y, int x, char c)
{
curWin = win;
xLoc = x;
yLoc = y;
getmaxyx(curWin, yMax, xMax);
keypad(curWin, true);
playerChar = c;
}
void Player::mvUp()
{
mvwaddch(curWin,yLoc, xLoc, '.');
yLoc --;
if(yLoc < 1)
{
yLoc = 1;
}
}
void Player::mvDown()
{
mvwaddch(curWin,yLoc, xLoc, '.');
yLoc ++;
if(yLoc > yMax-2)
{
yLoc = yMax-2;
}
}
void Player::mvLeft()
{
mvwaddch(curWin,yLoc, xLoc, '.');
xLoc --;
if(xLoc < 1)
{
xLoc = 1;
}
}
void Player::mvRight()
{
mvwaddch(curWin,yLoc, xLoc, '.');
xLoc ++;
if(xLoc > xMax-2)
{
xLoc = xMax-2;
}
}
int Player::getMv()
{
int choice = wgetch(curWin);
switch(choice)
{
case KEY_UP:
mvUp();
break;
case KEY_DOWN:
mvDown();
break;
case KEY_LEFT:
mvLeft();
break;
case KEY_RIGHT:
mvRight();
break;
default:
break;
}
return choice;
}
void Player::display()
{
mvwaddch(curWin,yLoc, xLoc, playerChar);
}
#endif
Loading…
Cancel
Save