diff --git a/ked/ncurses/compile_run.sh b/ked/ncurses/compile_run.sh index eb5da6e..5245972 100755 --- a/ked/ncurses/compile_run.sh +++ b/ked/ncurses/compile_run.sh @@ -1,5 +1,9 @@ #!/bin/bash +clear + +rm menu + g++ main.cpp -o menu -lncurses ./menu diff --git a/ked/ncurses/main.cpp b/ked/ncurses/main.cpp index a91830f..902cd1b 100644 --- a/ked/ncurses/main.cpp +++ b/ked/ncurses/main.cpp @@ -1,58 +1,60 @@ -#include -#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; } diff --git a/ked/ncurses/main.h b/ked/ncurses/main.h new file mode 100644 index 0000000..da83032 --- /dev/null +++ b/ked/ncurses/main.h @@ -0,0 +1,4 @@ +#include +#include + +#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. diff --git a/ked/ncurses/menu b/ked/ncurses/menu index 742aeb6..eb095fb 100755 Binary files a/ked/ncurses/menu and b/ked/ncurses/menu differ diff --git a/ked/ncurses/menu.h b/ked/ncurses/menu.h index 95a7ff4..ca9af38 100644 --- a/ked/ncurses/menu.h +++ b/ked/ncurses/menu.h @@ -1,180 +1,174 @@ -#include -#include - +#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 diff --git a/ked/ncurses/menuBar.h b/ked/ncurses/menuBar.h new file mode 100644 index 0000000..449c1dc --- /dev/null +++ b/ked/ncurses/menuBar.h @@ -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 diff --git a/ked/ncurses/terminal.h b/ked/ncurses/terminal.h new file mode 100644 index 0000000..66caa33 --- /dev/null +++ b/ked/ncurses/terminal.h @@ -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 diff --git a/ked/ncurses/basics/compile_run.sh b/ked/ncurses/training/basics/compile_run.sh similarity index 100% rename from ked/ncurses/basics/compile_run.sh rename to ked/ncurses/training/basics/compile_run.sh diff --git a/ked/ncurses/basics/main.c b/ked/ncurses/training/basics/main.c similarity index 100% rename from ked/ncurses/basics/main.c rename to ked/ncurses/training/basics/main.c diff --git a/ked/ncurses/ctrl_and_sprecial_var/compile_run.sh b/ked/ncurses/training/ctrl_and_sprecial_var/compile_run.sh similarity index 100% rename from ked/ncurses/ctrl_and_sprecial_var/compile_run.sh rename to ked/ncurses/training/ctrl_and_sprecial_var/compile_run.sh diff --git a/ked/ncurses/ctrl_and_sprecial_var/main.cpp b/ked/ncurses/training/ctrl_and_sprecial_var/main.cpp similarity index 100% rename from ked/ncurses/ctrl_and_sprecial_var/main.cpp rename to ked/ncurses/training/ctrl_and_sprecial_var/main.cpp diff --git a/ked/ncurses/ctrl_and_sprecial_var/menu b/ked/ncurses/training/ctrl_and_sprecial_var/menu similarity index 100% rename from ked/ncurses/ctrl_and_sprecial_var/menu rename to ked/ncurses/training/ctrl_and_sprecial_var/menu diff --git a/ked/ncurses/training/first_menu/compile_run.sh b/ked/ncurses/training/first_menu/compile_run.sh new file mode 100755 index 0000000..363db51 --- /dev/null +++ b/ked/ncurses/training/first_menu/compile_run.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +rm menu + +g++ main.cpp -o menu -lncurses + +./menu diff --git a/ked/ncurses/training/first_menu/main.cpp b/ked/ncurses/training/first_menu/main.cpp new file mode 100644 index 0000000..e9c876d --- /dev/null +++ b/ked/ncurses/training/first_menu/main.cpp @@ -0,0 +1,58 @@ +#include +#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; +} diff --git a/ked/ncurses/training/first_menu/menu.h b/ked/ncurses/training/first_menu/menu.h new file mode 100644 index 0000000..95a7ff4 --- /dev/null +++ b/ked/ncurses/training/first_menu/menu.h @@ -0,0 +1,180 @@ +#include +#include + +#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 diff --git a/ked/ncurses/game/compile_run.sh b/ked/ncurses/training/game/compile_run.sh similarity index 100% rename from ked/ncurses/game/compile_run.sh rename to ked/ncurses/training/game/compile_run.sh diff --git a/ked/ncurses/game/main.cpp b/ked/ncurses/training/game/main.cpp similarity index 100% rename from ked/ncurses/game/main.cpp rename to ked/ncurses/training/game/main.cpp diff --git a/ked/ncurses/game/player.hpp b/ked/ncurses/training/game/player.hpp similarity index 100% rename from ked/ncurses/game/player.hpp rename to ked/ncurses/training/game/player.hpp diff --git a/ked/ncurses/training/menuEx/compile_run.sh b/ked/ncurses/training/menuEx/compile_run.sh new file mode 100755 index 0000000..e1e0892 --- /dev/null +++ b/ked/ncurses/training/menuEx/compile_run.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +rm ./menu + +gcc main.c -o menu -lncurses + +./menu diff --git a/ked/ncurses/training/menuEx/main.c b/ked/ncurses/training/menuEx/main.c new file mode 100644 index 0000000..e06985e --- /dev/null +++ b/ked/ncurses/training/menuEx/main.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#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; + } +} diff --git a/ked/ncurses/training/menuEx/menu b/ked/ncurses/training/menuEx/menu new file mode 100755 index 0000000..05b4741 Binary files /dev/null and b/ked/ncurses/training/menuEx/menu differ diff --git a/ked/ncurses/training/menuEx/player.hpp b/ked/ncurses/training/menuEx/player.hpp new file mode 100644 index 0000000..68c34c9 --- /dev/null +++ b/ked/ncurses/training/menuEx/player.hpp @@ -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